{"library":"cadwyn","code":"import datetime\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\nfrom cadwyn import Cadwyn, VersionBundle, VersionedAPIRouter\nfrom cadwyn.structure import VersionChange, schema\n\n# 1. Define your schemas in the 'latest' version\nclass UserCreateRequest(BaseModel):\n    name: str\n    email: str\n\nclass UserResource(BaseModel):\n    id: int\n    name: str\n    email: str\n\n# 2. Define your API versions\n# Use ISO date strings for versions for future compatibility (v6.x+)\nVERSION_2024_01_01 = datetime.date(2024, 1, 1)\nVERSION_2023_01_01 = datetime.date(2023, 1, 1)\n\n# 3. Define version changes\nclass ChangeEmailFieldToOptional(VersionChange):\n    description = 'Make email field optional in UserCreateRequest'\n    version = VERSION_2023_01_01\n\n    @schema(UserCreateRequest).alter\n    def alter_user_create_request(cls):\n        cls.email = Field(default=None, union_of=[cls.email, type(None)])\n\n# 4. Create a VersionBundle\nversion_bundle = VersionBundle(\n    latest_version=VERSION_2024_01_01,\n    old_versions=[VERSION_2023_01_01],\n    version_changes=[ChangeEmailFieldToOptional],\n)\n\n# 5. Initialize Cadwyn and the versioned router\napp = FastAPI()\ncadwyn_app = Cadwyn(\n    versions=version_bundle,\n    api_version_header_name='x-api-version',\n    latest_schemas_package=__name__,\n    old_versions_package=__name__\n)\n\n# Use a standard FastAPI router but include it via Cadwyn\nrouter = VersionedAPIRouter(version_bundle=version_bundle)\n\n@router.post('/users', response_model=UserResource)\nasync def create_user(user: UserCreateRequest):\n    # Business logic always works with the latest schema\n    return {\"id\": 1, \"name\": user.name, \"email\": user.email}\n\n@router.get('/users/{user_id}', response_model=UserResource)\nasync def get_user(user_id: int):\n    return {\"id\": user_id, \"name\": \"John Doe\", \"email\": \"john.doe@example.com\"}\n\n# Cadwyn generates and includes versioned routes\ncadwyn_app.generate_and_include_versioned_routers(app, router)\n\n# To run: uvicorn your_module_name:app --reload\n# Test with curl -H 'x-api-version: 2024-01-01' -X POST -H 'Content-Type: application/json' -d '{\"name\": \"Alice\", \"email\": \"alice@example.com\"}' http://localhost:8000/users\n# Test with curl -H 'x-api-version: 2023-01-01' -X POST -H 'Content-Type: application/json' -d '{\"name\": \"Bob\"}' http://localhost:8000/users","lang":"python","description":"This quickstart demonstrates how to set up a basic FastAPI application with Cadwyn for API versioning. It defines two versions (2024-01-01 and 2023-01-01), with a version change making the `email` field optional in `UserCreateRequest` for the older version. The `Cadwyn` instance handles the generation and inclusion of versioned routers, allowing your core business logic to interact only with the latest schema.","tag":null,"tag_description":null,"last_tested":"2026-04-24","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}