![Sandy Walsh](/assets/img/avatar_default.png)
Docs changed too to reflect better count support (--count). Removed v2 api implementation example (Archive resource). We can always revisit once we nail down how archive retrieval will work. Change-Id: I79d1929a14fe51d36ecc5c54707902d5e772ad89
239 lines
9.7 KiB
Python
239 lines
9.7 KiB
Python
# Copyright (c) 2014 Dark Secret Software Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
|
|
import argparse
|
|
import prettytable
|
|
import sys
|
|
|
|
import base
|
|
|
|
|
|
class Streams(object):
|
|
def __init__(self, url, subparser=None):
|
|
self.url = url
|
|
if subparser:
|
|
parser = subparser.add_parser('streams')
|
|
parser.add_argument('--name', metavar='trigger_name',
|
|
help='Return streams of type trigger_name.')
|
|
parser.add_argument('--from', metavar='datetime', dest='_from',
|
|
help='Return streams last updated after datetime')
|
|
parser.add_argument('--to', metavar='datetime',
|
|
help='Return streams last updated before datetime')
|
|
parser.add_argument('--traits', metavar='trait_list',
|
|
help='Return streams with specific distinguishing traits.')
|
|
parser.add_argument('--details', action='store_true',
|
|
default=False, help='Return full event details.')
|
|
parser.add_argument('--state', choices=['active', 'firing',
|
|
'expiring', 'error', 'expire_error', 'completed',
|
|
'retry_fire', 'retry_expire'],
|
|
help='Only return streams in this state.')
|
|
|
|
group = parser.add_mutually_exclusive_group()
|
|
group.add_argument('--count', action='store_true',
|
|
default=False,
|
|
help='Return a count of streams matching filter criteria.')
|
|
group.add_argument('--id', metavar='stream_id', dest='stream_id',
|
|
help='Return a single specific stream by id.')
|
|
|
|
def get_streams_count(self, from_datetime=None, to_datetime=None,
|
|
traits=None, state=None, name=None, debug=False):
|
|
if traits:
|
|
traits = ",".join(["%s:%s" % item for item in traits.items()])
|
|
cmd = "streams/count"
|
|
params = base.remove_empty({'older_than': from_datetime,
|
|
'younger_than': to_datetime,
|
|
'name': name,
|
|
'state': state,
|
|
'distinguishing_traits': traits})
|
|
|
|
return base.get(self.url, cmd, params, debug=debug)
|
|
|
|
def get_streams(self, from_datetime=None, to_datetime=None,
|
|
traits=None, name=None, stream_id=None, debug=False,
|
|
state=None, details=None):
|
|
if stream_id:
|
|
params = base.remove_empty({'details': details})
|
|
return base.get(self.url, "streams/%s" % stream_id, params,
|
|
debug=debug)
|
|
|
|
if traits:
|
|
traits = ",".join(["%s:%s" % item for item in traits.items()])
|
|
cmd = "streams"
|
|
params = base.remove_empty({'older_than': from_datetime,
|
|
'younger_than': to_datetime,
|
|
'name': name,
|
|
'details': details,
|
|
'state': state,
|
|
'distinguishing_traits': traits})
|
|
|
|
return base.get(self.url, cmd, params, debug=debug)
|
|
|
|
def _cmdline(self, arguments):
|
|
_from = arguments._from
|
|
_to = arguments.to
|
|
_name = arguments.name
|
|
_traits = arguments.traits
|
|
_debug = arguments.debug
|
|
_state = arguments.state
|
|
_details = arguments.details
|
|
|
|
trait_dict = None
|
|
if _traits:
|
|
trait_pairs = _traits.split(',')
|
|
trait_dict = dict([tuple(item.split(':')) for item in trait_pairs])
|
|
|
|
if arguments.count:
|
|
rows = self.get_streams_count(from_datetime=_from, to_datetime=_to,
|
|
name=_name, traits=trait_dict,
|
|
state=_state, debug=_debug)
|
|
print rows
|
|
keys = ['count']
|
|
base.dump_response(keys, rows)
|
|
return
|
|
|
|
_stream_id = arguments.stream_id
|
|
rows = self.get_streams(from_datetime=_from, to_datetime=_to,
|
|
name=_name, traits=trait_dict,
|
|
details=_details, state=_state,
|
|
stream_id=_stream_id, debug=_debug)
|
|
|
|
keys = ['id', 'state', 'name', 'first_event', 'last_event',
|
|
'fire_timestamp', 'expire_timestamp']
|
|
for row in rows:
|
|
x = prettytable.PrettyTable(["Section", "Property", "Value"])
|
|
for key in keys:
|
|
x.add_row(["Stream", key, row.get(key)])
|
|
|
|
if 'distinguishing_traits' in row.keys():
|
|
for key, value in row['distinguishing_traits'].items():
|
|
x.add_row(["D.Trait", key, value])
|
|
|
|
print x
|
|
|
|
if 'events' in row.keys():
|
|
# This has detail rows ... handle those separately.
|
|
print "Events:"
|
|
for event in row['events']:
|
|
x = prettytable.PrettyTable(["Property", "Value"])
|
|
sorted_keys = sorted(event.keys())
|
|
for key in sorted_keys:
|
|
x.add_row([key, event[key]])
|
|
print x
|
|
|
|
|
|
class Events(object):
|
|
def __init__(self, url, subparser=None):
|
|
self.url = url
|
|
if subparser:
|
|
parser = subparser.add_parser('events')
|
|
parser.add_argument('--name', metavar='event_name',
|
|
help='Return events of type event_name.')
|
|
parser.add_argument('--from', metavar='datetime', dest='_from',
|
|
help='Return events generated before datetime')
|
|
parser.add_argument('--to', metavar='datetime',
|
|
help='Return events generated after datetime')
|
|
parser.add_argument('--traits', metavar='trait_list',
|
|
help='Return events with specific traits.')
|
|
|
|
group = parser.add_mutually_exclusive_group()
|
|
group.add_argument('--count', action='store_true',
|
|
default=False,
|
|
help='Return a count of events matching filter criteria.')
|
|
group.add_argument('--msg_id', metavar='message_id',
|
|
help='Return a single specific event by message id.')
|
|
|
|
|
|
def get_events_count(self, from_datetime=None, to_datetime=None,
|
|
traits=None, name=None, debug=False):
|
|
if traits:
|
|
traits = ",".join(["%s:%s" % item for item in traits.items()])
|
|
cmd = "events/count"
|
|
params = base.remove_empty({'from_datetime': from_datetime,
|
|
'to_datetime': to_datetime,
|
|
'event_name': name,
|
|
'traits': traits})
|
|
|
|
return base.get(self.url, cmd, params, debug=debug)
|
|
|
|
def get_events(self, from_datetime=None, to_datetime=None,
|
|
traits=None, name=None, msg_id=None, debug=False):
|
|
if msg_id:
|
|
return base.get(self.url, "events/%s" % msg_id, {}, debug=debug)
|
|
|
|
if traits:
|
|
traits = ",".join(["%s:%s" % item for item in traits.items()])
|
|
cmd = "events"
|
|
params = base.remove_empty({'from_datetime': from_datetime,
|
|
'to_datetime': to_datetime,
|
|
'event_name': name,
|
|
'traits': traits})
|
|
|
|
return base.get(self.url, cmd, params, debug=debug)
|
|
|
|
def _cmdline(self, arguments):
|
|
_from = arguments._from
|
|
_to = arguments.to
|
|
_name = arguments.name
|
|
_traits = arguments.traits
|
|
_debug = arguments.debug
|
|
|
|
trait_dict = None
|
|
if _traits:
|
|
trait_pairs = _traits.split(',')
|
|
trait_dict = dict([tuple(item.split(':')) for item in trait_pairs])
|
|
|
|
if arguments.count:
|
|
rows = self.get_events_count(from_datetime=_from, to_datetime=_to,
|
|
name=_name, traits=trait_dict,
|
|
debug=_debug)
|
|
keys = ['count']
|
|
base.dump_response(keys, rows)
|
|
return
|
|
|
|
_msg_id = arguments.msg_id
|
|
rows = self.get_events(from_datetime=_from, to_datetime=_to,
|
|
name=_name, traits=trait_dict,
|
|
msg_id=_msg_id, debug=_debug)
|
|
|
|
if isinstance(rows, dict):
|
|
rows = [rows]
|
|
keys = set()
|
|
for row in rows:
|
|
keys.update(row.keys())
|
|
keys = sorted(list(keys))
|
|
base.dump_response(keys, rows)
|
|
|
|
|
|
class V1(object):
|
|
def __init__(self, url, parser):
|
|
subparser = parser.add_subparsers(dest='command',
|
|
help="V1 API commands")
|
|
self.resources = {'events': Events(url, subparser),
|
|
'streams': Streams(url, subparser)}
|
|
|
|
def dispatch(self, arguments):
|
|
# We could let argparse dispatch automatically, but I
|
|
# want to make this work as a library as well as a
|
|
# cmdline tool, so it goes to an object vs. a function.
|
|
cmd = arguments.command
|
|
|
|
# This shouldn't be needed, but I'm being paranoid.
|
|
if cmd not in self.resources:
|
|
print "Unknown command: '%s'" % cmd
|
|
return
|
|
|
|
self.resources[cmd]._cmdline(arguments)
|