Update to 0.3.0

This commit is contained in:
2022-05-24 14:21:11 +03:00
parent 2068587712
commit 6093826c78
5 changed files with 171 additions and 104 deletions

11
.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
# Byte-compiled / optimized / DLL files
__pycache__/
# Distribution / packaging
build/
dist/
jsonrpc.egg-info/
prototypes/
.tox/
tests/

View File

@@ -1,51 +1,66 @@
import json
import logging
import traceback
from inspect import signature
PARSE_ERROR = -32700
INVALID_REQUEST = -32600
METHOD_NOT_FOUND = -32601
INVALID_PARAMS = -32602
INTERNAL_ERROR = -32603
GENERIC_APPLICATION_ERROR = -32000
from .exceptions import *
class JsonRpcException(Exception):
"""Исключение
"""
def __init__(self, id, code, message):
log = logging.getLogger(__name__)
class Response:
def __init__(self, id: int, result):
self.id = id
self.code = code
self.message = message
self.result = result
def as_dict(self):
"""Класс в JSON словарь
"""
result = {
'jsonrpc':'2.0',
'id': self.id,
'error': {
'code': self.code,
'message':self.message
def __json__(self):
response = {
"jsonrpc": "2.0",
"result": self.result,
"id": self.id,
}
}
return result
def __str__(self):
return json.dumps(self.as_dict())
return response
class Method:
def __init__(self, function, handler = None, fields = None):
def __init__(self, function, pre = None):
self.function = function
self.handler = handler
self.fields = fields
self.pre = pre
def __call__(self, query):
if self.handler is None:
return self.function()
result = self.handler(query, self.function)
return result
params = None
if 'params' in query:
params = query['params']
log.error(params)
if isinstance(self.pre, list):
pass
elif type(self.pre).__name__=='function':
self.pre(query)
if params is None:
response = self.function()
elif isinstance(params, list):
response = self.function(*params)
elif isinstance(params, dict):
response = self.function(**params)
else:
raise InvalidParamsError(
id=query['id'],
message='Invalid params: {0}'.format(params)
)
return response
def __repr__(self):
return '<{}>'.format(self.function)
class Wrapper:
def __init__(self, func):
self.func = func
class JSONRPC:
@@ -54,23 +69,15 @@ class JSONRPC:
def __init__(self):
self.methods = {}
def method(self, name: str, handler = None, fields = None):
def method(self, name: str, pre = None):
"""Декоратор метода
"""
assert len(name) > 0, 'Не указано имя метода'
# logging.info('{} {}: {}'.format(
# func.__module__,
# func.__name__,
# func.__doc__
# ))
# funcname = func.__name__
# modulename = func.__module__
def wrap(function):
# print(func)
method = Method(
function = function,
handler = handler,
fields = fields
pre = pre
)
self.methods[name] = method
return function
@@ -127,20 +134,17 @@ class JSONRPC:
"""Валидация запроса
"""
keys = query.keys()
logging.info(f'keys: {keys}')
if 'id' not in query:
return JsonRpcException(
query['id'],
INVALID_REQUEST,
f'Некорректный запрос: {query}'
).as_dict()
return InvalidRequestError(
id=query['id'],
message=f'Некорректный запрос: {query}'
).__json__()
if 'method' not in query:
return JsonRpcException(
query['id'],
INVALID_REQUEST,
f'Некорректный запрос: {query}'
).as_dict()
return InvalidRequestError(
id=query['id'],
message=f'Некорректный запрос: {query}'
).__json__()
def process(self, query):
"""Выполнение метода
@@ -148,58 +152,36 @@ class JSONRPC:
self.validate(query)
name = query['method']
if name not in self.methods:
return JsonRpcException(
result = MethodNotFoundError(
query['id'],
METHOD_NOT_FOUND,
f'Метод не найден: {name}'
).as_dict()
message=f'Метод не найден: {name}'
)
return result.__json__()
method = self.methods[name]
params = None
if 'params' in query:
params = query['params']
# for key in params:
# print(f'{key}: {type(params[key]).__name__} = {params[key]}')
logging.debug('params: {}'.format(params))
try:
if method.handler is None:
pass
else:
method.handler(
query,
method.function
response = method(query)
except JSONRPCError as e:
log.error(traceback.format_exc())
# print(traceback.format_exc())
response = traceback.format_exc()
except Exception as e:
log.error(traceback.format_exc())
response = InternalError(
id=query['id'],
# message=str(e)
message=traceback.format_exc()
)
if params is None:
response = method.function()
elif isinstance(params, list):
response = method.function(*params)
elif isinstance(params, dict):
response = method.function(**params)
else:
return JsonRpcException(
query['id'],
INVALID_PARAMS,
'Invalid params: {0}'.format(params)
response = Response(
id=query['id'],
result=response
)
except BaseException as e:
result = {
"jsonrpc": "2.0",
"id": query['id'],
"error": {
"message": str(e)
}
}
else:
result = {
"jsonrpc": "2.0",
"id": query['id'],
"result": response
}
result = response.__json__()
return result
def __call__(self, queries):
"""Вызов метода
"""
@@ -221,8 +203,8 @@ class JSONRPC:
def __len__(self):
return len(self.methods)
def __setitem__(self, key, function, handler = None, fields = None):
method = Method(function = function, handler = None, fields = None)
def __setitem__(self, key, function, pre=None):
method = Method(function=function, pre=pre)
self.methods[key] = method
def __delitem__(self, key):

74
jsonrpc/exceptions.py Normal file
View File

@@ -0,0 +1,74 @@
class JSONRPCError(Exception):
def __init__(self, id: int, message):
pass
def __json__(self):
result = {
"jsonrpc": "2.0",
"id": self.id,
"error": {
"code": self.CODE,
"message": self.message
}
}
return result
class InvalidRequestError(JSONRPCError):
CODE = -32600
def __init__(self, id: int, message: str = 'Invalid Request'):
self.id = id
self.message = message
self.code = CODE
class ParseError(JSONRPCError):
CODE = -32700
def __init__(self, id: int, message: str = 'Parse error'):
self.id = id
self.message = message
self.code = CODE
class MethodNotFoundError(JSONRPCError):
CODE = -32601
def __init__(self, id: int, message: str = 'Method not found'):
self.id = id
self.message = message
self.code = self.CODE
class InvalidParamsError(JSONRPCError):
CODE = -32602
def __init__(self, id: int, message: str = 'Invalid params'):
self.id = id
self.message = message
self.code = self.CODE
class InternalError(JSONRPCError):
"""Internal JSON-RPC error
"""
CODE = -32603
def __init__(self, id: int, message: str = 'Internal error'):
self.id = id
self.message = message
self.code = self.CODE
class ServerError(JSONRPCError):
"""Reserved for implementation-defined server-errors.
code: -32000 to -32099 Server error.
"""
CODE = -32000
def __init__(self, id: int, message: str = 'Server error'):
self.id = id
self.message = message
self.code = self.CODE

View File

@@ -1,3 +1,3 @@
[metadata]
name = jsonrpc
version = 0.2.0
version = 0.3.0

View File

@@ -5,7 +5,7 @@ from setuptools import setup, find_packages
setup(
name='jsonrpc',
version='0.2.0',
version='0.3.0',
author='RemiZOffAlex',
author_email='remizoffalex@gmail.com',
packages=find_packages(exclude=['prototypes', 'tests']),