Source code for smartrpyc.server.register

"""
Method Registers module

This module provides facilities for preparing a library of methods
to be exposed via the RPC.

The library creation can happen in several ways:

* Using a :py:class:`.MethodsRegister` decorator, to register a bunch
  of stand-alone functions
* Usinng a :py:class:`.MethodsObject` to expose all the methods in a
  given object (instance). This is especially useful if you need
  to expose methods from an object **instance**, ie. you need to share
  some state.
"""

__all__ = ['MethodsRegisterBase', 'MethodsRegister', 'MethodsObject']


[docs]class MethodsRegisterBase(object): """ Base for the Method Register objects. This class provides an abstract of the methods that can (and should) be exposed by a methods register object. """
[docs] def register(self, func=None, name=None): """Only used for registers supporting changes""" raise NotImplementedError
[docs] def lookup(self, method): """ The most important method, returning the appropriate method to be called. """ raise NotImplementedError
[docs] def list_methods(self): """List all the supported methods""" raise NotImplementedError
[docs]class MethodsRegister(MethodsRegisterBase): """ Register for methods to be exposed via RPC. Mostly a wrapper around a dict. Usage:: methods = MethodsRegister() @methods.register def my_method(request, arg1, arg2): pass @methods.register(name='method2') def my_other_method(request, arg1=123, arg2=None): pass methods.register(func=func, name='test') # then pass methods to the Server() constructor """ def __init__(self): self._methods = {}
[docs] def register(self, func=None, name=None): """ Refer to class docstring :params func: Callable to register :params name: Basestring to use as reference name for `func` """ # If name is None we'll get the name from the # function itself. name = name or callable(func) and func.__name__ def decorator(func): self.store(name, func) return func # If func is not None, it means the method # has been used either as a simple decorator # or as a plain method. The function will be # registered by calling decorator, otherwise, # decorator will be returned. return func and decorator(func) or decorator
[docs] def store(self, name, function): """ Method used to finally register a function. :params name: Functions lookup name :params function: Callable function """ if not isinstance(name, basestring) and \ not callable(function): # If we get here, most likely, the user has passed # a non callable function. See unittest for a clearer # example. raise ValueError("Unsupported arguments to register: " "{0} and {1}".format(name, function)) self._methods[name] = function
[docs] def lookup(self, method): return self._methods[method]
[docs] def list_methods(self): return self._methods.keys()
[docs]class MethodsObject(MethodsRegisterBase): """ Objects wrapper register. This is a "wrapper" register, that automatically exposes all the methods contained in the object passed to the constructor. """ _object = None
[docs] def lookup(self, method): return getattr(self._object, method)
[docs] def list_methods(self): return [m for m in dir(self._object) if not m.startswith('_')]
[docs] def set_object(self, obj): if self._object is not None: raise RuntimeError("You cannot set the object twice.") self._object = obj