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)
[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
Example of integrating Poetry with Docker leveraging multi-stage builds.

Poetry managed Python FastAPI application with Docker multi-stage builds This repo serves as a minimal reference on setting up docker multi-stage buil

Michael Oliver 266 Dec 27, 2022
Code for my JWT auth for FastAPI tutorial

FastAPI tutorial Code for my video tutorial FastAPI tutorial What is FastAPI? FastAPI is a high-performant REST API framework for Python. It's built o

José Haro Peralta 8 Dec 16, 2022
sample web application built with FastAPI + uvicorn

SPARKY Sample web application built with FastAPI & Python 3.8 shows simple Flask-like structure with a Bootstrap template index.html also has a backgr

mrx 21 Jan 03, 2022
Online Repo Browser

MSYS2 Web Interface A simple web interface for browsing the MSYS2 repos. Rebuild CSS/JS (optional): cd frontend npm install npm run build Run for Dev

MSYS2 64 Dec 30, 2022
📦 Autowiring dependency injection container for python 3

Lagom - Dependency injection container What Lagom is a dependency injection container designed to give you "just enough" help with building your depen

Steve B 146 Dec 29, 2022
Money Transaction is a system based on the recent famous FastAPI.

moneyTransfer Overview Money Transaction is a system based on the recent famous FastAPI. techniques selection System's technique selection is as follo

2 Apr 28, 2021
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
Publish Xarray Datasets via a REST API.

Xpublish Publish Xarray Datasets via a REST API. Serverside: Publish a Xarray Dataset through a rest API ds.rest.serve(host="0.0.0.0", port=9000) Clie

xarray-contrib 106 Jan 06, 2023
Fastapi practice project

todo-list-fastapi practice project How to run Install dependencies npm, yarn: standard-version, husky make: script for lint, test pipenv: virtualenv +

Deo Kim 10 Nov 30, 2022
Backend, modern REST API for obtaining match and odds data crawled from multiple sites. Using FastAPI, MongoDB as database, Motor as async MongoDB client, Scrapy as crawler and Docker.

Introduction Apiestas is a project composed of a backend powered by the awesome framework FastAPI and a crawler powered by Scrapy. This project has fo

Fran Lozano 54 Dec 13, 2022
Piccolo Admin provides a simple yet powerful admin interface on top of Piccolo tables

Piccolo Admin Piccolo Admin provides a simple yet powerful admin interface on top of Piccolo tables - allowing you to easily add / edit / filter your

188 Jan 09, 2023
A simple web to serve data table. It is built with Vuetify, Vue, FastApi.

simple-report-data-table-vuetify A simple web to serve data table. It is built with Vuetify, Vue, FastApi. The main features: RBAC with casbin simple

11 Dec 22, 2022
Reusable utilities for FastAPI

Reusable utilities for FastAPI Documentation: https://fastapi-utils.davidmontague.xyz Source Code: https://github.com/dmontagu/fastapi-utils FastAPI i

David Montague 1.3k Jan 04, 2023
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
FastAPI Admin Dashboard based on FastAPI and Tortoise ORM.

FastAPI ADMIN 中文文档 Introduction FastAPI-Admin is a admin dashboard based on fastapi and tortoise-orm. FastAPI-Admin provide crud feature out-of-the-bo

long2ice 1.6k Dec 31, 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
EML analyzer is an application to analyze the EML file

EML analyzer EML analyzer is an application to analyze the EML file which can: Analyze headers. Analyze bodies. Extract IOCs (URLs, domains, IP addres

Manabu Niseki 162 Dec 28, 2022
Basic FastAPI starter with GraphQL, Docker, and MongoDB configurations.

FastAPI + GraphQL Starter A python starter project using FastAPI and GraphQL. This project leverages docker for containerization and provides the scri

Cloud Bytes Collection 1 Nov 24, 2022
A rate limiter for Starlette and FastAPI

SlowApi A rate limiting library for Starlette and FastAPI adapted from flask-limiter. Note: this is alpha quality code still, the API may change, and

Laurent Savaete 565 Jan 02, 2023