FastAPI framework plugins

Overview

Plugins for FastAPI framework, high performance, easy to learn, fast to code, ready for production

Build Status Coverage Package version Join the chat at https://gitter.im/tiangolo/fastapi

fastapi-plugins

FastAPI framework plugins

Changes

See release notes

Installation

pip install fastapi-plugins
pip install fastapi-plugins[memcached]
pip install fastapi-plugins[all]

Plugins

Cache

Memcached

Valid variable are

  • MEMCACHED_HOST - Memcached server host.
  • MEMCACHED_PORT - Memcached server port. Default is 11211.
  • MEMCACHED_POOL_MINSIZE - Minimum number of free connection to create in pool. Default is 1.
  • MEMCACHED_POOL_SIZE - Maximum number of connection to keep in pool. Default is 10. Must be greater than 0. None is disallowed.
  • MEMCACHED_PRESTART_TRIES - The number tries to connect to the a Memcached instance.
  • MEMCACHED_PRESTART_WAIT - The interval in seconds to wait between connection failures on application start.
Example
    # run with `uvicorn demo_app:app`
    import typing
    import fastapi
    import pydantic
    
    from fastapi_plugins.memcached import MemcachedSettings
    from fastapi_plugins.memcached import MemcachedClient
    from fastapi_plugins.memcached import memcached_plugin
    from fastapi_plugins.memcached import depends_memcached
    
    class AppSettings(OtherSettings, MemcachedSettings):
        api_name: str = str(__name__)
    
    app = fastapi.FastAPI()
    config = AppSettings()
    
    @app.get("/")
    async def root_get(
            cache: MemcachedClient=fastapi.Depends(depends_memcached),
    ) -> typing.Dict:
        await cache.set(b'Hello', b'World')
        await cache.get(b'Hello')
        return dict(ping=await cache.ping())
    
    @app.on_event('startup')
    async def on_startup() -> None:
        await memcached_plugin.init_app(app, config=config)
        await memcached_plugin.init()
    
    @app.on_event('shutdown')
    async def on_shutdown() -> None:
        await memcached_plugin.terminate()

Redis

Supports

  • single instance
  • sentinel

Valid variable are

  • REDIS_TYPE
    • redis - single Redis instance
    • sentinel - Redis cluster
  • REDIS_URL - URL to connect to Redis server. Example redis://user:[email protected]:6379/2. Supports protocols redis://, rediss:// (redis over TLS) and unix://.
  • REDIS_HOST - Redis server host.
  • REDIS_PORT - Redis server port. Default is 6379.
  • REDIS_PASSWORD - Redis password for server.
  • REDIS_DB - Redis db (zero-based number index). Default is 0.
  • REDIS_CONNECTION_TIMEOUT - Redis connection timeout. Default is 2.
  • REDIS_POOL_MINSIZE - Minimum number of free connection to create in pool. Default is 1.
  • REDIS_POOL_MAXSIZE - Maximum number of connection to keep in pool. Default is 10. Must be greater than 0. None is disallowed.
  • REDIS_SENTINELS - List or a tuple of Redis sentinel addresses.
  • REDIS_SENTINEL_MASTER - The name of the master server in a sentinel configuration. Default is mymaster.
  • REDIS_PRESTART_TRIES - The number tries to connect to the a Redis instance.
  • REDIS_PRESTART_WAIT - The interval in seconds to wait between connection failures on application start.
Example
    # run with `uvicorn demo_app:app`
    import typing
    import aioredis
    import fastapi
    import pydantic
    import fastapi_plugins
    
    class AppSettings(OtherSettings, fastapi_plugins.RedisSettings):
        api_name: str = str(__name__)
    
    app = fastapi.FastAPI()
    config = AppSettings()
    
    @app.get("/")
    async def root_get(
            cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis),
    ) -> typing.Dict:
        return dict(ping=await cache.ping())
    
    @app.on_event('startup')
    async def on_startup() -> None:
        await fastapi_plugins.redis_plugin.init_app(app, config=config)
        await fastapi_plugins.redis_plugin.init()
    
    @app.on_event('shutdown')
    async def on_shutdown() -> None:
        await fastapi_plugins.redis_plugin.terminate()
Example with Docker Compose - Redis
version: '3.7'
services:
  redis:
    image: redis
    ports:
      - "6379:6379"
  demo_fastapi_plugin:
    image:    demo_fastapi_plugin
    environment:
      - REDIS_TYPE=redis
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    ports:
      - "8000:8000"
Example with Docker Compose - Redis Sentinel
version: '3.7'
services:
  ...
  redis-sentinel:
    ports:
      - "26379:26379"
    environment:
      - ...
    links:
      - redis-master
      - redis-slave
  demo_fastapi_plugin:
    image:    demo_fastapi_plugin
    environment:
      - REDIS_TYPE=sentinel
      - REDIS_SENTINELS=redis-sentinel:26379
    ports:
      - "8000:8000"

Scheduler

Simple schedule an awaitable job as a task.

  • long running async functions (e.g. monitor a file a system or events)
  • gracefully cancel spawned tasks

Valid variable are:

  • AIOJOBS_CLOSE_TIMEOUT - The timeout in seconds before canceling a task.
  • AIOJOBS_LIMIT - The number of concurrent tasks to be executed.
  • AIOJOBS_PENDING_LIMIT - The number of pending jobs (waiting fr execution).
# run with `uvicorn demo_app:app`
import ...
import fastapi_plugins

class AppSettings(OtherSettings, fastapi_plugins.RedisSettings, fastapi_plugins.SchedulerSettings):
    api_name: str = str(__name__)

app = fastapi.FastAPI()
config = AppSettings()

@app.post("/jobs/schedule/<timeout>")
async def job_post(
    timeout: int=fastapi.Query(..., title='the job sleep time'),
    cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis),
    scheduler: aiojobs.Scheduler=fastapi.Depends(fastapi_plugins.depends_scheduler),  # @IgnorePep8
) -> str:
    async def coro(job_id, timeout, cache):
        await cache.set(job_id, 'processing')
        try:
            await asyncio.sleep(timeout)
            if timeout == 8:
                raise Exception('ugly error')
        except asyncio.CancelledError:
            await cache.set(job_id, 'canceled')
        except Exception:
            await cache.set(job_id, 'erred')
        else:
            await cache.set(job_id, 'success')

    job_id = str(uuid.uuid4()).replace('-', '')
    await cache.set(job_id, 'pending')
    await scheduler.spawn(coro(job_id, timeout, cache))
    return job_id

@app.get("/jobs/status/<job_id>")
async def job_get(
    job_id: str=fastapi.Query(..., title='the job id'),
    cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis),
) -> typing.Dict:
    status = await cache.get(job_id)
    if status is None:
        raise fastapi.HTTPException(
            status_code=starlette.status.HTTP_404_NOT_FOUND,
            detail='Job %s not found' % job_id
        )
    return dict(job_id=job_id, status=status)

@app.on_event('startup')
async def on_startup() -> None:
    await fastapi_plugins.redis_plugin.init_app(app, config=config)
    await fastapi_plugins.redis_plugin.init()
    await fastapi_plugins.scheduler_plugin.init_app(app=app, config=config)
    await fastapi_plugins.scheduler_plugin.init()

@app.on_event('shutdown')
async def on_shutdown() -> None:
    await fastapi_plugins.scheduler_plugin.terminate()
    await fastapi_plugins.redis_plugin.terminate()

... more already in progress ...

Development

Issues and suggestions are welcome through issues

License

This project is licensed under the terms of the MIT license.

Comments
  • Why are you not closing the database connection before shutdown?

    Why are you not closing the database connection before shutdown?

    We (our team) were trying with your library, and stumbled on this "missing" feature.

    It's important to close the connections for a truly graceful shutdown. Was that a project decision? Didn't you just think about it?

    More important: would you be willing to receive a proposal for this implementation?

    question 
    opened by azisaka 6
  • Fix redis_url ignored

    Fix redis_url ignored

    redis_url setting is currently ignored and DSN is always built by using separate parameters

    This is just a PoC, I will provide a more thorough PR in the next days

    bug 
    opened by yakky 6
  • Remove __all__ in __init__

    Remove __all__ in __init__

    Hi, I noticed this project uses __all__ for most of its modules. However, in fastapi_plugins/__init__.py I see __all__ = [] which causes my editor to warn with things like 'RedisSettings' is not declared in __all__. I decided to simply remove __all__ from there since it is optional. Alternatively, I could combine __all__ from each of the imported modules.

    What do you think?

    bug 
    opened by MatthewScholefield 5
  •  AttributeError: 'State' object has no attribute 'REDIS'

    AttributeError: 'State' object has no attribute 'REDIS'

    Pytest API testing does not work if a function has a cache dependency.

    Here is the example

    @router.post("/login/", response_model=Token)
    async def login(form_data: OAuth2PasswordRequestForm = Depends(),
                    cache: aioredis.Redis = Depends(fastapi_plugins.depends_redis)):
                    ...
                    await cache.setex("SomeKey", 300, "SomeValue")
    
    
        @pytest.mark.asyncio
        async def test_login_view_pass(self, client):
            data = UserInput(**self.__generate_data())
            await user_create(data)
            response = await client.post(f"{settings.API_VERSION}/users/login/",
                                         data={"username": data.username,
                                               "password": data.password},
                                         headers={"Content-Type": "application/x-www-form-urlencoded"})
            assert response.status_code == status.HTTP_200_OK
    
    
    self = <starlette.datastructures.State object at 0x7f10ceccd610>, key = 'REDIS'
    
        def __getattr__(self, key: typing.Any) -> typing.Any:
            try:
                return self._state[key]
            except KeyError:
                message = "'{}' object has no attribute '{}'"
    >           raise AttributeError(message.format(self.__class__.__name__, key))
    E           AttributeError: 'State' object has no attribute 'REDIS'
    
    /usr/local/lib/python3.8/site-packages/starlette/datastructures.py:672: AttributeError
    

    Is there any way to solve this issue ?

    opened by Koshkaj 4
  • aioredis version issue: `AttributeError: module 'aioredis' has no attribute 'create_redis_pool'`

    aioredis version issue: `AttributeError: module 'aioredis' has no attribute 'create_redis_pool'`

    aioredis does not import anymore create_redis_pool method in its __init__ at least after v1.3.1 see here.

    Unfortunately fastapi-plugins is still using that method in _redis.init() and it defines aioredis>=1.3.* in its setup.py see here

    That can cause to raise the following exception in case aioredis > 1.3.1 has been installed in your system

    AttributeError: module 'aioredis' has no attribute 'create_redis_pool'
    
    bug 
    opened by kinderp 3
  • The startup example codes do not work, cannot `Depends`  fastapi_plugins.depends_redis

    The startup example codes do not work, cannot `Depends` fastapi_plugins.depends_redis

    I test fastapi-plugins using the example codes ,but it corrupts with

    fastapi.exceptions.FastAPIError: Invalid args for response field! 
    Hint: check that <class 'starlette.requests.HTTPConnection'> is a valid pydantic field type
    

    the codes all go here

    import fastapi, fastapi_plugins
    import aioredis, pydantic, typing
    
    @fastapi_plugins.registered_configuration
    class AppSettings(
            fastapi_plugins.ControlSettings,
            fastapi_plugins.RedisSettings,
            fastapi_plugins.SchedulerSettings
    ):
        api_name: str = str(__name__)
    
    
    app = fastapi.FastAPI()
    config = fastapi_plugins.get_config()
    
    @app.get("/")
    async def root_get(
            cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis), # TODO corrupts here,
            conf: pydantic.BaseSettings=fastapi.Depends(fastapi_plugins.depends_config) # noqa E501
    ) -> typing.Dict:
        return dict(ping=await cache.ping(), api_name=conf.api_name)
    
    @app.on_event('startup')
    async def on_startup() -> None:
        await fastapi_plugins.config_plugin.init_app(app, config)
        await fastapi_plugins.config_plugin.init()
        await fastapi_plugins.redis_plugin.init_app(app, config=config)
        await fastapi_plugins.redis_plugin.init()
        await fastapi_plugins.scheduler_plugin.init_app(app=app, config=config)
        await fastapi_plugins.scheduler_plugin.init()
        await fastapi_plugins.control_plugin.init_app(app, config=config, version="0.0.1", environ=config.dict())
        await fastapi_plugins.control_plugin.init()
    
    
    @app.on_event('shutdown')
    async def on_shutdown() -> None:
        await fastapi_plugins.control_plugin.terminate()
        await fastapi_plugins.scheduler_plugin.terminate()
        await fastapi_plugins.redis_plugin.terminate()
        await fastapi_plugins.config_plugin.terminate()
    

    packages info:

    pip show fastapi-plugins
    #Name: fastapi-plugins
    #Version: 0.8.1
    
    pip show fastapi
    #Name: fastapi
    #Version: 0.54.2
    

    what have I missed?

    opened by tearf001 2
Releases(0.11.0)
Owner
RES
software engineer :: python && c++
RES
Prometheus integration for Starlette.

Starlette Prometheus Introduction Prometheus integration for Starlette. Requirements Python 3.6+ Starlette 0.9+ Installation $ pip install starlette-p

José Antonio Perdiguero 229 Dec 21, 2022
A simple Redis Streams backed Chat app using Websockets, Asyncio and FastAPI/Starlette.

redis-streams-fastapi-chat A simple demo of Redis Streams backed Chat app using Websockets, Python Asyncio and FastAPI/Starlette. Requires Python vers

ludwig404 135 Dec 19, 2022
Flask + marshmallow for beautiful APIs

Flask-Marshmallow Flask + marshmallow for beautiful APIs Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmal

marshmallow-code 768 Dec 22, 2022
스타트업 개발자 채용

스타트업 개발자 채용 大 박람회 Seed ~ Series B에 있는 스타트업을 위한 채용정보 페이지입니다. Back-end, Frontend, Mobile 등 개발자를 대상으로 진행하고 있습니다. 해당 스타트업에 종사하시는 분뿐만 아니라 채용 관련 정보를 알고 계시다면

JuHyun Lee 58 Dec 14, 2022
This code generator creates FastAPI app from an openapi file.

fastapi-code-generator This code generator creates FastAPI app from an openapi file. This project is an experimental phase. fastapi-code-generator use

Koudai Aono 632 Jan 05, 2023
Run your jupyter notebooks as a REST API endpoint. This isn't a jupyter server but rather just a way to run your notebooks as a REST API Endpoint.

Jupter Notebook REST API Run your jupyter notebooks as a REST API endpoint. This isn't a jupyter server but rather just a way to run your notebooks as

Invictify 54 Nov 04, 2022
Easy and secure implementation of Azure AD for your FastAPI APIs 🔒

FastAPI-Azure-auth Azure AD Authentication for FastAPI apps made easy. 🚀 Description FastAPI is a modern, fast (high-performance), web framework for

Intility 216 Dec 27, 2022
Opinionated authorization package for FastAPI

FastAPI Authorization Installation pip install fastapi-authorization Usage Currently, there are two models available: RBAC: Role-based Access Control

Marcelo Trylesinski 18 Jul 04, 2022
Full stack, modern web application generator. Using FastAPI, PostgreSQL as database, Docker, automatic HTTPS and more.

Full Stack FastAPI and PostgreSQL - Base Project Generator Generate a backend and frontend stack using Python, including interactive API documentation

Sebastián Ramírez 10.8k Jan 08, 2023
A Sample App to Demonstrate React Native and FastAPI Integration

React Native - Service Integration with FastAPI Backend. A Sample App to Demonstrate React Native and FastAPI Integration UI Based on NativeBase toolk

YongKi Kim 4 Nov 17, 2022
Starlette middleware for Prerender

Prerender Python Starlette Starlette middleware for Prerender Documentation: https://BeeMyDesk.github.io/prerender-python-starlette/ Source Code: http

BeeMyDesk 14 May 02, 2021
Prometheus exporter for metrics from the MyAudi API

Prometheus Audi Exporter This Prometheus exporter exports metrics that it fetches from the MyAudi API. Usage Checkout submodules Install dependencies

Dieter Maes 7 Dec 19, 2022
Pagination support for flask

flask-paginate Pagination support for flask framework (study from will_paginate). It supports several css frameworks. It requires Python2.6+ as string

Lix Xu 264 Nov 07, 2022
A web application using [FastAPI + streamlit + Docker] Neural Style Transfer (NST) refers to a class of software algorithms that manipulate digital images

Neural Style Transfer Web App - [FastAPI + streamlit + Docker] NST - application based on the Perceptual Losses for Real-Time Style Transfer and Super

Roman Spiridonov 3 Dec 05, 2022
A Flask extension that enables or disables features based on configuration.

Flask FeatureFlags This is a Flask extension that adds feature flagging to your applications. This lets you turn parts of your site on or off based on

Rachel Greenfield 131 Sep 26, 2022
FastAPI CRUD template using Deta Base

Deta Base FastAPI CRUD FastAPI CRUD template using Deta Base Setup Install the requirements for the CRUD: pip3 install -r requirements.txt Add your D

Sebastian Ponce 2 Dec 15, 2021
Cookiecutter template for FastAPI projects using: Machine Learning, Poetry, Azure Pipelines and Pytests

cookiecutter-fastapi In order to create a template to FastAPI projects. 🚀 Important To use this project you don't need fork it. Just run cookiecutter

Arthur Henrique 225 Dec 28, 2022
Flood Detection with Google Earth Engine

ee-fastapi: Flood Detection System A ee-fastapi is a simple FastAPI web application for performing flood detection using Google Earth Engine in the ba

Cesar Aybar 69 Jan 06, 2023
An alternative implement of Imjad API | Imjad API 的开源替代

HibiAPI An alternative implement of Imjad API. Imjad API 的开源替代. 前言 由于Imjad API这是什么?使用人数过多, 致使调用超出限制, 所以本人希望提供一个开源替代来供社区进行自由的部署和使用, 从而减轻一部分该API的使用压力 优势

Mix Technology 450 Dec 29, 2022
User authentication fastapi with python

user-authentication-fastapi Authentication API Development Setup environment You should create a virtual environment and activate it: virtualenv venv

Sabir Hussain 3 Mar 03, 2022