Source code for gemstone.core.decorators

import functools
import re
import inspect

import tornado.gen

__all__ = [
    'event_handler',
    'exposed_method'
]


[docs]def public_method(func): """ Decorates a method to be exposed from a :py:class:`gemstone.PyMicroService` concrete implementation. The exposed method will be public. .. deprecated:: 0.9.0 Use :py:func:`exposed_method` instead. """ func.__gemstone_internal_public = True return func
[docs]def private_api_method(func): """ Decorates a method to be exposed (privately) from a :py:class:`gemstone.PyMicroService` concrete implementation. The exposed method will be private. .. deprecated:: 0.9.0 Use :py:func:`exposed_method` instead. """ func.__gemstone_internal_private = True return func
[docs]def event_handler(event_name): """ Decorator for designating a handler for an event type. ``event_name`` must be a string representing the name of the event type. The decorated function must accept a parameter: the body of the received event, which will be a Python object that can be encoded as a JSON (dict, list, str, int, bool, float or None) :param event_name: :return: """ def wrapper(func): func._event_handler = True func._handled_event = event_name return func return wrapper
[docs]def requires_handler_reference(func): """ Marks a method tha requires access to the :py:class:`gemstone.TornadoJsonRpcHandler` instance when calling the request. If a method is decorated with this, when it is called it will receive a ``handler`` argument as the first argument. Useful when you need to do specific operations such as setting a cookie, setting a secure cookie, get the ``current_user`` of the request, etc. .. deprecated:: 0.9.0 Use :py:func:`exposed_method` instead. """ func.__gemstone_internal_req_h_ref = True return func
def async_method(func): """ Marks a function as a Tornado generator (coroutine) .. deprecated:: 0.9.0 Use :py:func:`exposed_method` instead. """ func.__gemstone_is_coroutine = True return tornado.gen.coroutine(func) METHOD_NAME_REGEX = re.compile(r'^[a-zA-Z][a-zA-Z0-9_.]*$')
[docs]def exposed_method(name=None, private=False, is_coroutine=True, requires_handler_reference=False, **kwargs): """ Marks a method as exposed via JSON RPC. :param name: the name of the exposed method. Must contains only letters, digits, dots and underscores. If not present or is set explicitly to ``None``, this parameter will default to the name of the exposed method. If two methods with the same name are exposed, a ``ValueError`` is raised. :param public: Flag that specifies if the exposed method is public (can be accessed without token) :param private: Flag that specifies if the exposed method is private. :param is_coroutine: Flag that specifies if the method is a Tornado coroutine. If True, it will be wrapped with the :py:func:`tornado.gen.coroutine` decorator. :param kwargs: Not used. .. versionadded:: 0.9.0 """ def wrapper(func): # validation if name: method_name = name else: method_name = func.__name__ if not METHOD_NAME_REGEX.match(method_name): raise ValueError("Invalid method name: '{}'".format(method_name)) @functools.wraps(func) def real_wrapper(*args, **kwargs): return func(*args, **kwargs) # set appropriate flags if private: setattr(real_wrapper, "_exposed_private", True) else: setattr(real_wrapper, "_exposed_public", True) if is_coroutine: real_wrapper = async_method(real_wrapper) setattr(real_wrapper, "_is_coroutine", True) if requires_handler_reference: setattr(real_wrapper, "_req_h_ref", True) setattr(real_wrapper, "_exposed_name", method_name) return real_wrapper return wrapper