Metadata-Version: 2.5
Name: fastapi-router-versioning
Version: 1.2.0
Summary: Router-based API versioning for FastAPI, with per-version docs and a declarative route lifecycle.
Project-URL: Homepage, https://mat81black.github.io/fastapi-router-versioning/
Project-URL: Repository, https://github.com/mat81black/fastapi-router-versioning
Project-URL: Issues, https://github.com/mat81black/fastapi-router-versioning/issues
Project-URL: Documentation, https://mat81black.github.io/fastapi-router-versioning/
Project-URL: Changelog, https://mat81black.github.io/fastapi-router-versioning/release-notes/
Author-email: Matteo Nieddu <mat81black@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: annotated-doc>=0.0.2
Requires-Dist: fastapi!=0.137.0,!=0.137.1,>=0.120.0
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://raw.githubusercontent.com/mat81black/fastapi-router-versioning/main/docs/assets/images/logo.svg" alt="FastAPI Router Versioning logo" width="128" height="128">
</p>

<h1 align="center">
  <img src="https://raw.githubusercontent.com/mat81black/fastapi-router-versioning/main/docs/assets/images/wordmark.png" alt="FastAPI Router Versioning" width="480">
</h1>

<p align="center">
  <a href="https://github.com/mat81black/fastapi-router-versioning/actions"><img src="https://github.com/mat81black/fastapi-router-versioning/workflows/Test/badge.svg" alt="Build Status"></a>
  <a href="https://codecov.io/github/mat81black/fastapi-router-versioning"><img src="https://codecov.io/github/mat81black/fastapi-router-versioning/graph/badge.svg?token=4WQ63Q7ESY" alt="codecov"></a>
  <a href="https://pypi.org/project/fastapi-router-versioning/"><img src="https://img.shields.io/pypi/v/fastapi-router-versioning?color=%2334D058&label=pypi%20package" alt="pypi package"></a>
  <a href="https://pypi.org/project/fastapi-router-versioning/"><img src="https://img.shields.io/pypi/pyversions/fastapi-router-versioning.svg?color=%2334D058" alt="Supported Python versions"></a>
  <a href="https://github.com/mat81black/fastapi-router-versioning/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT"></a>
</p>

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.

Documentation: https://mat81black.github.io/fastapi-router-versioning/

---

## Features

- **SemVer and CalVer**: version routes with `(major, minor)` tuples, or with arbitrary sortable strings
- **Per-version docs**: isolated Swagger UI, ReDoc, and `openapi.json` for every active version
- **Declarative lifecycle**: mark a route's introduction, deprecation, and removal with one decorator
- **Deprecation headers**: opt-in `Deprecation`, `Sunset` and `Link` response headers on routes in their deprecation window
- **Latest alias**: expose the newest version under a fixed `/latest` prefix 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_path` at 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.0` and `0.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.

---

## Installation

```bash
pip install fastapi-router-versioning
# or
uv add fastapi-router-versioning
```

---

## Quick start

`RouterVersioner` is not a request-time dependency; there's no `Depends()` involved. It's a
one-time setup step: you build it, then call `.versionize()` once, and it reads the routers
you gave it and mounts one copy per version. Attach `@api_version` to every route **before**
calling `.versionize()`, since that call is what reads the router and wires everything up;
routes added to the router afterward are never picked up.

```python
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()
```

CalVer, the route lifecycle, the parameter reference and the advanced options are in the [documentation](https://mat81black.github.io/fastapi-router-versioning/).

---

## Release Notes

[RELEASE_NOTES](https://github.com/mat81black/fastapi-router-versioning/blob/main/docs/release-notes.md)

---

## License

[MIT](https://github.com/mat81black/fastapi-router-versioning/blob/main/LICENSE)
