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:password@localhost: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
Flask-vs-FastAPI - Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks.

Flask-vs-FastAPI Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks. IntroductionIn Flask is a popular mic

Mithlesh Navlakhe 1 Jan 1, 2022
FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by django-admin, and has as many powerful functions as django-admin.

简体中文 | English 项目介绍 FastAPI-Amis-Admin fastapi-amis-admin是一个拥有高性能,高效率,易拓展的fastapi管理后台框架. 启发自Django-Admin,并且拥有不逊色于Django-Admin的强大功能. 源码 · 在线演示 · 文档 · 文

AmisAdmin 318 Dec 31, 2022
:rocket: CLI tool for FastAPI. Generating new FastAPI projects & boilerplates made easy.

Project generator and manager for FastAPI. Source Code: View it on Github Features ?? Creates customizable project boilerplate. Creates customizable a

Yagiz Degirmenci 1k Jan 2, 2023
Simple FastAPI Example : Blog API using FastAPI : Beginner Friendly

fastapi_blog FastAPI : Simple Blog API with CRUD operation Steps to run the project: git clone https://github.com/mrAvi07/fastapi_blog.git cd fastapi-

Avinash Alanjkar 1 Oct 8, 2022
Пример использования GraphQL Ariadne с FastAPI и сравнение его с GraphQL Graphene FastAPI

FastAPI Ariadne Example Пример использования GraphQL Ariadne с FastAPI и сравнение его с GraphQL Graphene FastAPI - GitHub ###Запуск на локальном окру

ZeBrains Team 9 Nov 10, 2022
Sample-fastapi - A sample app using Fastapi that you can deploy on App Platform

Getting Started We provide a sample app using Fastapi that you can deploy on App

Erhan BÜTE 2 Jan 17, 2022
FastAPI Server Session is a dependency-based extension for FastAPI that adds support for server-sided session management

FastAPI Server-sided Session FastAPI Server Session is a dependency-based extension for FastAPI that adds support for server-sided session management.

DevGuyAhnaf 5 Dec 23, 2022
fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability

FastAPI2 Admin Introduction fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability. Now

Glib 14 Dec 5, 2022
Code Specialist 27 Oct 16, 2022
Fastapi-ml-template - Fastapi ml template with python

FastAPI ML Template Run Web API Local $ sh run.sh # poetry run uvicorn app.mai

Yuki Okuda 29 Nov 20, 2022
A FastAPI Framework for things like Database, Redis, Logging, JWT Authentication and Rate Limits

A FastAPI Framework for things like Database, Redis, Logging, JWT Authentication and Rate Limits Install You can install this Library with: pip instal

Tert0 33 Nov 28, 2022
API using python and Fastapi framework

Welcome ?? CFCApi is a API DEVELOPMENT PROJECT UNDER CODE FOR COMMUNITY ! Project Walkthrough ?? CFCApi run on Python using FASTapi Framework Docs The

Abhishek kushwaha 7 Jan 2, 2023
An extension library for FastAPI framework

FastLab An extension library for FastAPI framework Features Logging Models Utils Routers Installation use pip to install the package: pip install fast

Tezign Lab 10 Jul 11, 2022
This is an API developed in python with the FastApi framework and putting into practice the recommendations of the book Clean Architecture in Python by Leonardo Giordani,

This is an API developed in python with the FastApi framework and putting into practice the recommendations of the book Clean Architecture in Python by Leonardo Giordani,

null 0 Sep 24, 2022
A dynamic FastAPI router that automatically creates CRUD routes for your models

⚡ Create CRUD routes with lighting speed ⚡ A dynamic FastAPI router that automatically creates CRUD routes for your models

Adam Watkins 950 Jan 8, 2023
Adds simple SQLAlchemy support to FastAPI

FastAPI-SQLAlchemy FastAPI-SQLAlchemy provides a simple integration between FastAPI and SQLAlchemy in your application. It gives access to useful help

Michael Freeborn 465 Jan 7, 2023
Opinionated set of utilities on top of FastAPI

FastAPI Contrib Opinionated set of utilities on top of FastAPI Free software: MIT license Documentation: https://fastapi-contrib.readthedocs.io. Featu

identix.one 543 Jan 5, 2023
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 4, 2023
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 5, 2023