All Projects → smagafurov → Fastapi Jsonrpc

smagafurov / Fastapi Jsonrpc

JSON-RPC server based on fastapi

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Fastapi Jsonrpc

Swagger Jsdoc
Generates swagger/openapi specification based on jsDoc comments and YAML files.
Stars: ✭ 1,057 (+1189.02%)
Mutual labels:  swagger, openapi
Flask Restplus Server Example
Real-life RESTful server example on Flask-RESTplus
Stars: ✭ 1,240 (+1412.2%)
Mutual labels:  swagger, openapi
Intellij Swagger
A plugin to help you easily edit Swagger and OpenAPI specification files inside IntelliJ IDEA
Stars: ✭ 1,073 (+1208.54%)
Mutual labels:  swagger, openapi
Paw Swaggerimporter
Swagger/OpenAPI 2.0 Importer for Paw
Stars: ✭ 34 (-58.54%)
Mutual labels:  swagger, openapi
Dredd Example
Example application using Dredd and CI
Stars: ✭ 79 (-3.66%)
Mutual labels:  swagger, openapi
Molten Boilerplate
A boilerplate for the molten framework by Bogdanp https://github.com/Bogdanp/molten
Stars: ✭ 50 (-39.02%)
Mutual labels:  swagger, openapi
Express Jsdoc Swagger
Swagger OpenAPI 3.x generator
Stars: ✭ 69 (-15.85%)
Mutual labels:  swagger, openapi
Swagger2
Loading, parsing and validating requests to HTTP services based on Swagger v2.0 documents
Stars: ✭ 20 (-75.61%)
Mutual labels:  swagger, openapi
Springdoc Openapi
Library for OpenAPI 3 with spring-boot
Stars: ✭ 1,113 (+1257.32%)
Mutual labels:  swagger, openapi
Azure Rest Api Specs
The source for REST API specifications for Microsoft Azure.
Stars: ✭ 1,104 (+1246.34%)
Mutual labels:  swagger, openapi
Openapi Mock Generator
Progressive Web App for generating mocked data from an OpenAPI specification
Stars: ✭ 72 (-12.2%)
Mutual labels:  swagger, openapi
Openapi Spring Webflux Validator
🌱 A friendly kotlin library to validate API endpoints using an OpenApi 3.0 and Swagger 2.0 specification
Stars: ✭ 67 (-18.29%)
Mutual labels:  swagger, openapi
Rolodex
📇API Documentation Generator for Phoenix
Stars: ✭ 34 (-58.54%)
Mutual labels:  swagger, openapi
Compojure Api
Sweet web apis with Compojure & Swagger
Stars: ✭ 1,056 (+1187.8%)
Mutual labels:  swagger, openapi
Fastapi
FastAPI framework, high performance, easy to learn, fast to code, ready for production
Stars: ✭ 39,588 (+48178.05%)
Mutual labels:  swagger, openapi
Oav
Tools for validating OpenAPI (Swagger) files.
Stars: ✭ 55 (-32.93%)
Mutual labels:  swagger, openapi
Spectral
A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v2 & v3.
Stars: ✭ 876 (+968.29%)
Mutual labels:  swagger, openapi
Oval
oval: CLI for (O)penAPI Specification document (val)idation.
Stars: ✭ 15 (-81.71%)
Mutual labels:  swagger, openapi
Connect Api Specification
This repository contains the OpenAPI specification as well as templates for generating SDKs for Square's APIs
Stars: ✭ 56 (-31.71%)
Mutual labels:  swagger, openapi
Vue Openapi
OpenAPI viewer component for VueJS
Stars: ✭ 66 (-19.51%)
Mutual labels:  swagger, openapi

Description

JSON-RPC server based on fastapi:

https://fastapi.tiangolo.com

Motivation ^^^^^^^^^^

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

Installation

.. code-block:: bash

pip install fastapi-jsonrpc

Documentation

Read FastAPI documentation and see usage examples bellow

Simple usage example

.. code-block:: bash

pip install uvicorn

example1.py

.. code-block:: python

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

.. code-block:: bash

pip install uvicorn

example2.py

.. code-block:: python

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

.. image:: ./images/fastapi-jsonrpc.png

Development

  • Install poetry

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

  • Install dephell

    .. code-block:: bash

      pip install dephell
    
  • Install dependencies

    .. code-block:: bash

      poetry update
    
  • Regenerate README.rst

    .. code-block:: bash

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

    Edit pyproject.toml

    .. code-block:: bash

      poetry update
      dephell deps convert
    
  • Bump version

    .. code-block:: bash

      poetry version patch
      dephell deps convert
    
  • Publish to pypi

    .. code-block:: bash

      poetry publish --build
    
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].