A clean, decorator-based library for managing API endpoint lifecycle in FastAPI applications. Easily mark endpoints as deprecated, set sunset dates, and provide migration information with automatic HTTP header injection.
- π·οΈ Clean decorator syntax with dictionary configuration
- π
RFC-compliant headers (
Deprecation,Sunset,Link) - π Automatic header injection via middleware or decorators
- π Rich metadata support (migration URLs, replacement endpoints, reasons)
- β‘ Zero performance overhead when not using versioning
- π― Type hints and IDE support throughout
pip install fastapi-lifecyclefrom fastapi import FastAPI
from fastapi_lifecycle import deprecated, setup_versioning
app = FastAPI()
setup_versioning(app) # Add the middleware
@app.get("/users")
@deprecated({
'deprecated_at': '2024-01-15T00:00:00Z',
'sunset_at': '2024-06-15T00:00:00Z',
'migration_url': 'https://api.example.com/docs/migration#users-v2',
'replacement': 'GET /v2/users',
'reason': 'Moving to v2 API with enhanced user profiles'
})
async def get_users():
return {"users": []}Response headers:
Deprecation: Mon, 15 Jan 2024 00:00:00 GMT
Sunset: Sat, 15 Jun 2024 00:00:00 GMT
Link: <https://api.example.com/docs/migration#users-v2>; rel="deprecation"
X-API-Replacement: GET /v2/users
X-API-Deprecation-Reason: Moving to v2 API with enhanced user profilesMark an endpoint as deprecated with comprehensive configuration.
Configuration options:
deprecated_at(str | datetime): When the endpoint was deprecatedsunset_at(str | datetime): When the endpoint will be removedmigration_url(str): URL to migration documentationreplacement(str): Description of replacement endpointreason(str): Explanation for deprecationversion(str): Current API version
@deprecated({
'deprecated_at': '2024-01-15T00:00:00Z',
'reason': 'Use /v2/endpoint instead'
})
async def old_endpoint():
return {"message": "deprecated"}Mark an endpoint with a removal date.
Configuration options:
sunset_at(str | datetime): When endpoint will be removed (required)migration_url(str): URL to migration documentationreplacement(str): Description of replacement endpointreason(str): Explanation for removal
@sunset({
'sunset_at': '2024-12-31T23:59:59Z',
'migration_url': 'https://docs.api.com/migration',
'replacement': 'GET /v3/data'
})
async def ending_endpoint():
return {"data": "will be removed"}Comprehensive version management with deprecation and sunset support.
Configuration options:
version(str): API version (required)deprecated_at(str | datetime): When deprecatedsunset_at(str | datetime): When will be removedmigration_url(str): Migration documentation URLreplacement(str): Replacement endpoint descriptionreason(str): Version change explanation
@versioned({
'version': '1.2',
'deprecated_at': '2024-03-01T00:00:00Z',
'sunset_at': '2024-09-01T00:00:00Z',
'migration_url': 'https://docs.api.com/v2-migration'
})
async def versioned_endpoint():
return {"version": "1.2"}The library accepts dates in multiple formats:
# ISO 8601 strings (recommended)
'deprecated_at': '2024-01-15T00:00:00Z'
'deprecated_at': '2024-01-15T10:30:00+02:00'
# Python datetime objects
from datetime import datetime
'deprecated_at': datetime(2024, 1, 15)| Header | Description | Example |
|---|---|---|
Deprecation |
RFC 8594 deprecation date | Mon, 15 Jan 2024 00:00:00 GMT |
Sunset |
RFC 8594 sunset date | Sat, 15 Jun 2024 00:00:00 GMT |
Link |
RFC 8288 link to documentation | <https://docs.api.com/migration>; rel="deprecation" |
X-API-Version |
Current API version | 1.2 |
X-API-Replacement |
Replacement endpoint info | GET /v2/users |
X-API-Deprecation-Reason |
Human-readable reason | Enhanced functionality in v2 |
Stack decorators for complex scenarios:
@versioned({'version': '1.0'})
@deprecated({
'deprecated_at': '2024-01-15T00:00:00Z',
'reason': 'Migrating to GraphQL'
})
async def complex_endpoint():
return {"data": "complex"}Works seamlessly with FastAPI's Response dependency:
from fastapi import Response
@deprecated({'deprecated_at': '2024-01-15T00:00:00Z'})
async def endpoint_with_response(response: Response):
response.status_code = 200
return {"message": "Custom response handling"}Apply versioning based on conditions:
from fastapi_lifecycle import deprecated
def get_endpoint_config():
if FEATURE_FLAG_V2_MIGRATION:
return {
'deprecated_at': '2024-01-15T00:00:00Z',
'sunset_at': '2024-06-15T00:00:00Z',
'replacement': 'GET /v2/endpoint'
}
return {}
@deprecated(get_endpoint_config())
async def conditional_endpoint():
return {"data": "conditional"}- Python 3.8+
- FastAPI 0.68+
- python-dateutil
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
This library implements headers according to:
- RFC 8594 - The Sunset HTTP Header Field
- RFC 8288 - Web Linking (Link header)
- Internet-Draft - The Deprecation HTTP Header Field
Check out the examples/ directory for more comprehensive usage examples including:
- Basic deprecation scenarios
- Complex migration workflows
- Integration with API documentation
- Custom middleware configurations