JSON-RPC server based on fastapi

Overview

Description

JSON-RPC server based on fastapi:

https://fastapi.tiangolo.com

Motivation

Autogenerated OpenAPI and Swagger (thanks to fastapi) for JSON-RPC!!!

Installation

pip install fastapi-jsonrpc

Documentation

Read FastAPI documentation and see usage examples bellow

Simple usage example

pip install uvicorn

example1.py

import fastapi_jsonrpc as jsonrpc
from pydantic import BaseModel
from fastapi import Body


app = jsonrpc.API()

api_v1 = jsonrpc.Entrypoint('/api/v1/jsonrpc')


class MyError(jsonrpc.BaseError):
    CODE = 5000
    MESSAGE = 'My error'

    class DataModel(BaseModel):
        details: str


@api_v1.method(errors=[MyError])
def echo(
    data: str = Body(..., example='123'),
) -> str:
    if data == 'error':
        raise MyError(data={'details': 'error'})
    else:
        return data


app.bind_entrypoint(api_v1)


if __name__ == '__main__':
    import uvicorn
    uvicorn.run('example1:app', port=5000, debug=True, access_log=False)

Go to:

http://127.0.0.1:5000/docs

FastAPI dependencies usage example

pip install uvicorn

example2.py

import logging
from contextlib import asynccontextmanager

from pydantic import BaseModel, Field
import fastapi_jsonrpc as jsonrpc
from fastapi import Body, Header, Depends


logger = logging.getLogger(__name__)


# database models

class User:
    def __init__(self, name):
        self.name = name

    def __eq__(self, other):
        if not isinstance(other, User):
            return False
        return self.name == other.name


class Account:
    def __init__(self, account_id, owner, amount, currency):
        self.account_id = account_id
        self.owner = owner
        self.amount = amount
        self.currency = currency

    def owned_by(self, user: User):
        return self.owner == user


# fake database

users = {
    '1': User('user1'),
    '2': User('user2'),
}

accounts = {
    '1.1': Account('1.1', users['1'], 100, 'USD'),
    '1.2': Account('1.2', users['1'], 200, 'EUR'),
    '2.1': Account('2.1', users['2'], 300, 'USD'),
}


def get_user_by_token(auth_token) -> User:
    return users[auth_token]


def get_account_by_id(account_id) -> Account:
    return accounts[account_id]


# schemas

class Balance(BaseModel):
    """Account balance"""
    amount: int = Field(..., example=100)
    currency: str = Field(..., example='USD')


# errors

class AuthError(jsonrpc.BaseError):
    CODE = 7000
    MESSAGE = 'Auth error'


class AccountNotFound(jsonrpc.BaseError):
    CODE = 6000
    MESSAGE = 'Account not found'


class NotEnoughMoney(jsonrpc.BaseError):
    CODE = 6001
    MESSAGE = 'Not enough money'

    class DataModel(BaseModel):
        balance: Balance


# dependencies

def get_auth_user(
    # this will become the header-parameter of json-rpc method that uses this dependency
    auth_token: str = Header(
        None,
        alias='user-auth-token',
    ),
) -> User:
    if not auth_token:
        raise AuthError

    try:
        return get_user_by_token(auth_token)
    except KeyError:
        raise AuthError


def get_account(
    # this will become the parameter of the json-rpc method that uses this dependency
    account_id: str = Body(..., example='1.1'),
    user: User = Depends(get_auth_user),
) -> Account:
    try:
        account = get_account_by_id(account_id)
    except KeyError:
        raise AccountNotFound

    if not account.owned_by(user):
        raise AccountNotFound

    return account


# JSON-RPC middlewares

@asynccontextmanager
async def logging_middleware(ctx: jsonrpc.JsonRpcContext):
    logger.info('Request: %r', ctx.raw_request)
    try:
        yield
    finally:
        logger.info('Response: %r', ctx.raw_response)


# JSON-RPC entrypoint

common_errors = [AccountNotFound, AuthError]
common_errors.extend(jsonrpc.Entrypoint.default_errors)

api_v1 = jsonrpc.Entrypoint(
    # Swagger shows for entrypoint common parameters gathered by dependencies and common_dependencies:
    #    - json-rpc-parameter 'account_id'
    #    - header parameter 'user-auth-token'
    '/api/v1/jsonrpc',
    errors=common_errors,
    middlewares=[logging_middleware],
    # this dependencies called once for whole json-rpc batch request
    dependencies=[Depends(get_auth_user)],
    # this dependencies called separately for every json-rpc request in batch request
    common_dependencies=[Depends(get_account)],
)


# JSON-RPC methods of this entrypoint

# this json-rpc method has one json-rpc-parameter 'account_id' and one header parameter 'user-auth-token'
@api_v1.method()
def get_balance(
    account: Account = Depends(get_account),
) -> Balance:
    return Balance(
        amount=account.amount,
        currency=account.currency,
    )


# this json-rpc method has two json-rpc-parameters 'account_id', 'amount' and one header parameter 'user-auth-token'
@api_v1.method(errors=[NotEnoughMoney])
def withdraw(
    account: Account = Depends(get_account),
    amount: int = Body(..., gt=0, example=10),
) -> Balance:
    if account.amount - amount < 0:
        raise NotEnoughMoney(data={'balance': get_balance(account)})
    account.amount -= amount
    return get_balance(account)


# JSON-RPC API

app = jsonrpc.API()
app.bind_entrypoint(api_v1)


if __name__ == '__main__':
    import uvicorn
    uvicorn.run('example2:app', port=5000, debug=True, access_log=False)

Go to:

http://127.0.0.1:5000/docs

./images/fastapi-jsonrpc.png

Development

  • Install poetry

    https://github.com/sdispater/poetry#installation

  • Install dephell

    pip install dephell
  • Install dependencies

    poetry update
  • Regenerate README.rst

    rst_include include -q README.src.rst README.rst
  • Change dependencies

    Edit pyproject.toml

    poetry update
    dephell deps convert
  • Bump version

    poetry version patch
    dephell deps convert
  • Publish to pypi

    poetry publish --build
Comments
  • В swagger в Example Value выставляется неверное значение версии jsonrpc

    В swagger в Example Value выставляется неверное значение версии jsonrpc

    В swagger в примере запросе поле "jsonrpc" выставляется равным 2, как число. Необходимо, чтобы выставлялось "2.0", как строка.

    image image

    Есть предположение что, если тут значение example='"2.0"', то тогда swagger автоматом не преобразовывал бы это значение в численное.

    Версия библиотеки fastapi-jsonrpc==2.0.2, pydantic==1.7.3

    opened by DianaArapova 6
  • No validation error if id is not passed with request

    No validation error if id is not passed with request

    Hey folks Great lib and I'm using it with my projects quite often now

    I saw one strange behavior that I suppose needs some fixing or enhancement

    Here I'm sending a simple request via postman and getting a blank response:

    Request:
    
    {
        "jsonrpc": "2.0",
        "params": {
            "invite_id": "fb233510-9862-4f98-8278-8a173841857e"
        },
        "method": "verify_invite"
    }
    

    Response: image

    As you can see id field is missing on the JSON body, but no error is raised if it's missing there

    When I'm adding id to the body I got the correct JSON response:

    Request:
    
    {
        "jsonrpc": "2.0",
        "params": {
            "invite_id": "fb233510-9862-4f98-8278-8a173841857e"
        },
        "method": "verify_invite",
        "id": 0
    }
    

    Response: image

    Maybe I'm missing something and you can point me In the right direction of using things, but for me, it looks like there should be an error raised when id is not passed to the JSON body

    enhancement 
    opened by appvales-lemeshko 4
  • Allow using custom request class

    Allow using custom request class

    Hey

    My team and I came across a use case where we needed to allow some extra fields in the first level of the Json-RPC payload request.

    So I added an option to use a custom JsonRpcRequest class, inheriting from the initial fastapi-jsonrpc's JsonRpcRequest class.

    The usage is the following:

    
    import fastapi_jsonrpc as jsonrpc
    
    from fastapi.middleware.cors import CORSMiddleware
    from fastapi import Body
    from fastapi_jsonrpc import JsonRpcRequest
    
    app = jsonrpc.API()
    
    app.add_middleware(CORSMiddleware, allow_origins=["*"])
    
    
    class CustomJsonRpcRequest(JsonRpcRequest):
        extravalue: str
    
    api_v1 = jsonrpc.Entrypoint("/api", request_class=CustomJsonRpcRequest)
    
    
    @api_v1.method()
    def echo(
        data: str = Body(..., example="123"),
    ) -> dict:
        return {"from": "echo", "data": data}
    
    
    app.bind_entrypoint(api_v1)
    

    This example allows receiving this payload:

    {
      id: 0,
      jsonrpc: "2.0",
      method: "echo",
      params: {data: "testdata"},
      extravalue: "test"
    }
    

    I hope you'll find this feature useful 👍.

    opened by Smlep 4
  • New FastAPI version breaks fastapi-jsonrpc

    New FastAPI version breaks fastapi-jsonrpc

    Following release 0.18.0 of Starlette accepted by FastAPI in 0.76.0, starlette.Response object does not accept None value anymore for status_code (starlette/responses.py#L77). This breaks the EntrypointRoute.handle_http_request function.

    A fix might be possible, but freezing dependencies would be safer to avoid future issue with future updates.

    To reproduce:

    This minimal example does not work anymore

    # main.py
    import fastapi_jsonrpc as jsonrpc
    
    app = jsonrpc.API()
    api_v1 = jsonrpc.Entrypoint('/api/v1/jsonrpc')
    
    @api_v1.method()
    def echo(
        x: int,
    ) -> int:
        return x
    
    app.bind_entrypoint(api_v1)
    
    if __name__ == '__main__':
        import uvicorn
        uvicorn.run('main:app', port=5000, debug=True, access_log=False)
    
    pip install fastapi==0.76.0
    
    python main.py
    
    curl --request POST \
      --url http://localhost:5000/api/v1/jsonrpc \
      --header 'Content-Type: application/json' \
      --data '{
    	"method": "echo",
    	"id": "1",
    	"params": {
    	    "x": 1
    	}
    }'
    
    opened by VincentHch 3
  • Logs from JSON-RPC views are missing when running in pytest

    Logs from JSON-RPC views are missing when running in pytest

    Live logs are not captured for anything that happens in JSON-RPC views when running pytest (logging_middleware from README also doesn't output anything when running in pytest). But logs are present when running web app.

    Requirements:

    uvicorn==0.17.6
    fastapi==0.75.2
    fastapi-jsonrpc==2.2.0
    
    # checked on "pytest<7" too
    pytest==7.1.2
    # checked on "pytest-asyncio<0.16" too
    pytest-asyncio==0.18.3
    # checked on "httpx<0.20" too
    httpx==0.22.0
    

    pytest.ini

    [pytest]
    log_cli = True
    log_cli_level = INFO
    asyncio_mode=auto
    

    main.py

    import logging
    
    logging.basicConfig(level=logging.DEBUG)
    log = logging.getLogger(__name__)
    
    import fastapi_jsonrpc as jsonrpc
    from pydantic import BaseModel
    from fastapi import Body
    
    
    app = jsonrpc.API()
    
    api_v1 = jsonrpc.Entrypoint("/api/v1/jsonrpc")
    
    
    @app.get("/hello")
    def handle_hello(name: str):
        log.info("hello %s", name)
        return {"hello": name}
    
    
    class MyError(jsonrpc.BaseError):
        CODE = 9001
        MESSAGE = 'My error'
    
        class DataModel(BaseModel):
            details: str
    
    
    @api_v1.method(errors=[MyError])
    def echo(
        data: str = Body(..., example='123'),
    ) -> str:
        log.info("Process echo view, data: %s", data)
        if data == 'error':
            raise MyError(data={'details': 'error'})
        else:
            return data
    
    
    app.bind_entrypoint(api_v1)
    

    test_main.py

    import logging
    
    from pytest import fixture, mark
    from httpx import AsyncClient
    
    from main import app
    
    log = logging.getLogger(__name__)
    
    pytestmark = mark.asyncio
    
    
    @fixture
    async def async_client():
        async with AsyncClient(app=app, base_url="http://test") as ac:
            yield ac
    
    
    async def test_echo_jsonrpc(async_client):
        url = "/api/v1/jsonrpc"
        log.info("gonna run async test for JSON-RPC")
        response = await async_client.post(url)
        assert response.status_code == 200
        log.info("async test for JSON-RPC done")
    
    
    async def test_hello(async_client):
        url = "/hello"
        name = "John"
        log.info("gonna run async test for hello view")
        response = await async_client.get(url, params={"name": name})
        assert response.status_code == 200
        log.info("async test for hello view done")
    

    Getting logs when app is running

    1. Run app:
    uvicorn "main:app"
    
    1. visit http://127.0.0.1:8000/docs or use terminal utilities (curl, httpie) for requests
    2. call a regular FastAPI view:
    curl -X 'GET' \
      'http://127.0.0.1:8000/hello?name=John' \
      -H 'accept: application/json'
    
    {"hello":"John"}% 
    
    1. check terminal where the app is running for logs:
    INFO:main:hello John
    INFO:     127.0.0.1:51376 - "GET /hello?name=John HTTP/1.1" 200 OK
    

    The INFO:main:hello John log comes from the handle_hello view function 5) call a JSON-RPC FastAPI view:

    curl -X 'POST' \
      'http://127.0.0.1:8000/api/v1/jsonrpc' \     
      -H 'accept: application/json' \
      -H 'Content-Type: application/json' \
      -d '{
      "jsonrpc": "2.0",
      "id": 0,
      "method": "echo",
      "params": {
        "data": "spam and eggs"
      }
    }'
    
    {"jsonrpc":"2.0","result":"spam and eggs","id":0}%
    
    1. check terminal where the app is running for logs:
    INFO:main:Process echo view, data: spam and eggs
    INFO:     127.0.0.1:51388 - "POST /api/v1/jsonrpc HTTP/1.1" 200 OK
    

    The INFO:main:Process echo view, data: spam and eggs log comes from the echo JSON-RPC view function

    So we HAVE logs when the app runs.

    Run pytest and check logs

    1. Run pytest -s -v
    2. Check output:
    ========================= test session starts =========================
    platform darwin -- Python 3.9.9, pytest-7.1.2, pluggy-1.0.0 -- /Users/suren/Projects/fastapi-pytest-logging/venv/bin/python
    cachedir: .pytest_cache
    rootdir: /Users/suren/Projects/fastapi-pytest-logging, configfile: pytest.ini
    plugins: asyncio-0.18.3, anyio-3.5.0
    asyncio: mode=auto
    collected 2 items                                                     
    
    test_main.py::test_echo_jsonrpc 
    ---------------------------- live log call ----------------------------
    INFO     test_main:test_main.py:21 gonna run async test for JSON-RPC
    INFO     test_main:test_main.py:24 async test for JSON-RPC done
    PASSED
    test_main.py::test_hello 
    ---------------------------- live log call ----------------------------
    INFO     test_main:test_main.py:30 gonna run async test for hello view
    INFO     main:main.py:18 hello John
    INFO     test_main:test_main.py:33 async test for hello view done
    PASSED
    
    ========================== 2 passed in 0.14s ==========================
    

    test_echo_jsonrpc is missing the INFO:main:Process echo view log, but test_hello contains the INFO:main:hello log

    Expected behaviour: all logs are captured

    Is this fixable via some configs, or does this need to be fixed inside the lib?

    opened by mahenzon 3
  • Loosen version requirements on FastApi

    Loosen version requirements on FastApi

    This lib is (most likely) needlessly restricted to 0.55.x rather than 0.55+ and this gets rid of that restriction making it compatible with 0.56, 57, 58 etc

    This PR closes #9

    May I add this is blocking adoption for anyone not using specifically version 0.55 of fastapi on poetry (and potentially more) as there is no simple way to override version solving issues. For now I have vendored it and await for a version bump.

    Thanks for the lib!

    opened by arlyon 3
  • Logging access

    Logging access

    Because client makes post on only one route it's hard to tell what is request

    Maybe it's not about this library, but it would be really useful to have this feature out of the box.

    opened by denisSurkov 3
  • Upgrade to FastAPI >= 0.80

    Upgrade to FastAPI >= 0.80

    Currently this library is limited to not to be used with FastAPI greater then 0.80 but FastAPI has already released ver. 0.86. Is it possible to change this limitation, please?

    pyproject.toml
    fastapi = ">0.55,<0.80"
    
    opened by ksmolyanin 2
  • build(deps-dev): bump mistune from 0.8.4 to 2.0.3

    build(deps-dev): bump mistune from 0.8.4 to 2.0.3

    Bumps mistune from 0.8.4 to 2.0.3.

    Release notes

    Sourced from mistune's releases.

    Version 2.0.2

    Fix escape_url via lepture/mistune#295

    Version 2.0.1

    Fix XSS for image link syntax.

    Version 2.0.0

    First release of Mistune v2.

    Version 2.0.0 RC1

    In this release, we have a Security Fix for harmful links.

    Version 2.0.0 Alpha 1

    This is the first release of v2. An alpha version for users to have a preview of the new mistune.

    Changelog

    Sourced from mistune's changelog.

    Changelog

    Here is the full history of mistune v2.

    Version 2.0.4

    
    Released on Jul 15, 2022
    
    • Fix url plugin in &lt;a&gt; tag
    • Fix * formatting

    Version 2.0.3

    Released on Jun 27, 2022

    • Fix table plugin
    • Security fix for CVE-2022-34749

    Version 2.0.2

    
    Released on Jan 14, 2022
    

    Fix escape_url

    Version 2.0.1

    Released on Dec 30, 2021

    XSS fix for image link syntax.

    Version 2.0.0

    
    Released on Dec 5, 2021
    

    This is the first non-alpha release of mistune v2.

    Version 2.0.0rc1

    Released on Feb 16, 2021

    Version 2.0.0a6

    
    </tr></table> 
    

    ... (truncated)

    Commits
    • 3f422f1 Version bump 2.0.3
    • a6d4321 Fix asteris emphasis regex CVE-2022-34749
    • 5638e46 Merge pull request #307 from jieter/patch-1
    • 0eba471 Fix typo in guide.rst
    • 61e9337 Fix table plugin
    • 76dec68 Add documentation for renderer heading when TOC enabled
    • 799cd11 Version bump 2.0.2
    • babb0cf Merge pull request #295 from dairiki/bug.escape_url
    • fc2cd53 Make mistune.util.escape_url less aggressive
    • 3e8d352 Version bump 2.0.1
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • Query Parameter

    Query Parameter

    Hi,

    Does this library support the usage of the query parameters? (example: POST http://127.0.0.1:8000/api/v1/jsonrpc?skip=10)

    If yes, can you provide an example?

    Thank you! Fabio

    question 
    opened by fgiudici95 2
  • OpenAPI Becomes Invalid for Datamodel code generator

    OpenAPI Becomes Invalid for Datamodel code generator

    Prance gives errors like:

    Processing "https://.../openapi.json"...
     -> Resolving external references.
    
    [ValidationError]: ("{'content': {'application/json': {'schema': {'title': '_Request', 'required': ['method', 'params'], 'type': 'object', 'properties': {'jsonrpc': {'title': 'Jsonrpc', 'type': 'string', 'example': '2.0', 'const': '2.0'}, 'id': {'title': 'Id', 'anyOf': [{'type': 'string'}, {'type': 'integer'}], 'example': 0}, 'method': {'title': 'Method', 'type': 'string'}, 'params': {'title': 'Params', 'type': 'object'}}, 'additionalProperties': False}}}, 'required': True} is not valid under any of the given schemas", 'oneOf', deque(['paths', '/rpc', 'post', 'requestBody']), None, [<ValidationError: "{'title': '_Request', 'required': ['method', 'params'], 'type': 'object', 'properties': {'jsonrpc': {'title': 'Jsonrpc', 'type': 'string', 'example': '2.0', 'const': '2.0'}, 'id': {'title': 'Id', 'anyOf': [{'type': 'string'}, {'type': 'integer'}], 'example': 0}, 'method': {'title': 'Method', 'type': 'string'}, 'params': {'title': 'Params', 'type': 'object'}}, 'additionalProperties': False} is not valid under any of the given schemas">, <ValidationError: "'$ref' is a required property">], [{'$ref': '#/definitions/RequestBody'}, {'$ref': '#/definitions/Reference'}], {'content': {'application/json': {'schema': {'title': '_Request', 'required': ['method', 'params'], 'type': 'object', 'properties': {'jsonrpc': {'title': 'Jsonrpc', 'type': 'string', 'example': '2.0', 'const': '2.0'}, 'id': {'title': 'Id', 'anyOf': [{'type': 'string'}, {'type': 'integer'}], 'example': 0}, 'method': {'title': 'Method', 'type': 'string'}, 'params': {'title': 'Params', 'type': 'object'}}, 'additionalProperties': False}}}, 'required': True}, {'oneOf': [{'$ref': '#/definitions/RequestBody'}, {'$ref': '#/definitions/Reference'}]}, deque(['properties', 'paths', 'patternProperties', '^\\/', 'patternProperties', '^(get|put|post|delete|options|head|patch|trace)$', 'properties', 'requestBody', 'oneOf']), None)
    

    It makes impossible use of model generators for pydantic https://pydantic-docs.helpmanual.io/datamodel_code_generator/

    bug wontfix 
    opened by tigrus 2
  • build(deps): bump certifi from 2022.9.24 to 2022.12.7

    build(deps): bump certifi from 2022.9.24 to 2022.12.7

    Bumps certifi from 2022.9.24 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Multiple OpenAPI examples

    Multiple OpenAPI examples

    I understand that I can add examples to endpoints via

    @api.method()
    def endpoint(value1: str = Body(example='test'), value2: int = Body(example=3))
        ...
    

    What to do if I want to add multiple examples as discussed in https://fastapi.tiangolo.com/tutorial/schema-extra-example/?h=examples#body-with-multiple-examples ? The obvious thing to do would be to use list the examples in the Body, as it is done in plain FastAPI, but that doesn't work. Perhaps the Entrypoint#method method can accept an examples parameter (i.e. add it to the MethodRoute class)?

    opened by v-- 0
  • Support by-position parameters

    Support by-position parameters

    According to JSON-RPC 2.0 Specification , the params field of request object may be either by-position (Array) or by-name (Object).

    However the current implementation of fastapi-jsonrpc forces to use by-name parameter:

    https://github.com/smagafurov/fastapi-jsonrpc/blob/1329be64ea635a844cdb529eaf31a1ac3055ae58/fastapi_jsonrpc/init.py#L369

    This causes this awesome library is not usable in some circumstances. Can we support by-position parameters in the future version?

    opened by hongqn 1
  • Add bind_entrypoints option to reproduce FastApi's router feature

    Add bind_entrypoints option to reproduce FastApi's router feature

    closes #18

    Fastapi offers a router functionality detailed here. It can be really useful to split the methods into many files.

    This PR adds an option to bind_entrypoint so that multiple Entrypoint with the same path can be merged.

    Here is an example of how I would use this:

    # main.py
    from items import items_router
    from products import products_router
    
    
    app = jsonrpc.API()
    
    app.bind_entrypoint(items_router)
    
    app.bind_entrypoint(products_router, add_to_existing_path=True)
    
    
    # items.py
    import fastapi_jsonrpc as jsonrpc
    
    items_router = jsonrpc.Entrypoint("/api")
    
    
    @items_router.method()
    def list_items() -> dict:
        return {"from": "list_items"}
    
    # products.py
    import fastapi_jsonrpc as jsonrpc
    
    products_router = jsonrpc.Entrypoint("/api")
    
    
    @products_router.method()
    def list_products() -> dict:
        return {"from": "list_products"}
    

    With this example, both list_items and list_products methods can be accessed from /api.

    I have also added some tests for this feature.

    opened by Smlep 2
  • Allow using routers to split the code

    Allow using routers to split the code

    Hi,

    Fastapi offers a router functionality detailed here. It can be really useful to split the methods into many files.

    It would be nice to be able to do the same things with the JSONRPC methods. Currently, since Entrypoint inherits from fastapi's APIRouter, trying to bind another Entrypoint with the same path won't allow access to the methods from the second Entrypoint.

    There should be a way to bind 2 Entrypoint with the same path to one app, allowing both of their methods to be considered.

    Really great library btw, good work!

    opened by Smlep 3
  • Websocket support

    Websocket support

    Nice library! I was wondering if there are any plans to also support websockets (which is a nice extra fastapi provides), like these libraries do?:

    https://jsonrpcclient.readthedocs.io/en/latest/ https://github.com/codemation/easyrpc

    opened by pjotterplotter 1
Releases(v2.4.1)
Install multiple versions of r2 and its plugins via Pip on any system!

r2env This repository contains the tool available via pip to install and manage multiple versions of radare2 and its plugins. r2-tools doesn't conflic

radare org 18 Oct 11, 2022
fastapi-crud-sync

Developing and Testing an API with FastAPI and Pytest Syncronous Example Want to use this project? Build the images and run the containers: $ docker-c

59 Dec 11, 2022
A simple api written in python/fastapi that serves movies from a cassandra table.

A simple api written in python/fastapi that serves movies from a cassandra table. 1)clone the repo 2)rename sample_global_config_.py to global_config.

Sreeraj 1 Aug 26, 2021
JSON-RPC server based on fastapi

Description JSON-RPC server based on fastapi: https://fastapi.tiangolo.com Motivation Autogenerated OpenAPI and Swagger (thanks to fastapi) for JSON-R

199 Dec 30, 2022
[rewrite 중] 코로나바이러스감염증-19(COVID-19)의 국내/국외 발생 동향 조회 API | Coronavirus Infectious Disease-19 (COVID-19) outbreak trend inquiry API

COVID-19API 코로나 바이러스 감염증-19(COVID-19, SARS-CoV-2)의 국내/외 발생 동향 조회 API Corona Virus Infectious Disease-19 (COVID-19, SARS-CoV-2) outbreak trend inquiry

Euiseo Cha 28 Oct 29, 2022
FastAPI framework plugins

Plugins for FastAPI framework, high performance, easy to learn, fast to code, ready for production fastapi-plugins FastAPI framework plugins Cache Mem

RES 239 Dec 28, 2022
Analytics service that is part of iter8. Robust analytics and control to unleash cloud-native continuous experimentation.

iter8-analytics iter8 enables statistically robust continuous experimentation of microservices in your CI/CD pipelines. For in-depth information about

16 Oct 14, 2021
asgi-server-timing-middleware

ASGI Server-Timing middleware An ASGI middleware that wraps the excellent yappi profiler to let you measure the execution time of any function or coro

33 Dec 15, 2022
Ready-to-use and customizable users management for FastAPI

FastAPI Users Ready-to-use and customizable users management for FastAPI Documentation: https://frankie567.github.io/fastapi-users/ Source Code: https

François Voron 2.4k Jan 01, 2023
An extension for GINO to support Starlette server.

gino-starlette Introduction An extension for GINO to support starlette server. Usage The common usage looks like this: from starlette.applications imp

GINO Community 75 Dec 08, 2022
ASGI middleware for authentication, rate limiting, and building CRUD endpoints.

Piccolo API Utilities for easily exposing Piccolo models as REST endpoints in ASGI apps, such as Starlette and FastAPI. Includes a bunch of useful ASG

81 Dec 09, 2022
Adds integration of the Jinja template language to FastAPI.

fastapi-jinja Adds integration of the Jinja template language to FastAPI. This is inspired and based off fastapi-chamelon by Mike Kennedy. Check that

Marc Brooks 58 Nov 29, 2022
Async and Sync wrapper client around httpx, fastapi, date stuff

lazyapi Async and Sync wrapper client around httpx, fastapi, and datetime stuff. Motivation This library is forked from an internal project that works

2 Apr 19, 2022
Social Distancing Detector using deep learning and capable to run on edge AI devices such as NVIDIA Jetson, Google Coral, and more.

Smart Social Distancing Smart Social Distancing Introduction Getting Started Prerequisites Usage Processor Optional Parameters Configuring AWS credent

Neuralet 129 Dec 12, 2022
基于Pytorch的脚手架项目,Celery+FastAPI+Gunicorn+Nginx+Supervisor实现服务部署,支持Docker发布

cookiecutter-pytorch-fastapi 基于Pytorch的 脚手架项目 按规范添加推理函数即可实现Celery+FastAPI+Gunicorn+Nginx+Supervisor+Docker的快速部署 Requirements Python = 3.6 with pip in

17 Dec 23, 2022
Example app using FastAPI and JWT

FastAPI-Auth Example app using FastAPI and JWT virtualenv -p python3 venv source venv/bin/activate pip3 install -r requirements.txt mv config.yaml.exa

Sander 28 Oct 25, 2022
a lightweight web framework based on fastapi

start-fastapi Version 2021, based on FastAPI, an easy-to-use web app developed upon Starlette Framework Version 2020 中文文档 Requirements python 3.6+ (fo

HiKari 71 Dec 30, 2022
Deploy an inference API on AWS (EC2) using FastAPI Docker and Github Actions

Deploy an inference API on AWS (EC2) using FastAPI Docker and Github Actions To learn more about this project: medium blog post The goal of this proje

Ahmed BESBES 60 Dec 17, 2022
Example projects built using Piccolo.

Piccolo examples Here are some example Piccolo projects. Tutorials headless blog fastapi Build a documented API with an admin in minutes! Live project

15 Nov 23, 2022
Python supercharged for the fastai library

Welcome to fastcore Python goodies to make your coding faster, easier, and more maintainable Python is a powerful, dynamic language. Rather than bake

fast.ai 810 Jan 06, 2023