Skip to main content

InPlat JSON RPC library

Project description

Библиотека для разбора json-rpc подобных запросов, их валидации и вызова методов.

Пример использования:

from iprpc import method, MethodExecutor

class Handler:
    @method()
    async def sum(self, a: int, b: int) -> int:
        return a + b

executor = MethodExecutor(Handler())
res = await executor.call(b'{"method":"sum","params":{"a":1,"b":2}}')
assert res.result == 3
assert res.error is None

res = await executor.call(b'{"method":"sum","params":{"a":"NaN","b":2}}')
assert res.result is None
assert res.error is not None
print(res.error)
>> InvalidArguments(Exception('value is not a valid integer in a',),)

iprpc.MethodExecutor видит только те методы, которые отмечены декоратором iprpc.method. Если требуется дать сложное имя метода(например использовать спецсимволы в названии), то в декораторную функцию необходимо передать аргумент name с названием метода:

class Handler:
    @method(name="math.sum")
    async def sum(self, a: int, b: int) -> int:
        return a + b

При этом вызвать метод передав в него имя метода соответствующее название функции python уже не получится. Т.е., в примере выше, вызов {“method”:”sum”,”params”:{“a”:1,”b”:2} завершится ошибкой. Нужно^ {“method”:”math.sum”,”params”:{“a”:1,”b”:2}

Структура запроса

По-умолчанию структура запроса должна соответствовать следующей JSON схеме:

{
    "type": "object",
    "required": [ "method" ],
    "properties": {
        "method": {
            "type": "string"
        },
        "params": {
            "type": "object"
        }
    }
}

Структура может быть изменена. Ключи объека запроса с именем метода или/и параметрами могут иметь другие значения. Для этого нужно в MethodExecutor передать аргумент method_key или/и params_key:

executor = iprpc.MethodExecutor(TestHandler(), method_key='name', params_key='args')
await executor.call(b'{"name":"sum","args":{"a":1,"b":2}}')

Также аргументы метода можно передавать в корне запроса. Для этого params_key должен быть равен None:

executor = iprpc.MethodExecutor(TestHandler(), params_key=None)
await executor.call(b'{"method":"sum","a":1,"b":2}')

Валидация с помощью JSON Schema

Для задания правил валидации нужно передать в декоратор список правил. Правила представляют собой словарь, где ключ - это имя аргумента, а значение - это json схема. Пример:

class Handler:

    @method(validators={"a": {"type": "integer"},"b": {"type": "integer"}})
    async def sum(self, a, b):
        return a + b

Валиация с помощью pydantinc

Валидация происходит автоматически если есть аннотации типов в объявлении метода. Например:

class Handler:
    @method()
    async def sum(self, a: int, b: int):
        return a + b

При этом в запросе можно передавать значение в виде строки или другого совместимого типа, значение будет автоматически преобразовано(если это возможно).

Сериализация результата

Результат вызываемой функции будет преобразован к простым типам данных для дальнейшей сериализация в JSON. Например, если метод возвращает объект datetime, то он будет преобразован в строку в iso формате. Для большей информации см. функцию pydantic.json.pydantic_encoder

Сложный пример:

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str

class Handler:
    @method()
    async def rename(self, model: User, name: str) -> User:
        model.name = name
        return model

executor = MethodExecutor(Handler())
r = await executor.call(b'{"method":"rename","params":{"model": {"id": 1, "name": "Jhon Snow"},"name": "Jon Snow"}}'
print(r.result)
>> {'id': 1, 'name': 'Jon Snow'}

JSON-RPC 2.0

Пример:

from iprpc import method, JsonRpcError, JsonRpcExecutor

class Handler:
    @method()
    async def do_something(self, arg1: str):
        return arg1

executor = JsonRpcExecutor(Handler())

request = (
    b'{"jsonrpc": "2.0", "id": 1, '
    b'"method": "do_something", "params": {"arg1": 123}}'
)
resp = await executor.execute(request)

print('<< %s' % resp)
<< b'{"jsonrpc": "2.0", "id": 1, "result": "123"}'

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iprpc-0.2.3.tar.gz (10.7 kB view hashes)

Uploaded Source

Built Distribution

iprpc-0.2.3-py3-none-any.whl (9.1 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page