alexschimpf / fastapi-versionizer

FastAPI Versionizer
MIT License
81 stars 13 forks source link

FastAPI Versionizer

Credit

This was inspired by fastapi_versioning. This project addresses issues with fastapi_versioning and adds some additional features.

Installation

pip install fastapi-versionizer

Examples

You can find examples in the examples directory.

Summary

FastAPI Versionizer makes API versioning easy.

Here is a simple (and rather contrived) example:

from typing import List
from fastapi import FastAPI, APIRouter
from pydantic import BaseModel

from fastapi_versionizer.versionizer import Versionizer, api_version

class User(BaseModel):
    id: int
    name: str

class UserV2(BaseModel):
    id: int
    name: str
    age: int

db = {
    'users': {}
}
app = FastAPI(
    title='test',
    redoc_url=None
)
users_router = APIRouter(
    prefix='/users',
    tags=['Users']
)

@app.get('/status', tags=['Status'])
def get_status() -> str:
    return 'Ok'

@api_version(1)
@users_router.get('', deprecated=True)
def get_users() -> List[User]:
    return list(user for user in db['users'].values() if isinstance(user, User))

@api_version(1)
@users_router.post('', deprecated=True)
def create_user(user: User) -> User:
    db['users'][user.id] = user
    return user

@api_version(2)
@users_router.get('')
def get_users_v2() -> List[UserV2]:
    return list(user for user in db['users'].values() if isinstance(user, UserV2))

@api_version(2)
@users_router.post('')
def create_user_v2(user: UserV2) -> UserV2:
    db['users'][user.id] = user
    return user

app.include_router(users_router)

versions = Versionizer(
    app=app,
    prefix_format='/v{major}',
    semantic_version_format='{major}',
    latest_prefix='/latest',
    sort_routes=True
).versionize()

This will generate the following endpoints:

Details

FastAPI Versionizer works by modifying a FastAPI app in place, adding versioned routes and proper docs pages. Routes are annotated with version information, using the @api_version decorator. Using this decorator, you can specify the version (major and/or minor) that the route was introduced. You can also specify the first version when the route should be considered deprecated or even removed. Each new version will include all routes from previous versions that have not been overridden or marked for removal. An APIRouter will be created for each version, with the URL prefix defined by the prefix_format parameter described below,

Versionizer Parameters

Docs Customization

Gotchas

Static file mounts

If you need to mount static files, you'll have to add those to your FastAPI app after instantiating Versionizer. See the Static file mount example for more details.