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
consisting of two visible methods:
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:
When writing a server application, a higher level dispatching method is
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
Stores name-to-method mappings.
Add a method to the dispatcher.
- f – Callable to be added.
- name – Name to register it with. If
f.__name__will be used.
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
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
Retrieve a previously registered method.
Checks if a method matching
namehas been registered.
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
- 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
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_nameattribute on a function, causing it to be picked up if an instance of its parent class is registered using
@publicis a shortcut for
Parameters: name – The name to register the function with.