FastAPI Router Versioning¶
Router-based API versioning for FastAPI, with per-version docs and a declarative route lifecycle.
Running multiple API versions side by side usually means duplicating routers, hand-rolling prefixes, or branching on request paths. RouterVersioner does it declaratively instead: annotate each route with the version it belongs to, and it generates the URL prefixes, the per-version OpenAPI schema, and the docs, without moving anything else in your app.
from fastapi import APIRouter, FastAPI
from fastapi_router_versioning import (
RouterVersioner, VersionFormat, api_version,
)
app = FastAPI()
router = APIRouter()
@router.get("/items")
@api_version((1, 0))
def get_items_v1():
return {"version": "1.0", "items": ["a", "b"]}
@router.get("/items")
@api_version((2, 0))
def get_items_v2():
return {"version": "2.0", "items": ["a", "b", "c"]}
RouterVersioner(
app=app, routers=router,
version_format=VersionFormat.SEMVER
).versionize()
What you get¶
Every version gets its own Swagger UI, ReDoc and openapi.json, listing only the routes active in that version. These screenshots come from semver_app.py, where /lifecycle and /legacy-notice are deprecated in v2.0, /newcomer is added in v2.0, and a dedicated route takes over POST /settings.



Features¶
- SemVer and CalVer: version routes with
(major, minor)tuples, or with arbitrary sortable strings - Per-version docs: isolated Swagger UI, ReDoc, and
openapi.jsonfor every active version - Declarative lifecycle: mark a route's introduction, deprecation, and removal with one decorator
- Deprecation headers: opt-in
Deprecation,SunsetandLinkresponse headers on routes in their deprecation window - Latest alias: expose the newest version under a fixed
/latestprefix clients can pin to - Self-hosted docs assets: point Swagger UI and ReDoc at your own JS/CSS for air-gapped deployments
- Reverse proxy and sub-app aware: doc URLs pick up the ASGI
root_pathat request time - Route composition support: works across nested routers, WebSockets,
Depends, and OpenAPI Callbacks
Requirements¶
- Python ≥ 3.10
- FastAPI ≥ 0.120.0, except
0.137.0and0.137.1
Why two FastAPI versions are excluded
0.137.0 and 0.137.1 shipped a routing internals rewrite before iter_route_contexts() landed in 0.137.2, which this package relies on. Supporting that narrow gap would have meant a third compatibility code path instead of the two the package actually needs.