Dispatching in tinyrpc is very similiar to url-routing in web frameworks. Functions are registered with a specific name and made public, i.e. callable, to remote clients.
Exposing a few functions:¶
from tinyrpc.dispatch import RPCDispatcher dispatch = RPCDispatcher() @dispatch.public def foo(): # ... @dispatch.public def bar(arg): # ... # later on, assuming we know we want to call foo(*args, **kwargs): f = dispatch.get_method('foo') f(*args, **kwargs)
Using prefixes and instance registration:¶
from tinyrpc.dispatch import public class SomeWebsite(object): def __init__(self, ...): # note: this method will not be exposed def secret(self): # another unexposed method @public def get_user_info(self, user): # ... # using a different name @public('get_user_comment') def get_comment(self, comment_id): # ...
The code above declares an RPC interface for SomeWebsite objects, consisting of two visible methods: get_user_info(user) and get_user_comment(commend_id).
These can be used with a dispatcher now:
def hello(): # ... website1 = SomeWebsite(...) website2 = SomeWebsite(...) from tinyrpc.dispatch import RPCDispatcher dispatcher = RPCDispatcher() # directly register version method @dispatcher.public def version(): # ... # add earlier defined method dispatcher.add_method(hello) # register the two website instances dispatcher.register_instance(website1, 'sitea.') dispatcher.register_instance(website2, 'siteb.')
In the example above, the RPCDispatcher now knows a total of six registered methods: version, hello, sitea.get_user_info, sitea.get_user_comment, siteb.get_user_info, siteb.get_user_comment.
When writing a server application, a higher level dispatching method is available with dispatch():
from tinyrpc.dispatch import RPCDispatcher dispatcher = RPCDispatcher() # register methods like in the examples above # ... # now assumes that a valid RPCRequest has been obtained, as `request` response = dispatcher.dispatch(request) # response can be directly processed back to the client, all Exceptions have # been handled already
- class tinyrpc.dispatch.RPCDispatcher¶
Stores name-to-method mappings.
- add_method(f, name=None)¶
Add a method to the dispatcher.
- f – Callable to be added.
- name – Name to register it with. If None, f.__name__ will be used.
- add_subdispatch(dispatcher, prefix='')¶
Adds a subdispatcher, possibly in its own namespace.
- dispatcher – The dispatcher to add as a subdispatcher.
- prefix – A prefix. All of the new subdispatchers methods will be available as prefix + their original name.
Fully handle request.
The dispatch method determines which method to call, calls it and returns a response containing a result.
No exceptions will be thrown, rather, every exception will be turned into a response using error_respond().
If the method is found and called but throws an exception, the exception thrown is used as a response instead. This is the only case in which information from the exception is possibly propagated back to the client, as the exception is part of the requested method.
Parameters: request – An RPCRequest(). Returns: An RPCResponse().
Retrieve a previously registered method.
Checks if a method matching name has been registered.
If get_method() cannot find a method, every subdispatcher with a prefix matching the method name is checked as well.
If a method isn’t found, a KeyError is thrown.
- name – Callable to find.
- return – The callable.
Allows easy registering of functions to this dispatcher. Example:
dispatch = RPCDispatcher() @dispatch.public def foo(bar): # ... class Baz(object): def not_exposed(self): # ... @dispatch.public(name='do_something') def visible_method(arg1) # ...
Parameters: name – Name to register callable with
- register_instance(obj, prefix='')¶
Create new subdispatcher and register all public object methods on it.
- obj – The object whose public methods should be made available.
- prefix – A prefix for the new subdispatcher.
Classes can be made to support an RPC interface without coupling it to a dispatcher using a decorator:
Set RPC name on function.
This function decorator will set the _rpc_public_name attribute on a function, causing it to be picked up if an instance of its parent class is registered using register_instance().
@public is a shortcut for @public().
Parameters: name – The name to register the function with.