Skip to main content

Endpoint deprecation management for FastAPI made easy

Project description

FastAPI Deprecation

RFC 9745 compliant API deprecation for FastAPI.

Test Status Documentation Status


FastAPI Deprecation helps you manage the lifecycle of your API endpoints using standard HTTP headers (Deprecation, Sunset, Link) and automated blocking logic. It allows you to gracefully warn clients about upcoming deprecations and automatically shut down endpoints when they reach their sunset date.

Features

  • Standard Compliance: Fully implements RFC 9745 and RFC 8594 with support for multiple link relations (rel="alternate", rel="successor-version", etc.).
  • Decorator-based & Middleware: Simple @deprecated decorator for path operations, and DeprecationMiddleware for globally deprecating prefixes or intercepting 404s for sunset endpoints.
  • Automated Blocking: Automatically returns 410 Gone or 301 Moved Permanently (or custom responses) after the sunset_date.
  • OpenAPI Integration: Automatically modifies the Swagger UI/ReDoc to mark active deprecations and announces future upcoming deprecations.
  • Client-Side Caching: Optionally injects Cache-Control: max-age to ensure warning responses aren't cached beyond the sunset date.
  • Cache Invalidation: Inject Cache-Tag or Surrogate-Key for instant edge caching CDN (Cloudflare/Fastly) validation.
  • Extended Features:
    • Brownouts (Scheduled & Chaos): Schedule temporary shutdowns or configure probabilistic failure rates to simulate future removal and progressively force client migrations.
    • Telemetry: Track usage of deprecated endpoints.
    • Rate Limiting: Hook into your favorite rate limiting library (e.g., slowapi) to dynamically throttle legacy traffic.

Installation

pip install fastapi-deprecation
# or with uv
uv add fastapi-deprecation

Documentation

To run the documentation locally:

uv run zensical serve

Quick Start

from fastapi import FastAPI
from fastapi_deprecation import deprecated, auto_deprecate_openapi

app = FastAPI()

@app.get("/old-endpoint")
@deprecated(
    deprecation_date="2024-01-01",
    sunset_date="2025-01-01",
    alternative="/new-endpoint",
    detail="This endpoint is old and tired."
)
async def old():
    return {"message": "Enjoy it while it lasts!"}

# Don't forget to update the schema at the end!
auto_deprecate_openapi(app)

Example Application

For a comprehensive demonstration of all features (Middleware, Router-level deprecation, mounted sub-apps, custom responses, and brownouts), check out the Showcase Application included in the repository:

uv run python examples/showcase.py

Open http://localhost:8000/docs to see the API lifecycle in action.

How It Works

  1. Warning Phase (Before Sunset):

    • Requests return 200 OK.
    • Response headers include:
      • Deprecation: @1704067200 (Unix timestamp of deprecation_date)
      • Sunset: Wed, 01 Jan 2025 00:00:00 GMT
      • Link: </new-endpoint>; rel="alternative"
  2. Blocking Phase (After Sunset):

    • Requests return 410 Gone (or 301 Moved Permanently if alternative is set).
    • The detail message is returned in the response body.

Advanced Usage

1. Brownouts (Scheduled & Chaos)

You can simulate future shutdowns by scheduling "brownouts" — temporary periods where the endpoint returns 410 Gone (or 301 if alternative is set). This forces clients to notice the deprecation before the final sunset.

You can configure hardcoded datetime windows, or utilize Chaos Engineering probabilities to randomly fail requests.

@deprecated(
    deprecation_date="2025-01-01",
    sunset_date="2025-12-31",
    # 1. Scheduled: Fail during these exact windows
    brownouts=[
        ("2025-11-01T09:00:00Z", "2025-11-01T10:00:00Z"),
    ],
    # 2. Static Chaos: 5% of all traffic fails constantly
    brownout_probability=0.05,
    # 3. Progressive Chaos: Failure rate scales dynamically from 0% on Jan 1st to 100% on Dec 31st
    progressive_brownout=True,
    detail="Service is temporarily unavailable due to scheduled brownout."
)
async def my_endpoint(): ...

2. Telemetry & Logging

Track usage of deprecated endpoints using a global callback. This is useful for monitoring which clients are still using old APIs.

import logging
from fastapi import Request, Response
from fastapi_deprecation import set_deprecation_callback, DeprecationDependency

logger = logging.getLogger("deprecation")

def log_usage(request: Request, response: Response, dep: Any):
    logger.warning(
        f"Deprecated endpoint {request.url} accessed. "
        f"Deprecation date: {dep.deprecation_date}"
    )

set_deprecation_callback(log_usage)

3. Deprecating Entire Routers

To deprecate a whole group of endpoints, use DeprecationDependency on the APIRouter.

from fastapi import APIRouter, Depends
from fastapi_deprecation import DeprecationDependency

router = APIRouter(
    dependencies=[Depends(DeprecationDependency(deprecation_date="2024-01-01"))]
)

@router.get("/sub-route")
async def sub(): ...

4. Recursive OpenAPI Support

When using auto_deprecate_openapi(app), it automatically traverses potentially mounted sub-applications (app.mount(...)) and marks their routes as deprecated if configured.

root_app.mount("/v1", v1_app)
# This will update OpenAPI for both root_app AND v1_app
auto_deprecate_openapi(root_app)

5. Future Deprecation & Caching

You can announce a future deprecation date. The Deprecation header will still be sent, allowing clients to prepare.

You can also inject Cache-Control headers so clients don't mistakenly cache warning responses past the sunset date, or inject Cache-Tag / Surrogate-Key headers to instantly purge CDN edge caches.

@deprecated(
    deprecation_date="2030-01-01",
    sunset_date="2031-01-01",
    inject_cache_control=True,
    cache_tag="api-v1-deprecation-group"
)
async def future_proof(): ...

6. Custom Response Models & Multiple Links

Customize the HTTP 410/301 response payload dynamically using response, and provide extensive contextual documentation via multiple RFC 8594 Link relations.

from starlette.responses import JSONResponse

custom_error = JSONResponse(
    status_code=410,
    content={"message": "This endpoint is permanently removed. Use v2."}
)

@deprecated(
    sunset_date="2024-01-01",
    response=custom_error,
    links={
        "alternate": "https://api.example.com/v2/items",
        "latest-version": "https://api.example.com/v3/items"
    }
)
async def custom_sunset(): ...

7. Global Middleware

Deprecate entire prefixes at the ASGI level, intercepting 404 Not Found errors for removed routes and correctly returning 410 Gone with deprecation metadata.

from fastapi_deprecation import DeprecationMiddleware, DeprecationConfig

app.add_middleware(
    DeprecationMiddleware,
    deprecations={
        "/api/v1": DeprecationConfig(sunset_date="2025-01-01")
    }
)

See the Documentation for full details on API reference and advanced configuration.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_deprecation-0.4.0.tar.gz (81.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_deprecation-0.4.0-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_deprecation-0.4.0.tar.gz.

File metadata

  • Download URL: fastapi_deprecation-0.4.0.tar.gz
  • Upload date:
  • Size: 81.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_deprecation-0.4.0.tar.gz
Algorithm Hash digest
SHA256 ee9dfa53c7e6d057929f0ccb0fc042dd83d359d9bbde2ec9b8bfce299ab7a26f
MD5 1472c4b1f2858ef71feabb9a891123a9
BLAKE2b-256 dcf9011bfa2d5d34c5f234973a9394ec6f9f0923eb5462b4efe74270d4826669

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_deprecation-0.4.0.tar.gz:

Publisher: publish.yml on fractalvision/fastapi-deprecation

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastapi_deprecation-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_deprecation-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1b7cfb9126732f614718a0d5fbeab8d1af7cafc1e7fa60883d1722fa899cb111
MD5 92aa99261e4fa94311635c98902c532f
BLAKE2b-256 aacb464fb60b3aa74cc4643e8761706104f033986e6a1c13eade570ee1c4ead3

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastapi_deprecation-0.4.0-py3-none-any.whl:

Publisher: publish.yml on fractalvision/fastapi-deprecation

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page