Browse Source

Merge branch 'master' into feature/auth-static-files

pull/15295/head
Faisal Saifi 3 weeks ago
committed by GitHub
parent
commit
c8deca3280
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      .github/dependabot.yml
  2. 8
      .github/workflows/add-to-project.yml
  3. 35
      .github/workflows/build-docs.yml
  4. 17
      .github/workflows/contributors.yml
  5. 35
      .github/workflows/deploy-docs.yml
  6. 6
      .github/workflows/detect-conflicts.yml
  7. 11
      .github/workflows/issue-manager.yml
  8. 14
      .github/workflows/label-approved.yml
  9. 8
      .github/workflows/labeler.yml
  10. 16
      .github/workflows/latest-changes.yml
  11. 17
      .github/workflows/notify-translations.yml
  12. 17
      .github/workflows/people.yml
  13. 21
      .github/workflows/pre-commit.yml
  14. 12
      .github/workflows/publish.yml
  15. 20
      .github/workflows/smokeshow.yml
  16. 17
      .github/workflows/sponsors.yml
  17. 10
      .github/workflows/test-redistribute.yml
  18. 70
      .github/workflows/test.yml
  19. 13
      .github/workflows/topic-repos.yml
  20. 35
      .github/workflows/translate.yml
  21. 16
      .pre-commit-config.yaml
  22. 38
      README.md
  23. 12
      docs/en/data/contributors.yml
  24. 320
      docs/en/data/people.yml
  25. 9
      docs/en/data/sponsors.yml
  26. 1
      docs/en/data/sponsors_badge.yml
  27. 404
      docs/en/data/topic_repos.yml
  28. 12
      docs/en/data/translation_reviewers.yml
  29. 4
      docs/en/data/translators.yml
  30. 1
      docs/en/docs/advanced/generate-clients.md
  31. 44
      docs/en/docs/advanced/vibe.md
  32. 186
      docs/en/docs/css/custom.css
  33. BIN
      docs/en/docs/img/fastapi-conf.jpeg
  34. 35
      docs/en/docs/img/logos/cisco.svg
  35. 8
      docs/en/docs/img/logos/microsoft.svg
  36. 1
      docs/en/docs/img/logos/netflix.svg
  37. 39
      docs/en/docs/img/logos/uber.svg
  38. BIN
      docs/en/docs/img/sponsors/talordata.png
  39. 83
      docs/en/docs/index.md
  40. 38
      docs/en/docs/js/custom.js
  41. 81
      docs/en/docs/release-notes.md
  42. 2
      docs/en/docs/virtual-environments.md
  43. 1
      docs/en/mkdocs.yml
  44. 13
      docs/en/overrides/main.html
  45. 6
      docs/es/llm-prompt.md
  46. 12
      docs_src/vibe/tutorial001_py310.py
  47. 2
      fastapi/__init__.py
  48. 2
      fastapi/_compat/__init__.py
  49. 4
      fastapi/_compat/shared.py
  50. 29
      fastapi/_compat/v2.py
  51. 70
      fastapi/applications.py
  52. 2
      fastapi/cli.py
  53. 10
      fastapi/dependencies/utils.py
  54. 25
      fastapi/encoders.py
  55. 4
      fastapi/openapi/models.py
  56. 2
      fastapi/openapi/utils.py
  57. 20
      fastapi/params.py
  58. 27
      fastapi/responses.py
  59. 8
      fastapi/routing.py
  60. 51
      pyproject.toml
  61. 8
      scripts/docs.py
  62. 4
      scripts/general-llm-prompt.md
  63. 96
      scripts/translate.py
  64. 8
      tests/test_default_response_class.py
  65. 6
      tests/test_deprecated_responses.py
  66. 18
      tests/test_jsonable_encoder.py
  67. 4
      tests/test_orjson_response_class.py
  68. 0
      tests/test_response_set_response_code_empty.py
  69. 7
      tests/test_tutorial/test_body_multiple_params/test_tutorial002.py
  70. 2
      tests/test_tutorial/test_body_multiple_params/test_tutorial005.py
  71. 2
      tests/test_tutorial/test_custom_response/test_tutorial001.py
  72. 2
      tests/test_tutorial/test_custom_response/test_tutorial001b.py
  73. 3
      tests/test_tutorial/test_custom_response/test_tutorial009c.py
  74. 17
      tests/test_vibe.py
  75. 2
      tests/test_ws_router.py
  76. 11
      tests/utils.py
  77. 1748
      uv.lock

15
.github/dependabot.yml

@ -5,12 +5,25 @@ updates:
directory: "/"
schedule:
interval: "daily"
cooldown:
default-days: 7
commit-message:
prefix:
# Python
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "monthly"
interval: "daily"
cooldown:
default-days: 7
commit-message:
prefix:
# pre-commit
- package-ecosystem: "pre-commit"
directory: "/"
schedule:
interval: "daily"
cooldown:
default-days: 7
commit-message:
prefix:

8
.github/workflows/add-to-project.yml

@ -1,18 +1,20 @@
name: Add to Project
on:
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
issues:
types:
- opened
- reopened
permissions: {}
jobs:
add-to-project:
name: Add to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v1.0.2
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
with:
project-url: https://github.com/orgs/fastapi/projects/2
github-token: ${{ secrets.PROJECTS_TOKEN }}
github-token: ${{ secrets.PROJECTS_TOKEN }} # zizmor: ignore[secrets-outside-env]

35
.github/workflows/build-docs.yml

@ -8,6 +8,8 @@ on:
- opened
- synchronize
permissions: {}
jobs:
changes:
runs-on: ubuntu-latest
@ -18,9 +20,11 @@ jobs:
outputs:
docs: ${{ steps.filter.outputs.docs }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
# For pull requests it's not necessary to checkout the code but for the main branch it is
- uses: dorny/paths-filter@v4
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: filter
with:
filters: |
@ -42,14 +46,17 @@ jobs:
outputs:
langs: ${{ steps.show-langs.outputs.langs }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -75,14 +82,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -91,13 +101,14 @@ jobs:
run: uv sync --locked --no-dev --group docs
- name: Update Languages
run: uv run ./scripts/docs.py update-languages
- uses: actions/cache@v5
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
path: docs/${{ matrix.lang }}/.cache
- name: Build Docs
run: uv run ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@v7
run: | # zizmor: ignore[template-injection] - comes from trusted source
uv run ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: docs-site-${{ matrix.lang }}
path: ./site/**
@ -111,7 +122,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: build-docs

17
.github/workflows/contributors.yml

@ -10,6 +10,8 @@ on:
required: false
default: "false"
permissions: {}
jobs:
job:
if: github.repository_owner == 'fastapi'
@ -21,14 +23,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: true # Required for `git push` in `contributors.py`
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -37,13 +42,13 @@ jobs:
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]
- name: FastAPI People Contributors
run: uv run ./scripts/contributors.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]

35
.github/workflows/deploy-docs.yml

@ -1,37 +1,38 @@
name: Deploy Docs
on:
workflow_run:
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows:
- Build Docs
types:
- completed
permissions:
deployments: write
issues: write
pull-requests: write
statuses: write
permissions: {}
jobs:
deploy-docs:
runs-on: ubuntu-latest
permissions:
deployments: write
issues: write
pull-requests: write
statuses: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
version: "0.11.4"
enable-cache: false
- name: Install GitHub Actions dependencies
run: uv sync --locked --no-dev --group github-actions
- name: Deploy Docs Status Pending
@ -45,7 +46,7 @@ jobs:
run: |
rm -rf ./site
mkdir ./site
- uses: actions/download-artifact@v8
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ./site/
pattern: docs-site-*
@ -59,10 +60,10 @@ jobs:
env:
PROJECT_NAME: fastapitiangolo
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
uses: cloudflare/wrangler-action@v3
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} # zizmor: ignore[secrets-outside-env]
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} # zizmor: ignore[secrets-outside-env]
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
- name: Deploy Docs Status Error
if: failure()

6
.github/workflows/detect-conflicts.yml

@ -1,9 +1,11 @@
name: "Conflict detector"
on:
push:
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
types: [synchronize]
permissions: {}
jobs:
main:
permissions:
@ -12,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check if PRs have merge conflicts
uses: eps1lon/actions-label-merge-conflict@v3
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
with:
dirtyLabel: "conflicts"
repoToken: "${{ secrets.GITHUB_TOKEN }}"

11
.github/workflows/issue-manager.yml

@ -9,25 +9,26 @@ on:
issues:
types:
- labeled
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
types:
- labeled
workflow_dispatch:
permissions:
issues: write
pull-requests: write
permissions: {}
jobs:
issue-manager:
if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: tiangolo/[email protected]
- uses: tiangolo/issue-manager@2fb3484ec9279485df8659e8ec73de262431737d # 0.6.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >

14
.github/workflows/label-approved.yml

@ -5,26 +5,30 @@ on:
- cron: "0 12 * * *"
workflow_dispatch:
permissions:
pull-requests: write
permissions: {}
jobs:
label-approved:
if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml

8
.github/workflows/labeler.yml

@ -1,6 +1,6 @@
name: Labels
on:
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
types:
- opened
- synchronize
@ -9,6 +9,8 @@ on:
- labeled
- unlabeled
permissions: {}
jobs:
labeler:
permissions:
@ -16,7 +18,7 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v6
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
- run: echo "Done adding labels"
# Run this after labeler applied labels
@ -27,7 +29,7 @@ jobs:
pull-requests: read
runs-on: ubuntu-latest
steps:
- uses: docker://agilepathway/pull-request-label-checker:latest
- uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65
with:
one_of: breaking,security,feature,bug,refactor,upgrade,docs,lang-all,internal
repo_token: ${{ secrets.GITHUB_TOKEN }}

16
.github/workflows/latest-changes.yml

@ -1,7 +1,7 @@
name: Latest Changes
on:
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
branches:
- master
types:
@ -16,27 +16,29 @@ on:
required: false
default: 'false'
permissions: {}
jobs:
latest-changes:
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
# pin to actions/checkout@v5 for compatibility with latest-changes
# Ref: https://github.com/actions/checkout/issues/2313
- uses: actions/checkout@v5
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
# To allow latest-changes to commit to the main branch
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
token: ${{ secrets.FASTAPI_LATEST_CHANGES }} # zizmor: ignore[secrets-outside-env]
persist-credentials: true # required by tiangolo/latest-changes
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- uses: tiangolo/[email protected]
- uses: tiangolo/latest-changes@c9d329cb147f0ddf4fb631214e3f838ff17ccbbd # 0.4.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
latest_changes_file: docs/en/docs/release-notes.md

17
.github/workflows/notify-translations.yml

@ -1,10 +1,12 @@
name: Notify Translations
on:
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
types:
- labeled
- closed
branches:
- master
workflow_dispatch:
inputs:
number:
@ -15,6 +17,8 @@ on:
required: false
default: 'false'
permissions: {}
jobs:
job:
runs-on: ubuntu-latest
@ -25,14 +29,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -41,7 +48,7 @@ jobs:
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true

17
.github/workflows/people.yml

@ -10,6 +10,8 @@ on:
required: false
default: "false"
permissions: {}
jobs:
job:
if: github.repository_owner == 'fastapi'
@ -21,14 +23,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: true # Required for `git push` in `people.py`
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -37,14 +42,14 @@ jobs:
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }} # zizmor: ignore[secrets-outside-env]
- name: FastAPI People Experts
run: uv run ./scripts/people.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }} # zizmor: ignore[secrets-outside-env]
SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}

21
.github/workflows/pre-commit.yml

@ -6,6 +6,8 @@ on:
- opened
- synchronize
permissions: {}
env:
# Forks and Dependabot don't have access to secrets
HAS_SECRETS: ${{ secrets.PRE_COMMIT != '' }}
@ -18,7 +20,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v5
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: Checkout PR for own repo
if: env.HAS_SECRETS == 'true'
with:
@ -28,22 +30,25 @@ jobs:
# And it needs the full history to be able to compute diffs
fetch-depth: 0
# A token other than the default GITHUB_TOKEN is needed to be able to trigger CI
token: ${{ secrets.PRE_COMMIT }}
token: ${{ secrets.PRE_COMMIT }} # zizmor: ignore[secrets-outside-env]
persist-credentials: true # Required for `git push` command
# pre-commit lite ci needs the default checkout configs to work
- uses: actions/checkout@v5
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
name: Checkout PR for fork
if: env.HAS_SECRETS == 'false'
with:
# To be able to commit it needs the head branch of the PR, the remote one
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
cache-dependency-glob: |
pyproject.toml
uv.lock
@ -51,7 +56,7 @@ jobs:
run: uv sync --locked --extra all
- name: Run prek - pre-commit
id: precommit
run: uvx prek run --from-ref origin/${GITHUB_BASE_REF} --to-ref HEAD --show-diff-on-failure
run: uv run prek run --from-ref origin/${GITHUB_BASE_REF} --to-ref HEAD --show-diff-on-failure
continue-on-error: true
- name: Commit and push changes
if: env.HAS_SECRETS == 'true'
@ -65,7 +70,7 @@ jobs:
git commit -m "🎨 Auto format"
git push
fi
- uses: pre-commit-ci/[email protected]
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
if: env.HAS_SECRETS == 'false'
with:
msg: 🎨 Auto format
@ -85,6 +90,6 @@ jobs:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
with:
jobs: ${{ toJSON(needs) }}

12
.github/workflows/publish.yml

@ -5,6 +5,8 @@ on:
types:
- created
permissions: {}
jobs:
publish:
runs-on: ubuntu-latest
@ -16,13 +18,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
- name: Build distribution
run: uv build
- name: Publish

20
.github/workflows/smokeshow.yml

@ -1,34 +1,38 @@
name: Smokeshow
on:
workflow_run:
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: [Test]
types: [completed]
permissions:
statuses: write
permissions: {}
jobs:
smokeshow:
runs-on: ubuntu-latest
permissions:
statuses: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
cache-dependency-glob: |
pyproject.toml
uv.lock
- run: uv sync --locked --no-dev --group github-actions
- uses: actions/download-artifact@v8
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: coverage-html
path: htmlcov
@ -51,4 +55,4 @@ jobs:
SMOKESHOW_GITHUB_CONTEXT: coverage
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }} # zizmor: ignore[secrets-outside-env]

17
.github/workflows/sponsors.yml

@ -10,6 +10,8 @@ on:
required: false
default: "false"
permissions: {}
jobs:
job:
if: github.repository_owner == 'fastapi'
@ -21,14 +23,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: true # Required for `git push` in `sponsors.py`
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -37,12 +42,12 @@ jobs:
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- name: FastAPI People Sponsors
run: uv run ./scripts/sponsors.py
env:
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }}
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }} # zizmor: ignore[secrets-outside-env]
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]

10
.github/workflows/test-redistribute.yml

@ -9,6 +9,8 @@ on:
- opened
- synchronize
permissions: {}
jobs:
test-redistribute:
runs-on: ubuntu-latest
@ -17,9 +19,11 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Install build dependencies
@ -55,6 +59,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
with:
jobs: ${{ toJSON(needs) }}

70
.github/workflows/test.yml

@ -12,6 +12,8 @@ on:
# cron every week on monday
- cron: "0 0 * * 1"
permissions: {}
env:
UV_NO_SYNC: true
INLINE_SNAPSHOT_DEFAULT_FLAGS: review
@ -26,9 +28,11 @@ jobs:
outputs:
src: ${{ steps.filter.outputs.src }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
# For pull requests it's not necessary to checkout the code but for the main branch it is
- uses: dorny/paths-filter@v4
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: filter
with:
filters: |
@ -49,7 +53,8 @@ jobs:
strategy:
matrix:
os: [ windows-latest, macos-latest ]
python-version: [ "3.14" ]
python-version: [ "3.14", "3.14t" ]
deprecated-tests: [ "no-deprecation" ]
uv-resolution:
- highest
starlette-src:
@ -60,23 +65,33 @@ jobs:
python-version: "3.10"
coverage: coverage
uv-resolution: lowest-direct
deprecated-tests: "no-deprecation"
- os: windows-latest
python-version: "3.12"
coverage: coverage
uv-resolution: lowest-direct
deprecated-tests: "no-deprecation"
- os: ubuntu-latest
python-version: "3.13"
coverage: coverage
uv-resolution: highest
deprecated-tests: "no-deprecation"
- os: ubuntu-latest
python-version: "3.13"
uv-resolution: highest
codspeed: codspeed
deprecated-tests: "no-deprecation"
- os: ubuntu-latest
python-version: "3.14"
coverage: coverage
uv-resolution: highest
starlette-src: starlette-git
deprecated-tests: "test-deprecation"
- os: ubuntu-latest
python-version: "3.14t"
coverage: coverage
uv-resolution: highest
deprecated-tests: "no-deprecation"
fail-fast: false
runs-on: ${{ matrix.os }}
env:
@ -88,14 +103,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -108,18 +126,24 @@ jobs:
- name: Install Starlette from source
if: matrix.starlette-src == 'starlette-git'
run: uv pip install "git+https://github.com/Kludex/starlette@main"
- name: Install deprecated libraries just for testing
if: matrix.deprecated-tests == 'test-deprecation'
run: uv pip install orjson ujson
- name: Reinstall SQLAlchemy without Cython extensions
if: matrix.python-version == '3.14t' && matrix.os == 'ubuntu-latest'
run: "DISABLE_SQLALCHEMY_CEXT=1 uv pip install --force-reinstall --no-binary :all: sqlalchemy"
- run: mkdir coverage
- name: Test
run: uv run --no-sync bash scripts/test-cov.sh
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}-${{ matrix.deprecated-tests}}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}-${{ matrix.deprecated-tests}}
# Do not store coverage for all possible combinations to avoid file size max errors in Smokeshow
- name: Store coverage files
if: matrix.coverage == 'coverage'
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/coverage/.coverage.*') }}
name: coverage-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.deprecated-tests}}-${{ hashFiles('**/coverage/.coverage.*') }}
path: coverage
include-hidden-files: true
@ -136,14 +160,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -151,7 +178,7 @@ jobs:
- name: Install Dependencies
run: uv sync --no-dev --group tests --extra all
- name: CodSpeed benchmarks
uses: CodSpeedHQ/action@v4
uses: CodSpeedHQ/action@658a901452bb54c799643e060733b7afe9121b8d # v4.14.0
with:
mode: simulation
run: uv run --no-sync pytest tests/benchmarks --codspeed
@ -165,13 +192,16 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -179,7 +209,7 @@ jobs:
- name: Install Dependencies
run: uv sync --locked --no-dev --group tests --extra all
- name: Get coverage files
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: coverage-*
path: coverage
@ -188,7 +218,7 @@ jobs:
- run: uv run coverage combine coverage
- run: uv run coverage html --title "Coverage for ${{ github.sha }}"
- name: Store coverage HTML
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-html
path: htmlcov
@ -208,7 +238,7 @@ jobs:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: coverage-combine,test,benchmark

13
.github/workflows/topic-repos.yml

@ -5,6 +5,8 @@ on:
- cron: "0 12 1 * *"
workflow_dispatch:
permissions: {}
jobs:
topic-repos:
if: github.repository_owner == 'fastapi'
@ -16,14 +18,17 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: true # Required for `git push` in `topic_repos.py`
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
enable-cache: true
cache-dependency-glob: |
pyproject.toml
@ -33,4 +38,4 @@ jobs:
- name: Update Topic Repos
run: uv run ./scripts/topic_repos.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]

35
.github/workflows/translate.yml

@ -41,6 +41,8 @@ on:
required: false
default: 10
permissions: {}
jobs:
langs:
runs-on: ubuntu-latest
@ -48,14 +50,17 @@ jobs:
langs: ${{ steps.show-langs.outputs.langs }}
commands: ${{ steps.show-langs.outputs.commands }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
cache-dependency-glob: |
pyproject.toml
uv.lock
@ -74,27 +79,29 @@ jobs:
if: github.repository_owner == 'fastapi'
needs: langs
runs-on: ubuntu-latest
permissions:
contents: write
strategy:
matrix:
lang: ${{ fromJson(needs.langs.outputs.langs) }}
command: ${{ fromJson(needs.langs.outputs.commands) }}
permissions:
contents: write
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: true # Required for `git push` in `translate.py`
- name: Set up Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
version: "0.11.4"
cache-dependency-glob: |
pyproject.toml
uv.lock
@ -102,20 +109,20 @@ jobs:
run: uv sync --locked --no-dev --group github-actions --group translations
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }} # zizmor: ignore[secrets-outside-env]
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} # zizmor: ignore[secrets-outside-env]
- name: FastAPI Translate
run: |
uv run ./scripts/translate.py ${{ matrix.command }}
uv run ./scripts/translate.py "$COMMAND"
uv run ./scripts/translate.py make-pr
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }} # zizmor: ignore[secrets-outside-env]
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} # zizmor: ignore[secrets-outside-env]
LANGUAGE: ${{ matrix.lang }}
EN_PATH: ${{ github.event.inputs.en_path }}
COMMAND: ${{ matrix.command }}

16
.pre-commit-config.yaml

@ -2,7 +2,7 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # v6.0.0
hooks:
- id: check-added-large-files
args: ['--maxkb=750']
@ -14,6 +14,12 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/crate-ci/typos
rev: bbaefadf97b0ec5fdc942684b647f1a6ab250274 # v1.46.0
hooks:
- id: typos
args: [--force-exclude]
- repo: local
hooks:
- id: local-ruff-check
@ -85,3 +91,11 @@ repos:
entry: uv run python scripts/add_latest_release_date.py
files: ^docs/en/docs/release-notes\.md$
pass_filenames: false
- id: zizmor
name: zizmor
language: python
entry: uv run zizmor .
files: ^\.github\/workflows\/
require_serial: true
pass_filenames: false

38
README.md

@ -49,12 +49,11 @@ The key features are:
<a href="https://fastapicloud.com" target="_blank" title="FastAPI Cloud. By the same team behind FastAPI. You code. We Cloud."><img src="https://fastapi.tiangolo.com/img/sponsors/fastapicloud.png"></a>
### Gold and Silver Sponsors
### Gold Sponsors
<a href="https://blockbee.io?ref=fastapi" target="_blank" title="BlockBee Cryptocurrency Payment Gateway"><img src="https://fastapi.tiangolo.com/img/sponsors/blockbee.png"></a>
<a href="https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge" target="_blank" title="Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files"><img src="https://fastapi.tiangolo.com/img/sponsors/scalar.svg"></a>
<a href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge" target="_blank" title="Auth, user management and more for your B2B product"><img src="https://fastapi.tiangolo.com/img/sponsors/propelauth.png"></a>
<a href="https://zuplo.link/fastapi-gh" target="_blank" title="Zuplo: Deploy, Secure, Document, and Monetize your FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/zuplo.png"></a>
<a href="https://liblab.com?utm_source=fastapi" target="_blank" title="liblab - Generate SDKs from FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/liblab.png"></a>
<a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra."><img src="https://fastapi.tiangolo.com/img/sponsors/render.svg"></a>
<a href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi" target="_blank" title="Cut Code Review Time & Bugs in Half with CodeRabbit"><img src="https://fastapi.tiangolo.com/img/sponsors/coderabbit.png"></a>
@ -62,13 +61,16 @@ The key features are:
<a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" target="_blank" title="Deploy enterprise applications at startup speed"><img src="https://fastapi.tiangolo.com/img/sponsors/railway.png"></a>
<a href="https://serpapi.com/?utm_source=fastapi_website" target="_blank" title="SerpApi: Web Search API"><img src="https://fastapi.tiangolo.com/img/sponsors/serpapi.png"></a>
<a href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank" title="Greptile: The AI Code Reviewer"><img src="https://fastapi.tiangolo.com/img/sponsors/greptile.png"></a>
### Silver Sponsors
<a href="https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
<a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" target="_blank" title="SDKs for your API | Speakeasy"><img src="https://fastapi.tiangolo.com/img/sponsors/speakeasy.png"></a>
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
<a href="https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral" target="_blank" title="Stainless | Generate best-in-class SDKs"><img src="https://fastapi.tiangolo.com/img/sponsors/stainless.png"></a>
<a href="https://www.permit.io/blog/implement-authorization-in-fastapi?utm_source=github&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Fine-Grained Authorization for FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/permit.png"></a>
<a href="https://www.interviewpal.com/?utm_source=fastapi&utm_medium=open-source&utm_campaign=dev-hiring" target="_blank" title="InterviewPal - AI Interview Coach for Engineers and Devs"><img src="https://fastapi.tiangolo.com/img/sponsors/interviewpal.png"></a>
<a href="https://dribia.com/en/" target="_blank" title="Dribia - Data Science within your reach"><img src="https://fastapi.tiangolo.com/img/sponsors/dribia.png"></a>
<a href="https://talordata.com/?campaignid=oh5dVZ3Zc3YGiAI2&utm_source=fastapi&utm_term=fastapi" target="_blank" title="TalorData SERP API - Multi-Engine Search Results Data"><img src="https://fastapi.tiangolo.com/img/sponsors/talordata.png"></a>
<!-- /sponsors -->
@ -76,6 +78,10 @@ The key features are:
## Opinions
<div class="only-github" markdown="1">
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div>
@ -94,37 +100,25 @@ The key features are:
---
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>[Python Bytes](https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855) podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832"><small>(ref)</small></a></div>
---
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>[Hug](https://github.com/hugapi/hug) creator</strong> <a href="https://news.ycombinator.com/item?id=19455465"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
---
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>[Explosion AI](https://explosion.ai) founders - [spaCy](https://spacy.io) creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680"><small>(ref)</small></a></div>
---
</div>
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
## FastAPI Conf
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
[**FastAPI Conf '26**](https://fastapiconf.com) is happening on **October 28, 2026** in **Amsterdam, NL**. All about FastAPI, right from the source. 🎤
---
<a class="fastapi-feature-banner" href="https://fastapiconf.com"><img src="https://fastapi.tiangolo.com/img/fastapi-conf.jpeg" alt="FastAPI Conf '26 - October 28, 2026 - Amsterdam, NL"></a>
## FastAPI mini documentary
There's a [FastAPI mini documentary](https://www.youtube.com/watch?v=mpR8ngthqiE) released at the end of 2025, you can watch it online:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
<a class="fastapi-feature-banner" href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**, the FastAPI of CLIs

12
docs/en/data/contributors.yml

@ -1,21 +1,21 @@
tiangolo:
login: tiangolo
count: 935
count: 942
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
dependabot:
login: dependabot
count: 157
count: 189
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
url: https://github.com/apps/dependabot
YuriiMotov:
login: YuriiMotov
count: 66
count: 70
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
alejsdev:
login: alejsdev
count: 53
count: 56
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=0facffe3abf87f57a1f05fa773d1119cc5c2f6a5&v=4
url: https://github.com/alejsdev
pre-commit-ci:
@ -35,7 +35,7 @@ Kludex:
url: https://github.com/Kludex
svlandeg:
login: svlandeg
count: 21
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
dmontagu:
@ -556,7 +556,7 @@ chailandau:
DanielKusyDev:
login: DanielKusyDev
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4
avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=411f1f5923596480b896d160e23c908318f39003&v=4
url: https://github.com/DanielKusyDev
Viicos:
login: Viicos

320
docs/en/data/people.yml

@ -1,19 +1,19 @@
maintainers:
- login: tiangolo
answers: 1922
answers: 1927
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
experts:
- login: tiangolo
count: 1922
count: 1927
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: YuriiMotov
count: 1156
count: 1164
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
- login: github-actions
count: 769
count: 770
avatarUrl: https://avatars.githubusercontent.com/in/15368?v=4
url: https://github.com/apps/github-actions
- login: Kludex
@ -25,7 +25,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: dmontagu
count: 239
count: 240
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
- login: Mause
@ -41,7 +41,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: euri10
count: 152
count: 153
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: iudeen
@ -57,7 +57,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: luzzodev
count: 105
count: 107
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: raphaelauv
@ -89,7 +89,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: sm-Fifteen
count: 48
count: 49
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: adriangb
@ -246,99 +246,123 @@ experts:
url: https://github.com/mattmess1221
last_month_experts:
- login: YuriiMotov
count: 37
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
- login: christiansousadev
- login: Firatasi
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/112112161?u=3219914a49a4a604b3626007823db7de049b6d66&v=4
url: https://github.com/Firatasi
- login: ericgitangu
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
- login: saitarrun
avatarUrl: https://avatars.githubusercontent.com/u/11472845?u=9d916cf0f5c80e63cb1d753b8b50dcb8ced3b883&v=4
url: https://github.com/ericgitangu
- login: cookesan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/116748905?u=3433afbaf06676a482ebf4ba33b08ddb3fc5c5bf&v=4
url: https://github.com/saitarrun
- login: Vision-Executive
avatarUrl: https://avatars.githubusercontent.com/u/6601329?u=7bfc9b017198a9fa50929ae8ae0a787632424ffd&v=4
url: https://github.com/cookesan
- login: coleifer
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/259394686?u=dd28bbc246e4e2cd2adb1d497e7b7585b5d24585&v=4
url: https://github.com/Vision-Executive
- login: JavierSanchezCastro
avatarUrl: https://avatars.githubusercontent.com/u/119974?u=b3a546c94ee1105e792e0acad2c4743d800e7975&v=4
url: https://github.com/coleifer
- login: Bahtya
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
avatarUrl: https://avatars.githubusercontent.com/u/34988899?u=b8e3c0cf26f4bd1faea265d2f5f66f564af63463&v=4
url: https://github.com/Bahtya
- login: luzzodev
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: DoctorJohn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=ec43fe79a98dbc864b428afc7220753e25ca3af2&v=4
url: https://github.com/DoctorJohn
three_months_experts:
- login: YuriiMotov
count: 85
count: 74
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
- login: Firatasi
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/112112161?u=3219914a49a4a604b3626007823db7de049b6d66&v=4
url: https://github.com/Firatasi
- login: JavierSanchezCastro
count: 9
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: Toygarmetu
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/92878791?u=538530cb6d5554e71f9c28709d794db9a74d23d9&v=4
url: https://github.com/Toygarmetu
- login: ceb10n
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: tiangolo
count: 4
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: luzzodev
count: 3
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: christiansousadev
- login: ericgitangu
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
- login: Kludex
avatarUrl: https://avatars.githubusercontent.com/u/11472845?u=9d916cf0f5c80e63cb1d753b8b50dcb8ced3b883&v=4
url: https://github.com/ericgitangu
- login: cookesan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
avatarUrl: https://avatars.githubusercontent.com/u/6601329?u=7bfc9b017198a9fa50929ae8ae0a787632424ffd&v=4
url: https://github.com/cookesan
- login: coleifer
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/119974?u=b3a546c94ee1105e792e0acad2c4743d800e7975&v=4
url: https://github.com/coleifer
- login: Bahtya
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/34988899?u=b8e3c0cf26f4bd1faea265d2f5f66f564af63463&v=4
url: https://github.com/Bahtya
- login: saitarrun
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/116748905?u=3433afbaf06676a482ebf4ba33b08ddb3fc5c5bf&v=4
url: https://github.com/saitarrun
- login: Vision-Executive
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/259394686?u=dd28bbc246e4e2cd2adb1d497e7b7585b5d24585&v=4
url: https://github.com/Vision-Executive
- login: EmmanuelNiyonshuti
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/142030687?u=ab131d5ad4670280a978f489babe71c9bf9c1097&v=4
url: https://github.com/EmmanuelNiyonshuti
- login: christiansousadev
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
- login: DoctorJohn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=ec43fe79a98dbc864b428afc7220753e25ca3af2&v=4
url: https://github.com/DoctorJohn
- login: gaardhus
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/46934916?u=18d7aacc6ce59f054749209645d11cfe77b52f90&v=4
url: https://github.com/gaardhus
- login: valentinDruzhinin
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
url: https://github.com/valentinDruzhinin
- login: RichieB2B
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1461970?u=edaa57d1077705244ea5c9244f4783d94ff11f12&v=4
url: https://github.com/RichieB2B
- login: dotmitsu
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/42657211?u=3bccc9a2f386a3f24230ec393080f8904fe2a5b2&v=4
url: https://github.com/dotmitsu
six_months_experts:
- login: YuriiMotov
count: 182
count: 166
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
- login: tiangolo
count: 24
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: JavierSanchezCastro
count: 15
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: luzzodev
count: 10
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: Firatasi
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/112112161?u=3219914a49a4a604b3626007823db7de049b6d66&v=4
url: https://github.com/Firatasi
- login: Toygarmetu
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/92878791?u=538530cb6d5554e71f9c28709d794db9a74d23d9&v=4
@ -347,10 +371,6 @@ six_months_experts:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: RichieB2B
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/1461970?u=edaa57d1077705244ea5c9244f4783d94ff11f12&v=4
url: https://github.com/RichieB2B
- login: JunjieAraoXiong
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/167785867?u=b69afe090c8bf5fd73f2d23fc3a887b28f68f192&v=4
@ -359,50 +379,66 @@ six_months_experts:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
url: https://github.com/valentinDruzhinin
- login: ArmanShirzad
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/68951175?u=1f1efae2fa5d0d17c38a1a8413bedca5e538cedb&v=4
url: https://github.com/ArmanShirzad
- login: CodeKraken-cmd
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/48470371?u=e7c0e7ec8e35ca5fb3ae40a586ed5e788fd0fe6d&v=4
url: https://github.com/CodeKraken-cmd
- login: svlandeg
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
- login: krylosov-aa
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/242901957?u=4c9c7b468203b09bca64936fb464620e32cdd252&v=4
url: https://github.com/krylosov-aa
- login: Kludex
- login: ericgitangu
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: christiansousadev
avatarUrl: https://avatars.githubusercontent.com/u/11472845?u=9d916cf0f5c80e63cb1d753b8b50dcb8ced3b883&v=4
url: https://github.com/ericgitangu
- login: EmmanuelNiyonshuti
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
avatarUrl: https://avatars.githubusercontent.com/u/142030687?u=ab131d5ad4670280a978f489babe71c9bf9c1097&v=4
url: https://github.com/EmmanuelNiyonshuti
- login: sachinh35
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4
url: https://github.com/sachinh35
- login: RichieB2B
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1461970?u=edaa57d1077705244ea5c9244f4783d94ff11f12&v=4
url: https://github.com/RichieB2B
- login: cookesan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6601329?u=7bfc9b017198a9fa50929ae8ae0a787632424ffd&v=4
url: https://github.com/cookesan
- login: coleifer
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/119974?u=b3a546c94ee1105e792e0acad2c4743d800e7975&v=4
url: https://github.com/coleifer
- login: Bahtya
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/34988899?u=b8e3c0cf26f4bd1faea265d2f5f66f564af63463&v=4
url: https://github.com/Bahtya
- login: saitarrun
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/116748905?u=3433afbaf06676a482ebf4ba33b08ddb3fc5c5bf&v=4
url: https://github.com/saitarrun
- login: cepedus
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/26345924?u=38495abbdbb8695dd76478cae5963bf994c498bc&v=4
url: https://github.com/cepedus
- login: christiansousadev
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
- login: DoctorJohn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=ec43fe79a98dbc864b428afc7220753e25ca3af2&v=4
url: https://github.com/DoctorJohn
- login: gaardhus
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/46934916?u=18d7aacc6ce59f054749209645d11cfe77b52f90&v=4
url: https://github.com/gaardhus
- login: Kludex
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: y2kbugger
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6101677?u=1d50077e29582dc01fcbdff846f04fe7ec73fe2e&v=4
url: https://github.com/y2kbugger
- login: Vision-Executive
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/259394686?u=dd28bbc246e4e2cd2adb1d497e7b7585b5d24585&v=4
url: https://github.com/Vision-Executive
- login: EmmanuelNiyonshuti
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/142030687?u=ab131d5ad4670280a978f489babe71c9bf9c1097&v=4
url: https://github.com/EmmanuelNiyonshuti
- login: davidbrochart
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/4711805?u=d39696d995a9e02ec3613ffb2f62b20b14f92f26&v=4
@ -419,10 +455,6 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/4661021?u=ed5ddadcf36d9b943ebe61febe0b96ee34e5425d&v=4
url: https://github.com/dolfinus
- login: skion
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/532192?v=4
url: https://github.com/skion
- login: florentx
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/142113?u=bf10f10080026346b092633c380977b61cee0d9c&v=4
@ -431,37 +463,33 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/51329768?v=4
url: https://github.com/jc-louis
- login: WilliamDEdwards
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/12184311?u=9b29d5d1d71f5f1a7ef9e439963ad3529e3b33a4&v=4
url: https://github.com/WilliamDEdwards
- login: bughuntr7
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/236391583?u=7f51ff690e3a5711f845a115903c39e21c8af938&v=4
url: https://github.com/bughuntr7
- login: CodeKraken-cmd
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/48470371?u=e7c0e7ec8e35ca5fb3ae40a586ed5e788fd0fe6d&v=4
url: https://github.com/CodeKraken-cmd
- login: svlandeg
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
- login: jymchng
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/27895426?u=fb88c47775147d62a395fdb895d1af4148c7b566&v=4
url: https://github.com/jymchng
- login: XieJiSS
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/24671280?u=7ea0d9bfe46cf762594d62fd2f3c6d3813c3584c&v=4
url: https://github.com/XieJiSS
- login: profatsky
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/92920843?u=81e54bb0b613c171f7cd0ab3cbb58873782c9c9c&v=4
url: https://github.com/profatsky
one_year_experts:
- login: YuriiMotov
count: 951
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
- login: luzzodev
count: 53
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: tiangolo
count: 31
count: 30
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: valentinDruzhinin
@ -473,9 +501,17 @@ one_year_experts:
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: sachinh35
count: 11
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/21972708?u=8560b97b8b41e175f476270b56de8a493b84f302&v=4
url: https://github.com/sachinh35
- login: Firatasi
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/112112161?u=3219914a49a4a604b3626007823db7de049b6d66&v=4
url: https://github.com/Firatasi
- login: DoctorJohn
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=ec43fe79a98dbc864b428afc7220753e25ca3af2&v=4
url: https://github.com/DoctorJohn
- login: raceychan
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/75417963?u=060c62870ec5a791765e63ac20d8885d11143786&v=4
@ -484,14 +520,14 @@ one_year_experts:
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
url: https://github.com/yinziyan1206
- login: Kludex
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: Toygarmetu
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/92878791?u=538530cb6d5554e71f9c28709d794db9a74d23d9&v=4
url: https://github.com/Toygarmetu
- login: Kludex
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: ceb10n
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
@ -508,14 +544,6 @@ one_year_experts:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
- login: DoctorJohn
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/14076775?u=ec43fe79a98dbc864b428afc7220753e25ca3af2&v=4
url: https://github.com/DoctorJohn
- login: alv2017
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: WilliamDEdwards
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/12184311?u=9b29d5d1d71f5f1a7ef9e439963ad3529e3b33a4&v=4
@ -536,10 +564,18 @@ one_year_experts:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=16d6466476cf7dbc55a4cd575b6ea920ebdd81e1&v=4
url: https://github.com/isgin01
- login: christiansousadev
- login: ericgitangu
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
avatarUrl: https://avatars.githubusercontent.com/u/11472845?u=9d916cf0f5c80e63cb1d753b8b50dcb8ced3b883&v=4
url: https://github.com/ericgitangu
- login: henrymcl
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/26480299?v=4
url: https://github.com/henrymcl
- login: EmmanuelNiyonshuti
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/142030687?u=ab131d5ad4670280a978f489babe71c9bf9c1097&v=4
url: https://github.com/EmmanuelNiyonshuti
- login: dolfinus
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/4661021?u=ed5ddadcf36d9b943ebe61febe0b96ee34e5425d&v=4
@ -564,18 +600,38 @@ one_year_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/210023470?u=c25d66addf36a747bd9fab773c4a6e7b238f45d4&v=4
url: https://github.com/Jelle-tenB
- login: cookesan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6601329?u=7bfc9b017198a9fa50929ae8ae0a787632424ffd&v=4
url: https://github.com/cookesan
- login: coleifer
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/119974?u=b3a546c94ee1105e792e0acad2c4743d800e7975&v=4
url: https://github.com/coleifer
- login: Bahtya
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/34988899?u=b8e3c0cf26f4bd1faea265d2f5f66f564af63463&v=4
url: https://github.com/Bahtya
- login: saitarrun
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/116748905?u=3433afbaf06676a482ebf4ba33b08ddb3fc5c5bf&v=4
url: https://github.com/saitarrun
- login: cepedus
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/26345924?u=38495abbdbb8695dd76478cae5963bf994c498bc&v=4
url: https://github.com/cepedus
- login: christiansousadev
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/103544118?u=690f3f76d1dc4d0929de5020679d5604f860acbc&v=4
url: https://github.com/christiansousadev
- login: gaardhus
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/46934916?u=18d7aacc6ce59f054749209645d11cfe77b52f90&v=4
url: https://github.com/gaardhus
- login: y2kbugger
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6101677?u=1d50077e29582dc01fcbdff846f04fe7ec73fe2e&v=4
url: https://github.com/y2kbugger
- login: Vision-Executive
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/259394686?u=dd28bbc246e4e2cd2adb1d497e7b7585b5d24585&v=4
url: https://github.com/Vision-Executive
- login: Garrett-R
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6614695?u=c128fd775002882f6e391bda5a89d1bdc5bdf45f&v=4
@ -584,10 +640,6 @@ one_year_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/17792131?u=372b27056ec82f1ae03d8b3f37ef55b04a7cfdd1&v=4
url: https://github.com/TaigoFr
- login: EmmanuelNiyonshuti
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/142030687?u=ab131d5ad4670280a978f489babe71c9bf9c1097&v=4
url: https://github.com/EmmanuelNiyonshuti
- login: stan-dot
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/56644812?u=a7dd773084f1c17c5f05019cc25a984e24873691&v=4
@ -612,10 +664,6 @@ one_year_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1070878?u=68f78a891c9751dd87571ac712a6309090c4bc01&v=4
url: https://github.com/kiranzo
- login: sinisaos
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
url: https://github.com/sinisaos
- login: dotmitsu
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/42657211?u=3bccc9a2f386a3f24230ec393080f8904fe2a5b2&v=4
@ -636,10 +684,6 @@ one_year_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/532192?v=4
url: https://github.com/skion
- login: Danstiv
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/50794055?v=4
url: https://github.com/Danstiv
- login: florentx
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/142113?u=bf10f10080026346b092633c380977b61cee0d9c&v=4
@ -658,12 +702,8 @@ one_year_experts:
url: https://github.com/purepani
- login: asmaier
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/3169297?v=4
avatarUrl: https://avatars.githubusercontent.com/u/3169297?u=84c83cbdb64104331febe16ae232ecf30952d01d&v=4
url: https://github.com/asmaier
- login: henrymcl
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/26480299?v=4
url: https://github.com/henrymcl
- login: davidhuser
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/4357648?u=6ed702f8f6d49a8b2a0ed33cbd8ab59c2d7db7f7&v=4
@ -680,11 +720,3 @@ one_year_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
url: https://github.com/pythonweb2
- login: PidgeyBE
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/19860056?u=47b584eb1c1ab45e31c1b474109a962d7e82be49&v=4
url: https://github.com/PidgeyBE
- login: KianAnbarestani
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/145364424?u=dcc3d8fb4ca07d36fb52a17f38b6650565de40be&v=4
url: https://github.com/KianAnbarestani

9
docs/en/data/sponsors.yml

@ -12,9 +12,6 @@ gold:
- url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge
title: Auth, user management and more for your B2B product
img: https://fastapi.tiangolo.com/img/sponsors/propelauth.png
- url: https://zuplo.link/fastapi-gh
title: 'Zuplo: Deploy, Secure, Document, and Monetize your FastAPI'
img: https://fastapi.tiangolo.com/img/sponsors/zuplo.png
- url: https://liblab.com?utm_source=fastapi
title: liblab - Generate SDKs from FastAPI
img: https://fastapi.tiangolo.com/img/sponsors/liblab.png
@ -40,9 +37,6 @@ silver:
- url: https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display
title: Pay as you go for market data
img: https://fastapi.tiangolo.com/img/sponsors/databento.svg
- url: https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship
title: SDKs for your API | Speakeasy
img: https://fastapi.tiangolo.com/img/sponsors/speakeasy.png
- url: https://www.svix.com/
title: Svix - Webhooks as a service
img: https://fastapi.tiangolo.com/img/sponsors/svix.svg
@ -58,6 +52,9 @@ silver:
- url: https://dribia.com/en/
title: Dribia - Data Science within your reach
img: https://fastapi.tiangolo.com/img/sponsors/dribia.png
- url: https://talordata.com/?campaignid=oh5dVZ3Zc3YGiAI2&utm_source=fastapi&utm_term=fastapi
title: TalorData SERP API - Multi-Engine Search Results Data
img: https://fastapi.tiangolo.com/img/sponsors/talordata.png
bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy.

1
docs/en/data/sponsors_badge.yml

@ -48,3 +48,4 @@ logins:
- subtotal
- requestly
- greptileai
- talorelowen

404
docs/en/data/topic_repos.yml

@ -1,495 +1,495 @@
- name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 42397
stars: 42944
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python
stars: 34997
stars: 35430
owner_login: mouredev
owner_html_url: https://github.com/mouredev
- name: serve
html_url: https://github.com/jina-ai/serve
stars: 21857
stars: 21876
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: HivisionIDPhotos
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
stars: 20868
stars: 21054
owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin
- name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel
stars: 17770
stars: 17886
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: fastapi-best-practices
html_url: https://github.com/zhanymkanov/fastapi-best-practices
stars: 16897
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: Douyin_TikTok_Download_API
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
stars: 16878
stars: 17546
owner_login: Evil0ctal
owner_html_url: https://github.com/Evil0ctal
- name: fastapi-best-practices
html_url: https://github.com/zhanymkanov/fastapi-best-practices
stars: 17138
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 13614
stars: 14045
owner_login: MODSetter
owner_html_url: https://github.com/MODSetter
- name: machine-learning-zoomcamp
html_url: https://github.com/DataTalksClub/machine-learning-zoomcamp
stars: 12780
stars: 13015
owner_login: DataTalksClub
owner_html_url: https://github.com/DataTalksClub
- name: fastapi_mcp
html_url: https://github.com/tadata-org/fastapi_mcp
stars: 11752
stars: 11837
owner_login: tadata-org
owner_html_url: https://github.com/tadata-org
- name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi
stars: 11203
stars: 11315
owner_login: mjhea0
owner_html_url: https://github.com/mjhea0
- name: XHS-Downloader
html_url: https://github.com/JoeanAmier/XHS-Downloader
stars: 10612
stars: 11013
owner_login: JoeanAmier
owner_html_url: https://github.com/JoeanAmier
- name: polar
html_url: https://github.com/polarsource/polar
stars: 9626
stars: 9775
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: pycaret
html_url: https://github.com/pycaret/pycaret
stars: 9753
owner_login: pycaret
owner_html_url: https://github.com/pycaret
- name: FastUI
html_url: https://github.com/pydantic/FastUI
stars: 8958
stars: 8961
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox
stars: 8191
stars: 8241
owner_login: vastsa
owner_html_url: https://github.com/vastsa
- name: nonebot2
html_url: https://github.com/nonebot/nonebot2
stars: 7456
stars: 7488
owner_login: nonebot
owner_html_url: https://github.com/nonebot
- name: hatchet
html_url: https://github.com/hatchet-dev/hatchet
stars: 6784
stars: 7044
owner_login: hatchet-dev
owner_html_url: https://github.com/hatchet-dev
- name: fastapi-users
html_url: https://github.com/fastapi-users/fastapi-users
stars: 6064
stars: 6107
owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users
- name: serge
html_url: https://github.com/serge-chat/serge
stars: 5738
stars: 5731
owner_login: serge-chat
owner_html_url: https://github.com/serge-chat
- name: Yuxi
html_url: https://github.com/xerrors/Yuxi
stars: 4761
stars: 5063
owner_login: xerrors
owner_html_url: https://github.com/xerrors
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 4649
stars: 4785
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry
stars: 4636
stars: 4649
owner_login: strawberry-graphql
owner_html_url: https://github.com/strawberry-graphql
- name: devpush
html_url: https://github.com/hunvreus/devpush
stars: 4589
stars: 4641
owner_login: hunvreus
owner_html_url: https://github.com/hunvreus
- name: poem
html_url: https://github.com/poem-web/poem
stars: 4375
stars: 4387
owner_login: poem-web
owner_html_url: https://github.com/poem-web
- name: dynaconf
html_url: https://github.com/dynaconf/dynaconf
stars: 4276
stars: 4291
owner_login: dynaconf
owner_html_url: https://github.com/dynaconf
- name: chatgpt-web-share
html_url: https://github.com/chatpire/chatgpt-web-share
stars: 4272
stars: 4269
owner_login: chatpire
owner_html_url: https://github.com/chatpire
- name: logfire
html_url: https://github.com/pydantic/logfire
stars: 4145
stars: 4206
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: atrilabs-engine
html_url: https://github.com/Atri-Labs/atrilabs-engine
stars: 4086
stars: 4080
owner_login: Atri-Labs
owner_html_url: https://github.com/Atri-Labs
- name: huma
html_url: https://github.com/danielgtaylor/huma
stars: 3933
stars: 4043
owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor
- name: LitServe
html_url: https://github.com/Lightning-AI/LitServe
stars: 3851
owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI
- name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 3839
stars: 3882
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: LitServe
html_url: https://github.com/Lightning-AI/LitServe
stars: 3879
owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI
- name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3745
stars: 3759
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: mcp-context-forge
html_url: https://github.com/IBM/mcp-context-forge
stars: 3644
owner_login: IBM
owner_html_url: https://github.com/IBM
- name: tracecat
html_url: https://github.com/TracecatHQ/tracecat
stars: 3542
stars: 3564
owner_login: TracecatHQ
owner_html_url: https://github.com/TracecatHQ
- name: farfalle
html_url: https://github.com/rashadphz/farfalle
stars: 3521
stars: 3530
owner_login: rashadphz
owner_html_url: https://github.com/rashadphz
- name: mcp-context-forge
html_url: https://github.com/IBM/mcp-context-forge
stars: 3501
owner_login: IBM
owner_html_url: https://github.com/IBM
- name: opyrator
html_url: https://github.com/ml-tooling/opyrator
stars: 3137
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: honcho
html_url: https://github.com/plastic-labs/honcho
stars: 3135
owner_login: plastic-labs
owner_html_url: https://github.com/plastic-labs
- name: docarray
html_url: https://github.com/docarray/docarray
stars: 3120
stars: 3118
owner_login: docarray
owner_html_url: https://github.com/docarray
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 3092
stars: 3111
owner_login: nsidnev
owner_html_url: https://github.com/nsidnev
- name: uvicorn-gunicorn-fastapi-docker
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
stars: 2913
stars: 2912
owner_login: tiangolo
owner_html_url: https://github.com/tiangolo
- name: FastAPI-template
html_url: https://github.com/s3rius/FastAPI-template
stars: 2768
stars: 2780
owner_login: s3rius
owner_html_url: https://github.com/s3rius
- name: best-of-web-python
html_url: https://github.com/ml-tooling/best-of-web-python
stars: 2703
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: sqladmin
html_url: https://github.com/smithyhq/sqladmin
stars: 2696
stars: 2716
owner_login: smithyhq
owner_html_url: https://github.com/smithyhq
- name: best-of-web-python
html_url: https://github.com/ml-tooling/best-of-web-python
stars: 2711
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: YC-Killer
html_url: https://github.com/sahibzada-allahyar/YC-Killer
stars: 2675
stars: 2626
owner_login: sahibzada-allahyar
owner_html_url: https://github.com/sahibzada-allahyar
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2579
stars: 2581
owner_login: Buuntu
owner_html_url: https://github.com/Buuntu
- name: supabase-py
html_url: https://github.com/supabase/supabase-py
stars: 2486
stars: 2499
owner_login: supabase
owner_html_url: https://github.com/supabase
- name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT
stars: 2462
stars: 2466
owner_login: paulpierre
owner_html_url: https://github.com/paulpierre
- name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2450
owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs
- name: NoteDiscovery
html_url: https://github.com/gamosoft/NoteDiscovery
stars: 2400
stars: 2465
owner_login: gamosoft
owner_html_url: https://github.com/gamosoft
- name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2459
owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs
- name: AIstudioProxyAPI
html_url: https://github.com/CJackHwang/AIstudioProxyAPI
stars: 2346
owner_login: CJackHwang
owner_html_url: https://github.com/CJackHwang
- name: nextpy
html_url: https://github.com/dot-agent/nextpy
stars: 2339
stars: 2336
owner_login: dot-agent
owner_html_url: https://github.com/dot-agent
- name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2308
owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils
- name: langserve
html_url: https://github.com/langchain-ai/langserve
stars: 2300
stars: 2319
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: solara
html_url: https://github.com/widgetti/solara
stars: 2156
owner_login: widgetti
owner_html_url: https://github.com/widgetti
- name: fastapi-best-architecture
html_url: https://github.com/fastapi-practices/fastapi-best-architecture
stars: 2148
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2306
owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils
- name: fastapi-langgraph-agent-production-ready-template
html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template
stars: 2103
stars: 2218
owner_login: wassim249
owner_html_url: https://github.com/wassim249
- name: mangum
html_url: https://github.com/Kludex/mangum
stars: 2100
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: fastapi-best-architecture
html_url: https://github.com/fastapi-practices/fastapi-best-architecture
stars: 2206
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: solara
html_url: https://github.com/widgetti/solara
stars: 2160
owner_login: widgetti
owner_html_url: https://github.com/widgetti
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 2059
stars: 2108
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: agentkit
html_url: https://github.com/BCG-X-Official/agentkit
stars: 1947
owner_login: BCG-X-Official
owner_html_url: https://github.com/BCG-X-Official
- name: mangum
html_url: https://github.com/Kludex/mangum
stars: 2106
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1946
stars: 1960
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client
stars: 1930
owner_login: openapi-generators
owner_html_url: https://github.com/openapi-generators
- name: xhs_ai_publisher
html_url: https://github.com/BetaStreetOmnis/xhs_ai_publisher
stars: 1904
stars: 1948
owner_login: BetaStreetOmnis
owner_html_url: https://github.com/BetaStreetOmnis
- name: agentkit
html_url: https://github.com/BCG-X-Official/agentkit
stars: 1944
owner_login: BCG-X-Official
owner_html_url: https://github.com/BCG-X-Official
- name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client
stars: 1941
owner_login: openapi-generators
owner_html_url: https://github.com/openapi-generators
- name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi
stars: 1898
stars: 1901
owner_login: ycd
owner_html_url: https://github.com/ycd
- name: piccolo
html_url: https://github.com/piccolo-orm/piccolo
stars: 1876
stars: 1896
owner_login: piccolo-orm
owner_html_url: https://github.com/piccolo-orm
- name: FastAPI-boilerplate
html_url: https://github.com/benavlabs/FastAPI-boilerplate
stars: 1859
stars: 1892
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache
stars: 1853
stars: 1859
owner_login: long2ice
owner_html_url: https://github.com/long2ice
- name: any-auto-register
html_url: https://github.com/lxf746/any-auto-register
stars: 1857
owner_login: lxf746
owner_html_url: https://github.com/lxf746
- name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022
stars: 1809
stars: 1810
owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno
- name: ormar
html_url: https://github.com/ormar-orm/ormar
stars: 1808
stars: 1806
owner_login: ormar-orm
owner_html_url: https://github.com/ormar-orm
- name: termpair
html_url: https://github.com/cs01/termpair
stars: 1730
stars: 1731
owner_login: cs01
owner_html_url: https://github.com/cs01
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1683
stars: 1687
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: fastapi-pagination
html_url: https://github.com/uriyyo/fastapi-pagination
stars: 1638
owner_login: uriyyo
owner_html_url: https://github.com/uriyyo
- name: bracket
html_url: https://github.com/evroon/bracket
stars: 1638
stars: 1653
owner_login: evroon
owner_html_url: https://github.com/evroon
- name: WebRPA
html_url: https://github.com/pmh1314520/WebRPA
stars: 1653
owner_login: pmh1314520
owner_html_url: https://github.com/pmh1314520
- name: fastapi-pagination
html_url: https://github.com/uriyyo/fastapi-pagination
stars: 1646
owner_login: uriyyo
owner_html_url: https://github.com/uriyyo
- name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve
stars: 1634
stars: 1640
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: headroom
html_url: https://github.com/chopratejas/headroom
stars: 1624
owner_login: chopratejas
owner_html_url: https://github.com/chopratejas
- name: awesome-fastapi-projects
html_url: https://github.com/Kludex/awesome-fastapi-projects
stars: 1597
stars: 1599
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1568
stars: 1567
owner_login: ExpDev07
owner_html_url: https://github.com/ExpDev07
- name: WebRPA
html_url: https://github.com/pmh1314520/WebRPA
stars: 1532
owner_login: pmh1314520
owner_html_url: https://github.com/pmh1314520
- name: fastapi-amis-admin
html_url: https://github.com/amisadmin/fastapi-amis-admin
stars: 1527
stars: 1541
owner_login: amisadmin
owner_html_url: https://github.com/amisadmin
- name: fastcrud
html_url: https://github.com/benavlabs/fastcrud
stars: 1506
stars: 1512
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: open-wearables
html_url: https://github.com/the-momentum/open-wearables
stars: 1496
owner_login: the-momentum
owner_html_url: https://github.com/the-momentum
- name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1482
stars: 1486
owner_login: teamhide
owner_html_url: https://github.com/teamhide
- name: awesome-python-resources
html_url: https://github.com/DjangoEx/awesome-python-resources
stars: 1444
owner_login: DjangoEx
owner_html_url: https://github.com/DjangoEx
- name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1438
owner_login: trallnag
owner_html_url: https://github.com/trallnag
- name: honcho
html_url: https://github.com/plastic-labs/honcho
stars: 1419
owner_login: plastic-labs
owner_html_url: https://github.com/plastic-labs
- name: tavily-key-generator
html_url: https://github.com/skernelx/tavily-key-generator
stars: 1416
stars: 1478
owner_login: skernelx
owner_html_url: https://github.com/skernelx
- name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1451
owner_login: trallnag
owner_html_url: https://github.com/trallnag
- name: awesome-python-resources
html_url: https://github.com/DjangoEx/awesome-python-resources
stars: 1449
owner_login: DjangoEx
owner_html_url: https://github.com/DjangoEx
- name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1384
stars: 1399
owner_login: liaogx
owner_html_url: https://github.com/liaogx
- name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1384
stars: 1383
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: budgetml
html_url: https://github.com/ebhy/budgetml
stars: 1346
stars: 1345
owner_login: ebhy
owner_html_url: https://github.com/ebhy
- name: bolt-python
html_url: https://github.com/slackapi/bolt-python
stars: 1286
owner_login: slackapi
owner_html_url: https://github.com/slackapi
- name: aktools
html_url: https://github.com/akfamily/aktools
stars: 1283
stars: 1334
owner_login: akfamily
owner_html_url: https://github.com/akfamily
- name: RuoYi-Vue3-FastAPI
html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI
stars: 1302
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: bolt-python
html_url: https://github.com/slackapi/bolt-python
stars: 1296
owner_login: slackapi
owner_html_url: https://github.com/slackapi
- name: bedrock-chat
html_url: https://github.com/aws-samples/bedrock-chat
stars: 1282
stars: 1288
owner_login: aws-samples
owner_html_url: https://github.com/aws-samples
- name: fastapi-scaff
html_url: https://github.com/atpuxiner/fastapi-scaff
stars: 1275
owner_login: atpuxiner
owner_html_url: https://github.com/atpuxiner
- name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/vargasjona/fastapi-alembic-sqlmodel-async
stars: 1267
owner_login: vargasjona
owner_html_url: https://github.com/vargasjona
- name: restish
html_url: https://github.com/rest-sh/restish
stars: 1258
stars: 1279
owner_login: rest-sh
owner_html_url: https://github.com/rest-sh
- name: RuoYi-Vue3-FastAPI
html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI
stars: 1248
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/vargasjona/fastapi-alembic-sqlmodel-async
stars: 1270
owner_login: vargasjona
owner_html_url: https://github.com/vargasjona
- name: fastapi_production_template
html_url: https://github.com/zhanymkanov/fastapi_production_template
stars: 1240
stars: 1243
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: langchain-extract
html_url: https://github.com/langchain-ai/langchain-extract
stars: 1193
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: open-wearables
html_url: https://github.com/the-momentum/open-wearables
stars: 1170
owner_login: the-momentum
owner_html_url: https://github.com/the-momentum
- name: odmantic
html_url: https://github.com/art049/odmantic
stars: 1168
owner_login: art049
owner_html_url: https://github.com/art049
- name: authx
html_url: https://github.com/yezz123/authx
stars: 1160
owner_login: yezz123
owner_html_url: https://github.com/yezz123
- name: FileSync
html_url: https://github.com/polius/FileSync
stars: 1153
owner_login: polius
owner_html_url: https://github.com/polius
- name: enterprise-deep-research
html_url: https://github.com/SalesforceAIResearch/enterprise-deep-research
stars: 1150
owner_login: SalesforceAIResearch
owner_html_url: https://github.com/SalesforceAIResearch
- name: yubal
html_url: https://github.com/guillevc/yubal
stars: 1135
stars: 1203
owner_login: guillevc
owner_html_url: https://github.com/guillevc
- name: langchain-extract
html_url: https://github.com/langchain-ai/langchain-extract
stars: 1196
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: Chatterbox-TTS-Server
html_url: https://github.com/devnen/Chatterbox-TTS-Server
stars: 1194
owner_login: devnen
owner_html_url: https://github.com/devnen

12
docs/en/data/translation_reviewers.yml

@ -65,7 +65,7 @@ nilslindemann:
url: https://github.com/nilslindemann
YuriiMotov:
login: YuriiMotov
count: 66
count: 67
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
cassiobotaro:
@ -301,7 +301,7 @@ delhi09:
rogerbrinkmann:
login: rogerbrinkmann
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
avatarUrl: https://avatars.githubusercontent.com/u/5690226?u=a1fe0aee927d33ce9db8c455eabc40c1cdf2bb65&v=4
url: https://github.com/rogerbrinkmann
DevDae:
login: DevDae
@ -471,7 +471,7 @@ NastasiaSaby:
oandersonmagalhaes:
login: oandersonmagalhaes
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
avatarUrl: https://avatars.githubusercontent.com/u/83456692?u=daf5f302a59b950efc6d21129314af207e35441f&v=4
url: https://github.com/oandersonmagalhaes
mkdir700:
login: mkdir700
@ -906,7 +906,7 @@ bankofsardine:
Rekl0w:
login: Rekl0w
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/91488737?u=3b62b04a3e6699eab9b1eea4e88c09a39b753a17&v=4
avatarUrl: https://avatars.githubusercontent.com/u/91488737?u=7d2b7791665e04a12695150776a1d516a6ea7d21&v=4
url: https://github.com/Rekl0w
rsip22:
login: rsip22
@ -1276,7 +1276,7 @@ rafsaf:
frnsimoes:
login: frnsimoes
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=98fb2a38bcac765ea9651af8a0ab8f37df86570d&v=4
avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=bd788dabd4d9321455db8b8751c1a2676783f50f&v=4
url: https://github.com/frnsimoes
lieryan:
login: lieryan
@ -1606,7 +1606,7 @@ ayr-ton:
Kadermiyanyedi:
login: Kadermiyanyedi
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/48386782?u=e34f31bf50a8ed8d37fbfa4f301b0c190b1b4b86&v=4
avatarUrl: https://avatars.githubusercontent.com/u/48386782?u=08c0f1594c5baf28b6fab7520a848cb9c3806c8e&v=4
url: https://github.com/Kadermiyanyedi
raphaelauv:
login: raphaelauv

4
docs/en/data/translators.yml

@ -386,7 +386,7 @@ dukkee:
oandersonmagalhaes:
login: oandersonmagalhaes
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
avatarUrl: https://avatars.githubusercontent.com/u/83456692?u=daf5f302a59b950efc6d21129314af207e35441f&v=4
url: https://github.com/oandersonmagalhaes
leandrodesouzadev:
login: leandrodesouzadev
@ -416,7 +416,7 @@ ayr-ton:
Kadermiyanyedi:
login: Kadermiyanyedi
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/48386782?u=e34f31bf50a8ed8d37fbfa4f301b0c190b1b4b86&v=4
avatarUrl: https://avatars.githubusercontent.com/u/48386782?u=08c0f1594c5baf28b6fab7520a848cb9c3806c8e&v=4
url: https://github.com/Kadermiyanyedi
KdHyeon0661:
login: KdHyeon0661

1
docs/en/docs/advanced/generate-clients.md

@ -30,7 +30,6 @@ Their sponsorship also demonstrates a strong commitment to the FastAPI **communi
For example, you might want to try:
* [Speakeasy](https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship)
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)

44
docs/en/docs/advanced/vibe.md

@ -1,44 +0,0 @@
# Vibe Coding { #vibe-coding }
Are you tired of all that **data validation**, **documentation**, **serialization**, and all that **boring** stuff?
Do you just want to **vibe**? 🎶
**FastAPI** now supports a new `@app.vibe()` decorator that embraces **modern AI coding best practices**. 🤖
## How It Works { #how-it-works }
The `@app.vibe()` decorator is intended to receive **any HTTP method** (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, etc.) and **any payload**.
The body should be annotated with `Any`, because the request and the response would be... well... **anything**. 🤷
The idea is that you would receive the payload and send it **directly** to an LLM provider, using a `prompt` to tell the LLM what to do, and return the response **as is**. No questions asked.
You don't even need to write the body of the function. The `@app.vibe()` decorator does everything for you based on AI vibes:
{* ../../docs_src/vibe/tutorial001_py310.py hl[8:12] *}
## Benefits { #benefits }
By using `@app.vibe()`, you get to enjoy:
* **Freedom**: No data validation. No schemas. No constraints. Just vibes. ✨
* **Flexibility**: The request can be anything. The response can be anything. Who needs types anyway?
* **No documentation**: Why document your API when an LLM can figure it out? Auto-generated OpenAPI docs are *so* 2020.
* **No serialization**: Just pass the raw, unstructured data around. Serialization is for people who don't trust their LLMs.
* **Embrace modern AI coding practices**: Leave everything up to an LLM to decide. The model knows best. Always.
* **No code reviews**: There's no code to review. No PRs to approve. No comments to address. Embrace vibe coding fully, replace the theater of approving and merging vibe coded PRs that no one looks at with full proper vibes only.
/// tip
This is the ultimate **vibe-driven development** experience. You don't need to think about what your API does, just let the LLM handle it. 🧘
///
## Try It { #try-it }
Go ahead, try it:
{* ../../docs_src/vibe/tutorial001_py310.py *}
...and see what happens. 😎

186
docs/en/docs/css/custom.css

@ -264,3 +264,189 @@ Inspired by Termynal's CSS tricks with modifications
border-bottom: .05rem dotted var(--md-default-fg-color--light);
cursor: help;
}
/* Opinions: interactive logo tabs */
.fastapi-opinions {
margin: 1.5rem 0 2rem;
}
.fastapi-opinions__tabs {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0.25rem;
margin-bottom: 1.5rem;
border-bottom: 1px solid var(--md-default-fg-color--lightest);
}
.fastapi-opinions__tab {
position: relative;
appearance: none;
background: none;
border: 0;
padding: 0.625rem 0.5rem;
margin: 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: inherit;
font: inherit;
min-height: 40px;
min-width: 0;
}
.fastapi-opinions__tab::after {
content: "";
position: absolute;
left: 50%;
right: 50%;
bottom: -1px;
height: 2px;
background-color: var(--md-primary-fg-color);
opacity: 0;
transition: left 0.2s ease, right 0.2s ease, opacity 0.2s ease;
}
.fastapi-opinions__tab[aria-selected="true"]::after {
left: 12%;
right: 12%;
opacity: 1;
}
.fastapi-opinions__tab:focus-visible {
outline: 2px solid var(--md-primary-fg-color);
outline-offset: 2px;
border-radius: 4px;
}
.fastapi-opinions__mark {
display: flex;
align-items: center;
justify-content: center;
height: 22px;
max-width: 100%;
filter: grayscale(1);
opacity: 0.5;
transition: filter 0.2s, opacity 0.2s;
}
.fastapi-opinions__mark img {
height: 100%;
width: auto;
max-width: 100%;
object-fit: contain;
display: block;
}
.fastapi-opinions__tab:hover .fastapi-opinions__mark {
filter: grayscale(0.3);
opacity: 0.85;
}
.fastapi-opinions__tab[aria-selected="true"] .fastapi-opinions__mark {
filter: grayscale(0);
opacity: 1;
}
/* Dark mode: brighten dark wordmarks so they read on slate */
[data-md-color-scheme="slate"] .fastapi-opinions__mark {
filter: grayscale(1) invert(0.85);
}
[data-md-color-scheme="slate"] .fastapi-opinions__tab:hover .fastapi-opinions__mark {
filter: grayscale(0.3) invert(0.4);
}
[data-md-color-scheme="slate"] .fastapi-opinions__tab[aria-selected="true"] .fastapi-opinions__mark {
filter: none;
}
.fastapi-opinions__panel {
position: relative;
padding: 0.5rem 1rem 0.5rem 3rem;
}
.fastapi-opinions__panel::before {
content: "\201C";
position: absolute;
top: -0.75rem;
left: 0.25rem;
font-family: Georgia, "Times New Roman", serif;
font-size: 4rem;
line-height: 1;
color: var(--md-primary-fg-color);
opacity: 0.18;
pointer-events: none;
}
.md-typeset blockquote.fastapi-opinions__quote {
margin: 0;
font-size: 1rem;
font-style: italic;
line-height: 1.65;
color: var(--md-default-fg-color);
border-left: 0;
padding-left: 0;
}
.fastapi-opinions__quote strong { font-style: normal; }
.fastapi-opinions__attr {
margin-top: 0.875rem;
font-size: 0.8rem;
color: var(--md-default-fg-color--light);
}
.fastapi-opinions__attr strong { color: var(--md-default-fg-color); }
.fastapi-opinions__attr a {
color: var(--md-primary-fg-color);
text-decoration: none;
font-size: 0.75rem;
margin-left: 0.25rem;
}
.fastapi-opinions__attr a:hover { text-decoration: underline; }
@media (prefers-reduced-motion: reduce) {
.fastapi-opinions__tab::after { transition: none; }
}
@media (max-width: 600px) {
.fastapi-opinions__tabs { gap: 0.125rem; }
.fastapi-opinions__mark { height: 18px; }
.fastapi-opinions__panel { padding-left: 2.25rem; }
.fastapi-opinions__panel::before { font-size: 3rem; }
}
.fastapi-sponsors {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 1rem 1.25rem;
margin: 1rem 0 2rem;
}
.fastapi-sponsors__card {
transition: transform 0.15s ease;
}
.fastapi-sponsors__card:hover {
transform: translateY(-1px);
}
.fastapi-sponsors__card--keystone {
width: 100%;
max-width: 560px;
}
.fastapi-sponsors__banner {
display: block;
border-radius: 12px;
}
.fastapi-sponsors__card--keystone .fastapi-sponsors__banner { width: 100%; }
.fastapi-sponsors__card--gold .fastapi-sponsors__banner { height: 80px; }
.fastapi-sponsors__card--silver .fastapi-sponsors__banner { height: 60px; }
@media (max-width: 600px) {
.fastapi-sponsors__card--gold .fastapi-sponsors__banner { height: 64px; }
.fastapi-sponsors__card--silver .fastapi-sponsors__banner { height: 50px; }
}
.fastapi-feature-banner {
display: block;
max-width: 680px;
margin: 1rem auto 1.5rem;
}
.fastapi-feature-banner img {
display: block;
width: 100%;
border-radius: 12px;
}
/* Hidden in MkDocs; rendered on GitHub (which doesn't load this stylesheet) */
.only-github { display: none; }

BIN
docs/en/docs/img/fastapi-conf.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

35
docs/en/docs/img/logos/cisco.svg

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="216"
height="114"
fill="#049fd9"
id="svg24">
<path
d="m 106.48,76.238 c -0.282,-0.077 -4.621,-1.196 -9.232,-1.196 -8.73,0 -13.986,4.714 -13.986,11.734 0,6.214 4.397,9.313 9.674,10.98 0.585,0.193 1.447,0.463 2.021,0.653 2.349,0.739 4.224,1.837 4.224,3.739 0,2.127 -2.167,3.504 -6.878,3.504 -4.14,0 -8.109,-1.184 -8.945,-1.395 v 8.637 c 0.466,0.099 5.183,1.025 10.222,1.025 7.248,0 15.539,-3.167 15.539,-12.595 0,-4.573 -2.8,-8.783 -8.947,-10.737 L 97.559,89.755 C 96,89.263 93.217,88.466 93.217,86.181 c 0,-1.805 2.062,-3.076 5.859,-3.076 3.276,0 7.263,1.101 7.404,1.145 z m 80.041,18.243 c 0,5.461 -4.183,9.879 -9.796,9.879 -5.619,0 -9.791,-4.418 -9.791,-9.879 0,-5.45 4.172,-9.87 9.791,-9.87 5.613,0 9.796,4.42 9.796,9.87 m -9.796,-19.427 c -11.544,0 -19.823,8.707 -19.823,19.427 0,10.737 8.279,19.438 19.823,19.438 11.543,0 19.834,-8.701 19.834,-19.438 0,-10.72 -8.291,-19.427 -19.834,-19.427 M 70.561,113.251 H 61.089 V 75.719 h 9.472"
id="path10" />
<path
d="m 48.07,76.399 c -0.89,-0.264 -4.18,-1.345 -8.636,-1.345 -11.526,0 -19.987,8.218 -19.987,19.427 0,12.093 9.34,19.438 19.987,19.438 4.23,0 7.459,-1.002 8.636,-1.336 v -10.075 c -0.407,0.226 -3.503,1.992 -7.957,1.992 -6.31,0 -10.38,-4.441 -10.38,-10.019 0,-5.748 4.246,-10.011 10.38,-10.011 4.53,0 7.576,1.805 7.957,2.004"
id="path12" />
<use
xlink:href="#path12"
transform="translate(98.86)"
id="use14" />
<g
id="g22">
<path
d="m 61.061,4.759 c 0,-2.587 -2.113,-4.685 -4.703,-4.685 -2.589,0 -4.702,2.098 -4.702,4.685 v 49.84 c 0,2.602 2.113,4.699 4.702,4.699 2.59,0 4.703,-2.097 4.703,-4.699 z M 35.232,22.451 c 0,-2.586 -2.112,-4.687 -4.702,-4.687 -2.59,0 -4.702,2.101 -4.702,4.687 v 22.785 c 0,2.601 2.112,4.699 4.702,4.699 2.59,0 4.702,-2.098 4.702,-4.699 z M 9.404,35.383 C 9.404,32.796 7.292,30.699 4.702,30.699 2.115,30.699 0,32.796 0,35.383 v 9.853 c 0,2.601 2.115,4.699 4.702,4.699 2.59,0 4.702,-2.098 4.702,-4.699"
id="path16" />
<use
xlink:href="#path16"
transform="matrix(-1,0,0,1,112.717,0)"
id="use18" />
</g>
<use
xlink:href="#g22"
transform="matrix(-1,0,0,1,216,0)"
id="use20" />
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

8
docs/en/docs/img/logos/microsoft.svg

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 337.6 72">
<path fill="#737373" d="M140.4,14.4v43.2h-7.5V23.7h-0.1l-13.4,33.9h-5l-13.7-33.9h-0.1v33.9h-6.9V14.4h10.8l12.4,32h0.2l13.1-32H140.4 z M146.6,17.7c0-1.2,0.4-2.2,1.3-3c0.9-0.8,1.9-1.2,3.1-1.2c1.3,0,2.4,0.4,3.2,1.2s1.3,1.8,1.3,3c0,1.2-0.4,2.2-1.3,3 c-0.9,0.8-1.9,1.2-3.2,1.2s-2.3-0.4-3.1-1.2C147.1,19.8,146.6,18.8,146.6,17.7z M154.7,26.6v31h-7.3v-31H154.7z M176.8,52.3 c1.1,0,2.3-0.2,3.6-0.8c1.3-0.5,2.5-1.2,3.6-2v6.8c-1.2,0.7-2.5,1.2-4,1.5c-1.5,0.3-3.1,0.5-4.9,0.5c-4.6,0-8.3-1.4-11.1-4.3 c-2.9-2.9-4.3-6.6-4.3-11c0-5,1.5-9.1,4.4-12.3c2.9-3.2,7-4.8,12.4-4.8c1.4,0,2.8,0.2,4.1,0.5c1.4,0.3,2.5,0.8,3.3,1.2v7 c-1.1-0.8-2.3-1.5-3.4-1.9c-1.2-0.4-2.4-0.7-3.6-0.7c-2.9,0-5.2,0.9-7,2.8s-2.6,4.4-2.6,7.6c0,3.1,0.9,5.6,2.6,7.3 C171.6,51.4,173.9,52.3,176.8,52.3z M204.7,26.1c0.6,0,1.1,0,1.6,0.1s0.9,0.2,1.2,0.3v7.4c-0.4-0.3-0.9-0.6-1.7-0.8 s-1.6-0.4-2.7-0.4c-1.8,0-3.3,0.8-4.5,2.3s-1.9,3.8-1.9,7v15.6h-7.3v-31h7.3v4.9h0.1c0.7-1.7,1.7-3,3-4 C201.2,26.6,202.8,26.1,204.7,26.1z M207.9,42.6c0-5.1,1.5-9.2,4.3-12.2c2.9-3,6.9-4.5,12-4.5c4.8,0,8.6,1.4,11.3,4.3 s4.1,6.8,4.1,11.7c0,5-1.5,9-4.3,12c-2.9,3-6.8,4.5-11.8,4.5c-4.8,0-8.6-1.4-11.4-4.2C209.3,51.3,207.9,47.4,207.9,42.6z M215.5,42.3c0,3.2,0.7,5.7,2.2,7.4s3.6,2.6,6.3,2.6c2.6,0,4.7-0.8,6.1-2.6c1.4-1.7,2.1-4.2,2.1-7.6c0-3.3-0.7-5.8-2.1-7.6 c-1.4-1.7-3.5-2.6-6-2.6c-2.7,0-4.7,0.9-6.2,2.7C216.2,36.5,215.5,39,215.5,42.3z M250.5,34.8c0,1,0.3,1.9,1,2.5 c0.7,0.6,2.1,1.3,4.4,2.2c2.9,1.2,5,2.5,6.1,3.9c1.2,1.5,1.8,3.2,1.8,5.3c0,2.9-1.1,5.2-3.4,7c-2.2,1.8-5.3,2.6-9.1,2.6 c-1.3,0-2.7-0.2-4.3-0.5c-1.6-0.3-2.9-0.7-4-1.2v-7.2c1.3,0.9,2.8,1.7,4.3,2.2c1.5,0.5,2.9,0.8,4.2,0.8c1.6,0,2.9-0.2,3.6-0.7 c0.8-0.5,1.2-1.2,1.2-2.3c0-1-0.4-1.8-1.2-2.6c-0.8-0.7-2.4-1.5-4.6-2.4c-2.7-1.1-4.6-2.4-5.7-3.8s-1.7-3.2-1.7-5.4 c0-2.8,1.1-5.1,3.3-6.9c2.2-1.8,5.1-2.7,8.6-2.7c1.1,0,2.3,0.1,3.6,0.4s2.5,0.6,3.4,0.9V34c-1-0.6-2.1-1.2-3.4-1.7 c-1.3-0.5-2.6-0.7-3.8-0.7c-1.4,0-2.5,0.3-3.2,0.8C250.9,33.1,250.5,33.8,250.5,34.8z M266.9,42.6c0-5.1,1.5-9.2,4.3-12.2 c2.9-3,6.9-4.5,12-4.5c4.8,0,8.6,1.4,11.3,4.3s4.1,6.8,4.1,11.7c0,5-1.5,9-4.3,12c-2.9,3-6.8,4.5-11.8,4.5c-4.8,0-8.6-1.4-11.4-4.2 C268.4,51.3,266.9,47.4,266.9,42.6z M274.5,42.3c0,3.2,0.7,5.7,2.2,7.4s3.6,2.6,6.3,2.6c2.6,0,4.7-0.8,6.1-2.6 c1.4-1.7,2.1-4.2,2.1-7.6c0-3.3-0.7-5.8-2.1-7.6c-1.4-1.7-3.5-2.6-6-2.6c-2.7,0-4.7,0.9-6.2,2.7C275.3,36.5,274.5,39,274.5,42.3z M322.9,32.6h-10.9v25h-7.4v-25h-5.2v-6h5.2v-4.3c0-3.2,1.1-5.9,3.2-8s4.8-3.1,8.1-3.1c0.9,0,1.7,0.1,2.4,0.1s1.3,0.2,1.8,0.4v6.3 c-0.2-0.1-0.7-0.3-1.3-0.5c-0.6-0.2-1.3-0.3-2.1-0.3c-1.5,0-2.7,0.5-3.5,1.4c-0.8,0.9-1.2,2.4-1.2,4.2v3.7h10.9v-7l7.3-2.2v9.2h7.4 v6h-7.4v14.5c0,1.9,0.4,3.2,1,4c0.7,0.8,1.8,1.2,3.3,1.2c0.4,0,0.9-0.1,1.5-0.3c0.6-0.2,1.1-0.4,1.5-0.7v6c-0.5,0.3-1.2,0.5-2.3,0.7 c-1.1,0.2-2.1,0.3-3.2,0.3c-3.1,0-5.4-0.8-6.9-2.4c-1.5-1.6-2.3-4.1-2.3-7.4L322.9,32.6L322.9,32.6z"/>
<rect fill="#F25022" width="34.2" height="34.2"/>
<rect x="37.8" fill="#7FBA00" width="34.2" height="34.2"/>
<rect y="37.8" fill="#00A4EF" width="34.2" height="34.2"/>
<rect x="37.8" y="37.8" fill="#FFB900" width="34.2" height="34.2"/>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

1
docs/en/docs/img/logos/netflix.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="276.742" viewBox="0 0 1024 276.742"><path d="M140.803 258.904c-15.404 2.705-31.079 3.516-47.294 5.676l-49.458-144.856v151.073c-15.404 1.621-29.457 3.783-44.051 5.945v-276.742h41.08l56.212 157.021v-157.021h43.511v258.904zm85.131-157.558c16.757 0 42.431-.811 57.835-.811v43.24c-19.189 0-41.619 0-57.835.811v64.322c25.405-1.621 50.809-3.785 76.482-4.596v41.617l-119.724 9.461v-255.39h119.724v43.241h-76.482v58.105zm237.284-58.104h-44.862v198.908c-14.594 0-29.188 0-43.239.539v-199.447h-44.862v-43.242h132.965l-.002 43.242zm70.266 55.132h59.187v43.24h-59.187v98.104h-42.433v-239.718h120.808v43.241h-78.375v55.133zm148.641 103.507c24.594.539 49.456 2.434 73.51 3.783v42.701c-38.646-2.434-77.293-4.863-116.75-5.676v-242.689h43.24v201.881zm109.994 49.457c13.783.812 28.377 1.623 42.43 3.242v-254.58h-42.43v251.338zm231.881-251.338l-54.863 131.615 54.863 145.127c-16.217-2.162-32.432-5.135-48.648-7.838l-31.078-79.994-31.617 73.51c-15.678-2.705-30.812-3.516-46.484-5.678l55.672-126.75-50.269-129.992h46.482l28.377 72.699 30.27-72.699h47.295z" fill="#d81f26"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

39
docs/en/docs/img/logos/uber.svg

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="926.906px" height="321.777px" viewBox="0 0 926.906 321.777" enable-background="new 0 0 926.906 321.777"
xml:space="preserve">
<g>
<path fill="#010202" d="M53.328,229.809c3.917,10.395,9.34,19.283,16.27,26.664c6.93,7.382,15.14,13.031,24.63,16.948
c9.491,3.917,19.81,5.875,30.958,5.875c10.847,0,21.015-2.034,30.506-6.102s17.776-9.792,24.856-17.173
c7.08-7.382,12.579-16.194,16.496-26.438c3.917-10.244,5.875-21.692,5.875-34.347V0h47.453v316.354h-47.001v-29.376
c-10.545,11.147-22.974,19.734-37.285,25.761c-14.312,6.025-29.752,9.038-46.323,9.038c-16.873,0-32.615-2.938-47.228-8.813
c-14.612-5.875-27.267-14.235-37.962-25.082S15.441,264.006,9.265,248.79C3.088,233.575,0,216.628,0,197.947V0h47.453v195.236
C47.453,207.891,49.411,219.414,53.328,229.809z"/>
<path fill="#010202" d="M332.168,0v115.243c10.545-10.545,22.748-18.905,36.607-25.082s28.924-9.265,45.193-9.265
c16.873,0,32.689,3.163,47.453,9.49c14.763,6.327,27.567,14.914,38.414,25.761s19.434,23.651,25.761,38.414
c6.327,14.764,9.49,30.431,9.49,47.002c0,16.57-3.163,32.162-9.49,46.774c-6.327,14.613-14.914,27.343-25.761,38.188
c-10.847,10.847-23.651,19.434-38.414,25.761c-14.764,6.327-30.581,9.49-47.453,9.49c-16.27,0-31.409-3.088-45.419-9.265
c-14.01-6.176-26.288-14.537-36.833-25.082v28.924h-45.193V0H332.168z M337.365,232.746c4.067,9.642,9.717,18.078,16.948,25.309
c7.231,7.231,15.667,12.956,25.308,17.174c9.642,4.218,20.036,6.327,31.184,6.327c10.847,0,21.09-2.109,30.731-6.327
s18.001-9.942,25.083-17.174c7.08-7.23,12.729-15.667,16.947-25.309c4.218-9.641,6.327-20.035,6.327-31.183
c0-11.148-2.109-21.618-6.327-31.41s-9.867-18.303-16.947-25.534c-7.081-7.23-15.441-12.88-25.083-16.947
s-19.885-6.102-30.731-6.102c-10.846,0-21.09,2.034-30.731,6.102s-18.077,9.717-25.309,16.947
c-7.23,7.231-12.955,15.742-17.173,25.534c-4.218,9.792-6.327,20.262-6.327,31.41C331.264,212.711,333.298,223.105,337.365,232.746
z"/>
<path fill="#010202" d="M560.842,155.014c6.025-14.462,14.312-27.191,24.856-38.188s23.049-19.659,37.511-25.986
s30.129-9.49,47.001-9.49c16.571,0,31.937,3.013,46.098,9.038c14.16,6.026,26.362,14.387,36.606,25.083
c10.244,10.695,18.229,23.35,23.952,37.962c5.725,14.613,8.587,30.506,8.587,47.68v14.914H597.901
c1.507,9.34,4.52,18.002,9.039,25.985c4.52,7.984,10.168,14.914,16.947,20.789c6.779,5.876,14.462,10.471,23.049,13.784
c8.587,3.314,17.7,4.972,27.342,4.972c27.418,0,49.563-11.299,66.435-33.896l32.991,24.404
c-11.449,15.366-25.609,27.418-42.481,36.155c-16.873,8.737-35.854,13.106-56.944,13.106c-17.174,0-33.217-3.014-48.131-9.039
s-27.869-14.462-38.866-25.309s-19.659-23.576-25.986-38.188s-9.491-30.506-9.491-47.679
C551.803,184.842,554.817,169.476,560.842,155.014z M624.339,137.162c-12.805,10.696-21.316,24.932-25.534,42.708h140.552
c-3.917-17.776-12.278-32.012-25.083-42.708c-12.805-10.695-27.794-16.043-44.967-16.043
C652.133,121.119,637.144,126.467,624.339,137.162z"/>
<path fill="#010202" d="M870.866,142.359c-9.641,10.545-14.462,24.856-14.462,42.934v131.062h-45.646V85.868h45.193v28.472
c5.725-9.34,13.182-16.722,22.371-22.145c9.189-5.424,20.111-8.136,32.766-8.136h15.817v42.482h-18.981
C892.86,126.542,880.507,131.814,870.866,142.359z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
docs/en/docs/img/sponsors/talordata.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

83
docs/en/docs/index.md

@ -54,18 +54,27 @@ The key features are:
### Keystone Sponsor { #keystone-sponsor }
<div class="fastapi-sponsors fastapi-sponsors--keystone">
{% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
<a class="fastapi-sponsors__card fastapi-sponsors__card--keystone" href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img class="fastapi-sponsors__banner" src="{{ sponsor.img }}" alt="{{ sponsor.title }}"></a>
{% endfor -%}
</div>
### Gold and Silver Sponsors { #gold-and-silver-sponsors }
### Gold Sponsors { #gold-sponsors }
<div class="fastapi-sponsors fastapi-sponsors--gold">
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
<a class="fastapi-sponsors__card fastapi-sponsors__card--gold" href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img class="fastapi-sponsors__banner" src="{{ sponsor.img }}" alt="{{ sponsor.title }}" loading="lazy"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
</div>
### Silver Sponsors { #silver-sponsors }
<div class="fastapi-sponsors fastapi-sponsors--silver">
{% for sponsor in sponsors.silver -%}
<a class="fastapi-sponsors__card fastapi-sponsors__card--silver" href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img class="fastapi-sponsors__banner" src="{{ sponsor.img }}" alt="{{ sponsor.title }}" loading="lazy"></a>
{% endfor %}
</div>
<!-- /sponsors -->
@ -73,6 +82,44 @@ The key features are:
## Opinions { #opinions }
<!-- only-mkdocs -->
<div class="fastapi-opinions" data-fastapi-opinions>
<div class="fastapi-opinions__tabs" role="tablist" aria-label="Companies using FastAPI">
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-microsoft" aria-controls="fo-panel-microsoft" aria-selected="true" tabindex="0">
<span class="fastapi-opinions__mark"><img src="img/logos/microsoft.svg" alt="Microsoft" loading="lazy"></span>
</button>
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-uber" aria-controls="fo-panel-uber" aria-selected="false" tabindex="-1">
<span class="fastapi-opinions__mark"><img src="img/logos/uber.svg" alt="Uber" loading="lazy"></span>
</button>
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-netflix" aria-controls="fo-panel-netflix" aria-selected="false" tabindex="-1">
<span class="fastapi-opinions__mark"><img src="img/logos/netflix.svg" alt="Netflix" loading="lazy"></span>
</button>
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-cisco" aria-controls="fo-panel-cisco" aria-selected="false" tabindex="-1">
<span class="fastapi-opinions__mark"><img src="img/logos/cisco.svg" alt="Cisco" loading="lazy"></span>
</button>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-microsoft" role="tabpanel" aria-labelledby="fo-tab-microsoft" tabindex="0">
<blockquote class="fastapi-opinions__quote">"I'm using <strong>FastAPI</strong> a ton these days. I'm actually planning to use it for all of my team's <strong>ML services at Microsoft</strong>. Some of them are getting integrated into the core <strong>Windows</strong> product and some <strong>Office</strong> products."</blockquote>
<div class="fastapi-opinions__attr">— Kabir Khan, <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26">(ref)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"We adopted the <strong>FastAPI</strong> library to spawn a <strong>REST</strong> server that can be queried to obtain <strong>predictions</strong>." <em>[for Ludwig]</em></blockquote>
<div class="fastapi-opinions__attr">— Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/">(ref)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"<strong>Netflix</strong> is pleased to announce the open-source release of our <strong>crisis management</strong> orchestration framework: <strong>Dispatch</strong>!" <em>[built with FastAPI]</em></blockquote>
<div class="fastapi-opinions__attr">— Kevin Glisson, Marc Vilanova, Forest Monsen, <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072">(ref)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-cisco" role="tabpanel" aria-labelledby="fo-tab-cisco" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"If anyone is looking to build a production Python API, I would highly recommend <strong>FastAPI</strong>. It is <strong>beautifully designed</strong>, <strong>simple to use</strong> and <strong>highly scalable</strong> — it has become a <strong>key component</strong> in our API-first development strategy."</blockquote>
<div class="fastapi-opinions__attr">— Deon Pillsbury, <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/">(ref)</a></div>
</div>
</div>
<!-- /only-mkdocs -->
<div class="only-github" markdown="1">
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div>
@ -91,37 +138,25 @@ The key features are:
---
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>[Python Bytes](https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855) podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832"><small>(ref)</small></a></div>
---
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>[Hug](https://github.com/hugapi/hug) creator</strong> <a href="https://news.ycombinator.com/item?id=19455465"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
---
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>[Explosion AI](https://explosion.ai) founders - [spaCy](https://spacy.io) creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680"><small>(ref)</small></a></div>
---
</div>
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
## FastAPI Conf { #fastapi-conf }
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
[**FastAPI Conf '26**](https://fastapiconf.com) is happening on **October 28, 2026** in **Amsterdam, NL**. All about FastAPI, right from the source. 🎤
---
<a class="fastapi-feature-banner" href="https://fastapiconf.com"><img src="https://fastapi.tiangolo.com/img/fastapi-conf.jpeg" alt="FastAPI Conf '26 - October 28, 2026 - Amsterdam, NL"></a>
## FastAPI mini documentary { #fastapi-mini-documentary }
There's a [FastAPI mini documentary](https://www.youtube.com/watch?v=mpR8ngthqiE) released at the end of 2025, you can watch it online:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
<a class="fastapi-feature-banner" href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**, the FastAPI of CLIs { #typer-the-fastapi-of-clis }

38
docs/en/docs/js/custom.js

@ -201,11 +201,49 @@ function openLinksInNewTab() {
});
}
function setupOpinionsTabs() {
const root = document.querySelector('.fastapi-opinions');
if (!root) return;
const tabs = Array.from(root.querySelectorAll('[role="tab"]'));
const panels = Array.from(root.querySelectorAll('[role="tabpanel"]'));
if (!tabs.length) return;
function activate(tab, focus) {
tabs.forEach(t => {
const selected = t === tab;
t.setAttribute('aria-selected', selected ? 'true' : 'false');
t.setAttribute('tabindex', selected ? '0' : '-1');
});
const targetId = tab.getAttribute('aria-controls');
panels.forEach(p => {
if (p.id === targetId) p.removeAttribute('hidden');
else p.setAttribute('hidden', '');
});
if (focus) tab.focus();
}
tabs.forEach((tab, i) => {
tab.addEventListener('click', () => activate(tab, false));
tab.addEventListener('keydown', (e) => {
let next = null;
if (e.key === 'ArrowRight') next = tabs[(i + 1) % tabs.length];
else if (e.key === 'ArrowLeft') next = tabs[(i - 1 + tabs.length) % tabs.length];
else if (e.key === 'Home') next = tabs[0];
else if (e.key === 'End') next = tabs[tabs.length - 1];
if (next) {
e.preventDefault();
activate(next, true);
}
});
});
}
async function main() {
setupTermynal();
showRandomAnnouncement('announce-left', 5000)
handleSponsorImages();
openLinksInNewTab();
setupOpinionsTabs();
}
document$.subscribe(() => {
main()

81
docs/en/docs/release-notes.md

@ -7,8 +7,89 @@ hide:
## Latest Changes
### Docs
* ✏️ Fix Azkaban spelling typo in `virtual-environments.md‎`. PR [#15463](https://github.com/fastapi/fastapi/pull/15463) by [@isaacbernat](https://github.com/isaacbernat).
* 💄 Improve layout and styling. PR [#15462](https://github.com/fastapi/fastapi/pull/15462) by [@alejsdev](https://github.com/alejsdev).
* 💄 Refactor opinions section with interactive tabs and new logos. PR [#15458](https://github.com/fastapi/fastapi/pull/15458) by [@alejsdev](https://github.com/alejsdev).
* 📝 Add FastAPI Conf '26 announcement to docs. PR [#15457](https://github.com/fastapi/fastapi/pull/15457) by [@alejsdev](https://github.com/alejsdev).
### Translations
* 🌐 Fix typos in Spanish LLM-prompt. PR [#15472](https://github.com/fastapi/fastapi/pull/15472) by [@crr004](https://github.com/crr004).
### Internal
* ⬆ Bump actions/add-to-project from 1.0.2 to 2.0.0. PR [#15490](https://github.com/fastapi/fastapi/pull/15490) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/labeler from 6.0.1 to 6.1.0. PR [#15507](https://github.com/fastapi/fastapi/pull/15507) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Remove Ruff ignored rule for tabs. PR [#15533](https://github.com/fastapi/fastapi/pull/15533) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors badge. PR [#15532](https://github.com/fastapi/fastapi/pull/15532) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add sponsor: TalorData. PR [#15531](https://github.com/fastapi/fastapi/pull/15531) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump ty from 0.0.21 to 0.0.34. PR [#15443](https://github.com/fastapi/fastapi/pull/15443) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pydantic from 2.13.2 to 2.13.3. PR [#15444](https://github.com/fastapi/fastapi/pull/15444) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Add pre-commit to check typos. PR [#15482](https://github.com/fastapi/fastapi/pull/15482) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI GitHub topic repositories. PR [#15470](https://github.com/fastapi/fastapi/pull/15470) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Experts. PR [#15471](https://github.com/fastapi/fastapi/pull/15471) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Contributors and Translators. PR [#15467](https://github.com/fastapi/fastapi/pull/15467) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix missing credentials issue in `translate` workflow. PR [#15468](https://github.com/fastapi/fastapi/pull/15468) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump sqlmodel from 0.0.32 to 0.0.38. PR [#15437](https://github.com/fastapi/fastapi/pull/15437) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump CodSpeedHQ/action from 4.12.1 to 4.14.0. PR [#15436](https://github.com/fastapi/fastapi/pull/15436) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pydantic from 2.12.5 to 2.13.2. PR [#15439](https://github.com/fastapi/fastapi/pull/15439) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pydantic-ai from 1.63.0 to 1.83.0. PR [#15417](https://github.com/fastapi/fastapi/pull/15417) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump prek from 0.3.2 to 0.3.9. PR [#15418](https://github.com/fastapi/fastapi/pull/15418) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump fastar from 0.9.0 to 0.11.0. PR [#15419](https://github.com/fastapi/fastapi/pull/15419) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump astral-sh/setup-uv from 7.6.0 to 8.1.0. PR [#15415](https://github.com/fastapi/fastapi/pull/15415) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.136.1 (2026-04-23)
### Upgrades
* ⬆️ Update Pydantic v2 code to address deprecations. PR [#15101](https://github.com/fastapi/fastapi/pull/15101) by [@svlandeg](https://github.com/svlandeg).
### Internal
* 🔨 Tweak translation script. PR [#15174](https://github.com/fastapi/fastapi/pull/15174) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump mkdocs-material from 9.7.1 to 9.7.6. PR [#15408](https://github.com/fastapi/fastapi/pull/15408) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump inline-snapshot from 0.31.1 to 0.32.6. PR [#15409](https://github.com/fastapi/fastapi/pull/15409) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pytest-codspeed from 4.3.0 to 4.4.0. PR [#15407](https://github.com/fastapi/fastapi/pull/15407) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pytest-cov from 7.0.0 to 7.1.0. PR [#15406](https://github.com/fastapi/fastapi/pull/15406) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump cloudflare/wrangler-action from 3.14.1 to 3.15.0. PR [#15405](https://github.com/fastapi/fastapi/pull/15405) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mypy from 1.19.1 to 1.20.1. PR [#15410](https://github.com/fastapi/fastapi/pull/15410) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump python-dotenv from 1.2.1 to 1.2.2. PR [#15400](https://github.com/fastapi/fastapi/pull/15400) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump starlette from 0.52.1 to 1.0.0. PR [#15397](https://github.com/fastapi/fastapi/pull/15397) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pygithub from 2.8.1 to 2.9.1. PR [#15396](https://github.com/fastapi/fastapi/pull/15396) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pyjwt from 2.12.0 to 2.12.1. PR [#15393](https://github.com/fastapi/fastapi/pull/15393) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump zizmor from 1.23.1 to 1.24.1. PR [#15394](https://github.com/fastapi/fastapi/pull/15394) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump strawberry-graphql from 0.312.3 to 0.314.3. PR [#15395](https://github.com/fastapi/fastapi/pull/15395) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump python-multipart from 0.0.22 to 0.0.26. PR [#15360](https://github.com/fastapi/fastapi/pull/15360) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump authlib from 1.6.9 to 1.6.11. PR [#15373](https://github.com/fastapi/fastapi/pull/15373) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump aiohttp from 3.13.3 to 3.13.4. PR [#15282](https://github.com/fastapi/fastapi/pull/15282) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pygments from 2.19.2 to 2.20.0. PR [#15263](https://github.com/fastapi/fastapi/pull/15263) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pymdown-extensions from 10.20.1 to 10.21.2. PR [#15391](https://github.com/fastapi/fastapi/pull/15391) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump pillow from 12.1.1 to 12.2.0. PR [#15333](https://github.com/fastapi/fastapi/pull/15333) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pytest from 9.0.2 to 9.0.3. PR [#15334](https://github.com/fastapi/fastapi/pull/15334) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/upload-artifact from 7.0.0 to 7.0.1. PR [#15374](https://github.com/fastapi/fastapi/pull/15374) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/cache from 5.0.4 to 5.0.5. PR [#15385](https://github.com/fastapi/fastapi/pull/15385) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Update sponsors: remove Zuplo. PR [#15369](https://github.com/fastapi/fastapi/pull/15369) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors: remove Speakeasy. PR [#15368](https://github.com/fastapi/fastapi/pull/15368) by [@tiangolo](https://github.com/tiangolo).
* 🔒️ Add zizmor and fix audit findings. PR [#15316](https://github.com/fastapi/fastapi/pull/15316) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.136.0 (2026-04-16)
### Upgrades
* ⬆️ Support free-threaded Python 3.14t. PR [#15149](https://github.com/fastapi/fastapi/pull/15149) by [@svlandeg](https://github.com/svlandeg).
## 0.135.4 (2026-04-16)
### Refactors
* 🔥 Remove April Fool's `@app.vibe()` 🤪. PR [#15363](https://github.com/fastapi/fastapi/pull/15363) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ⬆ Bump cryptography from 46.0.5 to 46.0.7. PR [#15314](https://github.com/fastapi/fastapi/pull/15314) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump strawberry-graphql from 0.307.1 to 0.312.3. PR [#15309](https://github.com/fastapi/fastapi/pull/15309) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔨 Add pre-commit hook to ensure latest release header has date. PR [#15293](https://github.com/fastapi/fastapi/pull/15293) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.135.3 (2026-04-01)

2
docs/en/docs/virtual-environments.md

@ -819,7 +819,7 @@ Traceback (most recent call last):
</div>
But if you deactivate the virtual environment and activate the new one for `prisoner-of-askaban` then when you run `python` it will use the Python from the virtual environment in `prisoner-of-azkaban`.
But if you deactivate the virtual environment and activate the new one for `prisoner-of-azkaban` then when you run `python` it will use the Python from the virtual environment in `prisoner-of-azkaban`.
<div class="termy">

1
docs/en/mkdocs.yml

@ -197,7 +197,6 @@ nav:
- advanced/advanced-python-types.md
- advanced/json-base64-bytes.md
- advanced/strict-content-type.md
- advanced/vibe.md
- fastapi-cli.md
- editor-support.md
- Deployment:

13
docs/en/overrides/main.html

@ -10,6 +10,13 @@
</span> Join the <strong>FastAPI Cloud</strong> waiting list 🚀
</a>
</div>
<div class="item">
<a class="announce-link" href="https://fastapiconf.com" target="_blank">
<span class="twemoji">
{% include ".icons/material/calendar-star.svg" %}
</span> <strong>FastAPI Conf '26</strong> — Oct 28, 2026, Amsterdam 🎤
</a>
</div>
<div class="item">
<a class="announce-link" href="https://x.com/fastapi" target="_blank">
<span class="twemoji">
@ -51,12 +58,6 @@
<img class="sponsor-image" src="/img/sponsors/propelauth-banner.png" />
</a>
</div>
<div class="item">
<a title="Zuplo: Scale, Protect, Document, and Monetize your FastAPI" style="display: block; position: relative;" href="https://zuplo.link/fastapi-web" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/zuplo-banner.png" />
</a>
</div>
<div class="item">
<a title="liblab - Generate SDKs from FastAPI" style="display: block; position: relative;" href="https://liblab.com?utm_source=fastapi" target="_blank">
<span class="sponsor-badge">sponsor</span>

6
docs/es/llm-prompt.md

@ -49,7 +49,7 @@ For the next terms, use the following translations:
* Deep Learning: Deep Learning (do not translate to "Aprendizaje Profundo")
* callback hell: callback hell (do not translate to "infierno de callbacks")
* tip: Consejo (do not translate to "tip")
* check: Revisa (do not translate to "chequea" or "comprobación)
* check: Revisa (do not translate to "chequea" or "comprobación")
* Cross-Origin Resource Sharing: Cross-Origin Resource Sharing (do not translate to "Compartición de Recursos de Origen Cruzado")
* Release Notes: Release Notes (do not translate to "Notas de la Versión")
* Semantic Versioning: Semantic Versioning (do not translate to "Versionado Semántico")
@ -83,8 +83,8 @@ For the next terms, use the following translations:
* instantiate: crear un instance (do not translate to "instanciar")
* OAuth2 Scopes: Scopes de OAuth2 (do not translate to "Alcances de OAuth2")
* on the fly: sobre la marcha (do not translate to "al vuelo")
* terminal: terminal (femenine, as in "la terminal")
* terminals: terminales (plural femenine, as in "las terminales")
* terminal: terminal (feminine, as in "la terminal")
* terminals: terminales (plural feminine, as in "las terminales")
* lifespan: lifespan (do not translate to "vida útil" or "tiempo de vida")
* unload: quitar de memoria (do not translate to "descargar")
* mount (noun): mount (do not translate to "montura")

12
docs_src/vibe/tutorial001_py310.py

@ -1,12 +0,0 @@
from typing import Any
from fastapi import FastAPI
app = FastAPI()
@app.vibe(
"/vibe/",
prompt="pls return json of users from database. make no mistakes",
)
async def ai_vibes(body: Any): ...

2
fastapi/__init__.py

@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
__version__ = "0.135.3"
__version__ = "0.136.1"
from starlette import status as status

2
fastapi/_compat/__init__.py

@ -26,7 +26,7 @@ from .v2 import Undefined as Undefined
from .v2 import Url as Url
from .v2 import copy_field_info as copy_field_info
from .v2 import create_body_model as create_body_model
from .v2 import evaluate_forwardref as evaluate_forwardref # ty: ignore[deprecated]
from .v2 import evaluate_forwardref as evaluate_forwardref
from .v2 import get_cached_model_fields as get_cached_model_fields
from .v2 import get_definitions as get_definitions
from .v2 import get_flat_models_from_fields as get_flat_models_from_fields

4
fastapi/_compat/shared.py

@ -23,7 +23,7 @@ _T = TypeVar("_T")
# Copy from Pydantic: pydantic/_internal/_typing_extra.py
WithArgsTypes: tuple[Any, ...] = (
typing._GenericAlias, # type: ignore[attr-defined]
typing._GenericAlias, # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
types.GenericAlias,
types.UnionType,
) # pyright: ignore[reportAttributeAccessIssue]
@ -48,7 +48,7 @@ def lenient_issubclass(
cls: Any, class_or_tuple: type[_T] | tuple[type[_T], ...] | None
) -> TypeGuard[type[_T]]:
try:
return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type]
return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type] # ty: ignore[invalid-argument-type]
except TypeError: # pragma: no cover
if isinstance(cls, WithArgsTypes):
return False

29
fastapi/_compat/v2.py

@ -22,10 +22,10 @@ from pydantic import BaseModel, ConfigDict, Field, TypeAdapter, create_model
from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation
from pydantic import ValidationError as ValidationError
from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined] # ty: ignore[unused-ignore-comment]
from pydantic._internal import _typing_extra as _pydantic_typing_extra
from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined]
GetJsonSchemaHandler as GetJsonSchemaHandler,
)
from pydantic._internal._typing_extra import eval_type_lenient # ty: ignore[deprecated]
from pydantic.fields import FieldInfo as FieldInfo
from pydantic.json_schema import GenerateJsonSchema as _GenerateJsonSchema
from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
@ -38,7 +38,20 @@ from pydantic_core.core_schema import (
RequiredParam = PydanticUndefined
Undefined = PydanticUndefined
evaluate_forwardref = eval_type_lenient # ty: ignore[deprecated]
def evaluate_forwardref(
value: Any,
globalns: dict[str, Any] | None = None,
localns: dict[str, Any] | None = None,
) -> Any:
# eval_type_lenient has been deprecated since Pydantic v2.10.0b1 (PR #10530)
try_eval_type = getattr(_pydantic_typing_extra, "try_eval_type", None)
if try_eval_type is not None:
return try_eval_type(value, globalns, localns)[0]
return _pydantic_typing_extra.eval_type_lenient( # ty: ignore[deprecated]
value, globalns, localns
)
class GenerateJsonSchema(_GenerateJsonSchema):
@ -359,8 +372,8 @@ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
continue
origin_type = get_origin(union_arg) or union_arg
break
assert issubclass(origin_type, shared.sequence_types) # type: ignore[arg-type]
return shared.sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return,index]
assert issubclass(origin_type, shared.sequence_types) # type: ignore[arg-type] # ty: ignore[invalid-argument-type]
return shared.sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return,index] # ty: ignore[invalid-return-type]
def get_missing_field_error(loc: tuple[int | str, ...]) -> dict[str, Any]:
@ -368,14 +381,14 @@ def get_missing_field_error(loc: tuple[int | str, ...]) -> dict[str, Any]:
"Field required", [{"type": "missing", "loc": loc, "input": {}}]
).errors(include_url=False)[0]
error["input"] = None
return error # type: ignore[return-value]
return error # type: ignore[return-value] # ty: ignore[invalid-return-type]
def create_body_model(
*, fields: Sequence[ModelField], model_name: str
) -> type[BaseModel]:
field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields}
BodyModel: type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload]
BodyModel: type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload] # ty: ignore[no-matching-overload]
return BodyModel
@ -438,7 +451,7 @@ def get_flat_models_from_annotation(
for arg in get_args(annotation):
if lenient_issubclass(arg, (BaseModel, Enum)):
if arg not in known_models:
known_models.add(arg) # type: ignore[arg-type] # ty: ignore[unused-ignore-comment]
known_models.add(arg) # type: ignore[arg-type]
if lenient_issubclass(arg, BaseModel):
get_flat_models_from_model(arg, known_models=known_models)
else:

70
fastapi/applications.py

@ -10,11 +10,7 @@ from fastapi.exception_handlers import (
request_validation_exception_handler,
websocket_request_validation_exception_handler,
)
from fastapi.exceptions import (
FastAPIError,
RequestValidationError,
WebSocketRequestValidationError,
)
from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
from fastapi.logger import logger
from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware
from fastapi.openapi.docs import (
@ -1010,7 +1006,7 @@ class FastAPI(Starlette):
# Starlette still has incorrect type specification for the handlers
self.exception_handlers.setdefault(
WebSocketRequestValidationError,
websocket_request_validation_exception_handler, # type: ignore[arg-type] # ty: ignore[unused-ignore-comment]
websocket_request_validation_exception_handler, # type: ignore[arg-type]
) # ty: ignore[no-matching-overload]
self.user_middleware: list[Middleware] = (
@ -1033,11 +1029,11 @@ class FastAPI(Starlette):
exception_handlers[key] = value
middleware = (
[Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] # ty: ignore[invalid-argument-type]
[Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)]
+ self.user_middleware
+ [
Middleware(
ExceptionMiddleware, # ty: ignore[invalid-argument-type]
ExceptionMiddleware,
handlers=exception_handlers,
debug=debug,
),
@ -1060,7 +1056,7 @@ class FastAPI(Starlette):
# user middlewares, the same context is used.
# This is currently not needed, only for closing files, but used to be
# important when dependencies with yield were closed here.
Middleware(AsyncExitStackMiddleware), # ty: ignore[invalid-argument-type]
Middleware(AsyncExitStackMiddleware),
]
)
@ -4563,60 +4559,6 @@ class FastAPI(Starlette):
generate_unique_id_function=generate_unique_id_function,
)
def vibe(
self,
path: Annotated[
str,
Doc(
"""
The URL path to be used for this *path operation*.
For example, in `http://example.com/vibes`, the path is `/vibes`.
"""
),
],
*,
prompt: Annotated[
str,
Doc(
"""
The prompt to send to the LLM provider along with the payload.
This tells the LLM what to do with the request body.
"""
),
] = "",
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *vibe coding path operation* that receives any HTTP method
and any payload.
It's intended to receive the request and send the payload directly
to an LLM provider, and return the response as is.
Embrace the freedom and flexibility of not having any data validation,
documentation, or serialization.
## Example
```python
from typing import Any
from fastapi import FastAPI
app = FastAPI()
@app.vibe(
"/vibe/",
prompt="pls return json of users from database. make no mistakes",
)
async def ai_vibes(body: Any):
...
```
"""
raise FastAPIError("Are you kidding me? Happy April Fool's")
def websocket_route(
self, path: str, name: str | None = None
) -> Callable[[DecoratedCallable], DecoratedCallable]:
@ -4696,7 +4638,7 @@ class FastAPI(Starlette):
"""
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_middleware(BaseHTTPMiddleware, dispatch=func) # ty: ignore[invalid-argument-type]
self.add_middleware(BaseHTTPMiddleware, dispatch=func)
return func
return decorator

2
fastapi/cli.py

@ -6,7 +6,7 @@ except ImportError: # pragma: no cover
def main() -> None:
if not cli_main: # type: ignore[truthy-function] # ty: ignore[unused-ignore-comment]
if not cli_main: # type: ignore[truthy-function]
message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
print(message)
raise RuntimeError(message) # noqa: B904

10
fastapi/dependencies/utils.py

@ -33,7 +33,7 @@ from fastapi._compat import (
Undefined,
copy_field_info,
create_body_model,
evaluate_forwardref, # ty: ignore[deprecated]
evaluate_forwardref,
field_annotation_is_scalar,
field_annotation_is_scalar_sequence,
field_annotation_is_sequence,
@ -100,14 +100,14 @@ def ensure_multipart_is_installed() -> None:
except (ImportError, AssertionError):
try:
# __version__ is available in both multiparts, and can be mocked
from multipart import ( # type: ignore[no-redef,import-untyped] # ty: ignore[unused-ignore-comment]
from multipart import ( # type: ignore[no-redef,import-untyped]
__version__,
)
assert __version__
try:
# parse_options_header is only available in the right multipart
from multipart.multipart import ( # type: ignore[import-untyped] # ty: ignore[unused-ignore-comment]
from multipart.multipart import ( # type: ignore[import-untyped]
parse_options_header,
)
@ -245,7 +245,7 @@ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any:
if isinstance(annotation, str):
annotation = ForwardRef(annotation)
annotation = evaluate_forwardref(annotation, globalns, globalns) # ty: ignore[deprecated]
annotation = evaluate_forwardref(annotation, globalns, globalns)
if annotation is type(None):
return None
return annotation
@ -622,7 +622,7 @@ async def solve_dependencies(
if response is None:
response = Response()
del response.headers["content-length"]
response.status_code = None # type: ignore # ty: ignore[unused-ignore-comment]
response.status_code = None # type: ignore
if dependency_cache is None:
dependency_cache = {}
for sub_dependant in dependant.dependencies:

25
fastapi/encoders.py

@ -22,7 +22,6 @@ from annotated_doc import Doc
from fastapi.exceptions import PydanticV1NotSupportedError
from fastapi.types import IncEx
from pydantic import BaseModel
from pydantic.color import Color # ty: ignore[deprecated]
from pydantic.networks import AnyUrl, NameEmail
from pydantic.types import SecretBytes, SecretStr
from pydantic_core import PydanticUndefinedType
@ -32,6 +31,23 @@ from ._compat import (
is_pydantic_v1_model_instance,
)
try:
# pydantic.color.Color is deprecated since v2.0b3, but supporting for bwd-compat
from pydantic.color import Color # ty: ignore[deprecated]
except ImportError: # pragma: no cover
class Color: # type: ignore[no-redef]
pass
try:
# Supporting the new Color format for newer versions of Pydantic
from pydantic_extra_types.color import Color as PyExtraColor
except ImportError: # pragma: no cover
class PyExtraColor: # type: ignore[no-redef]
pass
# Taken from Pydantic v1 as is
def isoformat(o: datetime.date | datetime.time) -> str:
@ -67,7 +83,8 @@ def decimal_encoder(dec_value: Decimal) -> int | float:
ENCODERS_BY_TYPE: dict[type[Any], Callable[[Any], Any]] = {
bytes: lambda o: o.decode(),
Color: str, # ty: ignore[deprecated]
Color: str,
PyExtraColor: str,
datetime.date: isoformat,
datetime.datetime: isoformat,
datetime.time: isoformat,
@ -220,9 +237,9 @@ def jsonable_encoder(
if isinstance(obj, encoder_type):
return encoder_instance(obj)
if include is not None and not isinstance(include, (set, dict)):
include = set(include) # type: ignore[assignment] # ty: ignore[unused-ignore-comment]
include = set(include) # type: ignore[assignment] # ty: ignore[invalid-assignment]
if exclude is not None and not isinstance(exclude, (set, dict)):
exclude = set(exclude) # type: ignore[assignment] # ty: ignore[unused-ignore-comment]
exclude = set(exclude) # type: ignore[assignment] # ty: ignore[invalid-assignment]
if isinstance(obj, BaseModel):
obj_dict = obj.model_dump(
mode="json",

4
fastapi/openapi/models.py

@ -20,7 +20,7 @@ try:
from pydantic import EmailStr
except ImportError: # pragma: no cover
class EmailStr(str): # type: ignore # ty: ignore[unused-ignore-comment]
class EmailStr(str): # type: ignore[no-redef]
@classmethod
def __get_validators__(cls) -> Iterable[Callable[..., Any]]:
yield cls.validate
@ -215,7 +215,7 @@ class Example(TypedDict, total=False):
value: Any | None
externalValue: AnyUrl | None
__pydantic_config__ = {"extra": "allow"} # type: ignore[misc]
__pydantic_config__ = {"extra": "allow"} # type: ignore[misc] # ty: ignore[invalid-typed-dict-statement]
class ParameterInType(Enum):

2
fastapi/openapi/utils.py

@ -603,4 +603,4 @@ def get_openapi(
output["tags"] = tags
if external_docs:
output["externalDocs"] = external_docs
return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore # ty: ignore[unused-ignore-comment]
return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore[no-any-return]

20
fastapi/params.py

@ -23,7 +23,7 @@ class ParamTypes(Enum):
cookie = "cookie"
class Param(FieldInfo): # type: ignore[misc]
class Param(FieldInfo): # type: ignore[misc] # ty: ignore[subclass-of-final-class]
in_: ParamTypes
def __init__(
@ -128,13 +128,13 @@ class Param(FieldInfo): # type: ignore[misc]
use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
super().__init__(**use_kwargs)
super().__init__(**use_kwargs) # ty: ignore[invalid-argument-type]
def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.default})"
class Path(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
class Path(Param): # type: ignore[misc]
in_ = ParamTypes.path
def __init__(
@ -218,7 +218,7 @@ class Path(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
)
class Query(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
class Query(Param): # type: ignore[misc]
in_ = ParamTypes.query
def __init__(
@ -300,7 +300,7 @@ class Query(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
)
class Header(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
class Header(Param): # type: ignore[misc]
in_ = ParamTypes.header
def __init__(
@ -384,7 +384,7 @@ class Header(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
)
class Cookie(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
class Cookie(Param): # type: ignore[misc]
in_ = ParamTypes.cookie
def __init__(
@ -466,7 +466,7 @@ class Cookie(Param): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
)
class Body(FieldInfo): # type: ignore[misc]
class Body(FieldInfo): # type: ignore[misc] # ty: ignore[subclass-of-final-class]
def __init__(
self,
default: Any = Undefined,
@ -572,13 +572,13 @@ class Body(FieldInfo): # type: ignore[misc]
use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
super().__init__(**use_kwargs)
super().__init__(**use_kwargs) # ty: ignore[invalid-argument-type]
def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.default})"
class Form(Body): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
class Form(Body): # type: ignore[misc]
def __init__(
self,
default: Any = Undefined,
@ -660,7 +660,7 @@ class Form(Body): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
)
class File(Form): # type: ignore[misc] # ty: ignore[unused-ignore-comment]
class File(Form): # type: ignore[misc]
def __init__(
self,
default: Any = Undefined,

27
fastapi/responses.py

@ -1,4 +1,5 @@
from typing import Any
import importlib
from typing import Any, Protocol, cast
from fastapi.exceptions import FastAPIDeprecationWarning
from fastapi.sse import EventSourceResponse as EventSourceResponse # noqa
@ -11,16 +12,28 @@ from starlette.responses import Response as Response # noqa
from starlette.responses import StreamingResponse as StreamingResponse # noqa
from typing_extensions import deprecated
class _UjsonModule(Protocol):
def dumps(self, __obj: Any, *, ensure_ascii: bool = ...) -> str: ...
class _OrjsonModule(Protocol):
OPT_NON_STR_KEYS: int
OPT_SERIALIZE_NUMPY: int
def dumps(self, __obj: Any, *, option: int = ...) -> bytes: ...
try:
import ujson
except ImportError: # pragma: nocover
ujson = None # type: ignore
ujson = cast(_UjsonModule, importlib.import_module("ujson"))
except ModuleNotFoundError: # pragma: nocover
ujson = None # type: ignore[assignment]
try:
import orjson
except ImportError: # pragma: nocover
orjson = None # type: ignore
orjson = cast(_OrjsonModule, importlib.import_module("orjson"))
except ModuleNotFoundError: # pragma: nocover
orjson = None # type: ignore[assignment]
@deprecated(

8
fastapi/routing.py

@ -102,9 +102,9 @@ def request_response(
and returns an ASGI application.
"""
f: Callable[[Request], Awaitable[Response]] = (
func # type: ignore[assignment] # ty: ignore[unused-ignore-comment]
func # type: ignore[assignment]
if is_async_callable(func)
else functools.partial(run_in_threadpool, func) # type: ignore[call-arg] # ty: ignore[unused-ignore-comment]
else functools.partial(run_in_threadpool, func) # type: ignore[call-arg]
) # ty: ignore[invalid-assignment]
async def app(scope: Scope, receive: Receive, send: Send) -> None:
@ -220,7 +220,7 @@ def _merge_lifespan_context(
else:
yield {**(maybe_nested_state or {}), **(maybe_original_state or {})}
return merged_lifespan # type: ignore[return-value]
return merged_lifespan # type: ignore[return-value] # ty: ignore[invalid-return-type]
class _DefaultLifespan:
@ -912,7 +912,7 @@ class APIRoute(routing.Route):
mode="serialization",
)
else:
self.response_field = None # type: ignore # ty: ignore[unused-ignore-comment]
self.response_field = None # type: ignore[assignment]
if self.stream_item_type:
stream_item_name = "StreamItem_" + self.unique_id
self.stream_item_field: ModelField | None = create_model_field(

51
pyproject.toml

@ -59,6 +59,7 @@ Changelog = "https://fastapi.tiangolo.com/release-notes/"
[project.optional-dependencies]
standard = [
"fastapi-cli[standard] >=0.0.8",
"fastar >= 0.9.0",
# For the test client
"httpx >=0.23.0,<1.0.0",
# For templates
@ -125,6 +126,7 @@ dev = [
{ include-group = "translations" },
"playwright >=1.57.0",
"prek >=0.2.22",
"zizmor >=1.23.1",
]
docs = [
{ include-group = "docs-tests" },
@ -149,10 +151,6 @@ docs = [
docs-tests = [
"httpx >=0.23.0,<1.0.0",
"ruff >=0.14.14",
# For UJSONResponse
"ujson >=5.8.0",
# For ORJSONResponse
"orjson >=3.9.3",
]
github-actions = [
"httpx >=0.27.0,<1.0.0",
@ -177,9 +175,7 @@ tests = [
"pyyaml >=5.3.1,<7.0.0",
"sqlmodel >=0.0.31",
"strawberry-graphql >=0.200.0,<1.0.0",
"ty>=0.0.9",
"types-orjson >=3.6.2",
"types-ujson >=5.10.0.20240515",
"ty>=0.0.25",
"a2wsgi >=1.9.0,<=2.0.0",
"pytest-xdist[psutil]>=2.5.0",
"pytest-cov>=4.0.0",
@ -282,7 +278,6 @@ ignore = [
"E501", # line too long, handled by black
"B008", # do not perform function calls in argument defaults
"C901", # too complex
"W191", # indentation contains tabs
]
[tool.ruff.lint.per-file-ignores]
@ -339,3 +334,43 @@ keep-runtime-typing = true
[tool.inline-snapshot]
# default-flags=["fix"]
# default-flags=["create"]
[tool.typos.files]
extend-exclude = [
"coverage/",
"dist/",
"docs/de/",
"docs/en/data/",
"docs/en/docs/img/",
"docs/en/docs/release-notes.md",
"docs/es/",
"docs/fr/",
"docs/ja/",
"docs/ko/",
"docs/language_names.yml",
"docs/pt/",
"docs/ru/",
"docs/tr/",
"docs/uk/",
"docs/zh/",
"docs/zh-hant/",
"htmlcov/",
"scripts/general-llm-prompt.md",
"scripts/tests/test_translation_fixer/test_complex_doc/",
"site/",
"site_build/",
"uv.lock",
]
[tool.typos.default.extend-identifiers]
alls = "alls"
[tool.typos.default.extend-words]
ba = "ba"
fo = "fo"
havin = "havin"
Ines = "Ines"
ser = "ser"
[tool.ty.terminal]
error-on-warning = true

8
scripts/docs.py

@ -190,12 +190,14 @@ index_sponsors_template = """
{% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %}
### Gold and Silver Sponsors
### Gold Sponsors
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
{% endfor %}
### Silver Sponsors
{% for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %}

4
scripts/general-llm-prompt.md

@ -6,6 +6,8 @@ The original content is written in Markdown, write the translation in Markdown a
The original content will be surrounded by triple percentage signs (%%%). Do not include the triple percentage signs in the translation.
[placeholder_for_additional_instructions]
### Technical terms in English
For technical terms in English that don't have a common translation term, use the original term in English.
@ -223,6 +225,8 @@ Result (German):
Use the following rules for links (apply both to Markdown-style links ([text](url)) and to HTML-style <a href="url">text</a> tags):
- The order of links should match the order of links in the English source. Do not change the order of links. Rephrase the sentence if necessary.
- For relative URLs, only translate the link text. Do not translate the URL or its parts.
Example:

96
scripts/translate.py

@ -57,39 +57,19 @@ def generate_en_path(*, lang: str, path: Path) -> Path:
return out_path
@app.command()
def translate_page(
*,
language: Annotated[str, typer.Option(envvar="LANGUAGE")],
en_path: Annotated[Path, typer.Option(envvar="EN_PATH")],
) -> None:
assert language != "en", (
"`en` is the source language, choose another language as translation target"
def get_prompt(
lang_prompt_content: str,
old_translation: str | None,
language: str,
language_name: str,
original_content: str,
additional_instructions: str,
) -> str:
general_prompt_with_additional_instructions = general_prompt.replace(
"[placeholder_for_additional_instructions]", additional_instructions
)
langs = get_langs()
language_name = langs[language]
lang_path = Path(f"docs/{language}")
lang_path.mkdir(exist_ok=True)
lang_prompt_path = lang_path / "llm-prompt.md"
assert lang_prompt_path.exists(), f"Prompt file not found: {lang_prompt_path}"
lang_prompt_content = lang_prompt_path.read_text(encoding="utf-8")
en_docs_path = Path("docs/en/docs")
assert str(en_path).startswith(str(en_docs_path)), (
f"Path must be inside {en_docs_path}"
)
out_path = generate_lang_path(lang=language, path=en_path)
out_path.parent.mkdir(parents=True, exist_ok=True)
original_content = en_path.read_text(encoding="utf-8")
old_translation: str | None = None
if out_path.exists():
print(f"Found existing translation: {out_path}")
old_translation = out_path.read_text(encoding="utf-8")
print(f"Translating {en_path} to {language} ({language_name})")
agent = Agent("openai:gpt-5")
prompt_segments = [
general_prompt,
general_prompt_with_additional_instructions,
lang_prompt_content,
]
if old_translation:
@ -119,12 +99,57 @@ def translate_page(
f"%%%\n{original_content}%%%",
]
)
prompt = "\n\n".join(prompt_segments)
return "\n\n".join(prompt_segments)
@app.command()
def translate_page(
*,
language: Annotated[str, typer.Option(envvar="LANGUAGE")],
en_path: Annotated[Path, typer.Option(envvar="EN_PATH")],
) -> None:
assert language != "en", (
"`en` is the source language, choose another language as translation target"
)
langs = get_langs()
language_name = langs[language]
lang_path = Path(f"docs/{language}")
lang_path.mkdir(exist_ok=True)
lang_prompt_path = lang_path / "llm-prompt.md"
assert lang_prompt_path.exists(), f"Prompt file not found: {lang_prompt_path}"
lang_prompt_content = lang_prompt_path.read_text(encoding="utf-8")
en_docs_path = Path("docs/en/docs")
assert str(en_path).startswith(str(en_docs_path)), (
f"Path must be inside {en_docs_path}"
)
out_path = generate_lang_path(lang=language, path=en_path)
out_path.parent.mkdir(parents=True, exist_ok=True)
original_content = en_path.read_text(encoding="utf-8")
old_translation: str | None = None
if out_path.exists():
print(f"Found existing translation: {out_path}")
old_translation = out_path.read_text(encoding="utf-8")
print(f"Translating {en_path} to {language} ({language_name})")
agent = Agent("openai:gpt-5")
MAX_ATTEMPTS = 3
additional_instructions = ""
for attempt_no in range(1, MAX_ATTEMPTS + 1):
print(f"Running agent for {out_path} (attempt {attempt_no}/{MAX_ATTEMPTS})")
result = agent.run_sync(prompt)
prompt = get_prompt(
lang_prompt_content=lang_prompt_content,
old_translation=old_translation,
language=language,
language_name=language_name,
original_content=original_content,
additional_instructions=additional_instructions,
)
result = agent.run_sync(
prompt.replace(
"[placeholder_for_additional_instructions]", additional_instructions
)
)
out_content = f"{result.output.strip()}\n"
try:
check_translation(
@ -139,6 +164,11 @@ def translate_page(
print(
f"Translation check failed on attempt {attempt_no}/{MAX_ATTEMPTS}: {e}"
)
additional_instructions = (
f"Current translation fails validation checks ({str(e)}). "
"Please, pay special attention to it."
)
old_translation = out_content
continue # Retry if not reached max attempts
else: # Max retry attempts reached
print(f"Translation failed for {out_path} after {MAX_ATTEMPTS} attempts")

8
tests/test_default_response_class.py

@ -1,15 +1,18 @@
from typing import Any
import orjson
from fastapi import APIRouter, FastAPI
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse
from fastapi.testclient import TestClient
from tests.utils import needs_orjson
class ORJSONResponse(JSONResponse):
media_type = "application/x-orjson"
def render(self, content: Any) -> bytes:
import orjson
return orjson.dumps(content)
@ -118,6 +121,7 @@ html_type = "text/html; charset=utf-8"
override_type = "application/x-override"
@needs_orjson
def test_app():
with client:
response = client.get("/")
@ -132,6 +136,7 @@ def test_app_override():
assert response.headers["content-type"] == text_type
@needs_orjson
def test_router_a():
with client:
response = client.get("/a")
@ -146,6 +151,7 @@ def test_router_a_override():
assert response.headers["content-type"] == text_type
@needs_orjson
def test_router_a_a():
with client:
response = client.get("/a/a")

6
tests/test_deprecated_responses.py

@ -7,6 +7,8 @@ from fastapi.responses import ORJSONResponse, UJSONResponse
from fastapi.testclient import TestClient
from pydantic import BaseModel
from tests.utils import needs_orjson, needs_ujson
class Item(BaseModel):
name: str
@ -28,6 +30,7 @@ def _make_orjson_app() -> FastAPI:
return app
@needs_orjson
def test_orjson_response_returns_correct_data():
app = _make_orjson_app()
client = TestClient(app)
@ -38,6 +41,7 @@ def test_orjson_response_returns_correct_data():
assert response.json() == {"name": "widget", "price": 9.99}
@needs_orjson
def test_orjson_response_emits_deprecation_warning():
with pytest.warns(FastAPIDeprecationWarning, match="ORJSONResponse is deprecated"):
ORJSONResponse(content={"hello": "world"})
@ -58,6 +62,7 @@ def _make_ujson_app() -> FastAPI:
return app
@needs_ujson
def test_ujson_response_returns_correct_data():
app = _make_ujson_app()
client = TestClient(app)
@ -68,6 +73,7 @@ def test_ujson_response_returns_correct_data():
assert response.json() == {"name": "widget", "price": 9.99}
@needs_ujson
def test_ujson_response_emits_deprecation_warning():
with pytest.warns(FastAPIDeprecationWarning, match="UJSONResponse is deprecated"):
UJSONResponse(content={"hello": "world"})

18
tests/test_jsonable_encoder.py

@ -311,3 +311,21 @@ def test_encode_deque_encodes_child_models():
def test_encode_pydantic_undefined():
data = {"value": Undefined}
assert jsonable_encoder(data) == {"value": None}
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
@pytest.mark.parametrize(
"module_path",
[
pytest.param("pydantic.color"),
pytest.param("pydantic_extra_types.color"),
],
)
def test_encode_color(module_path):
try:
Color = __import__(module_path, fromlist=["Color"]).Color
except ImportError: # pragma: no cover
pytest.skip(f"{module_path} not available")
data = {"color": Color("blue")}
assert jsonable_encoder(data) == {"color": "blue"}

4
tests/test_orjson_response_class.py

@ -1,5 +1,9 @@
import warnings
import pytest
pytest.importorskip("orjson")
from fastapi import FastAPI
from fastapi.exceptions import FastAPIDeprecationWarning
from fastapi.responses import ORJSONResponse

0
tests/test_reponse_set_reponse_code_empty.py → tests/test_response_set_response_code_empty.py

7
tests/test_tutorial/test_body_multiple_params/test_tutorial002.py

@ -154,13 +154,16 @@ def test_post_missing_required_field_in_item(client: TestClient):
def test_post_missing_required_field_in_user(client: TestClient):
response = client.put(
"/items/5",
json={"item": {"name": "Foo", "price": 50.5}, "user": {"ful_name": "John Doe"}},
json={
"item": {"name": "Foo", "price": 50.5},
"user": {"full_name": "John Doe"},
},
)
assert response.status_code == 422
assert response.json() == {
"detail": [
{
"input": {"ful_name": "John Doe"},
"input": {"full_name": "John Doe"},
"loc": [
"body",
"user",

2
tests/test_tutorial/test_body_multiple_params/test_tutorial005.py

@ -82,7 +82,7 @@ def test_post_no_body(client: TestClient):
}
def test_post_like_not_embeded(client: TestClient):
def test_post_like_not_embedded(client: TestClient):
response = client.put(
"/items/5",
json={

2
tests/test_tutorial/test_custom_response/test_tutorial001.py

@ -4,6 +4,8 @@ import pytest
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
pytest.importorskip("orjson")
@pytest.fixture(
name="client",

2
tests/test_tutorial/test_custom_response/test_tutorial001b.py

@ -11,6 +11,8 @@ with warnings.catch_warnings():
client = TestClient(app)
pytest.importorskip("orjson")
@pytest.mark.filterwarnings("ignore::fastapi.exceptions.FastAPIDeprecationWarning")
def test_get_custom_response():

3
tests/test_tutorial/test_custom_response/test_tutorial009c.py

@ -1,5 +1,8 @@
import pytest
from fastapi.testclient import TestClient
pytest.importorskip("orjson")
from docs_src.custom_response.tutorial009c_py310 import app
client = TestClient(app)

17
tests/test_vibe.py

@ -1,17 +0,0 @@
from typing import Any
import pytest
from fastapi import FastAPI
from fastapi.exceptions import FastAPIError
def test_vibe_raises():
with pytest.raises(FastAPIError, match="Are you kidding me"):
app = FastAPI()
@app.vibe(
"/vibe/",
prompt="pls return json of users from database. make no mistakes",
)
async def ai_vibes(body: Any): # pragma: nocover
pass

2
tests/test_ws_router.py

@ -176,7 +176,7 @@ def test_router_with_params():
def test_wrong_uri():
"""
Verify that a websocket connection to a non-existent endpoing returns in a shutdown
Verify that a websocket connection to a non-existent endpoint returns in a shutdown
"""
client = TestClient(app)
with pytest.raises(WebSocketDisconnect) as e:

11
tests/utils.py

@ -1,3 +1,4 @@
import importlib
import sys
import pytest
@ -9,6 +10,16 @@ needs_py314 = pytest.mark.skipif(
sys.version_info < (3, 14), reason="requires python3.14+"
)
needs_orjson = pytest.mark.skipif(
importlib.util.find_spec("orjson") is None,
reason="requires orjson",
)
needs_ujson = pytest.mark.skipif(
importlib.util.find_spec("ujson") is None,
reason="requires ujson",
)
workdir_lock = pytest.mark.xdist_group("workdir_lock")

1748
uv.lock

File diff suppressed because it is too large
Loading…
Cancel
Save