Skip to content

Instantly share code, notes, and snippets.

@xshapira
Forked from Kludex/main.py
Created August 26, 2022 08:44
Show Gist options
  • Save xshapira/f3273cd168ada929ac26376efd82e2c0 to your computer and use it in GitHub Desktop.
Save xshapira/f3273cd168ada929ac26376efd82e2c0 to your computer and use it in GitHub Desktop.
Document each version on FastAPI
from fastapi import APIRouter, FastAPI
from utils import create_versioning_docs
app = FastAPI(docs_url=None, redoc_url=None)
v1_router = APIRouter(prefix="/v1")
v2_router = APIRouter(prefix="/v2")
create_versioning_docs(v1_router)
create_versioning_docs(v2_router)
@v1_router.get("/")
def get_hello_world():
return {"message": "Hello World"}
@v2_router.get("/")
def get_another_world():
return {"message": "Another World"}
app.include_router(v1_router)
app.include_router(v2_router)
fastapi==0.68.0
uvicorn==0.14.0
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
custom_openapi: DefaultDict[str, Optional[Dict[str, Any]]] = defaultdict(lambda: None)
def create_versioning_docs(router: APIRouter) -> None:
prefix = router.prefix
@router.get("/openapi.json", include_in_schema=False, name=f"{prefix}_openapi")
async def get_openapi_json(request: Request):
global custom_openapi
version = request.url.path.strip("/").split("/")[0]
if custom_openapi[version] is None:
custom_openapi[version] = copy.deepcopy(request.app.openapi())
# 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):
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):
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