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)
MLServer

MLServer An open source inference server to serve your machine learning models. ⚠️ This is a Work in Progress. Overview MLServer aims to provide an ea

Seldon 341 Jan 03, 2023
Web Version of avatarify to democratize even further

Web-avatarify for image animations This is the code base for this website and its backend. This aims to bring technology closer to everyone, just by a

Carlos Andrés Álvarez Restrepo 66 Nov 09, 2022
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
REST API with FastAPI and SQLite3.

REST API with FastAPI and SQLite3

Luis Quiñones Requelme 2 Mar 14, 2022
API & Webapp to answer questions about COVID-19. Using NLP (Question Answering) and trusted data sources.

This open source project serves two purposes. Collection and evaluation of a Question Answering dataset to improve existing QA/search methods - COVID-

deepset 329 Nov 10, 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
TODO aplication made with Python's FastAPI framework and Hexagonal Architecture

FastAPI Todolist Description Todolist aplication made with Python's FastAPI framework and Hexagonal Architecture. This is a test repository for the pu

Giovanni Armane 91 Dec 31, 2022
A complete end-to-end machine learning portal that covers processes starting from model training to the model predicting results using FastAPI.

Machine Learning Portal Goal Application Workflow Process Design Live Project Goal A complete end-to-end machine learning portal that covers processes

Shreyas K 39 Nov 24, 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
Lung Segmentation with fastapi

Lung Segmentation with fastapi This app uses FastAPI as backend. Usage for app.py First install required libraries by running: pip install -r requirem

Pejman Samadi 0 Sep 20, 2022
FastAPI Boilerplate

FastAPI Boilerplate Features SQlAlchemy session Custom user class Top-level dependency Dependencies for specific permissions Celery SQLAlchemy for asy

Hide 417 Jan 07, 2023
FastAPI on Google Cloud Run

cloudrun-fastapi Boilerplate for running FastAPI on Google Cloud Run with Google Cloud Build for deployment. For all documentation visit the docs fold

Anthony Corletti 139 Dec 27, 2022
signal-cli-rest-api is a wrapper around signal-cli and allows you to interact with it through http requests

signal-cli-rest-api signal-cli-rest-api is a wrapper around signal-cli and allows you to interact with it through http requests. Features register/ver

Sebastian Noel Lübke 31 Dec 09, 2022
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
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
This is a FastAPI application that provides a RESTful API for the Podcasts from different podcast's RSS feeds

The Podcaster API This is a FastAPI application that provides a RESTful API for the Podcasts from different podcast's RSS feeds. The API response is i

Sagar Giri 2 Nov 07, 2021
The template for building scalable web APIs based on FastAPI, Tortoise ORM and other.

FastAPI and Tortoise ORM. Powerful but simple template for web APIs w/ FastAPI (as web framework) and Tortoise-ORM (for working via database without h

prostomarkeloff 95 Jan 08, 2023
Backend logic implementation for realworld with awesome FastAPI

Backend logic implementation for realworld with awesome FastAPI

Nik 2.2k Jan 08, 2023
A Jupyter server based on FastAPI (Experimental)

jupyverse is experimental and should not be used in place of jupyter-server, which is the official Jupyter server.

Jupyter Server 122 Dec 27, 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