Fastopenapi
FastOpenAPI is a library for generating and integrating OpenAPI schemas using Pydantic v2 and various frameworks (AioHttp, Django, Falcon, Flask, Quart, Sanic, Starlette, Tornado).
Install / Use
/learn @mr-fatalyst/FastopenapiREADME
<p align="center">
<img src="https://raw.githubusercontent.com/mr-fatalyst/fastopenapi/master/logo.png" alt="Logo">
</p>
<p align="center">
<b>FastOpenAPI</b> is a library for generating and integrating OpenAPI schemas using Pydantic and various frameworks.
</p>
<p align="center">
This project was inspired by <a href="https://fastapi.tiangolo.com/">FastAPI</a> and aims to provide a similar developer-friendly experience.
</p>
<p align="center">
<img src="https://img.shields.io/github/license/mr-fatalyst/fastopenapi">
<img src="https://github.com/mr-fatalyst/fastopenapi/actions/workflows/master.yml/badge.svg">
<img src="https://codecov.io/gh/mr-fatalyst/fastopenapi/branch/master/graph/badge.svg">
<img src="https://img.shields.io/pypi/v/fastopenapi">
<img src="https://img.shields.io/pypi/pyversions/fastopenapi">
<img src="https://static.pepy.tech/badge/fastopenapi" alt="PyPI Downloads">
</p>
📦 Installation
Install only FastOpenAPI:
pip install fastopenapi
Install FastOpenAPI with a specific framework:
pip install fastopenapi[aiohttp]
pip install fastopenapi[falcon]
pip install fastopenapi[flask]
pip install fastopenapi[quart]
pip install fastopenapi[sanic]
pip install fastopenapi[starlette]
pip install fastopenapi[tornado]
pip install fastopenapi[django]
🛠️ Quick Start
Step 1. Create an application
- Create the
main.pyfile - Copy the code from an example
- For some examples uvicorn is required (
pip install uvicorn)
Examples:
-
<details> <summary>Click to expand the AioHTTP Example</summary>
</details>from aiohttp import web from pydantic import BaseModel from fastopenapi.routers import AioHttpRouter app = web.Application() router = AioHttpRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) async def hello(name: str): """Say hello from aiohttp""" return HelloResponse(message=f"Hello, {name}! It's aiohttp!") if __name__ == "__main__": web.run_app(app, host="127.0.0.1", port=8000) -
<details> <summary>Click to expand the Falcon Example</summary>
</details> <details> <summary>Click to expand the Falcon Async Example</summary>from falcon import App from pydantic import BaseModel from wsgiref.simple_server import make_server from fastopenapi.routers import FalconRouter app = App() router = FalconRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) def hello(name: str): """Say hello from Falcon""" return HelloResponse(message=f"Hello, {name}! It's Falcon!") if __name__ == "__main__": with make_server("", 8000, app) as httpd: print("Serving on port 8000...") httpd.serve_forever()
</details>import falcon.asgi import uvicorn from pydantic import BaseModel from fastopenapi.routers import FalconAsyncRouter app = falcon.asgi.App() router = FalconAsyncRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) async def hello(name: str): """Say hello from Falcon""" return HelloResponse(message=f"Hello, {name}! It's Falcon!") if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000) -
<details> <summary>Click to expand the Flask Example</summary>
</details>from flask import Flask from pydantic import BaseModel from fastopenapi.routers import FlaskRouter app = Flask(__name__) router = FlaskRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) def hello(name: str): """Say hello from Flask""" return HelloResponse(message=f"Hello, {name}! It's Flask!") if __name__ == "__main__": app.run(port=8000) -
<details> <summary>Click to expand the Quart Example</summary>
</details>from pydantic import BaseModel from quart import Quart from fastopenapi.routers import QuartRouter app = Quart(__name__) router = QuartRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) async def hello(name: str): """Say hello from Quart""" return HelloResponse(message=f"Hello, {name}! It's Quart!") if __name__ == "__main__": app.run(port=8000) -
<details> <summary>Click to expand the Sanic Example</summary>
</details>from pydantic import BaseModel from sanic import Sanic from fastopenapi.routers import SanicRouter app = Sanic("MySanicApp") router = SanicRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) async def hello(name: str): """Say hello from Sanic""" return HelloResponse(message=f"Hello, {name}! It's Sanic!") if __name__ == "__main__": app.run(host="0.0.0.0", port=8000) -
<details> <summary>Click to expand the Starlette Example</summary>
</details>import uvicorn from pydantic import BaseModel from starlette.applications import Starlette from fastopenapi.routers import StarletteRouter app = Starlette() router = StarletteRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) async def hello(name: str): """Say hello from Starlette""" return HelloResponse(message=f"Hello, {name}! It's Starlette!") if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000) -
<details> <summary>Click to expand the Tornado Example</summary>
</details>import asyncio from pydantic import BaseModel from tornado.web import Application from fastopenapi.routers.tornado import TornadoRouter app = Application() router = TornadoRouter(app=app) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) def hello(name: str): """Say hello from Tornado""" return HelloResponse(message=f"Hello, {name}! It's Tornado!") async def main(): app.listen(8000) await asyncio.Event().wait() if __name__ == "__main__": asyncio.run(main()) -
<details> <summary>Click to expand the Django Example</summary>
</details>from django.conf import settings from django.core.management import call_command from django.core.wsgi import get_wsgi_application from django.urls import path from pydantic import BaseModel from fastopenapi.routers import DjangoRouter settings.configure(DEBUG=True, SECRET_KEY="__CHANGEME__", ROOT_URLCONF=__name__) application = get_wsgi_application() router = DjangoRouter(app=True) class HelloResponse(BaseModel): message: str @router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse) def hello(name: str): """Say hello from django""" return HelloResponse(message=f"Hello, {name}! It's Django!") urlpatterns = [path("", router.urls)] if __name__ == "__main__": call_command("runserver")
Step 2. Run the server
Launch the application:
python main.py
Once launched, the documentation will be available at:
Swagger UI:
http://127.0.0.1:8000/docs
ReDoc UI:
http://127.0.0.1:8000/redoc
⚙️ Features
- Generate OpenAPI schemas with Pydantic v2.
- Data validation using Pydantic models.
- Supports multiple frameworks: AIOHTTP, Falcon, Flask, Quart, Sanic, Starlette, Tornado, Django.
- Proxy routing provides FastAPI-style routing
📖 Documentation
Explore the Docs for an overview of FastOpenAPI, its core components, and usage guidelines. The documentation is continuously updated and improved.
📂 Advanced Examples
Examples of integration and detailed usage for each framework are available in the examples directory.
