def __init__(self, *args, **kw): kw['required_fields'] = { 'uuid': Unicode(), 'tag': Tag(), 'name': Unicode(), 'description': Unicode(), 'endpoints': List(item_type=EndpointType()), } super(ChannelType, self).__init__(*args, **kw)
def __init__(self, *args, **kw): kw['required_fields'] = { 'uuid': Unicode(), 'type': Unicode(), 'name': Unicode(), 'description': Unicode(), 'channel_endpoints': List(item_type=EndpointType()), 'conversation_endpoints': List(item_type=EndpointType()), } super(RouterType, self).__init__(*args, **kw)
def __init__(self, *args, **kw): uuid_dict = Dict(required_fields={'uuid': Unicode()}) kw['required_fields'] = { 'source': uuid_dict, 'target': uuid_dict, } super(RoutingEntryType, self).__init__(*args, **kw)
def test_check_params(self): s = Signature(lambda slf, x, y: x, x=Int(), y=Unicode()) s.check_params([None, 1, u"a"], {}) self.assertRaises(RpcCheckError, s.check_params, [None, u"a", u"a"], {}) self.assertRaises(RpcCheckError, s.check_params, [None, 1, 2], {}) self.assertRaises(RpcCheckError, s.check_params, [None, 1, u"a", 3], {})
class DummyApi(object): def __init__(self, result=None): self.result = result @signature(a=Unicode(), b=Int()) def test(self, a, b): """Basic doc.""" return self.result
def test_optional_fields(self): d = Dict(optional_fields={'foo': Int(null=True), 'bar': Unicode()}) d.check("name", {'foo': None, 'bar': u'b'}) d.check("name", {'foo': 1, 'bar': u'b'}) d.check("name", {'foo': 1, 'bar': u'b', 'extra': 2}) d.check("name", {"foo": 1}) d.check("name", {"bar": u"b"}) self.assertRaises(RpcCheckError, d.check, "name", {"foo": u'b'})
def test_fallback_to_item_type(self): d = Dict(required_fields={'foo': Int()}, optional_fields={'bar': Int()}, item_type=Unicode()) d.check("name", {'foo': 1}) d.check("name", {'foo': 1, 'bar': 2}) d.check("name", {'foo': 1, 'bar': 2, 'extra': u'foo'}) self.assertRaises(RpcCheckError, d.check, "name", { 'foo': 1, 'bar': 2, 'extra': 3 })
def __init__(self, *args, **kw): """Description of a conversation. The following fields are required: * uuid: The conversation key. * type: The conversation type, e.g. 'bulk-message'. * name: The conversation name, e.g. 'My Bulk Sender'. * description: The conversation description, e.g. 'Some Bulk Message App'. * endpoints: A list of `EndpointType` dictionaries, e.g. `[{uuid: 'endpoint-uuid-4', name: 'default'}]`. """ kw['required_fields'] = { 'uuid': Unicode(), 'type': Unicode(), 'name': Unicode(), 'description': Unicode(), 'endpoints': List(item_type=EndpointType()), } super(ConversationType, self).__init__(*args, **kw)
def mk_jsonrpc_handler(name, handler, type_name): sig = signature( **{ "campaign_key": Unicode("Campaign key."), ("%s_key" % type_name): Unicode("%s key." % type_name.title()), "params": Dict("Additional action paramaters.", null=True), "returns": Dict("Result of the action.", null=True), }) jsonrpc_name = "jsonrpc_%s" % (name, ) # we use compile and exec to get exactly the signature we need code = compile(("def %s(self, campaign_key, %s_key, params=None):" " return self.dispatch_action(" " handler, campaign_key, %s_key, params)") % (jsonrpc_name, type_name, type_name), "<mk_jsonrpc_handler>", "exec") locs = {"handler": handler} exec(code, locs) jsonrpc_handler = sig(locs[jsonrpc_name]) return jsonrpc_handler
def test_jsonrpc_signature(self): s = Signature(lambda slf, x: unicode(x), x=Int("foo"), returns=Unicode("bar")) self.assertEqual(s.jsonrpc_signature(), [['string', 'int']])
def test_check_params_with_defaults(self): s = Signature(lambda slf, x, y=u"default": x, x=Int(), y=Unicode()) s.check_params([None, 1, u"a"], {}) s.check_params([None, 1], {})
x=Int("foo"), returns=Unicode("bar")) self.assertEqual(s.jsonrpc_signature(), [['string', 'int']]) class DummyApi(object): def __init__(self, result=None): self.result = result @signature(a=Unicode(), b=Int()) def test(self, a, b): """Basic doc.""" return self.result @signature(a=Unicode(), b=Int(), returns=Unicode(), requires_self=False) def dummy_function(a, b): return unicode(a * b) class TestSignatureDecorate(VumiTestCase): def test_decorate_unbound_method(self): api = DummyApi() self.assertEqual(api.test.signature, [['null', 'string', 'int']]) self.assertTrue(isinstance(api.test.signature_object, Signature)) self.assertEqual(api.test.__name__, 'test') self.assertEqual(api.test.__module__, 'vumi.tests.test_rpc') self.assertEqual( api.test.__doc__, 'Basic doc.\n\n:param Unicode a:\n:param Int b:\n:rtype Null:')
class GoApiServer(JSONRPC, GoApiSubHandler): def __init__(self, user_account_key, vumi_api): JSONRPC.__init__(self) GoApiSubHandler.__init__(self, user_account_key, vumi_api) self.putSubHandler('conversation', ConversationSubhandler(user_account_key, vumi_api)) self.putSubHandler('router', RouterSubhandler(user_account_key, vumi_api)) def _conversations(self, user_api): def format_conversations(convs): return [ConversationType.format_conversation(c) for c in convs] d = user_api.active_conversations() d.addCallback(format_conversations) return d def _channels(self, user_api): def format_channels(channels): return [ChannelType.format_channel(ch) for ch in channels] d = user_api.active_channels() d.addCallback(format_channels) return d def _routers(self, user_api): def format_routers(routers): return [RouterType.format_router(rb) for rb in routers] d = user_api.active_routers() d.addCallback(format_routers) return d def _routing_entries(self, user_api): def format_routing_entries(routing_table): return [ RoutingEntryType.format_entry((src_conn, src_endp), (dst_conn, dst_endp)) for src_conn, src_endp, dst_conn, dst_endp in routing_table.entries() ] d = user_api.get_routing_table() d.addCallback(format_routing_entries) return d @signature(returns=List("List of campaigns.", item_type=CampaignType())) def jsonrpc_campaigns(self): """List the campaigns a user has access to.""" return [CampaignType.format_campaign({ 'key': self.user_account_key, 'name': u"Your Campaign", })] @signature(campaign_key=Unicode("Campaign key."), returns=List("List of conversations.", item_type=ConversationType())) def jsonrpc_conversations(self, campaign_key): """List the active conversations under a particular campaign. """ user_api = self.get_user_api(campaign_key) return self._conversations(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=List("List of channels.", item_type=ChannelType())) def jsonrpc_channels(self, campaign_key): """List the active channels under a particular campaign. """ user_api = self.get_user_api(campaign_key) return self._channels(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=List("List of routers.", item_type=RouterType())) def jsonrpc_routers(self, campaign_key): """List the active routers under a particular campaign. """ user_api = self.get_user_api(campaign_key) return self._routers(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=List("List of routing table entries.", item_type=RoutingEntryType())) def jsonrpc_routing_entries(self, campaign_key): """List the routing entries from a particular campaign's routing table. """ user_api = self.get_user_api(campaign_key) return self._routing_entries(user_api) @signature(campaign_key=Unicode("Campaign key."), returns=RoutingType( "Complete description of the routing table.")) def jsonrpc_routing_table(self, campaign_key): """List the channels, conversations, routers and routing table entries that make up a campaign's routing. """ user_api = self.get_user_api(campaign_key) deferreds = [] deferreds.append(self._channels(user_api)) deferreds.append(self._routers(user_api)) deferreds.append(self._conversations(user_api)) deferreds.append(self._routing_entries(user_api)) def construct_json(results): for success, result in results: if not success: result.raiseException() results = [r[1] for r in results] channels, routers, conversations, routing_entries = results return RoutingType.format_routing( channels, routers, conversations, routing_entries) d = DeferredList(deferreds, consumeErrors=True) d.addCallback(construct_json) return d @signature(campaign_key=Unicode("Campaign key."), routing=RoutingType("Description of the new routing table.")) def jsonrpc_update_routing_table(self, campaign_key, routing): user_api = self.get_user_api(campaign_key) deferreds = [] deferreds.append(self._channels(user_api)) deferreds.append(self._routers(user_api)) deferreds.append(self._conversations(user_api)) def gather_endpoints(results): for success, result in results: if not success: result.raiseException() results = [r[1] for r in results] channels, routers, conversations = results recv_outbound_endpoints = set( endpoint['uuid'] for endpoint in itertools.chain( (e for c in channels for e in c['endpoints']), (e for r in routers for e in r['conversation_endpoints']), ) ) recv_inbound_endpoints = set( endpoint['uuid'] for endpoint in itertools.chain( (e for c in conversations for e in c['endpoints']), (e for r in routers for e in r['channel_endpoints']) ) ) return recv_outbound_endpoints, recv_inbound_endpoints def check_routing_table(endpoint_sets): """Check that endpoints link from known receives-outbound (right) endpoints to known receives-inbound (left) endpoints or vice versa. """ recv_outbound_endpoints, recv_inbound_endpoints = endpoint_sets routing_entries = routing['routing_entries'] for entry in routing_entries: source, target = entry['source'], entry['target'] src_uuid, dst_uuid = source['uuid'], target['uuid'] if src_uuid in recv_outbound_endpoints: if dst_uuid not in recv_inbound_endpoints: raise InvalidRoutingTable( "Source outbound-receiving endpoint %r should" " link to an inbound-receiving endpoint but links" " to %r" % (source, target)) elif src_uuid in recv_inbound_endpoints: if dst_uuid not in recv_outbound_endpoints: raise InvalidRoutingTable( "Source inbound-receiving endpoint %r should" " link to an outbound-receiving endpoint but links" " to %r" % (source, target)) else: raise InvalidRoutingTable("Unknown source endpoint %r" % (source,)) return routing_entries def populate_routing_table(routing_entries): routing_table = RoutingTable() for entry in routing_entries: source, target = entry['source'], entry['target'] src_conn, src_endp = EndpointType.parse_uuid( source['uuid']) dst_conn, dst_endp = EndpointType.parse_uuid( target['uuid']) routing_table.add_entry(src_conn, src_endp, dst_conn, dst_endp) d = user_api.get_user_account() d.addCallback(save_routing_table, routing_table) return d def save_routing_table(user_account, routing_table): user_account.routing_table = routing_table return user_account.save() def swallow_result(result): return None d = DeferredList(deferreds, consumeErrors=True) d.addCallback(gather_endpoints) d.addCallback(check_routing_table) d.addCallback(populate_routing_table) d.addCallback(swallow_result) return d
def __init__(self, *args, **kw): kw['required_fields'] = { 'key': Unicode(), 'name': Unicode(), } super(CampaignType, self).__init__(*args, **kw)
def __init__(self, *args, **kw): kw['required_fields'] = { 'uuid': Unicode(), 'name': Unicode(), } super(EndpointType, self).__init__(*args, **kw)
def test_check(self): u = Unicode() u.check("name", u"foo") self.assertRaises(RpcCheckError, u.check, "name", "foo") self.assertRaises(RpcCheckError, u.check, "name", 1)
class TagpoolApiServer(JSONRPC): def __init__(self, tagpool): JSONRPC.__init__(self) self.tagpool = tagpool @signature(pool=Unicode("Name of pool to acquire tag from."), owner=Unicode("Owner acquiring tag (or None).", null=True), reason=Dict("Metadata on why tag is being acquired (or None).", null=True), returns=Tag("Tag acquired (or None).", null=True)) def jsonrpc_acquire_tag(self, pool, owner=None, reason=None): """Acquire a tag from the pool (returns None if no tags are avaliable). """ d = self.tagpool.acquire_tag(pool, owner, reason) return d @signature(tag=Tag("Tag to acquire as [pool, tagname] pair."), owner=Unicode("Owner acquiring tag (or None).", null=True), reason=Dict("Metadata on why tag is being acquired (or None).", null=True), returns=Tag("Tag acquired (or None).", null=True)) def jsonrpc_acquire_specific_tag(self, tag, owner=None, reason=None): """Acquire the specific tag (returns None if the tag is unavailable). """ d = self.tagpool.acquire_specific_tag(tag, owner, reason) return d @signature(tag=Tag("Tag to release.")) def jsonrpc_release_tag(self, tag): """Release the specified tag if it exists and is inuse.""" return self.tagpool.release_tag(tag) @signature(tags=List("List of tags to declare.", item_type=Tag())) def jsonrpc_declare_tags(self, tags): """Declare all of the listed tags.""" return self.tagpool.declare_tags(tags) @signature(pool=Unicode("Name of pool to retreive metadata for."), returns=Dict("Retrieved metadata.")) def jsonrpc_get_metadata(self, pool): """Retrieve the metadata for the given pool.""" return self.tagpool.get_metadata(pool) @signature(pool=Unicode("Name of pool to update metadata for."), metadata=Dict("New value of metadata.")) def jsonrpc_set_metadata(self, pool, metadata): """Set the metadata for the given pool.""" return self.tagpool.set_metadata(pool, metadata) @signature(pool=Unicode("Name of the pool to purge.")) def jsonrpc_purge_pool(self, pool): """Delete the given pool and all associated metadata and tags. No tags from the pool may be inuse. """ return self.tagpool.purge_pool(pool) @signature(returns=List("List of pool names.", item_type=Unicode())) def jsonrpc_list_pools(self): """Return a list of all available pools.""" d = self.tagpool.list_pools() d.addCallback(list) return d @signature(pool=Unicode("Name of pool."), returns=List("List of free tags.", item_type=Tag())) def jsonrpc_free_tags(self, pool): """Return a list of free tags in the given pool.""" d = self.tagpool.free_tags(pool) return d @signature(pool=Unicode("Name of pool."), returns=List("List of tags inuse.", item_type=Tag())) def jsonrpc_inuse_tags(self, pool): """Return a list of tags currently in use within the given pool.""" d = self.tagpool.inuse_tags(pool) return d @signature(tag=Tag("Tag to return ownership information on."), returns=List("List of owner and reason.", length=2, null=True)) def jsonrpc_acquired_by(self, tag): """Returns the owner of an acquired tag and why is was acquired.""" d = self.tagpool.acquired_by(tag) d.addCallback(list) return d @signature(owner=Unicode("Owner of tags (or None for unowned tags).", null=True), returns=List("List of tags owned.", item_type=Tag())) def jsonrpc_owned_tags(self, owner): """Return a list of tags currently owned by an owner.""" return self.tagpool.owned_tags(owner)