diff --git a/.github/DISCUSSION_TEMPLATE/translations.yml b/.github/DISCUSSION_TEMPLATE/translations.yml
new file mode 100644
index 000000000..16e304d99
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/translations.yml
@@ -0,0 +1,45 @@
+labels: [lang-all]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for your interest in helping translate the FastAPI docs! 🌍
+
+ Please follow these instructions carefully to propose a new language translation. 🙏
+
+ This structured process helps ensure translations can be properly maintained long-term.
+ - type: checkboxes
+ id: checks
+ attributes:
+ label: Initial Checks
+ description: Please confirm and check all the following options.
+ options:
+ - label: I checked that this language is not already being translated in FastAPI docs.
+ required: true
+ - label: I searched existing discussions to ensure no one else proposed this language.
+ required: true
+ - label: I am a native speaker of the language I want to help translate.
+ required: true
+ - type: input
+ id: language
+ attributes:
+ label: Target Language
+ description: What language do you want to translate the FastAPI docs into?
+ placeholder: e.g. Latin
+ validations:
+ required: true
+ - type: textarea
+ id: additional_info
+ attributes:
+ label: Additional Information
+ description: Any other relevant information about your translation proposal
+ - type: markdown
+ attributes:
+ value: |
+ Translations are automatized with AI and then reviewed by native speakers. 🤖 🙋
+
+ This allows us to keep them consistent and up-to-date.
+
+ If there are several native speakers commenting on this discussion and
+ committing to help review new translations, the FastAPI team will review it
+ and potentially make it an official translation. 😎
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index e84e4e4ab..4b01354ed 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -21,7 +21,7 @@ jobs:
outputs:
docs: ${{ steps.filter.outputs.docs }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
# For pull requests it's not necessary to checkout the code but for the main branch it is
- uses: dorny/paths-filter@v3
id: filter
@@ -47,7 +47,7 @@ jobs:
outputs:
langs: ${{ steps.show-langs.outputs.langs }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -89,7 +89,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml
index 34b54b452..d957aa46e 100644
--- a/.github/workflows/contributors.yml
+++ b/.github/workflows/contributors.yml
@@ -24,7 +24,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
index 9ca69b208..40590793e 100644
--- a/.github/workflows/deploy-docs.yml
+++ b/.github/workflows/deploy-docs.yml
@@ -23,7 +23,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -48,7 +48,7 @@ jobs:
run: |
rm -rf ./site
mkdir ./site
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@v5
with:
path: ./site/
pattern: docs-site-*
diff --git a/.github/workflows/detect-conflicts.yml b/.github/workflows/detect-conflicts.yml
new file mode 100644
index 000000000..aba329db8
--- /dev/null
+++ b/.github/workflows/detect-conflicts.yml
@@ -0,0 +1,19 @@
+name: "Conflict detector"
+on:
+ push:
+ pull_request_target:
+ types: [synchronize]
+
+jobs:
+ main:
+ permissions:
+ contents: read
+ pull-requests: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check if PRs have merge conflicts
+ uses: eps1lon/actions-label-merge-conflict@v3
+ with:
+ dirtyLabel: "conflicts"
+ repoToken: "${{ secrets.GITHUB_TOKEN }}"
+ commentOnDirty: "This pull request has a merge conflict that needs to be resolved."
diff --git a/.github/workflows/label-approved.yml b/.github/workflows/label-approved.yml
index 908a9453d..5cd12e5d8 100644
--- a/.github/workflows/label-approved.yml
+++ b/.github/workflows/label-approved.yml
@@ -20,7 +20,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml
index b8b5c42ee..2fa832fab 100644
--- a/.github/workflows/latest-changes.yml
+++ b/.github/workflows/latest-changes.yml
@@ -24,7 +24,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
with:
# To allow latest-changes to commit to the main branch
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
@@ -34,7 +34,7 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- - uses: tiangolo/latest-changes@0.3.2
+ - uses: tiangolo/latest-changes@0.4.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
latest_changes_file: docs/en/docs/release-notes.md
diff --git a/.github/workflows/notify-translations.yml b/.github/workflows/notify-translations.yml
index 621d1253a..e5f0c3ebb 100644
--- a/.github/workflows/notify-translations.yml
+++ b/.github/workflows/notify-translations.yml
@@ -28,7 +28,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml
index 11931a05a..2e4ec1326 100644
--- a/.github/workflows/people.yml
+++ b/.github/workflows/people.yml
@@ -24,7 +24,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -51,3 +51,4 @@ jobs:
run: python ./scripts/people.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
+ SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index bf88d59b1..af4101484 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -20,7 +20,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -35,7 +35,7 @@ jobs:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
run: python -m build
- name: Publish
- uses: pypa/gh-action-pypi-publish@v1.12.4
+ uses: pypa/gh-action-pypi-publish@v1.13.0
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml
index d8a5dfb30..27f078838 100644
--- a/.github/workflows/smokeshow.yml
+++ b/.github/workflows/smokeshow.yml
@@ -21,7 +21,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: '3.9'
@@ -34,7 +34,7 @@ jobs:
requirements**.txt
pyproject.toml
- run: uv pip install -r requirements-github-actions.txt
- - uses: actions/download-artifact@v4
+ - uses: actions/download-artifact@v5
with:
name: coverage-html
path: htmlcov
diff --git a/.github/workflows/sponsors.yml b/.github/workflows/sponsors.yml
index 6da4d90e1..07153b6a9 100644
--- a/.github/workflows/sponsors.yml
+++ b/.github/workflows/sponsors.yml
@@ -24,7 +24,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/test-redistribute.yml b/.github/workflows/test-redistribute.yml
index 693f0c603..71d21ae52 100644
--- a/.github/workflows/test-redistribute.yml
+++ b/.github/workflows/test-redistribute.yml
@@ -22,7 +22,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c3940be01..620e55df3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -23,7 +23,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -61,7 +61,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
@@ -107,7 +107,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: '3.8'
@@ -122,7 +122,7 @@ jobs:
- name: Install Dependencies
run: uv pip install -r requirements-tests.txt
- name: Get coverage files
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v5
with:
pattern: coverage-*
path: coverage
diff --git a/.github/workflows/topic-repos.yml b/.github/workflows/topic-repos.yml
index 433aeb00b..9e953010d 100644
--- a/.github/workflows/topic-repos.yml
+++ b/.github/workflows/topic-repos.yml
@@ -19,7 +19,7 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml
new file mode 100644
index 000000000..b7c3efe13
--- /dev/null
+++ b/.github/workflows/translate.yml
@@ -0,0 +1,77 @@
+name: Translate
+
+on:
+ workflow_dispatch:
+ inputs:
+ debug_enabled:
+ description: Run with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
+ required: false
+ default: "false"
+ command:
+ description: Command to run
+ type: choice
+ options:
+ - translate-page
+ - translate-lang
+ - update-outdated
+ - add-missing
+ - update-and-add
+ - remove-all-removable
+ language:
+ description: Language to translate to as a letter code (e.g. "es" for Spanish)
+ type: string
+ required: false
+ default: ""
+ en_path:
+ description: File path in English to translate (e.g. docs/en/docs/index.md)
+ type: string
+ required: false
+ default: ""
+
+env:
+ UV_SYSTEM_PYTHON: 1
+
+jobs:
+ job:
+ if: github.repository_owner == 'fastapi'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Dump GitHub context
+ env:
+ GITHUB_CONTEXT: ${{ toJson(github) }}
+ run: echo "$GITHUB_CONTEXT"
+ - uses: actions/checkout@v5
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.11"
+ - name: Setup uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ version: "0.4.15"
+ enable-cache: true
+ cache-dependency-glob: |
+ requirements**.txt
+ pyproject.toml
+ - name: Install Dependencies
+ run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
+ # Allow debugging with tmate
+ - name: Setup tmate session
+ uses: mxschmitt/action-tmate@v3
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
+ with:
+ limit-access-to-actor: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ - name: FastAPI Translate
+ run: |
+ python ./scripts/translate.py ${{ github.event.inputs.command }}
+ python ./scripts/translate.py make-pr
+ env:
+ GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ LANGUAGE: ${{ github.event.inputs.language }}
+ EN_PATH: ${{ github.event.inputs.en_path }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 673c86127..cb701e151 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,7 +4,7 @@ default_language_version:
python: python3.10
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v5.0.0
+ rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-toml
@@ -14,7 +14,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.12.1
+ rev: v0.12.12
hooks:
- id: ruff
args:
diff --git a/README.md b/README.md
index ab5143084..6f13f9eae 100644
--- a/README.md
+++ b/README.md
@@ -42,12 +42,11 @@ The key features are:
* estimation based on tests on an internal development team, building production applications.
-## Sponsors
+## Sponsors { #sponsors }
-
@@ -55,7 +54,8 @@ The key features are:
-
+
+
@@ -67,7 +67,7 @@ The key features are:
Other sponsors
-## Opinions
+## Opinions { #opinions }
"_[...] 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._"
@@ -89,7 +89,7 @@ The key features are:
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
-
jinja2 - Required if you want to use the default template configuration.
* python-multipart - Required if you want to support form "parsing", with `request.form()`.
-Used by FastAPI / Starlette:
+Used by FastAPI:
* uvicorn - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
-* `fastapi-cli` - to provide the `fastapi` command.
+* `fastapi-cli[standard]` - to provide the `fastapi` command.
+ * This includes `fastapi-cloud-cli`, which allows you to deploy your FastAPI application to FastAPI Cloud.
-### Without `standard` Dependencies
+### Without `standard` Dependencies { #without-standard-dependencies }
If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
-### Additional Optional Dependencies
+### Without `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
+
+If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
+
+### Additional Optional Dependencies { #additional-optional-dependencies }
There are some additional dependencies you might want to install.
@@ -493,6 +498,6 @@ Additional optional FastAPI dependencies:
* orjson - Required if you want to use `ORJSONResponse`.
* ujson - Required if you want to use `UJSONResponse`.
-## License
+## License { #license }
This project is licensed under the terms of the MIT license.
diff --git a/SECURITY.md b/SECURITY.md
index db412cf2c..87e87e0ca 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -16,7 +16,7 @@ You can learn more about [FastAPI versions and how to pin and upgrade them](http
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
-I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you.
+I (the author, [@tiangolo](https://x.com/tiangolo)) will review it thoroughly and get back to you.
## Public Discussions
diff --git a/docs/az/docs/index.md b/docs/az/docs/index.md
index fbbbce130..4e14d7060 100644
--- a/docs/az/docs/index.md
+++ b/docs/az/docs/index.md
@@ -81,7 +81,7 @@ FastAPI Python ilə API yaratmaq üçün standart Python Brian Okken - Python Bytes podcast host (ref)
+
-## Combine predefined responses and custom ones
+## Combine predefined responses and custom ones { #combine-predefined-responses-and-custom-ones }
You might want to have some predefined responses that apply to many *path operations*, but you want to combine them with custom responses needed by each *path operation*.
@@ -239,7 +239,7 @@ For example:
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
-## More information about OpenAPI responses
+## More information about OpenAPI responses { #more-information-about-openapi-responses }
To see what exactly you can include in the responses, you can check these sections in the OpenAPI specification:
diff --git a/docs/en/docs/advanced/additional-status-codes.md b/docs/en/docs/advanced/additional-status-codes.md
index 077a00488..23bcd13c3 100644
--- a/docs/en/docs/advanced/additional-status-codes.md
+++ b/docs/en/docs/advanced/additional-status-codes.md
@@ -1,10 +1,10 @@
-# Additional Status Codes
+# Additional Status Codes { #additional-status-codes }
By default, **FastAPI** will return the responses using a `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`.
It will use the default status code or the one you set in your *path operation*.
-## Additional status codes
+## Additional status codes { #additional-status-codes_1 }
If you want to return additional status codes apart from the main one, you can do that by returning a `Response` directly, like a `JSONResponse`, and set the additional status code directly.
@@ -34,7 +34,7 @@ You could also use `from starlette.responses import JSONResponse`.
///
-## OpenAPI and API docs
+## OpenAPI and API docs { #openapi-and-api-docs }
If you return additional status codes and responses directly, they won't be included in the OpenAPI schema (the API docs), because FastAPI doesn't have a way to know beforehand what you are going to return.
diff --git a/docs/en/docs/advanced/advanced-dependencies.md b/docs/en/docs/advanced/advanced-dependencies.md
index f933fd264..c71c11404 100644
--- a/docs/en/docs/advanced/advanced-dependencies.md
+++ b/docs/en/docs/advanced/advanced-dependencies.md
@@ -1,6 +1,6 @@
-# Advanced Dependencies
+# Advanced Dependencies { #advanced-dependencies }
-## Parameterized dependencies
+## Parameterized dependencies { #parameterized-dependencies }
All the dependencies we have seen are a fixed function or class.
@@ -10,7 +10,7 @@ Let's imagine that we want to have a dependency that checks if the query paramet
But we want to be able to parameterize that fixed content.
-## A "callable" instance
+## A "callable" instance { #a-callable-instance }
In Python there's a way to make an instance of a class a "callable".
@@ -22,7 +22,7 @@ To do that, we declare a method `__call__`:
In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later.
-## Parameterize the instance
+## Parameterize the instance { #parameterize-the-instance }
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
@@ -30,7 +30,7 @@ And now, we can use `__init__` to declare the parameters of the instance that we
In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.
-## Create an instance
+## Create an instance { #create-an-instance }
We could create an instance of this class with:
@@ -38,7 +38,7 @@ We could create an instance of this class with:
And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.
-## Use the instance as a dependency
+## Use the instance as a dependency { #use-the-instance-as-a-dependency }
Then, we could use this `checker` in a `Depends(checker)`, instead of `Depends(FixedContentQueryChecker)`, because the dependency is the instance, `checker`, not the class itself.
diff --git a/docs/en/docs/advanced/async-tests.md b/docs/en/docs/advanced/async-tests.md
index 8d6929222..7b6f08371 100644
--- a/docs/en/docs/advanced/async-tests.md
+++ b/docs/en/docs/advanced/async-tests.md
@@ -1,4 +1,4 @@
-# Async Tests
+# Async Tests { #async-tests }
You have already seen how to test your **FastAPI** applications using the provided `TestClient`. Up to now, you have only seen how to write synchronous tests, without using `async` functions.
@@ -6,11 +6,11 @@ Being able to use asynchronous functions in your tests could be useful, for exam
Let's look at how we can make that work.
-## pytest.mark.anyio
+## pytest.mark.anyio { #pytest-mark-anyio }
If we want to call asynchronous functions in our tests, our test functions have to be asynchronous. AnyIO provides a neat plugin for this, that allows us to specify that some test functions are to be called asynchronously.
-## HTTPX
+## HTTPX { #httpx }
Even if your **FastAPI** application uses normal `def` functions instead of `async def`, it is still an `async` application underneath.
@@ -18,7 +18,7 @@ The `TestClient` does some magic inside to call the asynchronous FastAPI applica
The `TestClient` is based on HTTPX, and luckily, we can use it directly to test the API.
-## Example
+## Example { #example }
For a simple example, let's consider a file structure similar to the one described in [Bigger Applications](../tutorial/bigger-applications.md){.internal-link target=_blank} and [Testing](../tutorial/testing.md){.internal-link target=_blank}:
@@ -38,7 +38,7 @@ The file `test_main.py` would have the tests for `main.py`, it could look like t
{* ../../docs_src/async_tests/test_main.py *}
-## Run it
+## Run it { #run-it }
You can run your tests as usual via:
@@ -52,7 +52,7 @@ $ pytest
-## In Detail
+## In Detail { #in-detail }
The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously:
@@ -88,7 +88,7 @@ If your application relies on lifespan events, the `AsyncClient` won't trigger t
///
-## Other Asynchronous Function Calls
+## Other Asynchronous Function Calls { #other-asynchronous-function-calls }
As the testing function is now asynchronous, you can now also call (and `await`) other `async` functions apart from sending requests to your FastAPI application in your tests, exactly as you would call them anywhere else in your code.
diff --git a/docs/en/docs/advanced/behind-a-proxy.md b/docs/en/docs/advanced/behind-a-proxy.md
index 1f0d0fd9f..4d19d29e0 100644
--- a/docs/en/docs/advanced/behind-a-proxy.md
+++ b/docs/en/docs/advanced/behind-a-proxy.md
@@ -1,6 +1,105 @@
-# Behind a Proxy
+# Behind a Proxy { #behind-a-proxy }
-In some situations, you might need to use a **proxy** server like Traefik or Nginx with a configuration that adds an extra path prefix that is not seen by your application.
+In many situations, you would use a **proxy** like Traefik or Nginx in front of your FastAPI app.
+
+These proxies could handle HTTPS certificates and other things.
+
+## Proxy Forwarded Headers { #proxy-forwarded-headers }
+
+A **proxy** in front of your application would normally set some headers on the fly before sending the requests to your **server** to let the server know that the request was **forwarded** by the proxy, letting it know the original (public) URL, including the domain, that it is using HTTPS, etc.
+
+The **server** program (for example **Uvicorn** via **FastAPI CLI**) is capable of interpreting these headers, and then passing that information to your application.
+
+But for security, as the server doesn't know it is behind a trusted proxy, it won't interpret those headers.
+
+/// note | Technical Details
+
+The proxy headers are:
+
+* X-Forwarded-For
+* X-Forwarded-Proto
+* X-Forwarded-Host
+
+///
+
+### Enable Proxy Forwarded Headers { #enable-proxy-forwarded-headers }
+
+You can start FastAPI CLI with the *CLI Option* `--forwarded-allow-ips` and pass the IP addresses that should be trusted to read those forwarded headers.
+
+If you set it to `--forwarded-allow-ips="*"` it would trust all the incoming IPs.
+
+If your **server** is behind a trusted **proxy** and only the proxy talks to it, this would make it accept whatever is the IP of that **proxy**.
+
+
-## Available responses
+## Available responses { #available-responses }
Here are some of the available responses.
@@ -121,7 +121,7 @@ You could also use `from starlette.responses import HTMLResponse`.
///
-### `Response`
+### `Response` { #response }
The main `Response` class, all the other responses inherit from it.
@@ -138,23 +138,23 @@ FastAPI (actually Starlette) will automatically include a Content-Length header.
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
-### `HTMLResponse`
+### `HTMLResponse` { #htmlresponse }
Takes some text or bytes and returns an HTML response, as you read above.
-### `PlainTextResponse`
+### `PlainTextResponse` { #plaintextresponse }
Takes some text or bytes and returns a plain text response.
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
-### `JSONResponse`
+### `JSONResponse` { #jsonresponse }
Takes some data and returns an `application/json` encoded response.
This is the default response used in **FastAPI**, as you read above.
-### `ORJSONResponse`
+### `ORJSONResponse` { #orjsonresponse }
A fast alternative JSON response using `orjson`, as you read above.
@@ -164,7 +164,7 @@ This requires installing `orjson` for example with `pip install orjson`.
///
-### `UJSONResponse`
+### `UJSONResponse` { #ujsonresponse }
An alternative JSON response using `ujson`.
@@ -188,7 +188,7 @@ It's possible that `ORJSONResponse` might be a faster alternative.
///
-### `RedirectResponse`
+### `RedirectResponse` { #redirectresponse }
Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.
@@ -213,13 +213,13 @@ You can also use the `status_code` parameter combined with the `response_class`
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
-### `StreamingResponse`
+### `StreamingResponse` { #streamingresponse }
Takes an async generator or a normal generator/iterator and streams the response body.
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
-#### Using `StreamingResponse` with file-like objects
+#### Using `StreamingResponse` with file-like objects { #using-streamingresponse-with-file-like-objects }
If you have a file-like object (e.g. the object returned by `open()`), you can create a generator function to iterate over that file-like object.
@@ -243,7 +243,7 @@ Notice that here as we are using standard `open()` that doesn't support `async`
///
-### `FileResponse`
+### `FileResponse` { #fileresponse }
Asynchronously streams a file as the response.
@@ -264,7 +264,7 @@ You can also use the `response_class` parameter:
In this case, you can return the file path directly from your *path operation* function.
-## Custom response class
+## Custom response class { #custom-response-class }
You can create your own custom response class, inheriting from `Response` and using it.
@@ -292,7 +292,7 @@ Now instead of returning:
Of course, you will probably find much better ways to take advantage of this than formatting JSON. 😉
-## Default response class
+## Default response class { #default-response-class }
When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default.
@@ -308,6 +308,6 @@ You can still override `response_class` in *path operations* as before.
///
-## Additional documentation
+## Additional documentation { #additional-documentation }
You can also declare the media type and many other details in OpenAPI using `responses`: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.
diff --git a/docs/en/docs/advanced/dataclasses.md b/docs/en/docs/advanced/dataclasses.md
index 2936c6d5d..b7b9b65c5 100644
--- a/docs/en/docs/advanced/dataclasses.md
+++ b/docs/en/docs/advanced/dataclasses.md
@@ -1,4 +1,4 @@
-# Using Dataclasses
+# Using Dataclasses { #using-dataclasses }
FastAPI is built on top of **Pydantic**, and I have been showing you how to use Pydantic models to declare requests and responses.
@@ -28,7 +28,7 @@ But if you have a bunch of dataclasses laying around, this is a nice trick to us
///
-## Dataclasses in `response_model`
+## Dataclasses in `response_model` { #dataclasses-in-response-model }
You can also use `dataclasses` in the `response_model` parameter:
@@ -40,7 +40,7 @@ This way, its schema will show up in the API docs user interface:
-## Dataclasses in Nested Data Structures
+## Dataclasses in Nested Data Structures { #dataclasses-in-nested-data-structures }
You can also combine `dataclasses` with other type annotations to make nested data structures.
@@ -84,12 +84,12 @@ You can combine `dataclasses` with other type annotations in many different comb
Check the in-code annotation tips above to see more specific details.
-## Learn More
+## Learn More { #learn-more }
You can also combine `dataclasses` with other Pydantic models, inherit from them, include them in your own models, etc.
To learn more, check the Pydantic docs about dataclasses.
-## Version
+## Version { #version }
This is available since FastAPI version `0.67.0`. 🔖
diff --git a/docs/en/docs/advanced/events.md b/docs/en/docs/advanced/events.md
index 19465d891..c805e81ee 100644
--- a/docs/en/docs/advanced/events.md
+++ b/docs/en/docs/advanced/events.md
@@ -1,4 +1,4 @@
-# Lifespan Events
+# Lifespan Events { #lifespan-events }
You can define logic (code) that should be executed before the application **starts up**. This means that this code will be executed **once**, **before** the application **starts receiving requests**.
@@ -8,7 +8,7 @@ Because this code is executed before the application **starts** taking requests,
This can be very useful for setting up **resources** that you need to use for the whole app, and that are **shared** among requests, and/or that you need to **clean up** afterwards. For example, a database connection pool, or loading a shared machine learning model.
-## Use Case
+## Use Case { #use-case }
Let's start with an example **use case** and then see how to solve it with this.
@@ -22,7 +22,7 @@ You could load it at the top level of the module/file, but that would also mean
That's what we'll solve, let's load the model before the requests are handled, but only right before the application starts receiving requests, not while the code is being loaded.
-## Lifespan
+## Lifespan { #lifespan }
You can define this *startup* and *shutdown* logic using the `lifespan` parameter of the `FastAPI` app, and a "context manager" (I'll show you what that is in a second).
@@ -44,7 +44,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷
///
-### Lifespan function
+### Lifespan function { #lifespan-function }
The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
@@ -54,7 +54,7 @@ The first part of the function, before the `yield`, will be executed **before**
And the part after the `yield` will be executed **after** the application has finished.
-### Async Context Manager
+### Async Context Manager { #async-context-manager }
If you check, the function is decorated with an `@asynccontextmanager`.
@@ -84,7 +84,7 @@ The `lifespan` parameter of the `FastAPI` app takes an **async context manager**
{* ../../docs_src/events/tutorial003.py hl[22] *}
-## Alternative Events (deprecated)
+## Alternative Events (deprecated) { #alternative-events-deprecated }
/// warning
@@ -100,7 +100,7 @@ You can define event handlers (functions) that need to be executed before the ap
These functions can be declared with `async def` or normal `def`.
-### `startup` event
+### `startup` event { #startup-event }
To add a function that should be run before the application starts, declare it with the event `"startup"`:
@@ -112,7 +112,7 @@ You can add more than one event handler function.
And your application won't start receiving requests until all the `startup` event handlers have completed.
-### `shutdown` event
+### `shutdown` event { #shutdown-event }
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
@@ -138,7 +138,7 @@ So, we declare the event handler function with standard `def` instead of `async
///
-### `startup` and `shutdown` together
+### `startup` and `shutdown` together { #startup-and-shutdown-together }
There's a high chance that the logic for your *startup* and *shutdown* is connected, you might want to start something and then finish it, acquire a resource and then release it, etc.
@@ -146,7 +146,7 @@ Doing that in separated functions that don't share logic or variables together i
Because of that, it's now recommended to instead use the `lifespan` as explained above.
-## Technical Details
+## Technical Details { #technical-details }
Just a technical detail for the curious nerds. 🤓
@@ -160,6 +160,6 @@ Including how to handle lifespan state that can be used in other areas of your c
///
-## Sub Applications
+## Sub Applications { #sub-applications }
🚨 Keep in mind that these lifespan events (startup and shutdown) will only be executed for the main application, not for [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}.
diff --git a/docs/en/docs/advanced/generate-clients.md b/docs/en/docs/advanced/generate-clients.md
index 55e6a08b1..897c30808 100644
--- a/docs/en/docs/advanced/generate-clients.md
+++ b/docs/en/docs/advanced/generate-clients.md
@@ -1,34 +1,42 @@
-# Generate Clients
+# Generating SDKs { #generating-sdks }
-As **FastAPI** is based on the OpenAPI specification, you get automatic compatibility with many tools, including the automatic API docs (provided by Swagger UI).
+Because **FastAPI** is based on the **OpenAPI** specification, its APIs can be described in a standard format that many tools understand.
-One particular advantage that is not necessarily obvious is that you can **generate clients** (sometimes called **SDKs** ) for your API, for many different **programming languages**.
+This makes it easy to generate up-to-date **documentation**, client libraries (**SDKs**) in multiple languages, and **testing** or **automation workflows** that stay in sync with your code.
-## OpenAPI Client Generators
+In this guide, you'll learn how to generate a **TypeScript SDK** for your FastAPI backend.
-There are many tools to generate clients from **OpenAPI**.
+## Open Source SDK Generators { #open-source-sdk-generators }
-A common tool is OpenAPI Generator.
+A versatile option is the OpenAPI Generator, which supports **many programming languages** and can generate SDKs from your OpenAPI specification.
-If you are building a **frontend**, a very interesting alternative is openapi-ts.
+For **TypeScript clients**, Hey API is a purpose-built solution, providing an optimized experience for the TypeScript ecosystem.
-## Client and SDK Generators - Sponsor
+You can discover more SDK generators on OpenAPI.Tools.
-There are also some **company-backed** Client and SDK generators based on OpenAPI (FastAPI), in some cases they can offer you **additional features** on top of high-quality generated SDKs/clients.
+/// tip
-Some of them also ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**.
+FastAPI automatically generates **OpenAPI 3.1** specifications, so any tool you use must support this version.
-And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
+///
+
+## SDK Generators from FastAPI Sponsors { #sdk-generators-from-fastapi-sponsors }
+
+This section highlights **venture-backed** and **company-supported** solutions from companies that sponsor FastAPI. These products provide **additional features** and **integrations** on top of high-quality generated SDKs.
+
+By ✨ [**sponsoring FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, these companies help ensure the framework and its **ecosystem** remain healthy and **sustainable**.
+
+Their sponsorship also demonstrates a strong commitment to the FastAPI **community** (you), showing that they care not only about offering a **great service** but also about supporting a **robust and thriving framework**, FastAPI. 🙇
For example, you might want to try:
* Speakeasy
-* Stainless
+* Stainless
* liblab
-There are also several other companies offering similar services that you can search and find online. 🤓
+Some of these solutions may also be open source or offer free tiers, so you can try them without a financial commitment. Other commercial SDK generators are available and can be found online. 🤓
-## Generate a TypeScript Frontend Client
+## Create a TypeScript SDK { #create-a-typescript-sdk }
Let's start with a simple FastAPI application:
@@ -36,80 +44,33 @@ Let's start with a simple FastAPI application:
Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.
-### API Docs
+### API Docs { #api-docs }
-If you go to the API docs, you will see that it has the **schemas** for the data to be sent in requests and received in responses:
+If you go to `/docs`, you will see that it has the **schemas** for the data to be sent in requests and received in responses:
You can see those schemas because they were declared with the models in the app.
-That information is available in the app's **OpenAPI schema**, and then shown in the API docs (by Swagger UI).
+That information is available in the app's **OpenAPI schema**, and then shown in the API docs.
-And that same information from the models that is included in OpenAPI is what can be used to **generate the client code**.
+That same information from the models that is included in OpenAPI is what can be used to **generate the client code**.
-### Generate a TypeScript Client
+### Hey API { #hey-api }
-Now that we have the app with the models, we can generate the client code for the frontend.
+Once we have a FastAPI app with the models, we can use Hey API to generate a TypeScript client. The fastest way to do that is via npx.
-#### Install `openapi-ts`
-
-You can install `openapi-ts` in your frontend code with:
-
-
@@ -131,30 +92,30 @@ The response object will also have autocompletion:
-## FastAPI App with Tags
+## FastAPI App with Tags { #fastapi-app-with-tags }
-In many cases your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*.
+In many cases, your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*.
For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
-### Generate a TypeScript Client with Tags
+### Generate a TypeScript Client with Tags { #generate-a-typescript-client-with-tags }
If you generate a client for a FastAPI app using tags, it will normally also separate the client code based on the tags.
-This way you will be able to have things ordered and grouped correctly for the client code:
+This way, you will be able to have things ordered and grouped correctly for the client code:
-In this case you have:
+In this case, you have:
* `ItemsService`
* `UsersService`
-### Client Method Names
+### Client Method Names { #client-method-names }
-Right now the generated method names like `createItemItemsPost` don't look very clean:
+Right now, the generated method names like `createItemItemsPost` don't look very clean:
```TypeScript
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
@@ -166,17 +127,17 @@ OpenAPI requires that each operation ID is unique across all the *path operation
But I'll show you how to improve that next. 🤓
-## Custom Operation IDs and Better Method Names
+## Custom Operation IDs and Better Method Names { #custom-operation-ids-and-better-method-names }
You can **modify** the way these operation IDs are **generated** to make them simpler and have **simpler method names** in the clients.
-In this case you will have to ensure that each operation ID is **unique** in some other way.
+In this case, you will have to ensure that each operation ID is **unique** in some other way.
For example, you could make sure that each *path operation* has a tag, and then generate the operation ID based on the **tag** and the *path operation* **name** (the function name).
-### Custom Generate Unique ID Function
+### Custom Generate Unique ID Function { #custom-generate-unique-id-function }
-FastAPI uses a **unique ID** for each *path operation*, it is used for the **operation ID** and also for the names of any needed custom models, for requests or responses.
+FastAPI uses a **unique ID** for each *path operation*, which is used for the **operation ID** and also for the names of any needed custom models, for requests or responses.
You can customize that function. It takes an `APIRoute` and outputs a string.
@@ -186,15 +147,15 @@ You can then pass that custom function to **FastAPI** as the `generate_unique_id
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
-### Generate a TypeScript Client with Custom Operation IDs
+### Generate a TypeScript Client with Custom Operation IDs { #generate-a-typescript-client-with-custom-operation-ids }
-Now if you generate the client again, you will see that it has the improved method names:
+Now, if you generate the client again, you will see that it has the improved method names:
As you see, the method names now have the tag and then the function name, now they don't include information from the URL path and the HTTP operation.
-### Preprocess the OpenAPI Specification for the Client Generator
+### Preprocess the OpenAPI Specification for the Client Generator { #preprocess-the-openapi-specification-for-the-client-generator }
The generated code still has some **duplicated information**.
@@ -202,7 +163,7 @@ We already know that this method is related to the **items** because that word i
We will probably still want to keep it for OpenAPI in general, as that will ensure that the operation IDs are **unique**.
-But for the generated client we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**.
+But for the generated client, we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**.
We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this:
@@ -218,35 +179,21 @@ We could download the OpenAPI JSON to a file `openapi.json` and then we could **
With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names.
-### Generate a TypeScript Client with the Preprocessed OpenAPI
+### Generate a TypeScript Client with the Preprocessed OpenAPI { #generate-a-typescript-client-with-the-preprocessed-openapi }
-Now as the end result is in a file `openapi.json`, you would modify the `package.json` to use that local file, for example:
+Since the end result is now in an `openapi.json` file, you need to update your input location:
-```JSON hl_lines="7"
-{
- "name": "frontend-app",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios"
- },
- "author": "",
- "license": "",
- "devDependencies": {
- "@hey-api/openapi-ts": "^0.27.38",
- "typescript": "^4.6.2"
- }
-}
+```sh
+npx @hey-api/openapi-ts -i ./openapi.json -o src/client
```
After generating the new client, you would now have **clean method names**, with all the **autocompletion**, **inline errors**, etc:
-## Benefits
+## Benefits { #benefits }
-When using the automatically generated clients you would get **autocompletion** for:
+When using the automatically generated clients, you would get **autocompletion** for:
* Methods.
* Request payloads in the body, query parameters, etc.
@@ -256,6 +203,6 @@ You would also have **inline errors** for everything.
And whenever you update the backend code, and **regenerate** the frontend, it would have any new *path operations* available as methods, the old ones removed, and any other change would be reflected on the generated code. 🤓
-This also means that if something changed it will be **reflected** on the client code automatically. And if you **build** the client it will error out if you have any **mismatch** in the data used.
+This also means that if something changed, it will be **reflected** on the client code automatically. And if you **build** the client, it will error out if you have any **mismatch** in the data used.
So, you would **detect many errors** very early in the development cycle instead of having to wait for the errors to show up to your final users in production and then trying to debug where the problem is. ✨
diff --git a/docs/en/docs/advanced/index.md b/docs/en/docs/advanced/index.md
index 47385e2c6..9355516fb 100644
--- a/docs/en/docs/advanced/index.md
+++ b/docs/en/docs/advanced/index.md
@@ -1,6 +1,6 @@
-# Advanced User Guide
+# Advanced User Guide { #advanced-user-guide }
-## Additional Features
+## Additional Features { #additional-features }
The main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} should be enough to give you a tour through all the main features of **FastAPI**.
@@ -14,7 +14,7 @@ And it's possible that for your use case, the solution is in one of them.
///
-## Read the Tutorial first
+## Read the Tutorial first { #read-the-tutorial-first }
You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank}.
diff --git a/docs/en/docs/advanced/middleware.md b/docs/en/docs/advanced/middleware.md
index 792f8cfc7..3e4c5865c 100644
--- a/docs/en/docs/advanced/middleware.md
+++ b/docs/en/docs/advanced/middleware.md
@@ -1,4 +1,4 @@
-# Advanced Middleware
+# Advanced Middleware { #advanced-middleware }
In the main tutorial you read how to add [Custom Middleware](../tutorial/middleware.md){.internal-link target=_blank} to your application.
@@ -6,7 +6,7 @@ And then you also read how to handle [CORS with the `CORSMiddleware`](../tutoria
In this section we'll see how to use other middlewares.
-## Adding ASGI middlewares
+## Adding ASGI middlewares { #adding-asgi-middlewares }
As **FastAPI** is based on Starlette and implements the ASGI specification, you can use any ASGI middleware.
@@ -39,7 +39,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
`app.add_middleware()` receives a middleware class as the first argument and any additional arguments to be passed to the middleware.
-## Integrated middlewares
+## Integrated middlewares { #integrated-middlewares }
**FastAPI** includes several middlewares for common use cases, we'll see next how to use them.
@@ -51,7 +51,7 @@ For the next examples, you could also use `from starlette.middleware.something i
///
-## `HTTPSRedirectMiddleware`
+## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
Enforces that all incoming requests must either be `https` or `wss`.
@@ -59,7 +59,7 @@ Any incoming request to `http` or `ws` will be redirected to the secure scheme i
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
-## `TrustedHostMiddleware`
+## `TrustedHostMiddleware` { #trustedhostmiddleware }
Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.
@@ -68,10 +68,11 @@ Enforces that all incoming requests have a correctly set `Host` header, in order
The following arguments are supported:
* `allowed_hosts` - A list of domain names that should be allowed as hostnames. Wildcard domains such as `*.example.com` are supported for matching subdomains. To allow any hostname either use `allowed_hosts=["*"]` or omit the middleware.
+* `www_redirect` - If set to True, requests to non-www versions of the allowed hosts will be redirected to their www counterparts. Defaults to `True`.
If an incoming request does not validate correctly then a `400` response will be sent.
-## `GZipMiddleware`
+## `GZipMiddleware` { #gzipmiddleware }
Handles GZip responses for any request that includes `"gzip"` in the `Accept-Encoding` header.
@@ -98,7 +99,7 @@ The example below shows middleware applied at each scope. Notice how the inner r
{* ../../docs_src/advanced_middleware/tutorial004.py *}
-## Other middlewares
+## Other middlewares { #other-middlewares }
There are many other ASGI middlewares.
diff --git a/docs/en/docs/advanced/openapi-callbacks.md b/docs/en/docs/advanced/openapi-callbacks.md
index ca9065a89..059d893c2 100644
--- a/docs/en/docs/advanced/openapi-callbacks.md
+++ b/docs/en/docs/advanced/openapi-callbacks.md
@@ -1,4 +1,4 @@
-# OpenAPI Callbacks
+# OpenAPI Callbacks { #openapi-callbacks }
You could create an API with a *path operation* that could trigger a request to an *external API* created by someone else (probably the same developer that would be *using* your API).
@@ -6,7 +6,7 @@ The process that happens when your API app calls the *external API* is named a "
In this case, you could want to document how that external API *should* look like. What *path operation* it should have, what body it should expect, what response it should return, etc.
-## An app with callbacks
+## An app with callbacks { #an-app-with-callbacks }
Let's see all this with an example.
@@ -23,7 +23,7 @@ Then your API will (let's imagine):
* Send a notification back to the API user (the external developer).
* This will be done by sending a POST request (from *your API*) to some *external API* provided by that external developer (this is the "callback").
-## The normal **FastAPI** app
+## The normal **FastAPI** app { #the-normal-fastapi-app }
Let's first see how the normal API app would look like before adding the callback.
@@ -41,7 +41,7 @@ The `callback_url` query parameter uses a Pydantic OpenAPI 3 expression (see more below) where it can use variables with parameters and parts of the original request sent to *your API*.
-### The callback path expression
+### The callback path expression { #the-callback-path-expression }
The callback *path* can have an OpenAPI 3 expression that can contain parts of the original request sent to *your API*.
@@ -163,7 +163,7 @@ Notice how the callback URL used contains the URL received as a query parameter
///
-### Add the callback router
+### Add the callback router { #add-the-callback-router }
At this point you have the *callback path operation(s)* needed (the one(s) that the *external developer* should implement in the *external API*) in the callback router you created above.
@@ -177,7 +177,7 @@ Notice that you are not passing the router itself (`invoices_callback_router`) t
///
-### Check the docs
+### Check the docs { #check-the-docs }
Now you can start your app and go to http://127.0.0.1:8000/docs.
diff --git a/docs/en/docs/advanced/openapi-webhooks.md b/docs/en/docs/advanced/openapi-webhooks.md
index 97aaa41af..416cf4b75 100644
--- a/docs/en/docs/advanced/openapi-webhooks.md
+++ b/docs/en/docs/advanced/openapi-webhooks.md
@@ -1,4 +1,4 @@
-# OpenAPI Webhooks
+# OpenAPI Webhooks { #openapi-webhooks }
There are cases where you want to tell your API **users** that your app could call *their* app (sending a request) with some data, normally to **notify** of some type of **event**.
@@ -6,7 +6,7 @@ This means that instead of the normal process of your users sending requests to
This is normally called a **webhook**.
-## Webhooks steps
+## Webhooks steps { #webhooks-steps }
The process normally is that **you define** in your code what is the message that you will send, the **body of the request**.
@@ -16,7 +16,7 @@ And **your users** define in some way (for example in a web dashboard somewhere)
All the **logic** about how to register the URLs for webhooks and the code to actually send those requests is up to you. You write it however you want to in **your own code**.
-## Documenting webhooks with **FastAPI** and OpenAPI
+## Documenting webhooks with **FastAPI** and OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
With **FastAPI**, using OpenAPI, you can define the names of these webhooks, the types of HTTP operations that your app can send (e.g. `POST`, `PUT`, etc.) and the request **bodies** that your app would send.
@@ -28,7 +28,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0`
///
-## An app with webhooks
+## An app with webhooks { #an-app-with-webhooks }
When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`.
@@ -46,7 +46,7 @@ Notice that with webhooks you are actually not declaring a *path* (like `/items/
This is because it is expected that **your users** would define the actual **URL path** where they want to receive the webhook request in some other way (e.g. a web dashboard).
-### Check the docs
+### Check the docs { #check-the-docs }
Now you can start your app and go to http://127.0.0.1:8000/docs.
diff --git a/docs/en/docs/advanced/path-operation-advanced-configuration.md b/docs/en/docs/advanced/path-operation-advanced-configuration.md
index c4814ebd2..b9961f9f3 100644
--- a/docs/en/docs/advanced/path-operation-advanced-configuration.md
+++ b/docs/en/docs/advanced/path-operation-advanced-configuration.md
@@ -1,6 +1,6 @@
-# Path Operation Advanced Configuration
+# Path Operation Advanced Configuration { #path-operation-advanced-configuration }
-## OpenAPI operationId
+## OpenAPI operationId { #openapi-operationid }
/// warning
@@ -14,7 +14,7 @@ You would have to make sure that it is unique for each operation.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
-### Using the *path operation function* name as the operationId
+### Using the *path operation function* name as the operationId { #using-the-path-operation-function-name-as-the-operationid }
If you want to use your APIs' function names as `operationId`s, you can iterate over all of them and override each *path operation's* `operation_id` using their `APIRoute.name`.
@@ -36,13 +36,13 @@ Even if they are in different modules (Python files).
///
-## Exclude from OpenAPI
+## Exclude from OpenAPI { #exclude-from-openapi }
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
-## Advanced description from docstring
+## Advanced description from docstring { #advanced-description-from-docstring }
You can limit the lines used from the docstring of a *path operation function* for OpenAPI.
@@ -52,7 +52,7 @@ It won't show up in the documentation, but other tools (such as Sphinx) will be
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
-## Additional Responses
+## Additional Responses { #additional-responses }
You probably have seen how to declare the `response_model` and `status_code` for a *path operation*.
@@ -62,7 +62,7 @@ You can also declare additional responses with their models, status codes, etc.
There's a whole chapter here in the documentation about it, you can read it at [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.
-## OpenAPI Extra
+## OpenAPI Extra { #openapi-extra }
When you declare a *path operation* in your application, **FastAPI** automatically generates the relevant metadata about that *path operation* to be included in the OpenAPI schema.
@@ -88,7 +88,7 @@ If you only need to declare additional responses, a more convenient way to do it
You can extend the OpenAPI schema for a *path operation* using the parameter `openapi_extra`.
-### OpenAPI Extensions
+### OpenAPI Extensions { #openapi-extensions }
This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
@@ -129,7 +129,7 @@ And if you see the resulting OpenAPI (at `/openapi.json` in your API), you will
}
```
-### Custom OpenAPI *path operation* schema
+### Custom OpenAPI *path operation* schema { #custom-openapi-path-operation-schema }
The dictionary in `openapi_extra` will be deeply merged with the automatically generated OpenAPI schema for the *path operation*.
@@ -145,7 +145,7 @@ In this example, we didn't declare any Pydantic model. In fact, the request body
Nevertheless, we can declare the expected schema for the request body.
-### Custom OpenAPI content type
+### Custom OpenAPI content type { #custom-openapi-content-type }
Using this same trick, you could use a Pydantic model to define the JSON Schema that is then included in the custom OpenAPI schema section for the *path operation*.
diff --git a/docs/en/docs/advanced/response-change-status-code.md b/docs/en/docs/advanced/response-change-status-code.md
index 6d3f9f3e8..912ed0f1a 100644
--- a/docs/en/docs/advanced/response-change-status-code.md
+++ b/docs/en/docs/advanced/response-change-status-code.md
@@ -1,10 +1,10 @@
-# Response - Change Status Code
+# Response - Change Status Code { #response-change-status-code }
You probably read before that you can set a default [Response Status Code](../tutorial/response-status-code.md){.internal-link target=_blank}.
But in some cases you need to return a different status code than the default.
-## Use case
+## Use case { #use-case }
For example, imagine that you want to return an HTTP status code of "OK" `200` by default.
@@ -14,7 +14,7 @@ But you still want to be able to filter and convert the data you return with a `
For those cases, you can use a `Response` parameter.
-## Use a `Response` parameter
+## Use a `Response` parameter { #use-a-response-parameter }
You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies and headers).
diff --git a/docs/en/docs/advanced/response-cookies.md b/docs/en/docs/advanced/response-cookies.md
index f6d17f35d..d8f77b56a 100644
--- a/docs/en/docs/advanced/response-cookies.md
+++ b/docs/en/docs/advanced/response-cookies.md
@@ -1,6 +1,6 @@
-# Response Cookies
+# Response Cookies { #response-cookies }
-## Use a `Response` parameter
+## Use a `Response` parameter { #use-a-response-parameter }
You can declare a parameter of type `Response` in your *path operation function*.
@@ -16,7 +16,7 @@ And if you declared a `response_model`, it will still be used to filter and conv
You can also declare the `Response` parameter in dependencies, and set cookies (and headers) in them.
-## Return a `Response` directly
+## Return a `Response` directly { #return-a-response-directly }
You can also create cookies when returning a `Response` directly in your code.
@@ -36,7 +36,7 @@ And also that you are not sending any data that should have been filtered by a `
///
-### More info
+### More info { #more-info }
/// note | Technical Details
diff --git a/docs/en/docs/advanced/response-directly.md b/docs/en/docs/advanced/response-directly.md
index 759b762b5..3197e1bd4 100644
--- a/docs/en/docs/advanced/response-directly.md
+++ b/docs/en/docs/advanced/response-directly.md
@@ -1,4 +1,4 @@
-# Return a Response Directly
+# Return a Response Directly { #return-a-response-directly }
When you create a **FastAPI** *path operation* you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc.
@@ -10,7 +10,7 @@ But you can return a `JSONResponse` directly from your *path operations*.
It might be useful, for example, to return custom headers or cookies.
-## Return a `Response`
+## Return a `Response` { #return-a-response }
In fact, you can return any `Response` or any sub-class of it.
@@ -26,7 +26,7 @@ It won't do any data conversion with Pydantic models, it won't convert the conte
This gives you a lot of flexibility. You can return any data type, override any data declaration or validation, etc.
-## Using the `jsonable_encoder` in a `Response`
+## Using the `jsonable_encoder` in a `Response` { #using-the-jsonable-encoder-in-a-response }
Because **FastAPI** doesn't make any changes to a `Response` you return, you have to make sure its contents are ready for it.
@@ -44,7 +44,7 @@ You could also use `from starlette.responses import JSONResponse`.
///
-## Returning a custom `Response`
+## Returning a custom `Response` { #returning-a-custom-response }
The example above shows all the parts you need, but it's not very useful yet, as you could have just returned the `item` directly, and **FastAPI** would put it in a `JSONResponse` for you, converting it to a `dict`, etc. All that by default.
@@ -56,7 +56,7 @@ You could put your XML content in a string, put that in a `Response`, and return
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
-## Notes
+## Notes { #notes }
When you return a `Response` directly its data is not validated, converted (serialized), or documented automatically.
diff --git a/docs/en/docs/advanced/response-headers.md b/docs/en/docs/advanced/response-headers.md
index 97e888983..98747eabd 100644
--- a/docs/en/docs/advanced/response-headers.md
+++ b/docs/en/docs/advanced/response-headers.md
@@ -1,6 +1,6 @@
-# Response Headers
+# Response Headers { #response-headers }
-## Use a `Response` parameter
+## Use a `Response` parameter { #use-a-response-parameter }
You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies).
@@ -16,7 +16,7 @@ And if you declared a `response_model`, it will still be used to filter and conv
You can also declare the `Response` parameter in dependencies, and set headers (and cookies) in them.
-## Return a `Response` directly
+## Return a `Response` directly { #return-a-response-directly }
You can also add headers when you return a `Response` directly.
@@ -34,7 +34,7 @@ And as the `Response` can be used frequently to set headers and cookies, **FastA
///
-## Custom Headers
+## Custom Headers { #custom-headers }
Keep in mind that custom proprietary headers can be added using the 'X-' prefix.
diff --git a/docs/en/docs/advanced/security/http-basic-auth.md b/docs/en/docs/advanced/security/http-basic-auth.md
index 234e2f940..01b98eeff 100644
--- a/docs/en/docs/advanced/security/http-basic-auth.md
+++ b/docs/en/docs/advanced/security/http-basic-auth.md
@@ -1,4 +1,4 @@
-# HTTP Basic Auth
+# HTTP Basic Auth { #http-basic-auth }
For the simplest cases, you can use HTTP Basic Auth.
@@ -12,7 +12,7 @@ That tells the browser to show the integrated prompt for a username and password
Then, when you type that username and password, the browser sends them in the header automatically.
-## Simple HTTP Basic Auth
+## Simple HTTP Basic Auth { #simple-http-basic-auth }
* Import `HTTPBasic` and `HTTPBasicCredentials`.
* Create a "`security` scheme" using `HTTPBasic`.
@@ -26,7 +26,7 @@ When you try to open the URL for the first time (or click the "Execute" button i
-## Check the username
+## Check the username { #check-the-username }
Here's a more complete example.
@@ -52,7 +52,7 @@ if not (credentials.username == "stanleyjobson") or not (credentials.password ==
But by using the `secrets.compare_digest()` it will be secure against a type of attacks called "timing attacks".
-### Timing Attacks
+### Timing Attacks { #timing-attacks }
But what's a "timing attack"?
@@ -80,19 +80,19 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
Python will have to compare the whole `stanleyjobso` in both `stanleyjobsox` and `stanleyjobson` before realizing that both strings are not the same. So it will take some extra microseconds to reply back "Incorrect username or password".
-#### The time to answer helps the attackers
+#### The time to answer helps the attackers { #the-time-to-answer-helps-the-attackers }
At that point, by noticing that the server took some microseconds longer to send the "Incorrect username or password" response, the attackers will know that they got _something_ right, some of the initial letters were right.
And then they can try again knowing that it's probably something more similar to `stanleyjobsox` than to `johndoe`.
-#### A "professional" attack
+#### A "professional" attack { #a-professional-attack }
Of course, the attackers would not try all this by hand, they would write a program to do it, possibly with thousands or millions of tests per second. And they would get just one extra correct letter at a time.
But doing that, in some minutes or hours the attackers would have guessed the correct username and password, with the "help" of our application, just using the time taken to answer.
-#### Fix it with `secrets.compare_digest()`
+#### Fix it with `secrets.compare_digest()` { #fix-it-with-secrets-compare-digest }
But in our code we are actually using `secrets.compare_digest()`.
@@ -100,7 +100,7 @@ In short, it will take the same time to compare `stanleyjobsox` to `stanleyjobso
That way, using `secrets.compare_digest()` in your application code, it will be safe against this whole range of security attacks.
-### Return the error
+### Return the error { #return-the-error }
After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:
diff --git a/docs/en/docs/advanced/security/index.md b/docs/en/docs/advanced/security/index.md
index edb42132e..996d716b4 100644
--- a/docs/en/docs/advanced/security/index.md
+++ b/docs/en/docs/advanced/security/index.md
@@ -1,6 +1,6 @@
-# Advanced Security
+# Advanced Security { #advanced-security }
-## Additional Features
+## Additional Features { #additional-features }
There are some extra features to handle security apart from the ones covered in the [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank}.
@@ -12,7 +12,7 @@ And it's possible that for your use case, the solution is in one of them.
///
-## Read the Tutorial first
+## Read the Tutorial first { #read-the-tutorial-first }
The next sections assume you already read the main [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank}.
diff --git a/docs/en/docs/advanced/security/oauth2-scopes.md b/docs/en/docs/advanced/security/oauth2-scopes.md
index 4cb0b39bc..67c927cd0 100644
--- a/docs/en/docs/advanced/security/oauth2-scopes.md
+++ b/docs/en/docs/advanced/security/oauth2-scopes.md
@@ -1,12 +1,12 @@
-# OAuth2 scopes
+# OAuth2 scopes { #oauth2-scopes }
You can use OAuth2 scopes directly with **FastAPI**, they are integrated to work seamlessly.
This would allow you to have a more fine-grained permission system, following the OAuth2 standard, integrated into your OpenAPI application (and the API docs).
-OAuth2 with scopes is the mechanism used by many big authentication providers, like Facebook, Google, GitHub, Microsoft, Twitter, etc. They use it to provide specific permissions to users and applications.
+OAuth2 with scopes is the mechanism used by many big authentication providers, like Facebook, Google, GitHub, Microsoft, X (Twitter), etc. They use it to provide specific permissions to users and applications.
-Every time you "log in with" Facebook, Google, GitHub, Microsoft, Twitter, that application is using OAuth2 with scopes.
+Every time you "log in with" Facebook, Google, GitHub, Microsoft, X (Twitter), that application is using OAuth2 with scopes.
In this section you will see how to manage authentication and authorization with the same OAuth2 with scopes in your **FastAPI** application.
@@ -26,7 +26,7 @@ But if you know you need it, or you are curious, keep reading.
///
-## OAuth2 scopes and OpenAPI
+## OAuth2 scopes and OpenAPI { #oauth2-scopes-and-openapi }
The OAuth2 specification defines "scopes" as a list of strings separated by spaces.
@@ -58,15 +58,15 @@ For OAuth2 they are just strings.
///
-## Global view
+## Global view { #global-view }
First, let's quickly see the parts that change from the examples in the main **Tutorial - User Guide** for [OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Now using OAuth2 scopes:
-{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:125,129:135,140,156] *}
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
Now let's review those changes step by step.
-## OAuth2 Security scheme
+## OAuth2 Security scheme { #oauth2-security-scheme }
The first change is that now we are declaring the OAuth2 security scheme with two available scopes, `me` and `items`.
@@ -82,7 +82,7 @@ This is the same mechanism used when you give permissions while logging in with
-## JWT token with scopes
+## JWT token with scopes { #jwt-token-with-scopes }
Now, modify the token *path operation* to return the scopes requested.
@@ -98,9 +98,9 @@ But in your application, for security, you should make sure you only add the sco
///
-{* ../../docs_src/security/tutorial005_an_py310.py hl[156] *}
+{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *}
-## Declare scopes in *path operations* and dependencies
+## Declare scopes in *path operations* and dependencies { #declare-scopes-in-path-operations-and-dependencies }
Now we declare that the *path operation* for `/users/me/items/` requires the scope `items`.
@@ -124,7 +124,7 @@ We are doing it here to demonstrate how **FastAPI** handles scopes declared at d
///
-{* ../../docs_src/security/tutorial005_an_py310.py hl[5,140,171] *}
+{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
/// info | Technical Details
@@ -136,7 +136,7 @@ But when you import `Query`, `Path`, `Depends`, `Security` and others from `fast
///
-## Use `SecurityScopes`
+## Use `SecurityScopes` { #use-securityscopes }
Now update the dependency `get_current_user`.
@@ -152,7 +152,7 @@ This `SecurityScopes` class is similar to `Request` (`Request` was used to get t
{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
-## Use the `scopes`
+## Use the `scopes` { #use-the-scopes }
The parameter `security_scopes` will be of type `SecurityScopes`.
@@ -166,7 +166,7 @@ In this exception, we include the scopes required (if any) as a string separated
{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}
-## Verify the `username` and data shape
+## Verify the `username` and data shape { #verify-the-username-and-data-shape }
We verify that we get a `username`, and extract the scopes.
@@ -180,17 +180,17 @@ Instead of, for example, a `dict`, or something else, as it could break the appl
We also verify that we have a user with that username, and if not, we raise that same exception we created before.
-{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:128] *}
+{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *}
-## Verify the `scopes`
+## Verify the `scopes` { #verify-the-scopes }
We now verify that all the scopes required, by this dependency and all the dependants (including *path operations*), are included in the scopes provided in the token received, otherwise raise an `HTTPException`.
For this, we use `security_scopes.scopes`, that contains a `list` with all these scopes as `str`.
-{* ../../docs_src/security/tutorial005_an_py310.py hl[129:135] *}
+{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *}
-## Dependency tree and scopes
+## Dependency tree and scopes { #dependency-tree-and-scopes }
Let's review again this dependency tree and the scopes.
@@ -223,7 +223,7 @@ All depending on the `scopes` declared in each *path operation* and each depende
///
-## More details about `SecurityScopes`
+## More details about `SecurityScopes` { #more-details-about-securityscopes }
You can use `SecurityScopes` at any point, and in multiple places, it doesn't have to be at the "root" dependency.
@@ -233,7 +233,7 @@ Because the `SecurityScopes` will have all the scopes declared by dependants, yo
They will be checked independently for each *path operation*.
-## Check it
+## Check it { #check-it }
If you open the API docs, you can authenticate and specify which scopes you want to authorize.
@@ -245,7 +245,7 @@ And if you select the scope `me` but not the scope `items`, you will be able to
That's what would happen to a third party application that tried to access one of these *path operations* with a token provided by a user, depending on how many permissions the user gave the application.
-## About third party integrations
+## About third party integrations { #about-third-party-integrations }
In this example we are using the OAuth2 "password" flow.
@@ -269,6 +269,6 @@ But in the end, they are implementing the same OAuth2 standard.
**FastAPI** includes utilities for all these OAuth2 authentication flows in `fastapi.security.oauth2`.
-## `Security` in decorator `dependencies`
+## `Security` in decorator `dependencies` { #security-in-decorator-dependencies }
The same way you can define a `list` of `Depends` in the decorator's `dependencies` parameter (as explained in [Dependencies in path operation decorators](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), you could also use `Security` with `scopes` there.
diff --git a/docs/en/docs/advanced/settings.md b/docs/en/docs/advanced/settings.md
index 1af19a045..a218c3d01 100644
--- a/docs/en/docs/advanced/settings.md
+++ b/docs/en/docs/advanced/settings.md
@@ -1,4 +1,4 @@
-# Settings and Environment Variables
+# Settings and Environment Variables { #settings-and-environment-variables }
In many cases your application could need some external settings or configurations, for example secret keys, database credentials, credentials for email services, etc.
@@ -12,17 +12,17 @@ To understand environment variables you can read [Environment Variables](../envi
///
-## Types and validation
+## Types and validation { #types-and-validation }
These environment variables can only handle text strings, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, as Linux, Windows, macOS).
That means that any value read in Python from an environment variable will be a `str`, and any conversion to a different type or any validation has to be done in code.
-## Pydantic `Settings`
+## Pydantic `Settings` { #pydantic-settings }
Fortunately, Pydantic provides a great utility to handle these settings coming from environment variables with Pydantic: Settings management.
-### Install `pydantic-settings`
+### Install `pydantic-settings` { #install-pydantic-settings }
First, make sure you create your [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and then install the `pydantic-settings` package:
@@ -52,7 +52,7 @@ In Pydantic v1 it came included with the main package. Now it is distributed as
///
-### Create the `Settings` object
+### Create the `Settings` object { #create-the-settings-object }
Import `BaseSettings` from Pydantic and create a sub-class, very much like with a Pydantic model.
@@ -88,13 +88,13 @@ Then, when you create an instance of that `Settings` class (in this case, in the
Next it will convert and validate the data. So, when you use that `settings` object, you will have data of the types you declared (e.g. `items_per_user` will be an `int`).
-### Use the `settings`
+### Use the `settings` { #use-the-settings }
Then you can use the new `settings` object in your application:
{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
-### Run the server
+### Run the server { #run-the-server }
Next, you would run the server passing the configurations as environment variables, for example you could set an `ADMIN_EMAIL` and `APP_NAME` with:
@@ -120,7 +120,7 @@ The `app_name` would be `"ChimichangApp"`.
And the `items_per_user` would keep its default value of `50`.
-## Settings in another module
+## Settings in another module { #settings-in-another-module }
You could put those settings in another module file as you saw in [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}.
@@ -138,13 +138,13 @@ You would also need a file `__init__.py` as you saw in [Bigger Applications - Mu
///
-## Settings in a dependency
+## Settings in a dependency { #settings-in-a-dependency }
In some occasions it might be useful to provide the settings from a dependency, instead of having a global object with `settings` that is used everywhere.
This could be especially useful during testing, as it's very easy to override a dependency with your own custom settings.
-### The config file
+### The config file { #the-config-file }
Coming from the previous example, your `config.py` file could look like:
@@ -152,7 +152,7 @@ Coming from the previous example, your `config.py` file could look like:
Notice that now we don't create a default instance `settings = Settings()`.
-### The main app file
+### The main app file { #the-main-app-file }
Now we create a dependency that returns a new `config.Settings()`.
@@ -170,7 +170,7 @@ And then we can require it from the *path operation function* as a dependency an
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
-### Settings and testing
+### Settings and testing { #settings-and-testing }
Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
@@ -180,7 +180,7 @@ In the dependency override we set a new value for the `admin_email` when creatin
Then we can test that it is used.
-## Reading a `.env` file
+## Reading a `.env` file { #reading-a-env-file }
If you have many settings that possibly change a lot, maybe in different environments, it might be useful to put them on a file and then read them from it as if they were environment variables.
@@ -202,7 +202,7 @@ For this to work, you need to `pip install python-dotenv`.
///
-### The `.env` file
+### The `.env` file { #the-env-file }
You could have a `.env` file with:
@@ -211,7 +211,7 @@ ADMIN_EMAIL="deadpool@example.com"
APP_NAME="ChimichangApp"
```
-### Read settings from `.env`
+### Read settings from `.env` { #read-settings-from-env }
And then update your `config.py` with:
@@ -247,7 +247,7 @@ In Pydantic version 1 the configuration was done in an internal class `Config`,
Here we define the config `env_file` inside of your Pydantic `Settings` class, and set the value to the filename with the dotenv file we want to use.
-### Creating the `Settings` only once with `lru_cache`
+### Creating the `Settings` only once with `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
Reading a file from disk is normally a costly (slow) operation, so you probably want to do it only once and then reuse the same settings object, instead of reading it for each request.
@@ -274,7 +274,7 @@ But as we are using the `@lru_cache` decorator on top, the `Settings` object wil
Then for any subsequent call of `get_settings()` in the dependencies for the next requests, instead of executing the internal code of `get_settings()` and creating a new `Settings` object, it will return the same object that was returned on the first call, again and again.
-#### `lru_cache` Technical Details
+#### `lru_cache` Technical Details { #lru-cache-technical-details }
`@lru_cache` modifies the function it decorates to return the same value that was returned the first time, instead of computing it again, executing the code of the function every time.
@@ -337,7 +337,7 @@ That way, it behaves almost as if it was just a global variable. But as it uses
`@lru_cache` is part of `functools` which is part of Python's standard library, you can read more about it in the Python docs for `@lru_cache`.
-## Recap
+## Recap { #recap }
You can use Pydantic Settings to handle the settings or configurations for your application, with all the power of Pydantic models.
diff --git a/docs/en/docs/advanced/sub-applications.md b/docs/en/docs/advanced/sub-applications.md
index 48e329fc1..fbd0e1af3 100644
--- a/docs/en/docs/advanced/sub-applications.md
+++ b/docs/en/docs/advanced/sub-applications.md
@@ -1,18 +1,18 @@
-# Sub Applications - Mounts
+# Sub Applications - Mounts { #sub-applications-mounts }
If you need to have two independent FastAPI applications, with their own independent OpenAPI and their own docs UIs, you can have a main app and "mount" one (or more) sub-application(s).
-## Mounting a **FastAPI** application
+## Mounting a **FastAPI** application { #mounting-a-fastapi-application }
"Mounting" means adding a completely "independent" application in a specific path, that then takes care of handling everything under that path, with the _path operations_ declared in that sub-application.
-### Top-level application
+### Top-level application { #top-level-application }
First, create the main, top-level, **FastAPI** application, and its *path operations*:
{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
-### Sub-application
+### Sub-application { #sub-application }
Then, create your sub-application, and its *path operations*.
@@ -20,7 +20,7 @@ This sub-application is just another standard FastAPI application, but this is t
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
-### Mount the sub-application
+### Mount the sub-application { #mount-the-sub-application }
In your top-level application, `app`, mount the sub-application, `subapi`.
@@ -28,7 +28,7 @@ In this case, it will be mounted at the path `/subapi`:
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
-### Check the automatic API docs
+### Check the automatic API docs { #check-the-automatic-api-docs }
Now, run the `fastapi` command with your file:
@@ -56,7 +56,7 @@ You will see the automatic API docs for the sub-application, including only its
If you try interacting with any of the two user interfaces, they will work correctly, because the browser will be able to talk to each specific app or sub-app.
-### Technical Details: `root_path`
+### Technical Details: `root_path` { #technical-details-root-path }
When you mount a sub-application as described above, FastAPI will take care of communicating the mount path for the sub-application using a mechanism from the ASGI specification called a `root_path`.
diff --git a/docs/en/docs/advanced/templates.md b/docs/en/docs/advanced/templates.md
index d9b0ca6f1..f41c47fe8 100644
--- a/docs/en/docs/advanced/templates.md
+++ b/docs/en/docs/advanced/templates.md
@@ -1,4 +1,4 @@
-# Templates
+# Templates { #templates }
You can use any template engine you want with **FastAPI**.
@@ -6,7 +6,7 @@ A common choice is Jinja2, the same one used by Flask and other tools.
There are utilities to configure it easily that you can use directly in your **FastAPI** application (provided by Starlette).
-## Install dependencies
+## Install dependencies { #install-dependencies }
Make sure you create a [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and install `jinja2`:
@@ -20,7 +20,7 @@ $ pip install jinja2
-## Change the Theme
+## Change the Theme { #change-the-theme }
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
@@ -34,7 +34,7 @@ That configuration would change the syntax highlighting color theme:
-## Change Default Swagger UI Parameters
+## Change Default Swagger UI Parameters { #change-default-swagger-ui-parameters }
FastAPI includes some default configuration parameters appropriate for most of the use cases.
@@ -48,11 +48,11 @@ For example, to disable `deepLinking` you could pass these settings to `swagger_
{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
-## Other Swagger UI Parameters
+## Other Swagger UI Parameters { #other-swagger-ui-parameters }
To see all the other possible configurations you can use, read the official docs for Swagger UI parameters.
-## JavaScript-only settings
+## JavaScript-only settings { #javascript-only-settings }
Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).
diff --git a/docs/en/docs/how-to/custom-docs-ui-assets.md b/docs/en/docs/how-to/custom-docs-ui-assets.md
index 9d2238e4f..b38c4ec02 100644
--- a/docs/en/docs/how-to/custom-docs-ui-assets.md
+++ b/docs/en/docs/how-to/custom-docs-ui-assets.md
@@ -1,4 +1,4 @@
-# Custom Docs UI Static Assets (Self-Hosting)
+# Custom Docs UI Static Assets (Self-Hosting) { #custom-docs-ui-static-assets-self-hosting }
The API docs use **Swagger UI** and **ReDoc**, and each of those need some JavaScript and CSS files.
@@ -6,13 +6,13 @@ By default, those files are served from a CDN, for example you want to use `https://unpkg.com/`.
This could be useful if for example you live in a country that restricts some URLs.
-### Disable the automatic docs
+### Disable the automatic docs { #disable-the-automatic-docs }
The first step is to disable the automatic docs, as by default, those use the default CDN.
@@ -20,7 +20,7 @@ To disable them, set their URLs to `None` when creating your `FastAPI` app:
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
-### Include the custom docs
+### Include the custom docs { #include-the-custom-docs }
Now you can create the *path operations* for the custom docs.
@@ -46,23 +46,23 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
///
-### Create a *path operation* to test it
+### Create a *path operation* to test it { #create-a-path-operation-to-test-it }
Now, to be able to test that everything works, create a *path operation*:
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
-### Test it
+### Test it { #test-it }
Now, you should be able to go to your docs at http://127.0.0.1:8000/docs, and reload the page, it will load those assets from the new CDN.
-## Self-hosting JavaScript and CSS for docs
+## Self-hosting JavaScript and CSS for docs { #self-hosting-javascript-and-css-for-docs }
Self-hosting the JavaScript and CSS could be useful if, for example, you need your app to keep working even while offline, without open Internet access, or in a local network.
Here you'll see how to serve those files yourself, in the same FastAPI app, and configure the docs to use them.
-### Project file structure
+### Project file structure { #project-file-structure }
Let's say your project file structure looks like this:
@@ -85,7 +85,7 @@ Your new file structure could look like this:
└── static/
```
-### Download the files
+### Download the files { #download-the-files }
Download the static files needed for the docs and put them on that `static/` directory.
@@ -113,14 +113,14 @@ After that, your file structure could look like:
└── swagger-ui.css
```
-### Serve the static files
+### Serve the static files { #serve-the-static-files }
* Import `StaticFiles`.
* "Mount" a `StaticFiles()` instance in a specific path.
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
-### Test the static files
+### Test the static files { #test-the-static-files }
Start your application and go to http://127.0.0.1:8000/static/redoc.standalone.js.
@@ -138,7 +138,7 @@ That confirms that you are being able to serve static files from your app, and t
Now we can configure the app to use those static files for the docs.
-### Disable the automatic docs for static files
+### Disable the automatic docs for static files { #disable-the-automatic-docs-for-static-files }
The same as when using a custom CDN, the first step is to disable the automatic docs, as those use the CDN by default.
@@ -146,7 +146,7 @@ To disable them, set their URLs to `None` when creating your `FastAPI` app:
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
-### Include the custom docs for static files
+### Include the custom docs for static files { #include-the-custom-docs-for-static-files }
And the same way as with a custom CDN, now you can create the *path operations* for the custom docs.
@@ -172,13 +172,13 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
///
-### Create a *path operation* to test static files
+### Create a *path operation* to test static files { #create-a-path-operation-to-test-static-files }
Now, to be able to test that everything works, create a *path operation*:
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
-### Test Static Files UI
+### Test Static Files UI { #test-static-files-ui }
Now, you should be able to disconnect your WiFi, go to your docs at http://127.0.0.1:8000/docs, and reload the page.
diff --git a/docs/en/docs/how-to/custom-request-and-route.md b/docs/en/docs/how-to/custom-request-and-route.md
index 9b4160d75..6df24a080 100644
--- a/docs/en/docs/how-to/custom-request-and-route.md
+++ b/docs/en/docs/how-to/custom-request-and-route.md
@@ -1,4 +1,4 @@
-# Custom Request and APIRoute class
+# Custom Request and APIRoute class { #custom-request-and-apiroute-class }
In some cases, you may want to override the logic used by the `Request` and `APIRoute` classes.
@@ -14,7 +14,7 @@ If you are just starting with **FastAPI** you might want to skip this section.
///
-## Use cases
+## Use cases { #use-cases }
Some use cases include:
@@ -22,13 +22,13 @@ Some use cases include:
* Decompressing gzip-compressed request bodies.
* Automatically logging all request bodies.
-## Handling custom request body encodings
+## Handling custom request body encodings { #handling-custom-request-body-encodings }
Let's see how to make use of a custom `Request` subclass to decompress gzip requests.
And an `APIRoute` subclass to use that custom request class.
-### Create a custom `GzipRequest` class
+### Create a custom `GzipRequest` class { #create-a-custom-gziprequest-class }
/// tip
@@ -44,7 +44,7 @@ That way, the same route class can handle gzip compressed or uncompressed reques
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
-### Create a custom `GzipRoute` class
+### Create a custom `GzipRoute` class { #create-a-custom-gziproute-class }
Next, we create a custom subclass of `fastapi.routing.APIRoute` that will make use of the `GzipRequest`.
@@ -78,7 +78,7 @@ After that, all of the processing logic is the same.
But because of our changes in `GzipRequest.body`, the request body will be automatically decompressed when it is loaded by **FastAPI** when needed.
-## Accessing the request body in an exception handler
+## Accessing the request body in an exception handler { #accessing-the-request-body-in-an-exception-handler }
/// tip
@@ -98,7 +98,7 @@ If an exception occurs, the`Request` instance will still be in scope, so we can
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
-## Custom `APIRoute` class in a router
+## Custom `APIRoute` class in a router { #custom-apiroute-class-in-a-router }
You can also set the `route_class` parameter of an `APIRouter`:
diff --git a/docs/en/docs/how-to/extending-openapi.md b/docs/en/docs/how-to/extending-openapi.md
index 26c742c20..5e672665e 100644
--- a/docs/en/docs/how-to/extending-openapi.md
+++ b/docs/en/docs/how-to/extending-openapi.md
@@ -1,10 +1,10 @@
-# Extending OpenAPI
+# Extending OpenAPI { #extending-openapi }
There are some cases where you might need to modify the generated OpenAPI schema.
In this section you will see how.
-## The normal process
+## The normal process { #the-normal-process }
The normal (default) process, is as follows.
@@ -33,31 +33,31 @@ The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by Fa
///
-## Overriding the defaults
+## Overriding the defaults { #overriding-the-defaults }
Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need.
For example, let's add ReDoc's OpenAPI extension to include a custom logo.
-### Normal **FastAPI**
+### Normal **FastAPI** { #normal-fastapi }
First, write all your **FastAPI** application as normally:
{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
-### Generate the OpenAPI schema
+### Generate the OpenAPI schema { #generate-the-openapi-schema }
Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
-### Modify the OpenAPI schema
+### Modify the OpenAPI schema { #modify-the-openapi-schema }
Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
-### Cache the OpenAPI schema
+### Cache the OpenAPI schema { #cache-the-openapi-schema }
You can use the property `.openapi_schema` as a "cache", to store your generated schema.
@@ -67,13 +67,13 @@ It will be generated only once, and then the same cached schema will be used for
{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
-### Override the method
+### Override the method { #override-the-method }
Now you can replace the `.openapi()` method with your new function.
{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
-### Check it
+### Check it { #check-it }
Once you go to http://127.0.0.1:8000/redoc you will see that you are using your custom logo (in this example, **FastAPI**'s logo):
diff --git a/docs/en/docs/how-to/general.md b/docs/en/docs/how-to/general.md
index 04367c6b7..934719260 100644
--- a/docs/en/docs/how-to/general.md
+++ b/docs/en/docs/how-to/general.md
@@ -1,39 +1,39 @@
-# General - How To - Recipes
+# General - How To - Recipes { #general-how-to-recipes }
Here are several pointers to other places in the docs, for general or frequent questions.
-## Filter Data - Security
+## Filter Data - Security { #filter-data-security }
To ensure that you don't return more data than you should, read the docs for [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank}.
-## Documentation Tags - OpenAPI
+## Documentation Tags - OpenAPI { #documentation-tags-openapi }
To add tags to your *path operations*, and group them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}.
-## Documentation Summary and Description - OpenAPI
+## Documentation Summary and Description - OpenAPI { #documentation-summary-and-description-openapi }
To add a summary and description to your *path operations*, and show them in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}.
-## Documentation Response description - OpenAPI
+## Documentation Response description - OpenAPI { #documentation-response-description-openapi }
To define the description of the response, shown in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}.
-## Documentation Deprecate a *Path Operation* - OpenAPI
+## Documentation Deprecate a *Path Operation* - OpenAPI { #documentation-deprecate-a-path-operation-openapi }
To deprecate a *path operation*, and show it in the docs UI, read the docs for [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}.
-## Convert any Data to JSON-compatible
+## Convert any Data to JSON-compatible { #convert-any-data-to-json-compatible }
To convert any data to JSON-compatible, read the docs for [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
-## OpenAPI Metadata - Docs
+## OpenAPI Metadata - Docs { #openapi-metadata-docs }
To add metadata to your OpenAPI schema, including a license, version, contact, etc, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank}.
-## OpenAPI Custom URL
+## OpenAPI Custom URL { #openapi-custom-url }
To customize the OpenAPI URL (or remove it), read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}.
-## OpenAPI Docs URLs
+## OpenAPI Docs URLs { #openapi-docs-urls }
To update the URLs used for the automatically generated docs user interfaces, read the docs for [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
diff --git a/docs/en/docs/how-to/graphql.md b/docs/en/docs/how-to/graphql.md
index 361010736..99b024d39 100644
--- a/docs/en/docs/how-to/graphql.md
+++ b/docs/en/docs/how-to/graphql.md
@@ -1,4 +1,4 @@
-# GraphQL
+# GraphQL { #graphql }
As **FastAPI** is based on the **ASGI** standard, it's very easy to integrate any **GraphQL** library also compatible with ASGI.
@@ -14,7 +14,7 @@ Make sure you evaluate if the **benefits** for your use case compensate the **dr
///
-## GraphQL Libraries
+## GraphQL Libraries { #graphql-libraries }
Here are some of the **GraphQL** libraries that have **ASGI** support. You could use them with **FastAPI**:
@@ -27,7 +27,7 @@ Here are some of the **GraphQL** libraries that have **ASGI** support. You could
* Graphene
* With starlette-graphene3
-## GraphQL with Strawberry
+## GraphQL with Strawberry { #graphql-with-strawberry }
If you need or want to work with **GraphQL**, **Strawberry** is the **recommended** library as it has the design closest to **FastAPI's** design, it's all based on **type annotations**.
@@ -41,7 +41,7 @@ You can learn more about Strawberry in the Strawberry with FastAPI.
-## Older `GraphQLApp` from Starlette
+## Older `GraphQLApp` from Starlette { #older-graphqlapp-from-starlette }
Previous versions of Starlette included a `GraphQLApp` class to integrate with Graphene.
@@ -53,7 +53,7 @@ If you need GraphQL, I still would recommend you check out official GraphQL documentation.
diff --git a/docs/en/docs/how-to/index.md b/docs/en/docs/how-to/index.md
index 730dce5d5..5a8ce08de 100644
--- a/docs/en/docs/how-to/index.md
+++ b/docs/en/docs/how-to/index.md
@@ -1,4 +1,4 @@
-# How To - Recipes
+# How To - Recipes { #how-to-recipes }
Here you will see different recipes or "how to" guides for **several topics**.
diff --git a/docs/en/docs/how-to/separate-openapi-schemas.md b/docs/en/docs/how-to/separate-openapi-schemas.md
index 9a27638fe..3c78a56d3 100644
--- a/docs/en/docs/how-to/separate-openapi-schemas.md
+++ b/docs/en/docs/how-to/separate-openapi-schemas.md
@@ -1,4 +1,4 @@
-# Separate OpenAPI Schemas for Input and Output or Not
+# Separate OpenAPI Schemas for Input and Output or Not { #separate-openapi-schemas-for-input-and-output-or-not }
When using **Pydantic v2**, the generated OpenAPI is a bit more exact and **correct** than before. 😎
@@ -6,13 +6,13 @@ In fact, in some cases, it will even have **two JSON Schemas** in OpenAPI for th
Let's see how that works and how to change it if you need to do that.
-## Pydantic Models for Input and Output
+## Pydantic Models for Input and Output { #pydantic-models-for-input-and-output }
Let's say you have a Pydantic model with default values, like this one:
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *}
-### Model for Input
+### Model for Input { #model-for-input }
If you use this model as an input like here:
@@ -20,7 +20,7 @@ If you use this model as an input like here:
...then the `description` field will **not be required**. Because it has a default value of `None`.
-### Input Model in Docs
+### Input Model in Docs { #input-model-in-docs }
You can confirm that in the docs, the `description` field doesn't have a **red asterisk**, it's not marked as required:
@@ -28,7 +28,7 @@ You can confirm that in the docs, the `description` field doesn't have a **red a
-### Model for Output
+### Model for Output { #model-for-output }
But if you use the same model as an output, like here:
@@ -36,7 +36,7 @@ But if you use the same model as an output, like here:
...then because `description` has a default value, if you **don't return anything** for that field, it will still have that **default value**.
-### Model for Output Response Data
+### Model for Output Response Data { #model-for-output-response-data }
If you interact with the docs and check the response, even though the code didn't add anything in one of the `description` fields, the JSON response contains the default value (`null`):
@@ -55,7 +55,7 @@ Because of that, the JSON Schema for a model can be different depending on if it
* for **input** the `description` will **not be required**
* for **output** it will be **required** (and possibly `None`, or in JSON terms, `null`)
-### Model for Output in Docs
+### Model for Output in Docs { #model-for-output-in-docs }
You can check the output model in the docs too, **both** `name` and `description` are marked as **required** with a **red asterisk**:
@@ -63,7 +63,7 @@ You can check the output model in the docs too, **both** `name` and `description
-### Model for Input and Output in Docs
+### Model for Input and Output in Docs { #model-for-input-and-output-in-docs }
And if you check all the available Schemas (JSON Schemas) in OpenAPI, you will see that there are two, one `Item-Input` and one `Item-Output`.
@@ -77,7 +77,7 @@ But for `Item-Output`, `description` is **required**, it has a red asterisk.
With this feature from **Pydantic v2**, your API documentation is more **precise**, and if you have autogenerated clients and SDKs, they will be more precise too, with a better **developer experience** and consistency. 🎉
-## Do not Separate Schemas
+## Do not Separate Schemas { #do-not-separate-schemas }
Now, there are some cases where you might want to have the **same schema for input and output**.
@@ -93,7 +93,7 @@ Support for `separate_input_output_schemas` was added in FastAPI `0.102.0`. 🤓
{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *}
-### Same Schema for Input and Output Models in Docs
+### Same Schema for Input and Output Models in Docs { #same-schema-for-input-and-output-models-in-docs }
And now there will be one single schema for input and output for the model, only `Item`, and it will have `description` as **not required**:
diff --git a/docs/en/docs/how-to/testing-database.md b/docs/en/docs/how-to/testing-database.md
index d0ed15bca..400fdcfc6 100644
--- a/docs/en/docs/how-to/testing-database.md
+++ b/docs/en/docs/how-to/testing-database.md
@@ -1,4 +1,4 @@
-# Testing a Database
+# Testing a Database { #testing-a-database }
You can study about databases, SQL, and SQLModel in the SQLModel docs. 🤓
diff --git a/docs/en/docs/img/sponsors/mobbai-banner.png b/docs/en/docs/img/sponsors/mobbai-banner.png
new file mode 100644
index 000000000..1f59294ab
Binary files /dev/null and b/docs/en/docs/img/sponsors/mobbai-banner.png differ
diff --git a/docs/en/docs/img/sponsors/mobbai.png b/docs/en/docs/img/sponsors/mobbai.png
new file mode 100644
index 000000000..b519fd885
Binary files /dev/null and b/docs/en/docs/img/sponsors/mobbai.png differ
diff --git a/docs/en/docs/img/sponsors/railway-banner.png b/docs/en/docs/img/sponsors/railway-banner.png
new file mode 100644
index 000000000..f6146a7c1
Binary files /dev/null and b/docs/en/docs/img/sponsors/railway-banner.png differ
diff --git a/docs/en/docs/img/sponsors/railway.png b/docs/en/docs/img/sponsors/railway.png
new file mode 100644
index 000000000..dc6ccacc4
Binary files /dev/null and b/docs/en/docs/img/sponsors/railway.png differ
diff --git a/docs/en/docs/img/sponsors/speakeasy.png b/docs/en/docs/img/sponsors/speakeasy.png
index 5ddc25487..7bb9c3a18 100644
Binary files a/docs/en/docs/img/sponsors/speakeasy.png and b/docs/en/docs/img/sponsors/speakeasy.png differ
diff --git a/docs/en/docs/index.md b/docs/en/docs/index.md
index 0f3623ed5..aaadf3cc2 100644
--- a/docs/en/docs/index.md
+++ b/docs/en/docs/index.md
@@ -1,4 +1,4 @@
-# FastAPI
+# FastAPI { #fastapi }