def jsonrpc_method(name,
                   authenticated=False,
                   authentication_arguments=['username', 'password'],
                   safe=False,
                   validate=False,
                   site=default_site):
    """
    Wraps a function turns it into a json-rpc method. Adds several attributes
    to the function specific to the JSON-RPC machinery and adds it to the default
    jsonrpc_site if one isn't provided. You must import the module containing
    these functions in your urls.py.

        name

            The name of your method. IE: `namespace.methodName` The method name
            can include type information, like `ns.method(String, Array) -> Nil`.

        authenticated=False

            Adds `username` and `password` arguments to the beginning of your
            method if the user hasn't already been authenticated. These will
            be used to authenticate the user against `django.contrib.authenticate`
            If you use HTTP auth or other authentication middleware, `username`
            and `password` will not be added, and this method will only check
            against `request.user.is_authenticated`.

            You may pass a callable to replace `django.contrib.auth.authenticate`
            as the authentication method. It must return either a User or `None`
            and take the keyword arguments `username` and `password`.

        safe=False

            Designates whether or not your method may be accessed by HTTP GET.
            By default this is turned off.

        validate=False

            Validates the arguments passed to your method based on type
            information provided in the signature. Supply type information by
            including types in your method declaration. Like so:

            @jsonrpc_method('myapp.specialSauce(Array, String)', validate=True)
            def special_sauce(self, ingredients, instructions):
              return SpecialSauce(ingredients, instructions)

            Calls to `myapp.specialSauce` will now check each arguments type
            before calling `special_sauce`, throwing an `InvalidParamsError`
            when it encounters a discrepancy. This can significantly reduce the
            amount of code required to write JSON-RPC services.

        site=default_site

            Defines which site the jsonrpc method will be added to. Can be any
            object that provides a `register(name, func)` method.

    """

    def decorator(func):
        arg_names = getargspec(func)[0][1:]
        X = {'name': name, 'arg_names': arg_names}
        if authenticated:
            if authenticated is True or six.callable(authenticated):
                # TODO: this is an assumption
                X['arg_names'] = authentication_arguments + X['arg_names']
                X['name'] = _inject_args(X['name'], ('String', 'String'))
                from django.contrib.auth import authenticate as _authenticate
                from django.contrib.auth.models import User
            else:
                authenticate = authenticated

            @six.wraps(func)
            def _func(request, *args, **kwargs):
                user = getattr(request, 'user', None)
                is_authenticated = getattr(user, 'is_authenticated',
                                           lambda: False)
                if ((user is not None and six.callable(is_authenticated) and
                     not is_authenticated()) or user is None):
                    user = None
                    try:
                        creds = args[:len(authentication_arguments)]
                        if len(creds) == 0:
                            raise IndexError
                        # Django's authenticate() method takes arguments as dict
                        user = _authenticate(username=creds[0],
                                             password=creds[1], *creds[2:])
                        if user is not None:
                            args = args[len(authentication_arguments):]
                    except IndexError:
                        auth_kwargs = {}
                        try:
                            for auth_kwarg in authentication_arguments:
                                auth_kwargs[auth_kwarg] = kwargs[auth_kwarg]
                        except __HOLE__:
                            raise InvalidParamsError(
                                'Authenticated methods require at least '
                                '[%(arguments)s] or {%(arguments)s} arguments' %
                                {'arguments': ', '.join(authentication_arguments)})

                        user = _authenticate(**auth_kwargs)
                        if user is not None:
                            for auth_kwarg in authentication_arguments:
                                kwargs.pop(auth_kwarg)
                    if user is None:
                        raise InvalidCredentialsError
                    request.user = user
                return func(request, *args, **kwargs)
        else:
            _func = func

        @six.wraps(_func)
        def exc_printer(*a, **kw):
            try:
                return _func(*a, **kw)
            except Exception as e:
                try:
                    print('JSONRPC SERVICE EXCEPTION')
                    import traceback
                    traceback.print_exc()
                except:
                    pass
                six.reraise(*sys.exc_info())

        ret_func = exc_printer

        method, arg_types, return_type = \
      _parse_sig(X['name'], X['arg_names'], validate)
        ret_func.json_args = X['arg_names']
        ret_func.json_arg_types = arg_types
        ret_func.json_return_type = return_type
        ret_func.json_method = method
        ret_func.json_safe = safe
        ret_func.json_sig = X['name']
        ret_func.json_validate = validate
        site.register(method, ret_func)
        return ret_func

    return decorator
dataset/ETHPy150Open samuraisam/django-json-rpc/jsonrpc/__init__.py/jsonrpc_method