Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # encoding: utf-8
- __author__ = 'mFoxRU'
- import json
- from twisted.internet.defer import maybeDeferred
- class Rpc(object):
- _fields = {'jsonrpc', 'method'}
- def __init__(self):
- self._fn = {}
- self._sig = {}
- def process(self, user_id, msg, callback):
- """ Executes received JSON-RPC message
- :param user_id: Recipient user's ID
- :type user_id: int
- :param msg: JSON-RPC message
- :type msg: str
- :param callback: Callback for sending reply
- :type callback: collections.Callable
- """
- try:
- message = json.loads(msg)
- except (ValueError, TypeError):
- return callback(user_id, self.reply_err_parse())
- if not self._fields.issubset(message):
- return callback(user_id, self.reply_err_invalid())
- _id = message.get('id')
- method = message.get('method')
- params = message.get('params', {})
- params['user_id'] = user_id
- if method not in self._fn:
- return callback(user_id, self.reply_err_method(_id))
- if params.keys() != self._sig[method]:
- return callback(user_id, self.reply_err_params(_id))
- d = maybeDeferred(self._fn[method], **params)
- d.addCallback(self.success, user_id, _id, callback)
- d.addErrback(self.failure, user_id, _id, callback)
- def success(self, result, user_id, msg_id, callback):
- """ Send reply to user
- :param result: Call result
- :type result: tuple[bool | dict]
- :param user_id: Requester ID
- :type user_id: int
- :param msg_id: Request message ID
- :type msg_id: int
- :param callback: Callback for sending reply
- :type callback: collections.Callable
- """
- callback(user_id, self.reply_ok(msg_id, result[1]))
- def failure(self, failure, user_id, msg_id, callback):
- """Send error reply to user
- :param failure: Failure result
- :type failure: twisted.python.failure.Failure
- :param user_id: Requester ID
- :type user_id: int
- :param msg_id: Request message ID
- :type msg_id: int
- :param callback: Callback for sending reply
- :type callback: collections.Callable
- """
- callback(user_id, self.reply_err(
- msg_id, -2, failure.getErrorMessage()))
- def reg(self, name=None):
- """ Decorator to register function
- :param name: Optional
- :type name: []
- :return:
- """
- if callable(name):
- self.add(name)
- return name
- def f(fn):
- self.add(fn, name=name)
- return fn
- return f
- def add(self, fn, name=None):
- """ Register function
- :param fn: Function to add
- :type fn: collections.Callable
- :param name:
- """
- assert callable(fn), 'fn is not callable'.format(fn)
- if name is None:
- name = fn.__name__
- sig = list(fn.func_code.co_varnames[:fn.func_code.co_argcount])
- if 'self' in sig:
- sig.remove('self')
- print name, sig
- if name in self._fn:
- raise KeyError('Already have function with name {}'.format(name))
- self._fn[name] = fn
- self._sig[name] = sig
- @staticmethod
- def reply_ok(request_id, result):
- """Form result reply
- :param request_id: Request id
- :type request_id: int
- :param result:
- :type result: any
- :return: JSON-RPC formatted message
- :rtype: str
- """
- reply = {'jsonrpc': '2.0',
- 'id': request_id,
- 'result': result}
- return json.dumps(reply)
- @staticmethod
- def reply_err(request_id, error_code, error_msg):
- """Form error reply
- :param request_id: Request id
- :type request_id: [int, None]
- :param error_code: Error code
- :type error_code: int
- :param error_msg: Error message
- :type error_msg: str
- :return: JSON-RPC formatted message
- :rtype: str
- """
- reply = {'jsonrpc': '2.0',
- 'id': request_id,
- 'error': {
- 'code': error_code,
- 'message': error_msg
- }}
- return json.dumps(reply)
- @staticmethod
- def notification(method, params):
- """Form notification reply
- :param method:
- :type method: str
- :param params:
- :type params: dict
- :return: JSON-RPC formatted message
- :rtype: str
- """
- message = {'jsonrpc': '2.0',
- 'method': method,
- 'params': params}
- return json.dumps(message)
- @classmethod
- def reply_err_parse(cls):
- """Form parse error reply
- :return: JSON-RPC formatted message
- :rtype: str
- """
- return cls.reply_err(None, -32700, 'Parse error')
- @classmethod
- def reply_err_invalid(cls):
- """Form invalid JSON-RPC reply
- :return: JSON-RPC formatted message
- :rtype: str
- """
- return cls.reply_err(None, -32600, 'Invalid JSON-RPC')
- @classmethod
- def reply_err_method(cls, request_id=None):
- """Form method not found reply
- :param request_id: Request id
- :type request_id: int
- :return: JSON-RPC formatted message
- :rtype: str
- """
- return cls.reply_err(request_id, -32601, 'Method not found')
- @classmethod
- def reply_err_params(cls, request_id=None):
- """Form invalid parameter(s) reply
- :param request_id: Request id
- :type request_id: int
- :return: JSON-RPC formatted message
- :rtype: str
- """
- return cls.reply_err(request_id, -32602, 'Invalid method parameter(s)')
- rpc = Rpc()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement