Last active
September 21, 2024 10:34
-
-
Save vicchi/81213006e2fd7049da9e3aa10728af06 to your computer and use it in GitHub Desktop.
Versioned documentation in FastAPI, based on https://gist.github.com/Kludex/1c515aa38d22ec28d514da6b6f36da9f
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# uvicorn main:app --host $(hostname) --port 8080 --log-level debug --reload | |
from fastapi import APIRouter, FastAPI | |
from utils import create_versioned_docs | |
VERSION = '2.0.0' | |
TITLE = 'Sample Versioned API' | |
DESCRIPTION = 'Sample versioned API blurb' | |
app = FastAPI(docs_url=None, redoc_url=None, title=TITLE, version=VERSION, description=DESCRIPTION) | |
v1_router = APIRouter(prefix="/v1") | |
v2_router = APIRouter(prefix="/v2") | |
info = { | |
'version': '1.2.0', | |
'title': 'Sample Versioned API v1', | |
'description': 'Version specific blurb for v1' | |
} | |
create_versioned_docs(v1_router, **info) | |
info = { | |
'version': '2.0.0', | |
'title': 'Sample Versioned API v2', | |
'description': 'Version specific blurb for v2' | |
} | |
create_versioned_docs(v2_router, **info) | |
@v1_router.get("/") | |
def get_hello_world(): | |
return { | |
"version": "v1", | |
"message": "Hello World" | |
} | |
@v1_router.get("/foo") | |
def get_foo(): | |
return { | |
"version": "v1", | |
"message": "foo" | |
} | |
@v2_router.get("/") | |
def get_another_world(): | |
return { | |
"version": "v2", | |
"message": "Another World" | |
} | |
@v2_router.get("/bar") | |
def get_bar(): | |
return { | |
"version": "v2", | |
"message": "bar" | |
} | |
app.include_router(v1_router) | |
app.include_router(v2_router) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fastapi>=0.68.1 | |
gunicorn>=20.1.0 | |
pydantic>=1.8.2 | |
pylint>=2.10.2 | |
uvicorn>=0.15.0 | |
yapf>=0.31.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import copy | |
from collections import defaultdict | |
from typing import Any, DefaultDict, Dict, Optional | |
from fastapi import APIRouter, Request | |
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html | |
from fastapi.responses import HTMLResponse | |
custom_openapi: DefaultDict[str, Optional[Dict[str, Any]]] = defaultdict(lambda: None) | |
def create_versioned_docs(router: APIRouter, **info) -> None: | |
prefix = router.prefix | |
@router.get("/openapi.json", include_in_schema=False, name=f"{prefix}_openapi") | |
async def get_openapi_json(request: Request) -> dict: | |
version = request.url.path.strip("/").split("/")[0] | |
if custom_openapi[version] is None: | |
custom_openapi[version] = copy.deepcopy(request.app.openapi()) | |
for key, value in info.items(): | |
custom_openapi[version]['info'][key] = value | |
# Remove other version tags on openapi schema. | |
for path in custom_openapi[version]["paths"].copy(): | |
if not path.startswith(f"/{version}"): | |
del custom_openapi[version]["paths"][path] | |
return custom_openapi[version] | |
@router.get("/docs", include_in_schema=False, name=f"{prefix}_swagger") | |
async def get_swagger(request: Request) -> HTMLResponse: | |
return get_swagger_ui_html( | |
openapi_url=f"{prefix}/openapi.json", | |
title=request.app.title + " - Swagger UI", | |
) | |
@router.get("/redoc", include_in_schema=False, name=f"{prefix}_redoc") | |
async def redoc_html(request: Request) -> HTMLResponse: | |
return get_redoc_html( | |
openapi_url=f"{prefix}/openapi.json", | |
title=request.app.title + " - ReDoc" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment