fastapi-router-versioning 1.1.0__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/latest-changes.yml +5 -1
- fastapi_router_versioning-1.2.0/.github/workflows/build-docs.yml +97 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/bump-pre-commit-hooks.yml +1 -1
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/create-draft-release.yml +2 -2
- fastapi_router_versioning-1.2.0/.github/workflows/deploy-docs.yml +58 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/pre-commit.yml +1 -1
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/prepare-release.yml +2 -2
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/publish.yml +1 -1
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/test.yml +5 -4
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/zizmor.yml +1 -1
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.gitignore +4 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.pre-commit-config.yaml +9 -1
- fastapi_router_versioning-1.2.0/PKG-INFO +137 -0
- fastapi_router_versioning-1.2.0/README.md +105 -0
- fastapi_router_versioning-1.2.0/docs/advanced/callback-hook.md +18 -0
- fastapi_router_versioning-1.2.0/docs/advanced/callbacks-and-webhooks.md +33 -0
- fastapi_router_versioning-1.2.0/docs/advanced/custom-url-format.md +25 -0
- fastapi_router_versioning-1.2.0/docs/advanced/deprecation-headers.md +36 -0
- fastapi_router_versioning-1.2.0/docs/advanced/index.md +19 -0
- fastapi_router_versioning-1.2.0/docs/advanced/latest-alias.md +17 -0
- fastapi_router_versioning-1.2.0/docs/advanced/multiple-routers.md +28 -0
- fastapi_router_versioning-1.2.0/docs/advanced/openapi-hook.md +13 -0
- fastapi_router_versioning-1.2.0/docs/advanced/reverse-proxy-and-sub-apps.md +17 -0
- fastapi_router_versioning-1.2.0/docs/advanced/self-hosted-assets.md +15 -0
- fastapi_router_versioning-1.2.0/docs/advanced/validation-error-status-code.md +22 -0
- fastapi_router_versioning-1.2.0/docs/advanced/version-discovery.md +49 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/apple-touch-icon.png +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/favicon.ico +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/favicon.png +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/favicon.svg +1 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/logo-header.svg +1 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/logo.svg +1 -0
- fastapi_router_versioning-1.2.0/docs/assets/images/wordmark.png +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/latest-alias.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/quickstart-calver.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/quickstart-semver-v1.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/quickstart-semver-v2.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/redoc-v2.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/swagger-v1.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/swagger-v2.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/url-format-latest.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/url-format-v1.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/versions-dashboard.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/webhooks-v1.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/assets/screenshots/webhooks-v2.jpg +0 -0
- fastapi_router_versioning-1.2.0/docs/examples.md +131 -0
- fastapi_router_versioning-1.2.0/docs/how-it-works.md +62 -0
- fastapi_router_versioning-1.2.0/docs/index.md +68 -0
- fastapi_router_versioning-1.2.0/docs/lifecycle.md +61 -0
- fastapi_router_versioning-1.2.0/docs/quickstart.md +44 -0
- fastapi_router_versioning-1.2.0/docs/reference.md +18 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0/docs}/release-notes.md +18 -0
- fastapi_router_versioning-1.2.0/docs/stylesheets/extra.css +31 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/callback_hook.py +31 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/callbacks.py +20 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/custom_url_format.py +30 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/deprecation_headers.py +38 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/latest_alias.py +28 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/multiple_routers.py +28 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/openapi_hook.py +37 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/reverse_proxy.py +28 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/self_hosted_assets.py +33 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/validation_error_status_code.py +48 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/version_discovery.py +28 -0
- fastapi_router_versioning-1.2.0/docs_src/advanced/webhooks.py +54 -0
- fastapi_router_versioning-1.2.0/docs_src/lifecycle/legacy_route.py +16 -0
- fastapi_router_versioning-1.2.0/docs_src/quickstart/calver.py +19 -0
- fastapi_router_versioning-1.2.0/docs_src/quickstart/semver.py +25 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/__init__.py +1 -1
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_versions.py +31 -24
- fastapi_router_versioning-1.2.0/fastapi_router_versioning/versioner.py +286 -0
- fastapi_router_versioning-1.2.0/mkdocs.yml +129 -0
- fastapi_router_versioning-1.2.0/overrides/main.html +7 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/pyproject.toml +25 -3
- fastapi_router_versioning-1.2.0/scripts/build_icons.py +83 -0
- fastapi_router_versioning-1.2.0/scripts/docs-build.sh +6 -0
- fastapi_router_versioning-1.2.0/scripts/docs.sh +6 -0
- fastapi_router_versioning-1.2.0/scripts/docs_screenshots.py +144 -0
- fastapi_router_versioning-1.2.0/scripts/generate_readme.py +174 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/scripts/lint.sh +1 -1
- fastapi_router_versioning-1.2.0/tests/test_docs_src.py +55 -0
- fastapi_router_versioning-1.2.0/tests/test_docs_src_behavior.py +178 -0
- fastapi_router_versioning-1.2.0/tests/test_public_signature_docs.py +58 -0
- fastapi_router_versioning-1.2.0/tests/test_readme.py +10 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/uv.lock +688 -107
- fastapi_router_versioning-1.1.0/PKG-INFO +0 -622
- fastapi_router_versioning-1.1.0/README.md +0 -591
- fastapi_router_versioning-1.1.0/fastapi_router_versioning/versioner.py +0 -261
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/dependabot.yml +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/detect-conflicts.yml +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/guard-dependencies.yml +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/test-redistribute.yml +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.python-version +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/LICENSE +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/calver_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/dashboard_assets/versions_dashboard.css +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/dashboard_assets/versions_dashboard.html +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/deprecation_headers_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/download_static_assets.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/mounted_subapps_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/multi_router_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/openapi_hook_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/self_hosted_docs_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/semver_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/semver_major_only_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/validation_override_integration_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/versions_dashboard_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/versions_dashboard_hook_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/examples/webhook_versioning_app.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_builder.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_compat.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_dashboard.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_deprecation.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_docs.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_lifecycle.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_registry.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/_scheme.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/fastapi_router_versioning/py.typed +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/scripts/format.sh +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/scripts/prepare_release.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/scripts/test-cov-html.sh +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/scripts/test-cov.sh +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/scripts/test.sh +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/__init__.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_calver.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_examples.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_fastapi_integration.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_prepare_release.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_semver.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_deprecation_headers.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_docs.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_errors.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_lifecycle.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_versions_dashboard.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_versions_route.py +0 -0
- {fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/tests/test_versioner_webhooks.py +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: Build Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
permissions: {}
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
changes:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
# Required permissions
|
|
15
|
+
permissions:
|
|
16
|
+
pull-requests: read
|
|
17
|
+
timeout-minutes: 5
|
|
18
|
+
# Set job outputs to values from filter step
|
|
19
|
+
outputs:
|
|
20
|
+
docs: ${{ steps.filter.outputs.docs }}
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 #sync-pin:checkout-6
|
|
23
|
+
with:
|
|
24
|
+
persist-credentials: false
|
|
25
|
+
# For pull requests it's not necessary to checkout the code but for the main branch it is
|
|
26
|
+
- uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.2 #sync-pin:paths-filter-2
|
|
27
|
+
id: filter
|
|
28
|
+
with:
|
|
29
|
+
filters: |
|
|
30
|
+
docs:
|
|
31
|
+
- .github/workflows/build-docs.yml
|
|
32
|
+
- .github/workflows/deploy-docs.yml
|
|
33
|
+
- docs/**
|
|
34
|
+
- docs_src/**
|
|
35
|
+
- examples/**
|
|
36
|
+
- fastapi_router_versioning/**
|
|
37
|
+
- mkdocs.yml
|
|
38
|
+
- overrides/**
|
|
39
|
+
- scripts/docs-build.sh
|
|
40
|
+
- pyproject.toml
|
|
41
|
+
- uv.lock
|
|
42
|
+
|
|
43
|
+
build-docs:
|
|
44
|
+
needs:
|
|
45
|
+
- changes
|
|
46
|
+
if: needs.changes.outputs.docs == 'true'
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
timeout-minutes: 10
|
|
49
|
+
steps:
|
|
50
|
+
- name: Dump GitHub context
|
|
51
|
+
env:
|
|
52
|
+
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
53
|
+
run: echo "$GITHUB_CONTEXT"
|
|
54
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 #sync-pin:checkout-7
|
|
55
|
+
with:
|
|
56
|
+
persist-credentials: false
|
|
57
|
+
|
|
58
|
+
- name: Set up Python
|
|
59
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 #sync-pin:setup-python-3
|
|
60
|
+
with:
|
|
61
|
+
python-version-file: .python-version
|
|
62
|
+
|
|
63
|
+
- name: Setup uv
|
|
64
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv-4
|
|
65
|
+
with:
|
|
66
|
+
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
67
|
+
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
68
|
+
version: "0.11.18"
|
|
69
|
+
# Zensical's own docs advise against caching its build output on CI for now.
|
|
70
|
+
enable-cache: false
|
|
71
|
+
|
|
72
|
+
- name: Install Dependencies
|
|
73
|
+
run: uv sync --locked --no-dev --group docs
|
|
74
|
+
|
|
75
|
+
- name: Build docs
|
|
76
|
+
run: uv run --no-sync bash scripts/docs-build.sh
|
|
77
|
+
|
|
78
|
+
# The site is deployed by Deploy Docs, which runs once this workflow has finished
|
|
79
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 #sync-pin:upload-artifact-3
|
|
80
|
+
with:
|
|
81
|
+
name: docs-site
|
|
82
|
+
path: ./site
|
|
83
|
+
|
|
84
|
+
# https://github.com/marketplace/actions/alls-green#why
|
|
85
|
+
docs-alls-green: # This job does nothing and is only used for the branch protection
|
|
86
|
+
if: always()
|
|
87
|
+
needs:
|
|
88
|
+
- changes
|
|
89
|
+
- build-docs
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
timeout-minutes: 5
|
|
92
|
+
steps:
|
|
93
|
+
- name: Decide whether the needed jobs succeeded or failed
|
|
94
|
+
uses: re-actors/alls-green@b5b5b37504aa4183270bd3d855c52a67f212be35 # v1.2.2 #sync-pin:alls-green-2
|
|
95
|
+
with:
|
|
96
|
+
jobs: ${{ toJSON(needs) }}
|
|
97
|
+
allowed-skips: build-docs
|
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
with:
|
|
26
26
|
python-version-file: ".python-version"
|
|
27
27
|
- name: Setup uv
|
|
28
|
-
uses: astral-sh/setup-uv@
|
|
28
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv
|
|
29
29
|
with:
|
|
30
30
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
31
31
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
contents: write
|
|
17
17
|
env:
|
|
18
18
|
PREPARE_RELEASE_VERSION_FILE: fastapi_router_versioning/__init__.py
|
|
19
|
-
PREPARE_RELEASE_RELEASE_NOTES_FILE: release-notes.md
|
|
19
|
+
PREPARE_RELEASE_RELEASE_NOTES_FILE: docs/release-notes.md
|
|
20
20
|
steps:
|
|
21
21
|
- name: Dump GitHub context
|
|
22
22
|
env:
|
|
@@ -31,7 +31,7 @@ jobs:
|
|
|
31
31
|
with:
|
|
32
32
|
python-version-file: ".python-version"
|
|
33
33
|
- name: Install uv
|
|
34
|
-
uses: astral-sh/setup-uv@
|
|
34
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv
|
|
35
35
|
with:
|
|
36
36
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
37
37
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run: # zizmor: ignore[dangerous-triggers] -- only a successful push to main of this repository is deployed; pull request builds never are
|
|
5
|
+
workflows:
|
|
6
|
+
- Build Docs
|
|
7
|
+
types:
|
|
8
|
+
- completed
|
|
9
|
+
|
|
10
|
+
permissions: {}
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
deploy-docs:
|
|
14
|
+
if: >-
|
|
15
|
+
github.event.workflow_run.conclusion == 'success'
|
|
16
|
+
&& github.event.workflow_run.head_branch == 'main'
|
|
17
|
+
&& github.event.workflow_run.head_repository.full_name == github.repository
|
|
18
|
+
&& github.event.workflow_run.event == 'push'
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
permissions:
|
|
21
|
+
actions: read # download the artifact of the Build Docs run
|
|
22
|
+
pages: write
|
|
23
|
+
id-token: write
|
|
24
|
+
environment:
|
|
25
|
+
name: github-pages
|
|
26
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
27
|
+
concurrency:
|
|
28
|
+
group: pages
|
|
29
|
+
cancel-in-progress: false
|
|
30
|
+
timeout-minutes: 10
|
|
31
|
+
steps:
|
|
32
|
+
- name: Dump GitHub context
|
|
33
|
+
env:
|
|
34
|
+
GITHUB_CONTEXT: ${{ toJson(github) }}
|
|
35
|
+
run: echo "$GITHUB_CONTEXT"
|
|
36
|
+
- name: Clean site
|
|
37
|
+
run: |
|
|
38
|
+
rm -rf ./site
|
|
39
|
+
mkdir ./site
|
|
40
|
+
# Build Docs is skipped when nothing that goes into the site changed: it uploads no artifact,
|
|
41
|
+
# the download below finds nothing, and the steps that need ./site/ are skipped
|
|
42
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 #sync-pin:download-artifact-2
|
|
43
|
+
with:
|
|
44
|
+
path: ./site/
|
|
45
|
+
pattern: docs-site
|
|
46
|
+
merge-multiple: true
|
|
47
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
48
|
+
run-id: ${{ github.event.workflow_run.id }}
|
|
49
|
+
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 #sync-pin:upload-pages-artifact
|
|
50
|
+
# hashFiles returns an empty string if there are no files
|
|
51
|
+
if: hashFiles('./site/*')
|
|
52
|
+
with:
|
|
53
|
+
path: site
|
|
54
|
+
- name: Deploy to GitHub Pages
|
|
55
|
+
# hashFiles returns an empty string if there are no files
|
|
56
|
+
if: hashFiles('./site/*')
|
|
57
|
+
id: deployment
|
|
58
|
+
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 #sync-pin:deploy-pages
|
{fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/pre-commit.yml
RENAMED
|
@@ -30,7 +30,7 @@ jobs:
|
|
|
30
30
|
python-version-file: ".python-version"
|
|
31
31
|
|
|
32
32
|
- name: Setup uv
|
|
33
|
-
uses: astral-sh/setup-uv@
|
|
33
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv
|
|
34
34
|
with:
|
|
35
35
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
36
36
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
@@ -28,7 +28,7 @@ jobs:
|
|
|
28
28
|
pull-requests: write
|
|
29
29
|
env:
|
|
30
30
|
PREPARE_RELEASE_VERSION_FILE: fastapi_router_versioning/__init__.py
|
|
31
|
-
PREPARE_RELEASE_RELEASE_NOTES_FILE: release-notes.md
|
|
31
|
+
PREPARE_RELEASE_RELEASE_NOTES_FILE: docs/release-notes.md
|
|
32
32
|
steps:
|
|
33
33
|
- name: Dump GitHub context
|
|
34
34
|
env:
|
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
with:
|
|
43
43
|
python-version-file: ".python-version"
|
|
44
44
|
- name: Install uv
|
|
45
|
-
uses: astral-sh/setup-uv@
|
|
45
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv
|
|
46
46
|
with:
|
|
47
47
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
48
48
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
{fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/publish.yml
RENAMED
|
@@ -28,7 +28,7 @@ jobs:
|
|
|
28
28
|
with:
|
|
29
29
|
python-version-file: ".python-version"
|
|
30
30
|
- name: Install uv
|
|
31
|
-
uses: astral-sh/setup-uv@
|
|
31
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv
|
|
32
32
|
with:
|
|
33
33
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
34
34
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
{fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/test.yml
RENAMED
|
@@ -35,6 +35,7 @@ jobs:
|
|
|
35
35
|
filters: |
|
|
36
36
|
src:
|
|
37
37
|
- .github/workflows/test.yml
|
|
38
|
+
- docs_src/**
|
|
38
39
|
- examples/**
|
|
39
40
|
- fastapi_router_versioning/**
|
|
40
41
|
- scripts/**
|
|
@@ -80,7 +81,7 @@ jobs:
|
|
|
80
81
|
python-version: ${{ matrix.python-version }}
|
|
81
82
|
|
|
82
83
|
- name: Setup uv
|
|
83
|
-
uses: astral-sh/setup-uv@
|
|
84
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv
|
|
84
85
|
with:
|
|
85
86
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
86
87
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
@@ -168,7 +169,7 @@ jobs:
|
|
|
168
169
|
|
|
169
170
|
- name: Setup uv
|
|
170
171
|
if: steps.changed-tests.outputs.found == 'true'
|
|
171
|
-
uses: astral-sh/setup-uv@
|
|
172
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv-2
|
|
172
173
|
with:
|
|
173
174
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
174
175
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
@@ -210,7 +211,7 @@ jobs:
|
|
|
210
211
|
persist-credentials: false
|
|
211
212
|
|
|
212
213
|
- name: Setup uv
|
|
213
|
-
uses: astral-sh/setup-uv@
|
|
214
|
+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v9.0.0 #sync-pin:setup-uv-3
|
|
214
215
|
with:
|
|
215
216
|
# Before upgrading uv version, make sure astral-sh/setup-uv knows its checksum.
|
|
216
217
|
# See: https://github.com/astral-sh/setup-uv/issues/851#issuecomment-4282017837
|
|
@@ -243,7 +244,7 @@ jobs:
|
|
|
243
244
|
include-hidden-files: true
|
|
244
245
|
|
|
245
246
|
- name: Upload coverage to Codecov
|
|
246
|
-
uses: codecov/codecov-action@
|
|
247
|
+
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.0.0 #sync-pin:codecov-action
|
|
247
248
|
with:
|
|
248
249
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
249
250
|
files: coverage.xml
|
{fastapi_router_versioning-1.1.0 → fastapi_router_versioning-1.2.0}/.github/workflows/zizmor.yml
RENAMED
|
@@ -22,4 +22,4 @@ jobs:
|
|
|
22
22
|
with:
|
|
23
23
|
persist-credentials: false
|
|
24
24
|
- name: Run zizmor
|
|
25
|
-
uses: zizmorcore/zizmor-action@
|
|
25
|
+
uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.2 #sync-pin:zizmor-action
|
|
@@ -15,7 +15,7 @@ repos:
|
|
|
15
15
|
- id: trailing-whitespace
|
|
16
16
|
|
|
17
17
|
- repo: https://github.com/crate-ci/typos
|
|
18
|
-
rev:
|
|
18
|
+
rev: 53821664afd79bb88fcdd22fdc2f49d8d3f6cac9 # frozen: v1
|
|
19
19
|
hooks:
|
|
20
20
|
- id: typos
|
|
21
21
|
args: [ --force-exclude ]
|
|
@@ -50,6 +50,14 @@ repos:
|
|
|
50
50
|
language: unsupported
|
|
51
51
|
pass_filenames: false
|
|
52
52
|
|
|
53
|
+
- id: generate-readme
|
|
54
|
+
name: generate README.md from the docs
|
|
55
|
+
entry: uv run python scripts/generate_readme.py
|
|
56
|
+
language: unsupported
|
|
57
|
+
files: ^(docs/index\.md|docs/quickstart\.md|docs_src/quickstart/semver\.py|scripts/generate_readme\.py)$
|
|
58
|
+
require_serial: true
|
|
59
|
+
pass_filenames: false
|
|
60
|
+
|
|
53
61
|
- id: zizmor
|
|
54
62
|
name: zizmor
|
|
55
63
|
language: python
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: fastapi-router-versioning
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Router-based API versioning for FastAPI, with per-version docs and a declarative route lifecycle.
|
|
5
|
+
Project-URL: Homepage, https://mat81black.github.io/fastapi-router-versioning/
|
|
6
|
+
Project-URL: Repository, https://github.com/mat81black/fastapi-router-versioning
|
|
7
|
+
Project-URL: Issues, https://github.com/mat81black/fastapi-router-versioning/issues
|
|
8
|
+
Project-URL: Documentation, https://mat81black.github.io/fastapi-router-versioning/
|
|
9
|
+
Project-URL: Changelog, https://mat81black.github.io/fastapi-router-versioning/release-notes/
|
|
10
|
+
Author-email: Matteo Nieddu <mat81black@gmail.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Web Environment
|
|
15
|
+
Classifier: Framework :: FastAPI
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Requires-Dist: annotated-doc>=0.0.2
|
|
30
|
+
Requires-Dist: fastapi!=0.137.0,!=0.137.1,>=0.120.0
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<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">
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<h1 align="center">
|
|
38
|
+
<img src="https://raw.githubusercontent.com/mat81black/fastapi-router-versioning/main/docs/assets/images/wordmark.png" alt="FastAPI Router Versioning" width="480">
|
|
39
|
+
</h1>
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<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>
|
|
43
|
+
<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>
|
|
44
|
+
<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>
|
|
45
|
+
<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>
|
|
46
|
+
<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>
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
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.
|
|
50
|
+
|
|
51
|
+
Documentation: https://mat81black.github.io/fastapi-router-versioning/
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- **SemVer and CalVer**: version routes with `(major, minor)` tuples, or with arbitrary sortable strings
|
|
58
|
+
- **Per-version docs**: isolated Swagger UI, ReDoc, and `openapi.json` for every active version
|
|
59
|
+
- **Declarative lifecycle**: mark a route's introduction, deprecation, and removal with one decorator
|
|
60
|
+
- **Deprecation headers**: opt-in `Deprecation`, `Sunset` and `Link` response headers on routes in their deprecation window
|
|
61
|
+
- **Latest alias**: expose the newest version under a fixed `/latest` prefix clients can pin to
|
|
62
|
+
- **Self-hosted docs assets**: point Swagger UI and ReDoc at your own JS/CSS for air-gapped deployments
|
|
63
|
+
- **Reverse proxy and sub-app aware**: doc URLs pick up the ASGI `root_path` at request time
|
|
64
|
+
- **Route composition support**: works across nested routers, WebSockets, `Depends`, and OpenAPI Callbacks
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Requirements
|
|
69
|
+
|
|
70
|
+
- Python ≥ 3.10
|
|
71
|
+
- FastAPI ≥ 0.120.0, except `0.137.0` and `0.137.1`
|
|
72
|
+
|
|
73
|
+
> **Why two FastAPI versions are excluded**
|
|
74
|
+
>
|
|
75
|
+
> `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.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install fastapi-router-versioning
|
|
83
|
+
# or
|
|
84
|
+
uv add fastapi-router-versioning
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Quick start
|
|
90
|
+
|
|
91
|
+
`RouterVersioner` is not a request-time dependency; there's no `Depends()` involved. It's a
|
|
92
|
+
one-time setup step: you build it, then call `.versionize()` once, and it reads the routers
|
|
93
|
+
you gave it and mounts one copy per version. Attach `@api_version` to every route **before**
|
|
94
|
+
calling `.versionize()`, since that call is what reads the router and wires everything up;
|
|
95
|
+
routes added to the router afterward are never picked up.
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from fastapi import APIRouter, FastAPI
|
|
99
|
+
from fastapi_router_versioning import (
|
|
100
|
+
RouterVersioner, VersionFormat, api_version,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
app = FastAPI()
|
|
104
|
+
router = APIRouter()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@router.get("/items")
|
|
108
|
+
@api_version((1, 0))
|
|
109
|
+
def get_items_v1():
|
|
110
|
+
return {"version": "1.0", "items": ["a", "b"]}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@router.get("/items")
|
|
114
|
+
@api_version((2, 0))
|
|
115
|
+
def get_items_v2():
|
|
116
|
+
return {"version": "2.0", "items": ["a", "b", "c"]}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
RouterVersioner(
|
|
120
|
+
app=app, routers=router,
|
|
121
|
+
version_format=VersionFormat.SEMVER
|
|
122
|
+
).versionize()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
CalVer, the route lifecycle, the parameter reference and the advanced options are in the [documentation](https://mat81black.github.io/fastapi-router-versioning/).
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Release Notes
|
|
130
|
+
|
|
131
|
+
[RELEASE_NOTES](https://github.com/mat81black/fastapi-router-versioning/blob/main/docs/release-notes.md)
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
[MIT](https://github.com/mat81black/fastapi-router-versioning/blob/main/LICENSE)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<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">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/mat81black/fastapi-router-versioning/main/docs/assets/images/wordmark.png" alt="FastAPI Router Versioning" width="480">
|
|
7
|
+
</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<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>
|
|
11
|
+
<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>
|
|
12
|
+
<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>
|
|
13
|
+
<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>
|
|
14
|
+
<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>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
Documentation: https://mat81black.github.io/fastapi-router-versioning/
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- **SemVer and CalVer**: version routes with `(major, minor)` tuples, or with arbitrary sortable strings
|
|
26
|
+
- **Per-version docs**: isolated Swagger UI, ReDoc, and `openapi.json` for every active version
|
|
27
|
+
- **Declarative lifecycle**: mark a route's introduction, deprecation, and removal with one decorator
|
|
28
|
+
- **Deprecation headers**: opt-in `Deprecation`, `Sunset` and `Link` response headers on routes in their deprecation window
|
|
29
|
+
- **Latest alias**: expose the newest version under a fixed `/latest` prefix clients can pin to
|
|
30
|
+
- **Self-hosted docs assets**: point Swagger UI and ReDoc at your own JS/CSS for air-gapped deployments
|
|
31
|
+
- **Reverse proxy and sub-app aware**: doc URLs pick up the ASGI `root_path` at request time
|
|
32
|
+
- **Route composition support**: works across nested routers, WebSockets, `Depends`, and OpenAPI Callbacks
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Python ≥ 3.10
|
|
39
|
+
- FastAPI ≥ 0.120.0, except `0.137.0` and `0.137.1`
|
|
40
|
+
|
|
41
|
+
> **Why two FastAPI versions are excluded**
|
|
42
|
+
>
|
|
43
|
+
> `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.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install fastapi-router-versioning
|
|
51
|
+
# or
|
|
52
|
+
uv add fastapi-router-versioning
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Quick start
|
|
58
|
+
|
|
59
|
+
`RouterVersioner` is not a request-time dependency; there's no `Depends()` involved. It's a
|
|
60
|
+
one-time setup step: you build it, then call `.versionize()` once, and it reads the routers
|
|
61
|
+
you gave it and mounts one copy per version. Attach `@api_version` to every route **before**
|
|
62
|
+
calling `.versionize()`, since that call is what reads the router and wires everything up;
|
|
63
|
+
routes added to the router afterward are never picked up.
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from fastapi import APIRouter, FastAPI
|
|
67
|
+
from fastapi_router_versioning import (
|
|
68
|
+
RouterVersioner, VersionFormat, api_version,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
app = FastAPI()
|
|
72
|
+
router = APIRouter()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@router.get("/items")
|
|
76
|
+
@api_version((1, 0))
|
|
77
|
+
def get_items_v1():
|
|
78
|
+
return {"version": "1.0", "items": ["a", "b"]}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@router.get("/items")
|
|
82
|
+
@api_version((2, 0))
|
|
83
|
+
def get_items_v2():
|
|
84
|
+
return {"version": "2.0", "items": ["a", "b", "c"]}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
RouterVersioner(
|
|
88
|
+
app=app, routers=router,
|
|
89
|
+
version_format=VersionFormat.SEMVER
|
|
90
|
+
).versionize()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
CalVer, the route lifecycle, the parameter reference and the advanced options are in the [documentation](https://mat81black.github.io/fastapi-router-versioning/).
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Release Notes
|
|
98
|
+
|
|
99
|
+
[RELEASE_NOTES](https://github.com/mat81black/fastapi-router-versioning/blob/main/docs/release-notes.md)
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
[MIT](https://github.com/mat81black/fastapi-router-versioning/blob/main/LICENSE)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Run a function once for each versioned router before it is mounted.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Callback hook
|
|
6
|
+
|
|
7
|
+
`callback` runs for every versioned router, the `latest_prefix` alias included, right before
|
|
8
|
+
`RouterVersioner` includes it in the app, handy for logging every mount point or wiring metrics:
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
--8<-- "docs_src/advanced/callback_hook.py:snippet"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
If `versionize()` raises, don't catch the exception and retry. Errors found while the versions
|
|
15
|
+
are built, such as a callback that throws or two versions that resolve to the same prefix, are
|
|
16
|
+
raised before anything is added to the app, but the routers are then included one after another,
|
|
17
|
+
and this package makes no attempt to undo a partial inclusion. `versionize()` normally runs at
|
|
18
|
+
startup, so the app fails to start; fix the underlying issue and start it again.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Version OpenAPI webhooks and carry route callbacks into every version.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# OpenAPI callbacks and webhooks
|
|
6
|
+
|
|
7
|
+
Route-level **Callbacks** need no special handling: a `callbacks=[...]` argument on a route
|
|
8
|
+
is carried over to every versioned copy of it automatically:
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
--8<-- "docs_src/advanced/callbacks.py:snippet"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Webhooks** (`app.webhooks`) are visible in every version's schema by default. Pass
|
|
15
|
+
`webhook_routers` to version them the same way as regular routes, with `@api_version` on
|
|
16
|
+
each definition:
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
--8<-- "docs_src/advanced/webhooks.py:snippet"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
In [`webhook_versioning_app.py`](https://github.com/mat81black/fastapi-router-versioning/blob/main/examples/webhook_versioning_app.py), which follows this pattern, v1.0 lists two webhooks and v2.0 only `order-created`, with its v2 definition (the example's second webhook is `payment-received` rather than `payment-failed`):
|
|
23
|
+
|
|
24
|
+
=== "v1.0"
|
|
25
|
+
|
|
26
|
+
{ loading=lazy }
|
|
27
|
+
|
|
28
|
+
=== "v2.0"
|
|
29
|
+
|
|
30
|
+
{ loading=lazy }
|
|
31
|
+
|
|
32
|
+
A webhook version only becomes visible once a route version reaches that same prefix, since
|
|
33
|
+
both follow the same `remove_in` lifecycle.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Change how a version appears in URL prefixes and in the Swagger and ReDoc titles.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Custom URL format
|
|
6
|
+
|
|
7
|
+
`prefix_format` and `semantic_version_format` control how a version renders in URLs and in
|
|
8
|
+
doc titles, independently of how it's expressed in `@api_version`. A common use is dropping
|
|
9
|
+
the minor number from the URL while still tracking it internally:
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
--8<-- "docs_src/advanced/custom_url_format.py:snippet"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The routes are mounted under `/v1`, `/v2` and `/latest`, and the Swagger titles read `v1` and `v2` instead of `v1.0` and `v2.0`. Here are the docs at `/v1/docs` and at `/latest/docs`, which serves the newest version:
|
|
16
|
+
|
|
17
|
+
=== "/v1/docs"
|
|
18
|
+
|
|
19
|
+
{ loading=lazy }
|
|
20
|
+
|
|
21
|
+
=== "/latest/docs"
|
|
22
|
+
|
|
23
|
+
{ loading=lazy }
|
|
24
|
+
|
|
25
|
+
Routes are still decorated with `(major, minor)` tuples; only their URL and label change.
|