Browse Source

Merge branch 'master' into feat/per-router-exception-handlers

pull/15067/head
Michał Połtyn 2 months ago
committed by GitHub
parent
commit
5f30d73b88
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. 37
      README.md
  23. 12
      docs/en/data/contributors.yml
  24. 320
      docs/en/data/people.yml
  25. 6
      docs/en/data/sponsors.yml
  26. 404
      docs/en/data/topic_repos.yml
  27. 12
      docs/en/data/translation_reviewers.yml
  28. 4
      docs/en/data/translators.yml
  29. 1
      docs/en/docs/advanced/generate-clients.md
  30. 44
      docs/en/docs/advanced/vibe.md
  31. 186
      docs/en/docs/css/custom.css
  32. BIN
      docs/en/docs/img/fastapi-conf.jpeg
  33. 35
      docs/en/docs/img/logos/cisco.svg
  34. 8
      docs/en/docs/img/logos/microsoft.svg
  35. 1
      docs/en/docs/img/logos/netflix.svg
  36. 39
      docs/en/docs/img/logos/uber.svg
  37. 83
      docs/en/docs/index.md
  38. 38
      docs/en/docs/js/custom.js
  39. 75
      docs/en/docs/release-notes.md
  40. 2
      docs/en/docs/virtual-environments.md
  41. 1
      docs/en/mkdocs.yml
  42. 13
      docs/en/overrides/main.html
  43. 6
      docs/es/llm-prompt.md
  44. 12
      docs_src/vibe/tutorial001_py310.py
  45. 2
      fastapi/__init__.py
  46. 2
      fastapi/_compat/__init__.py
  47. 4
      fastapi/_compat/shared.py
  48. 29
      fastapi/_compat/v2.py
  49. 70
      fastapi/applications.py
  50. 2
      fastapi/cli.py
  51. 10
      fastapi/dependencies/utils.py
  52. 25
      fastapi/encoders.py
  53. 4
      fastapi/openapi/models.py
  54. 2
      fastapi/openapi/utils.py
  55. 20
      fastapi/params.py
  56. 27
      fastapi/responses.py
  57. 8
      fastapi/routing.py
  58. 50
      pyproject.toml
  59. 8
      scripts/docs.py
  60. 4
      scripts/general-llm-prompt.md
  61. 96
      scripts/translate.py
  62. 8
      tests/test_default_response_class.py
  63. 6
      tests/test_deprecated_responses.py
  64. 18
      tests/test_jsonable_encoder.py
  65. 4
      tests/test_orjson_response_class.py
  66. 0
      tests/test_response_set_response_code_empty.py
  67. 7
      tests/test_tutorial/test_body_multiple_params/test_tutorial002.py
  68. 2
      tests/test_tutorial/test_body_multiple_params/test_tutorial005.py
  69. 2
      tests/test_tutorial/test_custom_response/test_tutorial001.py
  70. 2
      tests/test_tutorial/test_custom_response/test_tutorial001b.py
  71. 3
      tests/test_tutorial/test_custom_response/test_tutorial009c.py
  72. 17
      tests/test_vibe.py
  73. 2
      tests/test_ws_router.py
  74. 11
      tests/utils.py
  75. 1748
      uv.lock

15
.github/dependabot.yml

@ -5,12 +5,25 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
cooldown:
default-days: 7
commit-message: commit-message:
prefix: prefix:
# Python # Python
- package-ecosystem: "uv" - package-ecosystem: "uv"
directory: "/" directory: "/"
schedule: 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: commit-message:
prefix: prefix:

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

@ -1,18 +1,20 @@
name: Add to Project name: Add to Project
on: on:
pull_request_target: pull_request_target: # zizmor: ignore[dangerous-triggers]
issues: issues:
types: types:
- opened - opened
- reopened - reopened
permissions: {}
jobs: jobs:
add-to-project: add-to-project:
name: Add to project name: Add to project
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/[email protected] - uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
with: with:
project-url: https://github.com/orgs/fastapi/projects/2 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 - opened
- synchronize - synchronize
permissions: {}
jobs: jobs:
changes: changes:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -18,9 +20,11 @@ jobs:
outputs: outputs:
docs: ${{ steps.filter.outputs.docs }} docs: ${{ steps.filter.outputs.docs }}
steps: 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 # 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 id: filter
with: with:
filters: | filters: |
@ -42,14 +46,17 @@ jobs:
outputs: outputs:
langs: ${{ steps.show-langs.outputs.langs }} langs: ${{ steps.show-langs.outputs.langs }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v6 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version-file: ".python-version" python-version-file: ".python-version"
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
@ -75,14 +82,17 @@ jobs:
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v6 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version-file: ".python-version" python-version-file: ".python-version"
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
@ -91,13 +101,14 @@ jobs:
run: uv sync --locked --no-dev --group docs run: uv sync --locked --no-dev --group docs
- name: Update Languages - name: Update Languages
run: uv run ./scripts/docs.py update-languages run: uv run ./scripts/docs.py update-languages
- uses: actions/cache@v5 - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with: with:
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }} key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
path: docs/${{ matrix.lang }}/.cache path: docs/${{ matrix.lang }}/.cache
- name: Build Docs - name: Build Docs
run: uv run ./scripts/docs.py build-lang ${{ matrix.lang }} run: | # zizmor: ignore[template-injection] - comes from trusted source
- uses: actions/upload-artifact@v7 uv run ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: docs-site-${{ matrix.lang }} name: docs-site-${{ matrix.lang }}
path: ./site/** path: ./site/**
@ -111,7 +122,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Decide whether the needed jobs succeeded or failed - 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: with:
jobs: ${{ toJSON(needs) }} jobs: ${{ toJSON(needs) }}
allowed-skips: build-docs allowed-skips: build-docs

17
.github/workflows/contributors.yml

@ -10,6 +10,8 @@ on:
required: false required: false
default: "false" default: "false"
permissions: {}
jobs: jobs:
job: job:
if: github.repository_owner == 'fastapi' if: github.repository_owner == 'fastapi'
@ -21,14 +23,17 @@ jobs:
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" 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 - name: Set up Python
uses: actions/setup-python@v6 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version-file: ".python-version" python-version-file: ".python-version"
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
@ -37,13 +42,13 @@ jobs:
run: uv sync --locked --no-dev --group github-actions run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate # Allow debugging with tmate
- name: Setup tmate session - 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' }} if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with: with:
limit-access-to-actor: true limit-access-to-actor: true
env: env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]
- name: FastAPI People Contributors - name: FastAPI People Contributors
run: uv run ./scripts/contributors.py run: uv run ./scripts/contributors.py
env: 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 name: Deploy Docs
on: on:
workflow_run: workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: workflows:
- Build Docs - Build Docs
types: types:
- completed - completed
permissions: permissions: {}
deployments: write
issues: write
pull-requests: write
statuses: write
jobs: jobs:
deploy-docs: deploy-docs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
deployments: write
issues: write
pull-requests: write
statuses: write
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v6 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version-file: ".python-version" python-version-file: ".python-version"
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
enable-cache: true version: "0.11.4"
cache-dependency-glob: | enable-cache: false
pyproject.toml
uv.lock
- name: Install GitHub Actions dependencies - name: Install GitHub Actions dependencies
run: uv sync --locked --no-dev --group github-actions run: uv sync --locked --no-dev --group github-actions
- name: Deploy Docs Status Pending - name: Deploy Docs Status Pending
@ -45,7 +46,7 @@ jobs:
run: | run: |
rm -rf ./site rm -rf ./site
mkdir ./site mkdir ./site
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with: with:
path: ./site/ path: ./site/
pattern: docs-site-* pattern: docs-site-*
@ -59,10 +60,10 @@ jobs:
env: env:
PROJECT_NAME: fastapitiangolo 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 ) }} 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: with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} # zizmor: ignore[secrets-outside-env]
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} # zizmor: ignore[secrets-outside-env]
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }} command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
- name: Deploy Docs Status Error - name: Deploy Docs Status Error
if: failure() if: failure()

6
.github/workflows/detect-conflicts.yml

@ -1,9 +1,11 @@
name: "Conflict detector" name: "Conflict detector"
on: on:
push: push:
pull_request_target: pull_request_target: # zizmor: ignore[dangerous-triggers]
types: [synchronize] types: [synchronize]
permissions: {}
jobs: jobs:
main: main:
permissions: permissions:
@ -12,7 +14,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check if PRs have merge conflicts - 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: with:
dirtyLabel: "conflicts" dirtyLabel: "conflicts"
repoToken: "${{ secrets.GITHUB_TOKEN }}" repoToken: "${{ secrets.GITHUB_TOKEN }}"

11
.github/workflows/issue-manager.yml

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

14
.github/workflows/label-approved.yml

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

8
.github/workflows/labeler.yml

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

16
.github/workflows/latest-changes.yml

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

17
.github/workflows/notify-translations.yml

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

17
.github/workflows/people.yml

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

21
.github/workflows/pre-commit.yml

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

12
.github/workflows/publish.yml

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

20
.github/workflows/smokeshow.yml

@ -1,34 +1,38 @@
name: Smokeshow name: Smokeshow
on: on:
workflow_run: workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: [Test] workflows: [Test]
types: [completed] types: [completed]
permissions: permissions: {}
statuses: write
jobs: jobs:
smokeshow: smokeshow:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
statuses: write
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@v6 with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version-file: ".python-version" python-version-file: ".python-version"
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
version: "0.11.4"
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
uv.lock uv.lock
- run: uv sync --locked --no-dev --group github-actions - run: uv sync --locked --no-dev --group github-actions
- uses: actions/download-artifact@v8 - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with: with:
name: coverage-html name: coverage-html
path: htmlcov path: htmlcov
@ -51,4 +55,4 @@ jobs:
SMOKESHOW_GITHUB_CONTEXT: coverage SMOKESHOW_GITHUB_CONTEXT: coverage
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }} 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 required: false
default: "false" default: "false"
permissions: {}
jobs: jobs:
job: job:
if: github.repository_owner == 'fastapi' if: github.repository_owner == 'fastapi'
@ -21,14 +23,17 @@ jobs:
env: env:
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT" 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 - name: Set up Python
uses: actions/setup-python@v6 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version-file: ".python-version" python-version-file: ".python-version"
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with: with:
version: "0.11.4"
enable-cache: true enable-cache: true
cache-dependency-glob: | cache-dependency-glob: |
pyproject.toml pyproject.toml
@ -37,12 +42,12 @@ jobs:
run: uv sync --locked --no-dev --group github-actions run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate # Allow debugging with tmate
- name: Setup tmate session - 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' }} if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with: with:
limit-access-to-actor: true limit-access-to-actor: true
- name: FastAPI People Sponsors - name: FastAPI People Sponsors
run: uv run ./scripts/sponsors.py run: uv run ./scripts/sponsors.py
env: env:
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }} SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }} # zizmor: ignore[secrets-outside-env]
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }} # zizmor: ignore[secrets-outside-env]

10
.github/workflows/test-redistribute.yml

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

70
.github/workflows/test.yml

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

13
.github/workflows/topic-repos.yml

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

16
.pre-commit-config.yaml

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

37
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> <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://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://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://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://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://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> <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,8 +61,10 @@ 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://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://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> <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://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.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.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.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>
@ -76,6 +77,10 @@ The key features are:
## Opinions ## 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._" "_[...] 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> <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 +99,25 @@ The key features are:
--- ---
"_I’m over the moon excited about **FastAPI**. It’s so fun!_" "_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%;">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._"
<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 [...]_" </div>
"_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>
---
"_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 ## 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: 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

12
docs/en/data/contributors.yml

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

320
docs/en/data/people.yml

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

6
docs/en/data/sponsors.yml

@ -12,9 +12,6 @@ gold:
- url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge - url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge
title: Auth, user management and more for your B2B product title: Auth, user management and more for your B2B product
img: https://fastapi.tiangolo.com/img/sponsors/propelauth.png 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 - url: https://liblab.com?utm_source=fastapi
title: liblab - Generate SDKs from FastAPI title: liblab - Generate SDKs from FastAPI
img: https://fastapi.tiangolo.com/img/sponsors/liblab.png 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 - url: https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display
title: Pay as you go for market data title: Pay as you go for market data
img: https://fastapi.tiangolo.com/img/sponsors/databento.svg 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/ - url: https://www.svix.com/
title: Svix - Webhooks as a service title: Svix - Webhooks as a service
img: https://fastapi.tiangolo.com/img/sponsors/svix.svg img: https://fastapi.tiangolo.com/img/sponsors/svix.svg

404
docs/en/data/topic_repos.yml

@ -1,495 +1,495 @@
- name: full-stack-fastapi-template - name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 42397 stars: 42944
owner_login: fastapi owner_login: fastapi
owner_html_url: https://github.com/fastapi owner_html_url: https://github.com/fastapi
- name: Hello-Python - name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python html_url: https://github.com/mouredev/Hello-Python
stars: 34997 stars: 35430
owner_login: mouredev owner_login: mouredev
owner_html_url: https://github.com/mouredev owner_html_url: https://github.com/mouredev
- name: serve - name: serve
html_url: https://github.com/jina-ai/serve html_url: https://github.com/jina-ai/serve
stars: 21857 stars: 21876
owner_login: jina-ai owner_login: jina-ai
owner_html_url: https://github.com/jina-ai owner_html_url: https://github.com/jina-ai
- name: HivisionIDPhotos - name: HivisionIDPhotos
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
stars: 20868 stars: 21054
owner_login: Zeyi-Lin owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin owner_html_url: https://github.com/Zeyi-Lin
- name: sqlmodel - name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel html_url: https://github.com/fastapi/sqlmodel
stars: 17770 stars: 17886
owner_login: fastapi owner_login: fastapi
owner_html_url: https://github.com/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 - name: Douyin_TikTok_Download_API
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
stars: 16878 stars: 17546
owner_login: Evil0ctal owner_login: Evil0ctal
owner_html_url: https://github.com/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 - name: SurfSense
html_url: https://github.com/MODSetter/SurfSense html_url: https://github.com/MODSetter/SurfSense
stars: 13614 stars: 14045
owner_login: MODSetter owner_login: MODSetter
owner_html_url: https://github.com/MODSetter owner_html_url: https://github.com/MODSetter
- name: machine-learning-zoomcamp - name: machine-learning-zoomcamp
html_url: https://github.com/DataTalksClub/machine-learning-zoomcamp html_url: https://github.com/DataTalksClub/machine-learning-zoomcamp
stars: 12780 stars: 13015
owner_login: DataTalksClub owner_login: DataTalksClub
owner_html_url: https://github.com/DataTalksClub owner_html_url: https://github.com/DataTalksClub
- name: fastapi_mcp - name: fastapi_mcp
html_url: https://github.com/tadata-org/fastapi_mcp html_url: https://github.com/tadata-org/fastapi_mcp
stars: 11752 stars: 11837
owner_login: tadata-org owner_login: tadata-org
owner_html_url: https://github.com/tadata-org owner_html_url: https://github.com/tadata-org
- name: awesome-fastapi - name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi html_url: https://github.com/mjhea0/awesome-fastapi
stars: 11203 stars: 11315
owner_login: mjhea0 owner_login: mjhea0
owner_html_url: https://github.com/mjhea0 owner_html_url: https://github.com/mjhea0
- name: XHS-Downloader - name: XHS-Downloader
html_url: https://github.com/JoeanAmier/XHS-Downloader html_url: https://github.com/JoeanAmier/XHS-Downloader
stars: 10612 stars: 11013
owner_login: JoeanAmier owner_login: JoeanAmier
owner_html_url: https://github.com/JoeanAmier owner_html_url: https://github.com/JoeanAmier
- name: polar - name: polar
html_url: https://github.com/polarsource/polar html_url: https://github.com/polarsource/polar
stars: 9626 stars: 9775
owner_login: polarsource owner_login: polarsource
owner_html_url: https://github.com/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 - name: FastUI
html_url: https://github.com/pydantic/FastUI html_url: https://github.com/pydantic/FastUI
stars: 8958 stars: 8961
owner_login: pydantic owner_login: pydantic
owner_html_url: https://github.com/pydantic owner_html_url: https://github.com/pydantic
- name: FileCodeBox - name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox html_url: https://github.com/vastsa/FileCodeBox
stars: 8191 stars: 8241
owner_login: vastsa owner_login: vastsa
owner_html_url: https://github.com/vastsa owner_html_url: https://github.com/vastsa
- name: nonebot2 - name: nonebot2
html_url: https://github.com/nonebot/nonebot2 html_url: https://github.com/nonebot/nonebot2
stars: 7456 stars: 7488
owner_login: nonebot owner_login: nonebot
owner_html_url: https://github.com/nonebot owner_html_url: https://github.com/nonebot
- name: hatchet - name: hatchet
html_url: https://github.com/hatchet-dev/hatchet html_url: https://github.com/hatchet-dev/hatchet
stars: 6784 stars: 7044
owner_login: hatchet-dev owner_login: hatchet-dev
owner_html_url: https://github.com/hatchet-dev owner_html_url: https://github.com/hatchet-dev
- name: fastapi-users - name: fastapi-users
html_url: https://github.com/fastapi-users/fastapi-users html_url: https://github.com/fastapi-users/fastapi-users
stars: 6064 stars: 6107
owner_login: fastapi-users owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users owner_html_url: https://github.com/fastapi-users
- name: serge - name: serge
html_url: https://github.com/serge-chat/serge html_url: https://github.com/serge-chat/serge
stars: 5738 stars: 5731
owner_login: serge-chat owner_login: serge-chat
owner_html_url: https://github.com/serge-chat owner_html_url: https://github.com/serge-chat
- name: Yuxi - name: Yuxi
html_url: https://github.com/xerrors/Yuxi html_url: https://github.com/xerrors/Yuxi
stars: 4761 stars: 5063
owner_login: xerrors owner_login: xerrors
owner_html_url: https://github.com/xerrors owner_html_url: https://github.com/xerrors
- name: Kokoro-FastAPI - name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 4649 stars: 4785
owner_login: remsky owner_login: remsky
owner_html_url: https://github.com/remsky owner_html_url: https://github.com/remsky
- name: strawberry - name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry html_url: https://github.com/strawberry-graphql/strawberry
stars: 4636 stars: 4649
owner_login: strawberry-graphql owner_login: strawberry-graphql
owner_html_url: https://github.com/strawberry-graphql owner_html_url: https://github.com/strawberry-graphql
- name: devpush - name: devpush
html_url: https://github.com/hunvreus/devpush html_url: https://github.com/hunvreus/devpush
stars: 4589 stars: 4641
owner_login: hunvreus owner_login: hunvreus
owner_html_url: https://github.com/hunvreus owner_html_url: https://github.com/hunvreus
- name: poem - name: poem
html_url: https://github.com/poem-web/poem html_url: https://github.com/poem-web/poem
stars: 4375 stars: 4387
owner_login: poem-web owner_login: poem-web
owner_html_url: https://github.com/poem-web owner_html_url: https://github.com/poem-web
- name: dynaconf - name: dynaconf
html_url: https://github.com/dynaconf/dynaconf html_url: https://github.com/dynaconf/dynaconf
stars: 4276 stars: 4291
owner_login: dynaconf owner_login: dynaconf
owner_html_url: https://github.com/dynaconf owner_html_url: https://github.com/dynaconf
- name: chatgpt-web-share - name: chatgpt-web-share
html_url: https://github.com/chatpire/chatgpt-web-share html_url: https://github.com/chatpire/chatgpt-web-share
stars: 4272 stars: 4269
owner_login: chatpire owner_login: chatpire
owner_html_url: https://github.com/chatpire owner_html_url: https://github.com/chatpire
- name: logfire - name: logfire
html_url: https://github.com/pydantic/logfire html_url: https://github.com/pydantic/logfire
stars: 4145 stars: 4206
owner_login: pydantic owner_login: pydantic
owner_html_url: https://github.com/pydantic owner_html_url: https://github.com/pydantic
- name: atrilabs-engine - name: atrilabs-engine
html_url: https://github.com/Atri-Labs/atrilabs-engine html_url: https://github.com/Atri-Labs/atrilabs-engine
stars: 4086 stars: 4080
owner_login: Atri-Labs owner_login: Atri-Labs
owner_html_url: https://github.com/Atri-Labs owner_html_url: https://github.com/Atri-Labs
- name: huma - name: huma
html_url: https://github.com/danielgtaylor/huma html_url: https://github.com/danielgtaylor/huma
stars: 3933 stars: 4043
owner_login: danielgtaylor owner_login: danielgtaylor
owner_html_url: https://github.com/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 - name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 3839 stars: 3882
owner_login: koxudaxi owner_login: koxudaxi
owner_html_url: https://github.com/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 - name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3745 stars: 3759
owner_login: fastapi-admin owner_login: fastapi-admin
owner_html_url: https://github.com/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 - name: tracecat
html_url: https://github.com/TracecatHQ/tracecat html_url: https://github.com/TracecatHQ/tracecat
stars: 3542 stars: 3564
owner_login: TracecatHQ owner_login: TracecatHQ
owner_html_url: https://github.com/TracecatHQ owner_html_url: https://github.com/TracecatHQ
- name: farfalle - name: farfalle
html_url: https://github.com/rashadphz/farfalle html_url: https://github.com/rashadphz/farfalle
stars: 3521 stars: 3530
owner_login: rashadphz owner_login: rashadphz
owner_html_url: https://github.com/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 - name: opyrator
html_url: https://github.com/ml-tooling/opyrator html_url: https://github.com/ml-tooling/opyrator
stars: 3137 stars: 3137
owner_login: ml-tooling owner_login: ml-tooling
owner_html_url: https://github.com/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 - name: docarray
html_url: https://github.com/docarray/docarray html_url: https://github.com/docarray/docarray
stars: 3120 stars: 3118
owner_login: docarray owner_login: docarray
owner_html_url: https://github.com/docarray owner_html_url: https://github.com/docarray
- name: fastapi-realworld-example-app - name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 3092 stars: 3111
owner_login: nsidnev owner_login: nsidnev
owner_html_url: https://github.com/nsidnev owner_html_url: https://github.com/nsidnev
- name: uvicorn-gunicorn-fastapi-docker - name: uvicorn-gunicorn-fastapi-docker
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
stars: 2913 stars: 2912
owner_login: tiangolo owner_login: tiangolo
owner_html_url: https://github.com/tiangolo owner_html_url: https://github.com/tiangolo
- name: FastAPI-template - name: FastAPI-template
html_url: https://github.com/s3rius/FastAPI-template html_url: https://github.com/s3rius/FastAPI-template
stars: 2768 stars: 2780
owner_login: s3rius owner_login: s3rius
owner_html_url: https://github.com/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 - name: sqladmin
html_url: https://github.com/smithyhq/sqladmin html_url: https://github.com/smithyhq/sqladmin
stars: 2696 stars: 2716
owner_login: smithyhq owner_login: smithyhq
owner_html_url: https://github.com/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 - name: YC-Killer
html_url: https://github.com/sahibzada-allahyar/YC-Killer html_url: https://github.com/sahibzada-allahyar/YC-Killer
stars: 2675 stars: 2626
owner_login: sahibzada-allahyar owner_login: sahibzada-allahyar
owner_html_url: https://github.com/sahibzada-allahyar owner_html_url: https://github.com/sahibzada-allahyar
- name: fastapi-react - name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react html_url: https://github.com/Buuntu/fastapi-react
stars: 2579 stars: 2581
owner_login: Buuntu owner_login: Buuntu
owner_html_url: https://github.com/Buuntu owner_html_url: https://github.com/Buuntu
- name: supabase-py - name: supabase-py
html_url: https://github.com/supabase/supabase-py html_url: https://github.com/supabase/supabase-py
stars: 2486 stars: 2499
owner_login: supabase owner_login: supabase
owner_html_url: https://github.com/supabase owner_html_url: https://github.com/supabase
- name: RasaGPT - name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT html_url: https://github.com/paulpierre/RasaGPT
stars: 2462 stars: 2466
owner_login: paulpierre owner_login: paulpierre
owner_html_url: https://github.com/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 - name: NoteDiscovery
html_url: https://github.com/gamosoft/NoteDiscovery html_url: https://github.com/gamosoft/NoteDiscovery
stars: 2400 stars: 2465
owner_login: gamosoft owner_login: gamosoft
owner_html_url: https://github.com/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 - name: nextpy
html_url: https://github.com/dot-agent/nextpy html_url: https://github.com/dot-agent/nextpy
stars: 2339 stars: 2336
owner_login: dot-agent owner_login: dot-agent
owner_html_url: https://github.com/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 - name: langserve
html_url: https://github.com/langchain-ai/langserve html_url: https://github.com/langchain-ai/langserve
stars: 2300 stars: 2319
owner_login: langchain-ai owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai owner_html_url: https://github.com/langchain-ai
- name: solara - name: fastapi-utils
html_url: https://github.com/widgetti/solara html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2156 stars: 2306
owner_login: widgetti owner_login: fastapiutils
owner_html_url: https://github.com/widgetti owner_html_url: https://github.com/fastapiutils
- 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-langgraph-agent-production-ready-template - name: fastapi-langgraph-agent-production-ready-template
html_url: https://github.com/wassim249/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_login: wassim249
owner_html_url: https://github.com/wassim249 owner_html_url: https://github.com/wassim249
- name: mangum - name: fastapi-best-architecture
html_url: https://github.com/Kludex/mangum html_url: https://github.com/fastapi-practices/fastapi-best-architecture
stars: 2100 stars: 2206
owner_login: Kludex owner_login: fastapi-practices
owner_html_url: https://github.com/Kludex 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 - name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 2059 stars: 2108
owner_login: mizhexiaoxiao owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao owner_html_url: https://github.com/mizhexiaoxiao
- name: agentkit - name: mangum
html_url: https://github.com/BCG-X-Official/agentkit html_url: https://github.com/Kludex/mangum
stars: 1947 stars: 2106
owner_login: BCG-X-Official owner_login: Kludex
owner_html_url: https://github.com/BCG-X-Official owner_html_url: https://github.com/Kludex
- name: slowapi - name: slowapi
html_url: https://github.com/laurentS/slowapi html_url: https://github.com/laurentS/slowapi
stars: 1946 stars: 1960
owner_login: laurentS owner_login: laurentS
owner_html_url: https://github.com/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 - name: xhs_ai_publisher
html_url: https://github.com/BetaStreetOmnis/xhs_ai_publisher html_url: https://github.com/BetaStreetOmnis/xhs_ai_publisher
stars: 1904 stars: 1948
owner_login: BetaStreetOmnis owner_login: BetaStreetOmnis
owner_html_url: https://github.com/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 - name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi html_url: https://github.com/ycd/manage-fastapi
stars: 1898 stars: 1901
owner_login: ycd owner_login: ycd
owner_html_url: https://github.com/ycd owner_html_url: https://github.com/ycd
- name: piccolo - name: piccolo
html_url: https://github.com/piccolo-orm/piccolo html_url: https://github.com/piccolo-orm/piccolo
stars: 1876 stars: 1896
owner_login: piccolo-orm owner_login: piccolo-orm
owner_html_url: https://github.com/piccolo-orm owner_html_url: https://github.com/piccolo-orm
- name: FastAPI-boilerplate - name: FastAPI-boilerplate
html_url: https://github.com/benavlabs/FastAPI-boilerplate html_url: https://github.com/benavlabs/FastAPI-boilerplate
stars: 1859 stars: 1892
owner_login: benavlabs owner_login: benavlabs
owner_html_url: https://github.com/benavlabs owner_html_url: https://github.com/benavlabs
- name: fastapi-cache - name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache html_url: https://github.com/long2ice/fastapi-cache
stars: 1853 stars: 1859
owner_login: long2ice owner_login: long2ice
owner_html_url: https://github.com/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 - name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022 html_url: https://github.com/rochacbruno/python-week-2022
stars: 1809 stars: 1810
owner_login: rochacbruno owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno owner_html_url: https://github.com/rochacbruno
- name: ormar - name: ormar
html_url: https://github.com/ormar-orm/ormar html_url: https://github.com/ormar-orm/ormar
stars: 1808 stars: 1806
owner_login: ormar-orm owner_login: ormar-orm
owner_html_url: https://github.com/ormar-orm owner_html_url: https://github.com/ormar-orm
- name: termpair - name: termpair
html_url: https://github.com/cs01/termpair html_url: https://github.com/cs01/termpair
stars: 1730 stars: 1731
owner_login: cs01 owner_login: cs01
owner_html_url: https://github.com/cs01 owner_html_url: https://github.com/cs01
- name: fastapi-crudrouter - name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1683 stars: 1687
owner_login: awtkns owner_login: awtkns
owner_html_url: https://github.com/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 - name: bracket
html_url: https://github.com/evroon/bracket html_url: https://github.com/evroon/bracket
stars: 1638 stars: 1653
owner_login: evroon owner_login: evroon
owner_html_url: https://github.com/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 - name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve html_url: https://github.com/jina-ai/langchain-serve
stars: 1634 stars: 1640
owner_login: jina-ai owner_login: jina-ai
owner_html_url: https://github.com/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 - name: awesome-fastapi-projects
html_url: https://github.com/Kludex/awesome-fastapi-projects html_url: https://github.com/Kludex/awesome-fastapi-projects
stars: 1597 stars: 1599
owner_login: Kludex owner_login: Kludex
owner_html_url: https://github.com/Kludex owner_html_url: https://github.com/Kludex
- name: coronavirus-tracker-api - name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1568 stars: 1567
owner_login: ExpDev07 owner_login: ExpDev07
owner_html_url: https://github.com/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 - name: fastapi-amis-admin
html_url: https://github.com/amisadmin/fastapi-amis-admin html_url: https://github.com/amisadmin/fastapi-amis-admin
stars: 1527 stars: 1541
owner_login: amisadmin owner_login: amisadmin
owner_html_url: https://github.com/amisadmin owner_html_url: https://github.com/amisadmin
- name: fastcrud - name: fastcrud
html_url: https://github.com/benavlabs/fastcrud html_url: https://github.com/benavlabs/fastcrud
stars: 1506 stars: 1512
owner_login: benavlabs owner_login: benavlabs
owner_html_url: https://github.com/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 - name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1482 stars: 1486
owner_login: teamhide owner_login: teamhide
owner_html_url: https://github.com/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 - name: tavily-key-generator
html_url: https://github.com/skernelx/tavily-key-generator html_url: https://github.com/skernelx/tavily-key-generator
stars: 1416 stars: 1478
owner_login: skernelx owner_login: skernelx
owner_html_url: https://github.com/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 - name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1384 stars: 1399
owner_login: liaogx owner_login: liaogx
owner_html_url: https://github.com/liaogx owner_html_url: https://github.com/liaogx
- name: fastapi-code-generator - name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1384 stars: 1383
owner_login: koxudaxi owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi owner_html_url: https://github.com/koxudaxi
- name: budgetml - name: budgetml
html_url: https://github.com/ebhy/budgetml html_url: https://github.com/ebhy/budgetml
stars: 1346 stars: 1345
owner_login: ebhy owner_login: ebhy
owner_html_url: https://github.com/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 - name: aktools
html_url: https://github.com/akfamily/aktools html_url: https://github.com/akfamily/aktools
stars: 1283 stars: 1334
owner_login: akfamily owner_login: akfamily
owner_html_url: https://github.com/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 - name: bedrock-chat
html_url: https://github.com/aws-samples/bedrock-chat html_url: https://github.com/aws-samples/bedrock-chat
stars: 1282 stars: 1288
owner_login: aws-samples owner_login: aws-samples
owner_html_url: https://github.com/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 - name: restish
html_url: https://github.com/rest-sh/restish html_url: https://github.com/rest-sh/restish
stars: 1258 stars: 1279
owner_login: rest-sh owner_login: rest-sh
owner_html_url: https://github.com/rest-sh owner_html_url: https://github.com/rest-sh
- name: RuoYi-Vue3-FastAPI - name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI html_url: https://github.com/vargasjona/fastapi-alembic-sqlmodel-async
stars: 1248 stars: 1270
owner_login: insistence owner_login: vargasjona
owner_html_url: https://github.com/insistence owner_html_url: https://github.com/vargasjona
- name: fastapi_production_template - name: fastapi_production_template
html_url: https://github.com/zhanymkanov/fastapi_production_template html_url: https://github.com/zhanymkanov/fastapi_production_template
stars: 1240 stars: 1243
owner_login: zhanymkanov owner_login: zhanymkanov
owner_html_url: https://github.com/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 - name: yubal
html_url: https://github.com/guillevc/yubal html_url: https://github.com/guillevc/yubal
stars: 1135 stars: 1203
owner_login: guillevc owner_login: guillevc
owner_html_url: https://github.com/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 url: https://github.com/nilslindemann
YuriiMotov: YuriiMotov:
login: YuriiMotov login: YuriiMotov
count: 66 count: 67
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4 avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov url: https://github.com/YuriiMotov
cassiobotaro: cassiobotaro:
@ -301,7 +301,7 @@ delhi09:
rogerbrinkmann: rogerbrinkmann:
login: rogerbrinkmann login: rogerbrinkmann
count: 20 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 url: https://github.com/rogerbrinkmann
DevDae: DevDae:
login: DevDae login: DevDae
@ -471,7 +471,7 @@ NastasiaSaby:
oandersonmagalhaes: oandersonmagalhaes:
login: oandersonmagalhaes login: oandersonmagalhaes
count: 12 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 url: https://github.com/oandersonmagalhaes
mkdir700: mkdir700:
login: mkdir700 login: mkdir700
@ -906,7 +906,7 @@ bankofsardine:
Rekl0w: Rekl0w:
login: Rekl0w login: Rekl0w
count: 6 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 url: https://github.com/Rekl0w
rsip22: rsip22:
login: rsip22 login: rsip22
@ -1276,7 +1276,7 @@ rafsaf:
frnsimoes: frnsimoes:
login: frnsimoes login: frnsimoes
count: 3 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 url: https://github.com/frnsimoes
lieryan: lieryan:
login: lieryan login: lieryan
@ -1606,7 +1606,7 @@ ayr-ton:
Kadermiyanyedi: Kadermiyanyedi:
login: Kadermiyanyedi login: Kadermiyanyedi
count: 2 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 url: https://github.com/Kadermiyanyedi
raphaelauv: raphaelauv:
login: raphaelauv login: raphaelauv

4
docs/en/data/translators.yml

@ -386,7 +386,7 @@ dukkee:
oandersonmagalhaes: oandersonmagalhaes:
login: oandersonmagalhaes login: oandersonmagalhaes
count: 2 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 url: https://github.com/oandersonmagalhaes
leandrodesouzadev: leandrodesouzadev:
login: leandrodesouzadev login: leandrodesouzadev
@ -416,7 +416,7 @@ ayr-ton:
Kadermiyanyedi: Kadermiyanyedi:
login: Kadermiyanyedi login: Kadermiyanyedi
count: 2 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 url: https://github.com/Kadermiyanyedi
KdHyeon0661: KdHyeon0661:
login: 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: 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) * [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi) * [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); border-bottom: .05rem dotted var(--md-default-fg-color--light);
cursor: help; 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

83
docs/en/docs/index.md

@ -54,18 +54,27 @@ The key features are:
### Keystone Sponsor { #keystone-sponsor } ### Keystone Sponsor { #keystone-sponsor }
<div class="fastapi-sponsors fastapi-sponsors--keystone">
{% for sponsor in 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 -%} {% 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 -%} {% 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 -%} {% endfor -%}
{%- for sponsor in sponsors.silver -%} </div>
<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
### 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 %} {% endfor %}
</div>
<!-- /sponsors --> <!-- /sponsors -->
@ -73,6 +82,44 @@ The key features are:
## Opinions { #opinions } ## 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._" "_[...] 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> <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!_" "_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%;">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._"
<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 [...]_" </div>
"_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>
---
"_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 } ## 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: 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 } ## **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() { async function main() {
setupTermynal(); setupTermynal();
showRandomAnnouncement('announce-left', 5000) showRandomAnnouncement('announce-left', 5000)
handleSponsorImages(); handleSponsorImages();
openLinksInNewTab(); openLinksInNewTab();
setupOpinionsTabs();
} }
document$.subscribe(() => { document$.subscribe(() => {
main() main()

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

@ -7,8 +7,83 @@ hide:
## Latest Changes ## 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 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 ### 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). * ⬆ 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). * 🔨 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).

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

@ -819,7 +819,7 @@ Traceback (most recent call last):
</div> </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"> <div class="termy">

1
docs/en/mkdocs.yml

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

13
docs/en/overrides/main.html

@ -10,6 +10,13 @@
</span> Join the <strong>FastAPI Cloud</strong> waiting list 🚀 </span> Join the <strong>FastAPI Cloud</strong> waiting list 🚀
</a> </a>
</div> </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"> <div class="item">
<a class="announce-link" href="https://x.com/fastapi" target="_blank"> <a class="announce-link" href="https://x.com/fastapi" target="_blank">
<span class="twemoji"> <span class="twemoji">
@ -51,12 +58,6 @@
<img class="sponsor-image" src="/img/sponsors/propelauth-banner.png" /> <img class="sponsor-image" src="/img/sponsors/propelauth-banner.png" />
</a> </a>
</div> </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"> <div class="item">
<a title="liblab - Generate SDKs from FastAPI" style="display: block; position: relative;" href="https://liblab.com?utm_source=fastapi" target="_blank"> <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> <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") * Deep Learning: Deep Learning (do not translate to "Aprendizaje Profundo")
* callback hell: callback hell (do not translate to "infierno de callbacks") * callback hell: callback hell (do not translate to "infierno de callbacks")
* tip: Consejo (do not translate to "tip") * 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") * 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") * Release Notes: Release Notes (do not translate to "Notas de la Versión")
* Semantic Versioning: Semantic Versioning (do not translate to "Versionado Semántico") * 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") * instantiate: crear un instance (do not translate to "instanciar")
* OAuth2 Scopes: Scopes de OAuth2 (do not translate to "Alcances de OAuth2") * OAuth2 Scopes: Scopes de OAuth2 (do not translate to "Alcances de OAuth2")
* on the fly: sobre la marcha (do not translate to "al vuelo") * on the fly: sobre la marcha (do not translate to "al vuelo")
* terminal: terminal (femenine, as in "la terminal") * terminal: terminal (feminine, as in "la terminal")
* terminals: terminales (plural femenine, as in "las terminales") * terminals: terminales (plural feminine, as in "las terminales")
* lifespan: lifespan (do not translate to "vida útil" or "tiempo de vida") * lifespan: lifespan (do not translate to "vida útil" or "tiempo de vida")
* unload: quitar de memoria (do not translate to "descargar") * unload: quitar de memoria (do not translate to "descargar")
* mount (noun): mount (do not translate to "montura") * 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""" """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 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 Url as Url
from .v2 import copy_field_info as copy_field_info from .v2 import copy_field_info as copy_field_info
from .v2 import create_body_model as create_body_model 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_cached_model_fields as get_cached_model_fields
from .v2 import get_definitions as get_definitions from .v2 import get_definitions as get_definitions
from .v2 import get_flat_models_from_fields as get_flat_models_from_fields 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 # Copy from Pydantic: pydantic/_internal/_typing_extra.py
WithArgsTypes: tuple[Any, ...] = ( WithArgsTypes: tuple[Any, ...] = (
typing._GenericAlias, # type: ignore[attr-defined] typing._GenericAlias, # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
types.GenericAlias, types.GenericAlias,
types.UnionType, types.UnionType,
) # pyright: ignore[reportAttributeAccessIssue] ) # pyright: ignore[reportAttributeAccessIssue]
@ -48,7 +48,7 @@ def lenient_issubclass(
cls: Any, class_or_tuple: type[_T] | tuple[type[_T], ...] | None cls: Any, class_or_tuple: type[_T] | tuple[type[_T], ...] | None
) -> TypeGuard[type[_T]]: ) -> TypeGuard[type[_T]]:
try: 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 except TypeError: # pragma: no cover
if isinstance(cls, WithArgsTypes): if isinstance(cls, WithArgsTypes):
return False 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 PydanticSchemaGenerationError as PydanticSchemaGenerationError
from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation
from pydantic import ValidationError as ValidationError 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, GetJsonSchemaHandler as GetJsonSchemaHandler,
) )
from pydantic._internal._typing_extra import eval_type_lenient # ty: ignore[deprecated]
from pydantic.fields import FieldInfo as FieldInfo from pydantic.fields import FieldInfo as FieldInfo
from pydantic.json_schema import GenerateJsonSchema as _GenerateJsonSchema from pydantic.json_schema import GenerateJsonSchema as _GenerateJsonSchema
from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
@ -38,7 +38,20 @@ from pydantic_core.core_schema import (
RequiredParam = PydanticUndefined RequiredParam = PydanticUndefined
Undefined = 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): class GenerateJsonSchema(_GenerateJsonSchema):
@ -359,8 +372,8 @@ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
continue continue
origin_type = get_origin(union_arg) or union_arg origin_type = get_origin(union_arg) or union_arg
break break
assert issubclass(origin_type, shared.sequence_types) # type: ignore[arg-type] 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] 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]: 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": {}}] "Field required", [{"type": "missing", "loc": loc, "input": {}}]
).errors(include_url=False)[0] ).errors(include_url=False)[0]
error["input"] = None error["input"] = None
return error # type: ignore[return-value] return error # type: ignore[return-value] # ty: ignore[invalid-return-type]
def create_body_model( def create_body_model(
*, fields: Sequence[ModelField], model_name: str *, fields: Sequence[ModelField], model_name: str
) -> type[BaseModel]: ) -> type[BaseModel]:
field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields} 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 return BodyModel
@ -438,7 +451,7 @@ def get_flat_models_from_annotation(
for arg in get_args(annotation): for arg in get_args(annotation):
if lenient_issubclass(arg, (BaseModel, Enum)): if lenient_issubclass(arg, (BaseModel, Enum)):
if arg not in known_models: 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): if lenient_issubclass(arg, BaseModel):
get_flat_models_from_model(arg, known_models=known_models) get_flat_models_from_model(arg, known_models=known_models)
else: else:

70
fastapi/applications.py

@ -10,11 +10,7 @@ from fastapi.exception_handlers import (
request_validation_exception_handler, request_validation_exception_handler,
websocket_request_validation_exception_handler, websocket_request_validation_exception_handler,
) )
from fastapi.exceptions import ( from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
FastAPIError,
RequestValidationError,
WebSocketRequestValidationError,
)
from fastapi.logger import logger from fastapi.logger import logger
from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware
from fastapi.openapi.docs import ( from fastapi.openapi.docs import (
@ -1010,7 +1006,7 @@ class FastAPI(Starlette):
# Starlette still has incorrect type specification for the handlers # Starlette still has incorrect type specification for the handlers
self.exception_handlers.setdefault( self.exception_handlers.setdefault(
WebSocketRequestValidationError, 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] ) # ty: ignore[no-matching-overload]
self.user_middleware: list[Middleware] = ( self.user_middleware: list[Middleware] = (
@ -1033,11 +1029,11 @@ class FastAPI(Starlette):
exception_handlers[key] = value exception_handlers[key] = value
middleware = ( middleware = (
[Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] # ty: ignore[invalid-argument-type] [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)]
+ self.user_middleware + self.user_middleware
+ [ + [
Middleware( Middleware(
ExceptionMiddleware, # ty: ignore[invalid-argument-type] ExceptionMiddleware,
handlers=exception_handlers, handlers=exception_handlers,
debug=debug, debug=debug,
), ),
@ -1060,7 +1056,7 @@ class FastAPI(Starlette):
# user middlewares, the same context is used. # user middlewares, the same context is used.
# This is currently not needed, only for closing files, but used to be # This is currently not needed, only for closing files, but used to be
# important when dependencies with yield were closed here. # 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, 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( def websocket_route(
self, path: str, name: str | None = None self, path: str, name: str | None = None
) -> Callable[[DecoratedCallable], DecoratedCallable]: ) -> Callable[[DecoratedCallable], DecoratedCallable]:
@ -4696,7 +4638,7 @@ class FastAPI(Starlette):
""" """
def decorator(func: DecoratedCallable) -> DecoratedCallable: 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 func
return decorator return decorator

2
fastapi/cli.py

@ -6,7 +6,7 @@ except ImportError: # pragma: no cover
def main() -> None: 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' message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
print(message) print(message)
raise RuntimeError(message) # noqa: B904 raise RuntimeError(message) # noqa: B904

10
fastapi/dependencies/utils.py

@ -33,7 +33,7 @@ from fastapi._compat import (
Undefined, Undefined,
copy_field_info, copy_field_info,
create_body_model, create_body_model,
evaluate_forwardref, # ty: ignore[deprecated] evaluate_forwardref,
field_annotation_is_scalar, field_annotation_is_scalar,
field_annotation_is_scalar_sequence, field_annotation_is_scalar_sequence,
field_annotation_is_sequence, field_annotation_is_sequence,
@ -100,14 +100,14 @@ def ensure_multipart_is_installed() -> None:
except (ImportError, AssertionError): except (ImportError, AssertionError):
try: try:
# __version__ is available in both multiparts, and can be mocked # __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__, __version__,
) )
assert __version__ assert __version__
try: try:
# parse_options_header is only available in the right multipart # 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, 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: def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any:
if isinstance(annotation, str): if isinstance(annotation, str):
annotation = ForwardRef(annotation) annotation = ForwardRef(annotation)
annotation = evaluate_forwardref(annotation, globalns, globalns) # ty: ignore[deprecated] annotation = evaluate_forwardref(annotation, globalns, globalns)
if annotation is type(None): if annotation is type(None):
return None return None
return annotation return annotation
@ -622,7 +622,7 @@ async def solve_dependencies(
if response is None: if response is None:
response = Response() response = Response()
del response.headers["content-length"] 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: if dependency_cache is None:
dependency_cache = {} dependency_cache = {}
for sub_dependant in dependant.dependencies: 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.exceptions import PydanticV1NotSupportedError
from fastapi.types import IncEx from fastapi.types import IncEx
from pydantic import BaseModel from pydantic import BaseModel
from pydantic.color import Color # ty: ignore[deprecated]
from pydantic.networks import AnyUrl, NameEmail from pydantic.networks import AnyUrl, NameEmail
from pydantic.types import SecretBytes, SecretStr from pydantic.types import SecretBytes, SecretStr
from pydantic_core import PydanticUndefinedType from pydantic_core import PydanticUndefinedType
@ -32,6 +31,23 @@ from ._compat import (
is_pydantic_v1_model_instance, 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 # Taken from Pydantic v1 as is
def isoformat(o: datetime.date | datetime.time) -> str: 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]] = { ENCODERS_BY_TYPE: dict[type[Any], Callable[[Any], Any]] = {
bytes: lambda o: o.decode(), bytes: lambda o: o.decode(),
Color: str, # ty: ignore[deprecated] Color: str,
PyExtraColor: str,
datetime.date: isoformat, datetime.date: isoformat,
datetime.datetime: isoformat, datetime.datetime: isoformat,
datetime.time: isoformat, datetime.time: isoformat,
@ -220,9 +237,9 @@ def jsonable_encoder(
if isinstance(obj, encoder_type): if isinstance(obj, encoder_type):
return encoder_instance(obj) return encoder_instance(obj)
if include is not None and not isinstance(include, (set, dict)): 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)): 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): if isinstance(obj, BaseModel):
obj_dict = obj.model_dump( obj_dict = obj.model_dump(
mode="json", mode="json",

4
fastapi/openapi/models.py

@ -20,7 +20,7 @@ try:
from pydantic import EmailStr from pydantic import EmailStr
except ImportError: # pragma: no cover except ImportError: # pragma: no cover
class EmailStr(str): # type: ignore # ty: ignore[unused-ignore-comment] class EmailStr(str): # type: ignore[no-redef]
@classmethod @classmethod
def __get_validators__(cls) -> Iterable[Callable[..., Any]]: def __get_validators__(cls) -> Iterable[Callable[..., Any]]:
yield cls.validate yield cls.validate
@ -215,7 +215,7 @@ class Example(TypedDict, total=False):
value: Any | None value: Any | None
externalValue: AnyUrl | 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): class ParameterInType(Enum):

2
fastapi/openapi/utils.py

@ -603,4 +603,4 @@ def get_openapi(
output["tags"] = tags output["tags"] = tags
if external_docs: if external_docs:
output["externalDocs"] = 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" cookie = "cookie"
class Param(FieldInfo): # type: ignore[misc] class Param(FieldInfo): # type: ignore[misc] # ty: ignore[subclass-of-final-class]
in_: ParamTypes in_: ParamTypes
def __init__( 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} 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: def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.default})" 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 in_ = ParamTypes.path
def __init__( 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 in_ = ParamTypes.query
def __init__( 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 in_ = ParamTypes.header
def __init__( 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 in_ = ParamTypes.cookie
def __init__( 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__( def __init__(
self, self,
default: Any = Undefined, 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} 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: def __repr__(self) -> str:
return f"{self.__class__.__name__}({self.default})" 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__( def __init__(
self, self,
default: Any = Undefined, 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__( def __init__(
self, self,
default: Any = Undefined, 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.exceptions import FastAPIDeprecationWarning
from fastapi.sse import EventSourceResponse as EventSourceResponse # noqa 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 starlette.responses import StreamingResponse as StreamingResponse # noqa
from typing_extensions import deprecated 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: try:
import ujson ujson = cast(_UjsonModule, importlib.import_module("ujson"))
except ImportError: # pragma: nocover except ModuleNotFoundError: # pragma: nocover
ujson = None # type: ignore ujson = None # type: ignore[assignment]
try: try:
import orjson orjson = cast(_OrjsonModule, importlib.import_module("orjson"))
except ImportError: # pragma: nocover except ModuleNotFoundError: # pragma: nocover
orjson = None # type: ignore orjson = None # type: ignore[assignment]
@deprecated( @deprecated(

8
fastapi/routing.py

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

50
pyproject.toml

@ -59,6 +59,7 @@ Changelog = "https://fastapi.tiangolo.com/release-notes/"
[project.optional-dependencies] [project.optional-dependencies]
standard = [ standard = [
"fastapi-cli[standard] >=0.0.8", "fastapi-cli[standard] >=0.0.8",
"fastar >= 0.9.0",
# For the test client # For the test client
"httpx >=0.23.0,<1.0.0", "httpx >=0.23.0,<1.0.0",
# For templates # For templates
@ -125,6 +126,7 @@ dev = [
{ include-group = "translations" }, { include-group = "translations" },
"playwright >=1.57.0", "playwright >=1.57.0",
"prek >=0.2.22", "prek >=0.2.22",
"zizmor >=1.23.1",
] ]
docs = [ docs = [
{ include-group = "docs-tests" }, { include-group = "docs-tests" },
@ -149,10 +151,6 @@ docs = [
docs-tests = [ docs-tests = [
"httpx >=0.23.0,<1.0.0", "httpx >=0.23.0,<1.0.0",
"ruff >=0.14.14", "ruff >=0.14.14",
# For UJSONResponse
"ujson >=5.8.0",
# For ORJSONResponse
"orjson >=3.9.3",
] ]
github-actions = [ github-actions = [
"httpx >=0.27.0,<1.0.0", "httpx >=0.27.0,<1.0.0",
@ -177,9 +175,7 @@ tests = [
"pyyaml >=5.3.1,<7.0.0", "pyyaml >=5.3.1,<7.0.0",
"sqlmodel >=0.0.31", "sqlmodel >=0.0.31",
"strawberry-graphql >=0.200.0,<1.0.0", "strawberry-graphql >=0.200.0,<1.0.0",
"ty>=0.0.9", "ty>=0.0.25",
"types-orjson >=3.6.2",
"types-ujson >=5.10.0.20240515",
"a2wsgi >=1.9.0,<=2.0.0", "a2wsgi >=1.9.0,<=2.0.0",
"pytest-xdist[psutil]>=2.5.0", "pytest-xdist[psutil]>=2.5.0",
"pytest-cov>=4.0.0", "pytest-cov>=4.0.0",
@ -339,3 +335,43 @@ keep-runtime-typing = true
[tool.inline-snapshot] [tool.inline-snapshot]
# default-flags=["fix"] # default-flags=["fix"]
# default-flags=["create"] # 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 -%} {% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a> <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %} {% endfor %}
### Gold and Silver Sponsors ### Gold Sponsors
{% for sponsor in sponsors.gold -%} {% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a> <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor -%} {% endfor %}
{%- for sponsor in sponsors.silver -%} ### Silver Sponsors
{% for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a> <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %} {% 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. 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 ### Technical terms in English
For technical terms in English that don't have a common translation term, use the original term 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): 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. - For relative URLs, only translate the link text. Do not translate the URL or its parts.
Example: Example:

96
scripts/translate.py

@ -57,39 +57,19 @@ def generate_en_path(*, lang: str, path: Path) -> Path:
return out_path return out_path
@app.command() def get_prompt(
def translate_page( lang_prompt_content: str,
*, old_translation: str | None,
language: Annotated[str, typer.Option(envvar="LANGUAGE")], language: str,
en_path: Annotated[Path, typer.Option(envvar="EN_PATH")], language_name: str,
) -> None: original_content: str,
assert language != "en", ( additional_instructions: str,
"`en` is the source language, choose another language as translation target" ) -> 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 = [ prompt_segments = [
general_prompt, general_prompt_with_additional_instructions,
lang_prompt_content, lang_prompt_content,
] ]
if old_translation: if old_translation:
@ -119,12 +99,57 @@ def translate_page(
f"%%%\n{original_content}%%%", 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 MAX_ATTEMPTS = 3
additional_instructions = ""
for attempt_no in range(1, MAX_ATTEMPTS + 1): for attempt_no in range(1, MAX_ATTEMPTS + 1):
print(f"Running agent for {out_path} (attempt {attempt_no}/{MAX_ATTEMPTS})") 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" out_content = f"{result.output.strip()}\n"
try: try:
check_translation( check_translation(
@ -139,6 +164,11 @@ def translate_page(
print( print(
f"Translation check failed on attempt {attempt_no}/{MAX_ATTEMPTS}: {e}" 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 continue # Retry if not reached max attempts
else: # Max retry attempts reached else: # Max retry attempts reached
print(f"Translation failed for {out_path} after {MAX_ATTEMPTS} attempts") 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 from typing import Any
import orjson
from fastapi import APIRouter, FastAPI from fastapi import APIRouter, FastAPI
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from tests.utils import needs_orjson
class ORJSONResponse(JSONResponse): class ORJSONResponse(JSONResponse):
media_type = "application/x-orjson" media_type = "application/x-orjson"
def render(self, content: Any) -> bytes: def render(self, content: Any) -> bytes:
import orjson
return orjson.dumps(content) return orjson.dumps(content)
@ -118,6 +121,7 @@ html_type = "text/html; charset=utf-8"
override_type = "application/x-override" override_type = "application/x-override"
@needs_orjson
def test_app(): def test_app():
with client: with client:
response = client.get("/") response = client.get("/")
@ -132,6 +136,7 @@ def test_app_override():
assert response.headers["content-type"] == text_type assert response.headers["content-type"] == text_type
@needs_orjson
def test_router_a(): def test_router_a():
with client: with client:
response = client.get("/a") response = client.get("/a")
@ -146,6 +151,7 @@ def test_router_a_override():
assert response.headers["content-type"] == text_type assert response.headers["content-type"] == text_type
@needs_orjson
def test_router_a_a(): def test_router_a_a():
with client: with client:
response = client.get("/a/a") 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 fastapi.testclient import TestClient
from pydantic import BaseModel from pydantic import BaseModel
from tests.utils import needs_orjson, needs_ujson
class Item(BaseModel): class Item(BaseModel):
name: str name: str
@ -28,6 +30,7 @@ def _make_orjson_app() -> FastAPI:
return app return app
@needs_orjson
def test_orjson_response_returns_correct_data(): def test_orjson_response_returns_correct_data():
app = _make_orjson_app() app = _make_orjson_app()
client = TestClient(app) client = TestClient(app)
@ -38,6 +41,7 @@ def test_orjson_response_returns_correct_data():
assert response.json() == {"name": "widget", "price": 9.99} assert response.json() == {"name": "widget", "price": 9.99}
@needs_orjson
def test_orjson_response_emits_deprecation_warning(): def test_orjson_response_emits_deprecation_warning():
with pytest.warns(FastAPIDeprecationWarning, match="ORJSONResponse is deprecated"): with pytest.warns(FastAPIDeprecationWarning, match="ORJSONResponse is deprecated"):
ORJSONResponse(content={"hello": "world"}) ORJSONResponse(content={"hello": "world"})
@ -58,6 +62,7 @@ def _make_ujson_app() -> FastAPI:
return app return app
@needs_ujson
def test_ujson_response_returns_correct_data(): def test_ujson_response_returns_correct_data():
app = _make_ujson_app() app = _make_ujson_app()
client = TestClient(app) client = TestClient(app)
@ -68,6 +73,7 @@ def test_ujson_response_returns_correct_data():
assert response.json() == {"name": "widget", "price": 9.99} assert response.json() == {"name": "widget", "price": 9.99}
@needs_ujson
def test_ujson_response_emits_deprecation_warning(): def test_ujson_response_emits_deprecation_warning():
with pytest.warns(FastAPIDeprecationWarning, match="UJSONResponse is deprecated"): with pytest.warns(FastAPIDeprecationWarning, match="UJSONResponse is deprecated"):
UJSONResponse(content={"hello": "world"}) 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(): def test_encode_pydantic_undefined():
data = {"value": Undefined} data = {"value": Undefined}
assert jsonable_encoder(data) == {"value": None} 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 warnings
import pytest
pytest.importorskip("orjson")
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.exceptions import FastAPIDeprecationWarning from fastapi.exceptions import FastAPIDeprecationWarning
from fastapi.responses import ORJSONResponse 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): def test_post_missing_required_field_in_user(client: TestClient):
response = client.put( response = client.put(
"/items/5", "/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.status_code == 422
assert response.json() == { assert response.json() == {
"detail": [ "detail": [
{ {
"input": {"ful_name": "John Doe"}, "input": {"full_name": "John Doe"},
"loc": [ "loc": [
"body", "body",
"user", "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( response = client.put(
"/items/5", "/items/5",
json={ json={

2
tests/test_tutorial/test_custom_response/test_tutorial001.py

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

2
tests/test_tutorial/test_custom_response/test_tutorial001b.py

@ -11,6 +11,8 @@ with warnings.catch_warnings():
client = TestClient(app) client = TestClient(app)
pytest.importorskip("orjson")
@pytest.mark.filterwarnings("ignore::fastapi.exceptions.FastAPIDeprecationWarning") @pytest.mark.filterwarnings("ignore::fastapi.exceptions.FastAPIDeprecationWarning")
def test_get_custom_response(): 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 from fastapi.testclient import TestClient
pytest.importorskip("orjson")
from docs_src.custom_response.tutorial009c_py310 import app from docs_src.custom_response.tutorial009c_py310 import app
client = TestClient(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(): 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) client = TestClient(app)
with pytest.raises(WebSocketDisconnect) as e: with pytest.raises(WebSocketDisconnect) as e:

11
tests/utils.py

@ -1,3 +1,4 @@
import importlib
import sys import sys
import pytest import pytest
@ -9,6 +10,16 @@ needs_py314 = pytest.mark.skipif(
sys.version_info < (3, 14), reason="requires python3.14+" 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") workdir_lock = pytest.mark.xdist_group("workdir_lock")

1748
uv.lock

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