* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbrtitle="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Intuitive**: Great editor support. <dfntitle="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* Automatic and clear errors when the data is invalid.
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* Validation even for deeply nested JSON objects.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* JSON.
* Path parameters.
* Path parameters.
* Query parameters.
* Query parameters.
@ -385,7 +379,7 @@ item: Item
* Headers.
* Headers.
* Forms.
* Forms.
* Files.
* Files.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
@ -448,7 +442,7 @@ For a more complete example including more features, see the <a href="https://fa
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbrtitle="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* A very powerful and easy to use **<dfntitle="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <ahref="https://strawberry.rocks"class="external-link"target="_blank">Strawberry</a> and other libraries.
* **GraphQL** integration with <ahref="https://strawberry.rocks"class="external-link"target="_blank">Strawberry</a> and other libraries.
@ -533,7 +527,7 @@ Used by Starlette:
* <ahref="https://www.python-httpx.org"target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <ahref="https://www.python-httpx.org"target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <ahref="https://jinja.palletsprojects.com"target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <ahref="https://jinja.palletsprojects.com"target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbrtitle="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfntitle="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
@ -35,7 +35,7 @@ Siehe Abschnitt `### Content of code snippets` im allgemeinen Prompt in `scripts
//// tab | Test
//// tab | Test
Gestern schrieb mein Freund: „Wenn man unkorrekt korrekt schreibt, hat man es unkorrekt geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚unkorrekt‘ ist unkorrekterweise nicht ‚„unkorrekt“‘“.
Gestern schrieb mein Freund: „Wenn man ‚incorrectly‘ korrekt schreibt, hat man es falsch geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚incorrectly‘ ist inkorrekterweise nicht ‚„incorrectly“‘“.
/// note | Hinweis
/// note | Hinweis
@ -202,11 +202,6 @@ Hier einige Dinge, die in HTML-„abbr“-Elemente gepackt sind (einige sind erf
### Das abbr gibt eine Erklärung { #the-abbr-gives-an-explanation }
* <abbrtitle="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</abbr>
* <abbrtitle="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</abbr>
### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation }
### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbrtitle="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
* <abbrtitle="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
@ -224,6 +219,11 @@ Siehe Abschnitt `### HTML abbr elements` im allgemeinen Prompt in `scripts/trans
////
////
## HTML „dfn“-Elemente { #html-dfn-elements }
* <dfntitle="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
* <dfntitle="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</dfn>
## Überschriften { #headings }
## Überschriften { #headings }
//// tab | Test
//// tab | Test
@ -248,7 +248,7 @@ Die einzige strenge Regel für Überschriften ist, dass das LLM den Hash-Teil in
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
Für einige sprachsspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
# Body – Mehrere Parameter { #body-multiple-parameters }
# Body – Mehrere Parameter { #body-multiple-parameters }
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbrtitle="Anfragekörper">Requestbody</abbr>-Deklarationen an.
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbrtitle="Requestbody">Requestbody</abbr>-Deklarationen an.
## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters }
## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters }
@ -101,13 +101,13 @@ Natürlich können Sie auch, wann immer Sie das brauchen, weitere Query-Paramete
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben:
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben:
@ -202,11 +202,6 @@ Here some things wrapped in HTML "abbr" elements (Some are invented):
* <abbrtitle="XML Web Token">XWT</abbr>
* <abbrtitle="XML Web Token">XWT</abbr>
* <abbrtitle="Parallel Server Gateway Interface">PSGI</abbr>
* <abbrtitle="Parallel Server Gateway Interface">PSGI</abbr>
### The abbr gives an explanation { #the-abbr-gives-an-explanation }
* <abbrtitle="A group of machines that are configured to be connected and work together in some way.">cluster</abbr>
* <abbrtitle="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</abbr>
### The abbr gives a full phrase and an explanation { #the-abbr-gives-a-full-phrase-and-an-explanation }
### The abbr gives a full phrase and an explanation { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbrtitle="Mozilla Developer Network: documentation for developers, written by the Firefox people">MDN</abbr>
* <abbrtitle="Mozilla Developer Network: documentation for developers, written by the Firefox people">MDN</abbr>
@ -224,6 +219,11 @@ See section `### HTML abbr elements` in the general prompt in `scripts/translate
////
////
## HTML "dfn" elements { #html-dfn-elements }
* <dfntitle="A group of machines that are configured to be connected and work together in some way.">cluster</dfn>
* <dfntitle="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</dfn>
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.
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.
@ -26,7 +26,7 @@ In this case, this `__call__` is what **FastAPI** will use to check for addition
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
Here are some additional ideas that might be useful when working with Python types.
## Using `Union` or `Optional` { #using-union-or-optional }
If your code for some reason can't use `|`, for example if it's not in a type annotation but in something like `response_model=`, instead of using the vertical bar (`|`) you can use `Union` from `typing`.
For example, you could declare that something could be a `str` or `None`:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing` also has a shortcut to declare that something could be `None`, with `Optional`.
Here's a tip from my very **subjective** point of view:
* 🚨 Avoid using `Optional[SomeType]`
* Instead ✨ **use `Union[SomeType, None]`** ✨.
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
I think `Union[SomeType, None]` is more explicit about what it means.
It's just about the words and names. But those words can affect how you and your teammates think about the code.
As an example, let's take this function:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:
```Python
say_hi() # Oh, no, this throws an error! 😱
```
The `name` parameter is **still required** (not *optional*) because it doesn't have a default value. Still, `name` accepts `None` as the value:
```Python
say_hi(name=None) # This works, None is valid 🎉
```
The good news is, in most cases, you will be able to simply use `|` to define unions of types:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
So, normally you don't have to worry about names like `Optional` and `Union`. 😎
And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.
And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.
@ -193,7 +193,7 @@ You can get the current `root_path` used by your application for each request, i
Here we are including it in the message just for demonstration purposes.
Here we are including it in the message just for demonstration purposes.
@ -220,7 +220,7 @@ The response would be something like:
Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app:
Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app:
@ -30,7 +30,7 @@ This is because by default, FastAPI will inspect every item inside and make sure
But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class.
But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class.
In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
@ -136,7 +136,7 @@ It accepts the following parameters:
FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types.
FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types.
1. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
1. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
@ -256,11 +256,11 @@ Takes a different set of arguments to instantiate than the other response types:
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
In this case, you can return the file path directly from your *path operation* function.
In this case, you can return the file path directly from your *path operation* function.
@ -274,7 +274,7 @@ Let's say you want it to return indented and formatted JSON, so you want to use
You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`:
You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`:
Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.
Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.
@ -48,7 +48,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷
The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
@ -32,7 +32,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0`
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()`.
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()`.
@ -40,7 +40,7 @@ Even if they are in different modules (Python files).
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`:
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`:
## Advanced description from docstring { #advanced-description-from-docstring }
## Advanced description from docstring { #advanced-description-from-docstring }
@ -92,7 +92,7 @@ You can extend the OpenAPI schema for a *path operation* using the parameter `op
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):
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):
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <abbrtitle="converted from some plain format, like bytes, into Python objects">parsed</abbr> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <dfntitle="converted from some plain format, like bytes, into Python objects">parsed</dfn> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
Nevertheless, we can declare the expected schema for the request body.
Nevertheless, we can declare the expected schema for the request body.
@ -153,7 +153,7 @@ And you could do this even if the data type in the request is not JSON.
For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:
For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:
Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.
Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.
@ -161,7 +161,7 @@ Then we use the request directly, and extract the body as `bytes`. This means th
And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:
And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@ -22,7 +22,7 @@ You can also add headers when you return a `Response` directly.
Create a response as described in [Return a Response Directly](response-directly.md){.internal-link target=_blank} and pass the headers as an additional parameter:
Create a response as described in [Return a Response Directly](response-directly.md){.internal-link target=_blank} and pass the headers as an additional parameter:
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
@ -40,7 +40,7 @@ To handle that, we first convert the `username` and `password` to `bytes` encodi
Then we can use `secrets.compare_digest()` to ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`.
Then we can use `secrets.compare_digest()` to ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`.
@ -104,4 +104,4 @@ That way, using `secrets.compare_digest()` in your application code, it will be
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:
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:
@ -54,7 +54,7 @@ The same way as with Pydantic models, you declare class attributes with type ann
You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.
You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.
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.
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.
* Declare a `Request` parameter in the *path operation* that will return a template.
* Declare a `Request` parameter in the *path operation* that will return a template.
* Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
* Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
You can read more details about the ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
You can read more details about the ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
For the deprecated `startup` and `shutdown` events, you can use the `TestClient` as follows:
For the deprecated `startup` and `shutdown` events, you can use the `TestClient` as follows:
You can receive and send binary, text, and JSON data.
You can receive and send binary, text, and JSON data.
@ -154,7 +154,7 @@ With that you can connect the WebSocket and then send and receive messages:
When a WebSocket connection is closed, the `await websocket.receive_text()` will raise a `WebSocketDisconnect` exception, which you can then catch and handle like in this example.
When a WebSocket connection is closed, the `await websocket.receive_text()` will raise a `WebSocketDisconnect` exception, which you can then catch and handle like in this example.
One of the main features needed by API systems is data "<abbrtitle="also called marshalling, conversion">serialization</abbr>" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc.
One of the main features needed by API systems is data "<dfntitle="also called marshalling, conversion">serialization</dfn>" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc.
Another big feature needed by APIs is data validation, making sure that the data is valid, given certain parameters. For example, that some field is an `int`, and not some random string. This is especially useful for incoming data.
Another big feature needed by APIs is data validation, making sure that the data is valid, given certain parameters. For example, that some field is an `int`, and not some random string. This is especially useful for incoming data.
@ -145,7 +145,7 @@ Without a data validation system, you would have to do all the checks by hand, i
These features are what Marshmallow was built to provide. It is a great library, and I have used it a lot before.
These features are what Marshmallow was built to provide. It is a great library, and I have used it a lot before.
But it was created before there existed Python type hints. So, to define every <abbrtitle="the definition of how data should be formed">schema</abbr> you need to use specific utils and classes provided by Marshmallow.
But it was created before there existed Python type hints. So, to define every <dfntitle="the definition of how data should be formed">schema</dfn> you need to use specific utils and classes provided by Marshmallow.
/// check | Inspired **FastAPI** to
/// check | Inspired **FastAPI** to
@ -155,7 +155,7 @@ Use code to define "schemas" that provide data types and validation, automatical
Starlette is a lightweight <abbrtitle="The new standard for building asynchronous Python web applications">ASGI</abbr> framework/toolkit, which is ideal for building high-performance asyncio services.
Starlette is a lightweight <dfntitle="The new standard for building asynchronous Python web applications">ASGI</dfn> framework/toolkit, which is ideal for building high-performance asyncio services.
It is very simple and intuitive. It's designed to be easily extensible, and have modular components.
It is very simple and intuitive. It's designed to be easily extensible, and have modular components.
@ -13,7 +13,7 @@ Create a virtual environment and install the required packages with <a href="htt
<divclass="termy">
<divclass="termy">
```console
```console
$ uv sync
$ uv sync --extra all
---> 100%
---> 100%
```
```
@ -32,9 +32,9 @@ That way, you don't have to "install" your local version to be able to test ever
/// note | Technical Details
/// note | Technical Details
This only happens when you install using `uv sync` instead of running `pip install fastapi` directly.
This only happens when you install using `uv sync --extra all` instead of running `pip install fastapi` directly.
That is because `uv sync` will install the local version of FastAPI in "editable" mode by default.
That is because `uv sync --extra all` will install the local version of FastAPI in "editable" mode by default.
///
///
@ -179,19 +179,23 @@ as Uvicorn by default will use the port `8000`, the documentation on port `8008`
Help with translations is VERY MUCH appreciated! And it can't be done without the help from the community. 🌎 🚀
Help with translations is VERY MUCH appreciated! And it can't be done without the help from the community. 🌎 🚀
Here are the steps to help with translations.
Translation pull requests are made by LLMs guided with prompts designed by the FastAPI team together with the community of native speakers for each supported language.
#### Review Translation PRs
#### LLM Prompt per Language
Translation pull requests are made by LLMs guided with prompts designed by the FastAPI team together with the community of native speakers for each supported language.
Each language has a directory: <ahref="https://github.com/fastapi/fastapi/tree/master/docs"class="external-link"target="_blank">https://github.com/fastapi/fastapi/tree/master/docs</a>, in it you can see a file `llm-prompt.md` with the prompt specific for that language.
For example, for Spanish, the prompt is at: <ahref="https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md"class="external-link"target="_blank">`docs/es/llm-prompt.md`</a>.
If you see mistakes in your language, you can make suggestions to the prompt in that file for your language, and request the specific pages you would like to re-generate after the changes.
These translations are normally still reviewed by native speakers, and here's where you can help!
#### Reviewing Translation PRs
* Check the currently <ahref="https://github.com/fastapi/fastapi/pulls"class="external-link"target="_blank">existing pull requests</a> for your language. You can filter the pull requests by the ones with the label for your language. For example, for Spanish, the label is <ahref="https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review"class="external-link"target="_blank">`lang-es`</a>.
You can also check the currently <ahref="https://github.com/fastapi/fastapi/pulls"class="external-link"target="_blank">existing pull requests</a> for your language. You can filter the pull requests by the ones with the label for your language. For example, for Spanish, the label is <ahref="https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review"class="external-link"target="_blank">`lang-es`</a>.
* When reviewing a pull request, it's better not to suggest changes in the same pull request, because it is LLM generated, and it won't be possible to make sure that small individual changes are replicated in other similar sections, or that they are preserved when translating the same content again.
When reviewing a pull request, it's better not to suggest changes in the same pull request, because it is LLM generated, and it won't be possible to make sure that small individual changes are replicated in other similar sections, or that they are preserved when translating the same content again.
* Instead of adding suggestions to the translation PR, make the suggestions to the LLM prompt file for that language, in a new PR. For example, for Spanish, the LLM prompt file is at: <ahref="https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md"class="external-link"target="_blank">`docs/es/llm-prompt.md`</a>.
Instead of adding suggestions to the translation PR, make the suggestions to the LLM prompt file for that language, in a new PR. For example, for Spanish, the LLM prompt file is at: <ahref="https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md"class="external-link"target="_blank">`docs/es/llm-prompt.md`</a>.
/// tip
/// tip
@ -201,9 +205,9 @@ Check the docs about <a href="https://help.github.com/en/github/collaborating-wi
#### Subscribe to Notifications for Your Language
#### Subscribe to Notifications for Your Language
* Check if there's a <ahref="https://github.com/fastapi/fastapi/discussions/categories/translations"class="external-link"target="_blank">GitHub Discussion</a> to coordinate translations for your language. You can subscribe to it, and when there's a new pull request to review, an automatic comment will be added to the discussion.
Check if there's a <ahref="https://github.com/fastapi/fastapi/discussions/categories/translations"class="external-link"target="_blank">GitHub Discussion</a> to coordinate translations for your language. You can subscribe to it, and when there's a new pull request to review, an automatic comment will be added to the discussion.
* To check the 2-letter code for the language you want to translate, you can use the table <ahref="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes"class="external-link"target="_blank">List of ISO 639-1 codes</a>.
To check the 2-letter code for the language you want to translate, you can use the table <ahref="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes"class="external-link"target="_blank">List of ISO 639-1 codes</a>.
@ -168,7 +166,7 @@ Now in the same project directory create a file `Dockerfile` with:
```{ .dockerfile .annotate }
```{ .dockerfile .annotate }
# (1)!
# (1)!
FROM python:3.9
FROM python:3.14
# (2)!
# (2)!
WORKDIR /code
WORKDIR /code
@ -392,7 +390,7 @@ If your FastAPI is a single file, for example, `main.py` without an `./app` dire
Then you would just have to change the corresponding paths to copy the file inside the `Dockerfile`:
Then you would just have to change the corresponding paths to copy the file inside the `Dockerfile`:
```{ .dockerfile .annotate hl_lines="10 13" }
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
FROM python:3.14
WORKDIR /code
WORKDIR /code
@ -456,7 +454,7 @@ Without using containers, making applications run on startup and with restarts c
## Replication - Number of Processes { #replication-number-of-processes }
## Replication - Number of Processes { #replication-number-of-processes }
If you have a <abbrtitle="A group of machines that are configured to be connected and work together in some way.">cluster</abbr> of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container.
If you have a <dfntitle="A group of machines that are configured to be connected and work together in some way.">cluster</dfn> of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container.
One of those distributed container management systems like Kubernetes normally has some integrated way of handling **replication of containers** while still supporting **load balancing** for the incoming requests. All at the **cluster level**.
One of those distributed container management systems like Kubernetes normally has some integrated way of handling **replication of containers** while still supporting **load balancing** for the incoming requests. All at the **cluster level**.
@ -501,7 +499,7 @@ Of course, there are **special cases** where you could want to have **a containe
In those cases, you can use the `--workers` command line option to set the number of workers that you want to run:
In those cases, you can use the `--workers` command line option to set the number of workers that you want to run:
@ -65,7 +65,7 @@ Here's an example of how an HTTPS API could look like, step by step, paying atte
It would probably all start by you **acquiring** some **domain name**. Then, you would configure it in a DNS server (possibly your same cloud provider).
It would probably all start by you **acquiring** some **domain name**. Then, you would configure it in a DNS server (possibly your same cloud provider).
You would probably get a cloud server (a virtual machine) or something similar, and it would have a <abbrtitle="That doesn't change">fixed</abbr>**public IP address**.
You would probably get a cloud server (a virtual machine) or something similar, and it would have a <dfntitle="Doesn't change over time. Not dynamic.">fixed</dfn>**public IP address**.
In the DNS server(s) you would configure a record (an "`A record`") to point **your domain** to the public **IP address of your server**.
In the DNS server(s) you would configure a record (an "`A record`") to point **your domain** to the public **IP address of your server**.
### Based on open standards { #based-on-open-standards }
### Based on open standards { #based-on-open-standards }
* <ahref="https://github.com/OAI/OpenAPI-Specification"class="external-link"target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <abbrtitle="also known as: endpoints, routes">path</abbr><abbrtitle="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>, parameters, request bodies, security, etc.
* <ahref="https://github.com/OAI/OpenAPI-Specification"class="external-link"target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <dfntitle="also known as: endpoints, routes">path</dfn><dfntitle="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</dfn>, parameters, request bodies, security, etc.
* Automatic data model documentation with <ahref="https://json-schema.org/"class="external-link"target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
* Automatic data model documentation with <ahref="https://json-schema.org/"class="external-link"target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
* Designed around these standards, after a meticulous study. Instead of an afterthought layer on top.
* Designed around these standards, after a meticulous study. Instead of an afterthought layer on top.
* This also allows using automatic **client code generation** in many languages.
* This also allows using automatic **client code generation** in many languages.
@ -136,7 +136,7 @@ All built as reusable tools and components that are easy to integrate with your
FastAPI includes an extremely easy to use, but extremely powerful <abbrtitle='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></abbr> system.
FastAPI includes an extremely easy to use, but extremely powerful <dfntitle='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></dfn> system.
* Even dependencies can have dependencies, creating a hierarchy or **"graph" of dependencies**.
* Even dependencies can have dependencies, creating a hierarchy or **"graph" of dependencies**.
* All **automatically handled** by the framework.
* All **automatically handled** by the framework.
@ -153,8 +153,8 @@ Any integration is designed to be so simple to use (with dependencies) that you
### Tested { #tested }
### Tested { #tested }
* 100% <abbrtitle="The amount of code that is automatically tested">test coverage</abbr>.
* 100% <dfntitle="The amount of code that is automatically tested">test coverage</dfn>.
* 100% <abbrtitle="Python type annotations, with this your editor and external tools can give you better support">type annotated</abbr> code base.
* 100% <dfntitle="Python type annotations, with this your editor and external tools can give you better support">type annotated</dfn> code base.
* Used in production applications.
* Used in production applications.
## Starlette features { #starlette-features }
## Starlette features { #starlette-features }
@ -190,7 +190,7 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on
* **No brainfuck**:
* **No brainfuck**:
* No new schema definition micro-language to learn.
* No new schema definition micro-language to learn.
* If you know Python types you know how to use Pydantic.
* If you know Python types you know how to use Pydantic.
* Plays nicely with your **<abbrtitle="Integrated Development Environment: similar to a code editor">IDE</abbr>/<abbrtitle="A program that checks for code errors">linter</abbr>/brain**:
* Plays nicely with your **<abbrtitle="Integrated Development Environment: similar to a code editor">IDE</abbr>/<dfntitle="A program that checks for code errors">linter</dfn>/brain**:
* Because pydantic data structures are just instances of classes you define; auto-completion, linting, mypy and your intuition should all work properly with your validated data.
* Because pydantic data structures are just instances of classes you define; auto-completion, linting, mypy and your intuition should all work properly with your validated data.
* Validate **complex structures**:
* Validate **complex structures**:
* Use of hierarchical Pydantic models, Python `typing`’s `List` and `Dict`, etc.
* Use of hierarchical Pydantic models, Python `typing`’s `List` and `Dict`, etc.
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbrtitle="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Intuitive**: Great editor support. <dfntitle="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* Automatic and clear errors when the data is invalid.
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* Validation even for deeply nested JSON objects.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* JSON.
* Path parameters.
* Path parameters.
* Query parameters.
* Query parameters.
@ -382,7 +376,7 @@ item: Item
* Headers.
* Headers.
* Forms.
* Forms.
* Files.
* Files.
* <abbrtitle="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* <dfntitle="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
@ -445,7 +439,7 @@ For a more complete example including more features, see the <a href="https://fa
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbrtitle="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* A very powerful and easy to use **<dfntitle="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <ahref="https://strawberry.rocks"class="external-link"target="_blank">Strawberry</a> and other libraries.
* **GraphQL** integration with <ahref="https://strawberry.rocks"class="external-link"target="_blank">Strawberry</a> and other libraries.
@ -530,7 +524,7 @@ Used by Starlette:
* <ahref="https://www.python-httpx.org"target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <ahref="https://www.python-httpx.org"target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <ahref="https://jinja.palletsprojects.com"target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <ahref="https://jinja.palletsprojects.com"target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbrtitle="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <ahref="https://github.com/Kludex/python-multipart"target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfntitle="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
Python has support for optional "type hints" (also called "type annotations").
Python has support for optional "type hints" (also called "type annotations").
These **"type hints"** or annotations are a special syntax that allow declaring the <abbrtitle="for example: str, int, float, bool">type</abbr> of a variable.
These **"type hints"** or annotations are a special syntax that allow declaring the <dfntitle="for example: str, int, float, bool">type</dfn> of a variable.
By declaring types for your variables, editors and tools can give you better support.
By declaring types for your variables, editors and tools can give you better support.
@ -22,7 +22,7 @@ If you are a Python expert, and you already know everything about type hints, sk
### Generic types with type parameters { #generic-types-with-type-parameters }
### `typing` module { #typing-module }
There are some data structures that can contain other values, like `dict`, `list`, `set` and `tuple`. And the internal values can have their own type too.
For some additional use cases, you might need to import some things from the standard library `typing` module, for example when you want to declare that something has "any type", you can use `Any` from `typing`:
These types that have internal types are called "**generic**" types. And it's possible to declare them, even with their internal types.
```python
from typing import Any
To declare those types and the internal types, you can use the standard Python module `typing`. It exists specifically to support these type hints.
#### Newer versions of Python { #newer-versions-of-python }
def some_function(data: Any):
print(data)
The syntax using `typing` is **compatible** with all versions, from Python 3.6 to the latest ones, including Python 3.9, Python 3.10, etc.
```
As Python advances, **newer versions** come with improved support for these type annotations and in many cases you won't even need to import and use the `typing` module to declare the type annotations.
### Generic types { #generic-types }
If you can choose a more recent version of Python for your project, you will be able to take advantage of that extra simplicity.
Some types can take "type parameters" in square brackets, to define their internal types, for example a "list of strings" would be declared `list[str]`.
In all the docs there are examples compatible with each version of Python (when there's a difference).
These types that can take type parameters are called **Generic types** or **Generics**.
For example "**Python 3.6+**" means it's compatible with Python 3.6 or above (including 3.7, 3.8, 3.9, 3.10, etc). And "**Python 3.9+**" means it's compatible with Python 3.9 or above (including 3.10, etc).
You can use the same builtin types as generics (with square brackets and types inside):
If you can use the **latest versions of Python**, use the examples for the latest version, those will have the **best and simplest syntax**, for example, "**Python 3.10+**".
* `list`
* `tuple`
* `set`
* `dict`
#### List { #list }
#### List { #list }
@ -167,7 +170,7 @@ As the type, put `list`.
As the list is a type that contains some internal types, you put them in square brackets:
As the list is a type that contains some internal types, you put them in square brackets:
You can declare that a variable can be any of **several types**, for example, an `int` or a `str`.
You can declare that a variable can be any of **several types**, for example, an `int` or a `str`.
In Python 3.6 and above (including Python 3.10) you can use the `Union` type from `typing` and put inside the square brackets the possible types to accept.
To define it you use the <dfntitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</dfn> to separate both types.
In Python 3.10 there's also a **new syntax** where you can put the possible types separated by a <abbrtitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr>.
//// tab | Python 3.10+
This is called a "union", because the variable can be anything in the union of those two sets of types.
Using `Optional[str]` instead of just `str` will let the editor help you detect errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
`Optional[Something]` is actually a shortcut for `Union[Something, None]`, they are equivalent.
This also means that in Python 3.10, you can use `Something | None`:
//// tab | Python 3.10+
//// tab | Python 3.10+
```Python hl_lines="1"
```Python hl_lines="1"
@ -266,96 +245,7 @@ This also means that in Python 3.10, you can use `Something | None`:
////
////
//// tab | Python 3.9+
Using `str | None` instead of just `str` will let the editor help you detect errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
#### Using `Union` or `Optional` { #using-union-or-optional }
If you are using a Python version below 3.10, here's a tip from my very **subjective** point of view:
* 🚨 Avoid using `Optional[SomeType]`
* Instead ✨ **use `Union[SomeType, None]`** ✨.
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
I think `Union[SomeType, None]` is more explicit about what it means.
It's just about the words and names. But those words can affect how you and your teammates think about the code.
And then you won't have to worry about names like `Optional` and `Union`. 😎
#### Generic types { #generic-types }
These types that take type parameters in square brackets are called **Generic types** or **Generics**, for example:
//// tab | Python 3.10+
You can use the same builtin types as generics (with square brackets and types inside):
* `list`
* `tuple`
* `set`
* `dict`
And the same as with previous Python versions, from the `typing` module:
* `Union`
* `Optional`
* ...and others.
In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <abbrtitle='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> to declare unions of types, that's a lot better and simpler.
////
//// tab | Python 3.9+
You can use the same builtin types as generics (with square brackets and types inside):
* `list`
* `tuple`
* `set`
* `dict`
And generics from the `typing` module:
* `Union`
* `Optional`
* ...and others.
////
### Classes as types { #classes-as-types }
### Classes as types { #classes-as-types }
@ -363,11 +253,11 @@ You can also declare a class as the type of a variable.
@ -403,19 +293,13 @@ To learn more about <a href="https://docs.pydantic.dev/" class="external-link" t
You will see a lot more of all this in practice in the [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
You will see a lot more of all this in practice in the [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
/// tip
Pydantic has a special behavior when you use `Optional` or `Union[Something, None]` without a default value, you can read more about it in the Pydantic docs about <ahref="https://docs.pydantic.dev/2.3/usage/models/#required-fields"class="external-link"target="_blank">Required Optional fields</a>.
///
## Type Hints with Metadata Annotations { #type-hints-with-metadata-annotations }
## Type Hints with Metadata Annotations { #type-hints-with-metadata-annotations }
Python also has a feature that allows putting **additional <abbr title="Data about the data, in this case, information about the type, e.g. a description.">metadata</abbr>** in these type hints using `Annotated`.
Python also has a feature that allows putting **additional <dfn title="Data about the data, in this case, information about the type, e.g. a description.">metadata</dfn>** in these type hints using `Annotated`.
Since Python 3.9, `Annotated` is a part of the standard library, so you can import it from `typing`.
You can declare a parameter in a *path operation function* or dependency to be of type `Request` and then you can access the raw request object directly, without any validation, etc.
You can declare a parameter in a *path operation function* or dependency to be of type `Request` and then you can access the raw request object directly, without any validation, etc.
Read more about it in the [FastAPI docs about using Request directly](https://fastapi.tiangolo.com/advanced/using-request-directly/)
@ -4,6 +4,8 @@ You can declare a parameter in a *path operation function* or dependency to be o
You can also use it directly to create an instance of it and return it from your *path operations*.
You can also use it directly to create an instance of it and return it from your *path operations*.
Read more about it in the [FastAPI docs about returning a custom Response](https://fastapi.tiangolo.com/advanced/response-directly/#returning-a-custom-response)
@ -56,6 +56,8 @@ There are a couple of custom FastAPI response classes, you can use them to optim
## Starlette Responses
## Starlette Responses
You can read more about all of them in the [FastAPI docs for Custom Response](https://fastapi.tiangolo.com/advanced/custom-response/) and in the [Starlette docs about Responses](https://starlette.dev/responses/).
When defining WebSockets, you normally declare a parameter of type `WebSocket` and with it you can read data from the client and send data to it.
When defining WebSockets, you normally declare a parameter of type `WebSocket` and with it you can read data from the client and send data to it.
Read more about it in the [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/)
It is provided directly by Starlette, but you can import it from `fastapi`:
It is provided directly by Starlette, but you can import it from `fastapi`:
```python
```python
@ -44,16 +46,6 @@ When you want to define dependencies that should be compatible with both HTTP an
- send_json
- send_json
- close
- close
When a client disconnects, a `WebSocketDisconnect` exception is raised, you can catch it.
You can import it directly form `fastapi`:
```python
from fastapi import WebSocketDisconnect
```
::: fastapi.WebSocketDisconnect
## WebSockets - additional classes
## WebSockets - additional classes
Additional classes for handling WebSockets.
Additional classes for handling WebSockets.
@ -66,4 +58,16 @@ from fastapi.websockets import WebSocketDisconnect, WebSocketState
::: fastapi.websockets.WebSocketDisconnect
::: fastapi.websockets.WebSocketDisconnect
When a client disconnects, a `WebSocketDisconnect` exception is raised, you can catch it.
You can import it directly form `fastapi`:
```python
from fastapi import WebSocketDisconnect
```
Read more about it in the [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/#handling-disconnections-and-multiple-clients)
::: fastapi.websockets.WebSocketState
::: fastapi.websockets.WebSocketState
`WebSocketState` is an enumeration of the possible states of a WebSocket connection.
* 📝 Update docs for JWT to prevent timing attacks. PR [#14908](https://github.com/fastapi/fastapi/pull/14908) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for uk (update-all). PR [#14914](https://github.com/fastapi/fastapi/pull/14914) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for tr (update-all). PR [#14913](https://github.com/fastapi/fastapi/pull/14913) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for ru (update-outdated). PR [#14909](https://github.com/fastapi/fastapi/pull/14909) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* ⬆ Bump cryptography from 46.0.4 to 46.0.5. PR [#14892](https://github.com/fastapi/fastapi/pull/14892) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pillow from 12.1.0 to 12.1.1. PR [#14899](https://github.com/fastapi/fastapi/pull/14899) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.129.0
### Breaking Changes
* ➖ Drop support for Python 3.9. PR [#14897](https://github.com/fastapi/fastapi/pull/14897) by [@tiangolo](https://github.com/tiangolo).
### Refactors
* 🎨 Update internal types for Python 3.10. PR [#14898](https://github.com/fastapi/fastapi/pull/14898) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Update highlights in webhooks docs. PR [#14905](https://github.com/fastapi/fastapi/pull/14905) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update source examples and docs from Python 3.9 to 3.10. PR [#14900](https://github.com/fastapi/fastapi/pull/14900) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔨 Update docs.py scripts to migrate Python 3.9 to Python 3.10. PR [#14906](https://github.com/fastapi/fastapi/pull/14906) by [@tiangolo](https://github.com/tiangolo).
## 0.128.8
### Docs
* 📝 Fix grammar in `docs/en/docs/tutorial/first-steps.md`. PR [#14708](https://github.com/fastapi/fastapi/pull/14708) by [@SanjanaS10](https://github.com/SanjanaS10).
### Internal
* 🔨 Tweak PDM hook script. PR [#14895](https://github.com/fastapi/fastapi/pull/14895) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Update build setup for `fastapi-slim`, deprecate it, and make it only depend on `fastapi`. PR [#14894](https://github.com/fastapi/fastapi/pull/14894) by [@tiangolo](https://github.com/tiangolo).
## 0.128.7
### Features
* ✨ Show a clear error on attempt to include router into itself. PR [#14258](https://github.com/fastapi/fastapi/pull/14258) by [@JavierSanchezCastro](https://github.com/JavierSanchezCastro).
* ✨ Replace `dict` by `Mapping` on `HTTPException.headers`. PR [#12997](https://github.com/fastapi/fastapi/pull/12997) by [@rijenkii](https://github.com/rijenkii).
### Refactors
* ♻️ Simplify reading files in memory, do it sequentially instead of (fake) parallel. PR [#14884](https://github.com/fastapi/fastapi/pull/14884) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Use `dfn` tag for definitions instead of `abbr` in docs. PR [#14744](https://github.com/fastapi/fastapi/pull/14744) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* ✅ Tweak comment in test to reference PR. PR [#14885](https://github.com/fastapi/fastapi/pull/14885) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update LLM-prompt for `abbr` and `dfn` tags. PR [#14747](https://github.com/fastapi/fastapi/pull/14747) by [@YuriiMotov](https://github.com/YuriiMotov).
* ✅ Test order for the submitted byte Files. PR [#14828](https://github.com/fastapi/fastapi/pull/14828) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🔧 Configure `test` workflow to run tests with `inline-snapshot=review`. PR [#14876](https://github.com/fastapi/fastapi/pull/14876) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.128.6
### Fixes
* 🐛 Fix `on_startup` and `on_shutdown` parameters of `APIRouter`. PR [#14873](https://github.com/fastapi/fastapi/pull/14873) by [@YuriiMotov](https://github.com/YuriiMotov).
### Translations
* 🌐 Update translations for zh (update-outdated). PR [#14843](https://github.com/fastapi/fastapi/pull/14843) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ✅ Fix parameterized tests with snapshots. PR [#14875](https://github.com/fastapi/fastapi/pull/14875) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.128.5
### Refactors
* ♻️ Refactor and simplify Pydantic v2 (and v1) compatibility internal utils. PR [#14862](https://github.com/fastapi/fastapi/pull/14862) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ✅ Add inline snapshot tests for OpenAPI before changes from Pydantic v2. PR [#14864](https://github.com/fastapi/fastapi/pull/14864) by [@tiangolo](https://github.com/tiangolo).
## 0.128.4
### Refactors
* ♻️ Refactor internals, simplify Pydantic v2/v1 utils, `create_model_field`, better types for `lenient_issubclass`. PR [#14860](https://github.com/fastapi/fastapi/pull/14860) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Simplify internals, remove Pydantic v1 only logic, no longer needed. PR [#14857](https://github.com/fastapi/fastapi/pull/14857) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor internals, cleanup unneeded Pydantic v1 specific logic. PR [#14856](https://github.com/fastapi/fastapi/pull/14856) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for fr (outdated pages). PR [#14839](https://github.com/fastapi/fastapi/pull/14839) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for tr (outdated and missing). PR [#14838](https://github.com/fastapi/fastapi/pull/14838) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* ⬆️ Upgrade development dependencies. PR [#14854](https://github.com/fastapi/fastapi/pull/14854) by [@tiangolo](https://github.com/tiangolo).
## 0.128.3
### Refactors
* ♻️ Re-implement `on_event` in FastAPI for compatibility with the next Starlette, while keeping backwards compatibility. PR [#14851](https://github.com/fastapi/fastapi/pull/14851) by [@tiangolo](https://github.com/tiangolo).
### Upgrades
* ⬆️ Upgrade Starlette supported version range to `starlette>=0.40.0,<1.0.0`. PR [#14853](https://github.com/fastapi/fastapi/pull/14853) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for ru (update-outdated). PR [#14834](https://github.com/fastapi/fastapi/pull/14834) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 👷 Run tests with Starlette from git. PR [#14849](https://github.com/fastapi/fastapi/pull/14849) by [@tiangolo](https://github.com/tiangolo).
* 👷 Run tests with lower bound uv sync, upgrade `fastapi[all]` minimum dependencies: `ujson >=5.8.0`, `orjson >=3.9.3`. PR [#14846](https://github.com/fastapi/fastapi/pull/14846) by [@tiangolo](https://github.com/tiangolo).
## 0.128.2
### Features
* ✨ Add support for PEP695 `TypeAliasType`. PR [#13920](https://github.com/fastapi/fastapi/pull/13920) by [@cstruct](https://github.com/cstruct).
* ✨ Allow `Response` type hint as dependency annotation. PR [#14794](https://github.com/fastapi/fastapi/pull/14794) by [@jonathan-fulton](https://github.com/jonathan-fulton).
### Fixes
* 🐛 Fix using `Json[list[str]]` type (issue #10997). PR [#14616](https://github.com/fastapi/fastapi/pull/14616) by [@mkanetsuna](https://github.com/mkanetsuna).
### Docs
* 📝 Update docs for translations. PR [#14830](https://github.com/fastapi/fastapi/pull/14830) by [@tiangolo](https://github.com/tiangolo).
* 📝 Fix duplicate word in `advanced-dependencies.md`. PR [#14815](https://github.com/fastapi/fastapi/pull/14815) by [@Rayyan-Oumlil](https://github.com/Rayyan-Oumlil).
### Translations
* 🌐 Enable Traditional Chinese translations. PR [#14842](https://github.com/fastapi/fastapi/pull/14842) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Enable French docs translations. PR [#14841](https://github.com/fastapi/fastapi/pull/14841) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for fr (translate-page). PR [#14837](https://github.com/fastapi/fastapi/pull/14837) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for de (update-outdated). PR [#14836](https://github.com/fastapi/fastapi/pull/14836) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (update-outdated). PR [#14833](https://github.com/fastapi/fastapi/pull/14833) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (update-outdated). PR [#14835](https://github.com/fastapi/fastapi/pull/14835) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (update-outdated). PR [#14832](https://github.com/fastapi/fastapi/pull/14832) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for tr (update-outdated). PR [#14831](https://github.com/fastapi/fastapi/pull/14831) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for tr (add-missing). PR [#14790](https://github.com/fastapi/fastapi/pull/14790) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for fr (update-outdated). PR [#14826](https://github.com/fastapi/fastapi/pull/14826) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh-hant (update-outdated). PR [#14825](https://github.com/fastapi/fastapi/pull/14825) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (update-outdated). PR [#14822](https://github.com/fastapi/fastapi/pull/14822) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Update docs and translations scripts, enable Turkish. PR [#14824](https://github.com/fastapi/fastapi/pull/14824) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔨 Add max pages to translate to configs. PR [#14840](https://github.com/fastapi/fastapi/pull/14840) by [@tiangolo](https://github.com/tiangolo).
## 0.128.1
### Features
* ✨ Add `viewport` meta tag to improve Swagger UI on mobile devices. PR [#14777](https://github.com/fastapi/fastapi/pull/14777) by [@Joab0](https://github.com/Joab0).
* 🚸 Improve error message for invalid query parameter type annotations. PR [#14479](https://github.com/fastapi/fastapi/pull/14479) by [@retwish](https://github.com/retwish).
### Fixes
* 🐛 Update `ValidationError` schema to include `input` and `ctx`. PR [#14791](https://github.com/fastapi/fastapi/pull/14791) by [@jonathan-fulton](https://github.com/jonathan-fulton).
* 🐛 Fix TYPE_CHECKING annotations for Python 3.14 (PEP 649). PR [#14789](https://github.com/fastapi/fastapi/pull/14789) by [@mgu](https://github.com/mgu).
* 🐛 Strip whitespaces from `Authorization` header credentials. PR [#14786](https://github.com/fastapi/fastapi/pull/14786) by [@WaveTheory1](https://github.com/WaveTheory1).
* 🐛 Fix OpenAPI duplication of `anyOf` refs for app-level responses with specified `content` and `model` as `Union`. PR [#14463](https://github.com/fastapi/fastapi/pull/14463) by [@DJMcoder](https://github.com/DJMcoder).
### Refactors
* 🎨 Tweak types for mypy. PR [#14816](https://github.com/fastapi/fastapi/pull/14816) by [@tiangolo](https://github.com/tiangolo).
* 🏷️ Re-export `IncEx` type from Pydantic instead of duplicating it. PR [#14641](https://github.com/fastapi/fastapi/pull/14641) by [@mvanderlee](https://github.com/mvanderlee).
* 💡 Update comment for Pydantic internals. PR [#14814](https://github.com/fastapi/fastapi/pull/14814) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Update docs for contributing translations, simplify title. PR [#14817](https://github.com/fastapi/fastapi/pull/14817) by [@tiangolo](https://github.com/tiangolo).
* 📝 Fix typing issue in `docs_src/app_testing/app_b` code example. PR [#14573](https://github.com/fastapi/fastapi/pull/14573) by [@timakaa](https://github.com/timakaa).
* 📝 Fix example of license identifier in documentation. PR [#14492](https://github.com/fastapi/fastapi/pull/14492) by [@johnson-earls](https://github.com/johnson-earls).
* 📝 Add banner to translated pages. PR [#14809](https://github.com/fastapi/fastapi/pull/14809) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Add links to related sections of docs to docstrings. PR [#14776](https://github.com/fastapi/fastapi/pull/14776) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Update embedded code examples to Python 3.10 syntax. PR [#14758](https://github.com/fastapi/fastapi/pull/14758) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Fix dependency installation command in `docs/en/docs/contributing.md`. PR [#14757](https://github.com/fastapi/fastapi/pull/14757) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Use return type annotation instead of `response_model` when possible. PR [#14753](https://github.com/fastapi/fastapi/pull/14753) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Use `WSGIMiddleware` from `a2wsgi` instead of deprecated `fastapi.middleware.wsgi.WSGIMiddleware`. PR [#14756](https://github.com/fastapi/fastapi/pull/14756) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Fix minor typos in release notes. PR [#14780](https://github.com/fastapi/fastapi/pull/14780) by [@whyvineet](https://github.com/whyvineet).
* 🐛 Fix copy button in custom.js. PR [#14722](https://github.com/fastapi/fastapi/pull/14722) by [@fcharrier](https://github.com/fcharrier).
* 🐛 Fix copy button in custom.js. PR [#14722](https://github.com/fastapi/fastapi/pull/14722) by [@fcharrier](https://github.com/fcharrier).
* 📝 Add contribution instructions about LLM generated code and comments and automated tools for PRs. PR [#14706](https://github.com/fastapi/fastapi/pull/14706) by [@tiangolo](https://github.com/tiangolo).
* 📝 Add contribution instructions about LLM generated code and comments and automated tools for PRs. PR [#14706](https://github.com/fastapi/fastapi/pull/14706) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs for management tasks. PR [#14705](https://github.com/fastapi/fastapi/pull/14705) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs for management tasks. PR [#14705](https://github.com/fastapi/fastapi/pull/14705) by [@tiangolo](https://github.com/tiangolo).
@ -18,6 +211,12 @@ hide:
### Translations
### Translations
* 🌐 Improve LLM prompt of `uk` documentation. PR [#14795](https://github.com/fastapi/fastapi/pull/14795) by [@roli2py](https://github.com/roli2py).
* 🌐 Update translations for ja (update-outdated). PR [#14588](https://github.com/fastapi/fastapi/pull/14588) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (update outdated, found by fixer tool). PR [#14739](https://github.com/fastapi/fastapi/pull/14739) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for tr (update-outdated). PR [#14745](https://github.com/fastapi/fastapi/pull/14745) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update `llm-prompt.md` for Korean language. PR [#14763](https://github.com/fastapi/fastapi/pull/14763) by [@seuthootDev](https://github.com/seuthootDev).
* 🌐 Update translations for ko (update outdated, found by fixer tool). PR [#14738](https://github.com/fastapi/fastapi/pull/14738) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for de (update-outdated). PR [#14690](https://github.com/fastapi/fastapi/pull/14690) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for de (update-outdated). PR [#14690](https://github.com/fastapi/fastapi/pull/14690) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update LLM prompt for Russian translations. PR [#14733](https://github.com/fastapi/fastapi/pull/14733) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update LLM prompt for Russian translations. PR [#14733](https://github.com/fastapi/fastapi/pull/14733) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for ru (update-outdated). PR [#14693](https://github.com/fastapi/fastapi/pull/14693) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ru (update-outdated). PR [#14693](https://github.com/fastapi/fastapi/pull/14693) by [@tiangolo](https://github.com/tiangolo).
@ -36,6 +235,20 @@ hide:
### Internal
### Internal
* ⬇️ Downgrade LLM translations model to GPT-5 to reduce mistakes. PR [#14823](https://github.com/fastapi/fastapi/pull/14823) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix translation script commit in place. PR [#14818](https://github.com/fastapi/fastapi/pull/14818) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Update translation script to retry if LLM-response doesn't pass validation with Translation Fixer tool. PR [#14749](https://github.com/fastapi/fastapi/pull/14749) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👷 Run tests only on relevant code changes (not on docs). PR [#14813](https://github.com/fastapi/fastapi/pull/14813) by [@tiangolo](https://github.com/tiangolo).
* 👷 Run mypy by pre-commit. PR [#14806](https://github.com/fastapi/fastapi/pull/14806) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump ruff from 0.14.3 to 0.14.14. PR [#14798](https://github.com/fastapi/fastapi/pull/14798) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pyasn1 from 0.6.1 to 0.6.2. PR [#14804](https://github.com/fastapi/fastapi/pull/14804) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump sqlmodel from 0.0.27 to 0.0.31. PR [#14802](https://github.com/fastapi/fastapi/pull/14802) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0. PR [#14801](https://github.com/fastapi/fastapi/pull/14801) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump gitpython from 3.1.45 to 3.1.46. PR [#14800](https://github.com/fastapi/fastapi/pull/14800) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump typer from 0.16.0 to 0.21.1. PR [#14799](https://github.com/fastapi/fastapi/pull/14799) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👥 Update FastAPI People - Contributors and Translators. PR [#14796](https://github.com/fastapi/fastapi/pull/14796) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#14759](https://github.com/fastapi/fastapi/pull/14759) by [@svlandeg](https://github.com/svlandeg).
* 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors, LambdaTest changes to TestMu AI. PR [#14734](https://github.com/fastapi/fastapi/pull/14734) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors, LambdaTest changes to TestMu AI. PR [#14734](https://github.com/fastapi/fastapi/pull/14734) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump actions/cache from 4 to 5. PR [#14511](https://github.com/fastapi/fastapi/pull/14511) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/cache from 4 to 5. PR [#14511](https://github.com/fastapi/fastapi/pull/14511) by [@dependabot[bot]](https://github.com/apps/dependabot).
@ -280,7 +493,7 @@ hide:
### Refactors
### Refactors
* 🔥 Remove dangling extra condiitonal no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo).
* 🔥 Remove dangling extra conditional no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor internals, update `is_coroutine` check to reuse internal supported variants (unwrap, check class). PR [#14434](https://github.com/fastapi/fastapi/pull/14434) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor internals, update `is_coroutine` check to reuse internal supported variants (unwrap, check class). PR [#14434](https://github.com/fastapi/fastapi/pull/14434) by [@tiangolo](https://github.com/tiangolo).
### Translations
### Translations
@ -415,7 +628,7 @@ hide:
### Docs
### Docs
* 📝 Upate docs for advanced dependencies with `yield`, noting the changes in 0.121.0, adding `scope`. PR [#14287](https://github.com/fastapi/fastapi/pull/14287) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs for advanced dependencies with `yield`, noting the changes in 0.121.0, adding `scope`. PR [#14287](https://github.com/fastapi/fastapi/pull/14287) by [@tiangolo](https://github.com/tiangolo).
### Internal
### Internal
@ -2643,7 +2856,7 @@ Read more in the [advisory: Content-Type Header ReDoS](https://github.com/tiango
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/handling-errors.md`. PR [#1953](https://github.com/tiangolo/fastapi/pull/1953) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/handling-errors.md`. PR [#1953](https://github.com/tiangolo/fastapi/pull/1953) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/response-status-code.md`. PR [#1942](https://github.com/tiangolo/fastapi/pull/1942) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/response-status-code.md`. PR [#1942](https://github.com/tiangolo/fastapi/pull/1942) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/extra-models.md`. PR [#1941](https://github.com/tiangolo/fastapi/pull/1941) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/extra-models.md`. PR [#1941](https://github.com/tiangolo/fastapi/pull/1941) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese tranlsation for `docs/ja/docs/tutorial/schema-extra-example.md`. PR [#1931](https://github.com/tiangolo/fastapi/pull/1931) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/schema-extra-example.md`. PR [#1931](https://github.com/tiangolo/fastapi/pull/1931) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/body-nested-models.md`. PR [#1930](https://github.com/tiangolo/fastapi/pull/1930) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/body-nested-models.md`. PR [#1930](https://github.com/tiangolo/fastapi/pull/1930) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/body-fields.md`. PR [#1923](https://github.com/tiangolo/fastapi/pull/1923) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/body-fields.md`. PR [#1923](https://github.com/tiangolo/fastapi/pull/1923) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add German translation for `docs/de/docs/tutorial/index.md`. PR [#9502](https://github.com/tiangolo/fastapi/pull/9502) by [@fhabers21](https://github.com/fhabers21).
* 🌐 Add German translation for `docs/de/docs/tutorial/index.md`. PR [#9502](https://github.com/tiangolo/fastapi/pull/9502) by [@fhabers21](https://github.com/fhabers21).
@ -4019,7 +4232,7 @@ You hopefully updated to a supported version of Python a while ago. If you haven
### Fixes
### Fixes
* 🐛 Fix `RuntimeError` raised when `HTTPException` has a status code with no content. PR [#5365](https://github.com/tiangolo/fastapi/pull/5365) by [@iudeen](https://github.com/iudeen).
* 🐛 Fix `RuntimeError` raised when `HTTPException` has a status code with no content. PR [#5365](https://github.com/tiangolo/fastapi/pull/5365) by [@iudeen](https://github.com/iudeen).
* 🐛 Fix empty reponse body when default `status_code` is empty but the a `Response` parameter with `response.status_code` is set. PR [#5360](https://github.com/tiangolo/fastapi/pull/5360) by [@tmeckel](https://github.com/tmeckel).
* 🐛 Fix empty response body when default `status_code` is empty but the a `Response` parameter with `response.status_code` is set. PR [#5360](https://github.com/tiangolo/fastapi/pull/5360) by [@tmeckel](https://github.com/tmeckel).
#### How relative imports work { #how-relative-imports-work }
#### How relative imports work { #how-relative-imports-work }
@ -279,7 +279,7 @@ We are not adding the prefix `/items` nor the `tags=["items"]` to each *path ope
But we can still add _more_`tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:
But we can still add _more_`tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:
@ -305,13 +305,13 @@ You import and create a `FastAPI` class as normally.
And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:
And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:
As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".
As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".
@ -374,13 +374,13 @@ the `router` from `users` would overwrite the one from `items` and we wouldn't b
So, to be able to use both of them in the same file, we import the submodules directly:
So, to be able to use both of them in the same file, we import the submodules directly:
@ -420,13 +420,13 @@ It contains an `APIRouter` with some admin *path operations* that your organizat
For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:
For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:
But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.
But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.
We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:
We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:
That way, the original `APIRouter` will stay unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.
That way, the original `APIRouter` will stay unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.
@ -447,7 +447,7 @@ We can also add *path operations* directly to the `FastAPI` app.
@ -185,7 +185,7 @@ The function parameters will be recognized as follows:
FastAPI will know that the value of `q` is not required because of the default value `= None`.
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `str | None`(Python 3.10+) or `Union` in `Union[str, None]` (Python 3.9+) is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`.
The `str | None` is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`.
But adding the type annotations will allow your editor to give you better support and detect errors.
But adding the type annotations will allow your editor to give you better support and detect errors.
@ -46,7 +46,7 @@ But even if you **fill the data** and click "Execute", because the docs UI works
In some special use cases (probably not very common), you might want to **restrict** the cookies that you want to receive.
In some special use cases (probably not very common), you might want to **restrict** the cookies that you want to receive.
Your API now has the power to control its own <abbrtitle="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</abbr>. 🤪🍪
Your API now has the power to control its own <dfntitle="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</dfn>. 🤪🍪
You can use Pydantic's model configuration to `forbid` any `extra` fields:
You can use Pydantic's model configuration to `forbid` any `extra` fields:
@ -54,9 +54,9 @@ You can use Pydantic's model configuration to `forbid` any `extra` fields:
If a client tries to send some **extra cookies**, they will receive an **error** response.
If a client tries to send some **extra cookies**, they will receive an **error** response.
Poor cookie banners with all their effort to get your consent for the <abbrtitle="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API to reject it</abbr>. 🍪
Poor cookie banners with all their effort to get your consent for the <dfntitle="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API to reject it</dfn>. 🍪
For example, if the client tries to send a `santa_tracker` cookie with a value of `good-list-please`, the client will receive an **error** response telling them that the `santa_tracker`<abbrtitle="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</abbr>:
For example, if the client tries to send a `santa_tracker` cookie with a value of `good-list-please`, the client will receive an **error** response telling them that the `santa_tracker`<dfntitle="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</dfn>:
```json
```json
{
{
@ -73,4 +73,4 @@ For example, if the client tries to send a `santa_tracker` cookie with a value o
## Summary { #summary }
## Summary { #summary }
You can use **Pydantic models** to declare <abbrtitle="Have a last cookie before you go. 🍪">**cookies**</abbr> in **FastAPI**. 😎
You can use **Pydantic models** to declare <dfntitle="Have a last cookie before you go. 🍪">**cookies**</dfn> in **FastAPI**. 😎
The default parameters used by the `CORSMiddleware` implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context.
The default parameters used by the `CORSMiddleware` implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context.
These dependencies will be executed/solved the same way as normal dependencies. But their value (if they return any) won't be passed to your *path operation function*.
These dependencies will be executed/solved the same way as normal dependencies. But their value (if they return any) won't be passed to your *path operation function*.
@ -44,13 +44,13 @@ You can use the same dependency *functions* you use normally.
They can declare request requirements (like headers) or other sub-dependencies:
They can declare request requirements (like headers) or other sub-dependencies:
@ -58,7 +58,7 @@ And they can return values or not, the values won't be used.
So, you can reuse a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
So, you can reuse a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
# Dependencies with yield { #dependencies-with-yield }
# Dependencies with yield { #dependencies-with-yield }
FastAPI supports dependencies that do some <abbrtitle='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</abbr>.
FastAPI supports dependencies that do some <dfntitle='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</dfn>.
To do this, use `yield` instead of `return`, and write the extra steps (code) after.
To do this, use `yield` instead of `return`, and write the extra steps (code) after.
@ -29,15 +29,15 @@ For example, you could use this to create a database session and close it after
Only the code prior to and including the `yield` statement is executed before creating a response:
Only the code prior to and including the `yield` statement is executed before creating a response:
The same way, you could have some dependencies with `yield` and some other dependencies with `return`, and have some of those depend on some of the others.
The same way, you could have some dependencies with `yield` and some other dependencies with `return`, and have some of those depend on some of the others.
@ -109,7 +109,7 @@ But it's there for you if you need it. 🤓
If you want to catch exceptions and create a custom response based on that, create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
If you want to catch exceptions and create a custom response based on that, create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
@ -117,7 +117,7 @@ If you want to catch exceptions and create a custom response based on that, crea
If you catch an exception using `except` in a dependency with `yield` and you don't raise it again (or raise a new exception), FastAPI won't be able to notice there was an exception, the same way that would happen with regular Python:
If you catch an exception using `except` in a dependency with `yield` and you don't raise it again (or raise a new exception), FastAPI won't be able to notice there was an exception, the same way that would happen with regular Python:
In this case, the client will see an *HTTP 500 Internal Server Error* response as it should, given that we are not raising an `HTTPException` or similar, but the server will **not have any logs** or any other indication of what was the error. 😱
In this case, the client will see an *HTTP 500 Internal Server Error* response as it should, given that we are not raising an `HTTPException` or similar, but the server will **not have any logs** or any other indication of what was the error. 😱
@ -127,7 +127,7 @@ If you catch an exception in a dependency with `yield`, unless you are raising a
You can re-raise the same exception using `raise`:
You can re-raise the same exception using `raise`:
Now the client will get the same *HTTP 500 Internal Server Error* response, but the server will have our custom `InternalError` in the logs. 😎
Now the client will get the same *HTTP 500 Internal Server Error* response, but the server will have our custom `InternalError` in the logs. 😎
@ -190,7 +190,7 @@ Normally the exit code of dependencies with `yield` is executed **after the resp
But if you know that you won't need to use the dependency after returning from the *path operation function*, you can use `Depends(scope="function")` to tell FastAPI that it should close the dependency after the *path operation function* returns, but **before** the **response is sent**.
But if you know that you won't need to use the dependency after returning from the *path operation function*, you can use `Depends(scope="function")` to tell FastAPI that it should close the dependency after the *path operation function* returns, but **before** the **response is sent**.
And all the ideas in the section about [adding `dependencies` to the *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} still apply, but in this case, to all of the *path operations* in the app.
And all the ideas in the section about [adding `dependencies` to the *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} still apply, but in this case, to all of the *path operations* in the app.
**FastAPI** has a very powerful but intuitive **<abbrtitle="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
**FastAPI** has a very powerful but intuitive **<dfntitle="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
It is designed to be very simple to use, and to make it very easy for any developer to integrate other components with **FastAPI**.
It is designed to be very simple to use, and to make it very easy for any developer to integrate other components with **FastAPI**.
If one of your dependencies is declared multiple times for the same *path operation*, for example, multiple dependencies have a common sub-dependency, **FastAPI** will know to call that sub-dependency only once per request.
If one of your dependencies is declared multiple times for the same *path operation*, for example, multiple dependencies have a common sub-dependency, **FastAPI** will know to call that sub-dependency only once per request.
And it will save the returned value in a <abbrtitle="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</abbr> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
And it will save the returned value in a <dfntitle="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</dfn> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter `use_cache=False` when using `Depends`:
In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter `use_cache=False` when using `Depends`:
@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
If you want to use the exception along with the same default exception handlers from **FastAPI**, you can import and reuse the default exception handlers from `fastapi.exception_handlers`:
If you want to use the exception along with the same default exception handlers from **FastAPI**, you can import and reuse the default exception handlers from `fastapi.exception_handlers`:
In this example you are just printing the error with a very expressive message, but you get the idea. You can use the exception and then just reuse the default exception handlers.
In this example you are just printing the error with a very expressive message, but you get the idea. You can use the exception and then just reuse the default exception handlers.
Notice that you can use Markdown inside of the descriptions, for example "login" will be shown in bold (**login**) and "fancy" will be shown in italics (_fancy_).
Notice that you can use Markdown inside of the descriptions, for example "login" will be shown in bold (**login**) and "fancy" will be shown in italics (_fancy_).
@ -72,7 +72,7 @@ You don't have to add metadata for all the tags that you use.
Use the `tags` parameter with your *path operations* (and `APIRouter`s) to assign them to different tags:
Use the `tags` parameter with your *path operations* (and `APIRouter`s) to assign them to different tags:
If you want to disable the OpenAPI schema completely you can set `openapi_url=None`, that will also disable the documentation user interfaces that use it.
If you want to disable the OpenAPI schema completely you can set `openapi_url=None`, that will also disable the documentation user interfaces that use it.
@ -117,4 +117,4 @@ You can configure the two documentation user interfaces included:
For example, to set Swagger UI to be served at `/documentation` and disable ReDoc:
For example, to set Swagger UI to be served at `/documentation` and disable ReDoc:
@ -57,7 +57,7 @@ And also after the `response` is generated, before returning it.
For example, you could add a custom header `X-Process-Time` containing the time in seconds that it took to process the request and generate a response:
For example, you could add a custom header `X-Process-Time` containing the time in seconds that it took to process the request and generate a response:
## Description from docstring { #description-from-docstring }
## Description from docstring { #description-from-docstring }
As descriptions tend to be long and cover multiple lines, you can declare the *path operation* description in the function <abbrtitle="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</abbr> and **FastAPI** will read it from there.
As descriptions tend to be long and cover multiple lines, you can declare the *path operation* description in the function <dfntitle="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</dfn> and **FastAPI** will read it from there.
You can write <ahref="https://en.wikipedia.org/wiki/Markdown"class="external-link"target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
You can write <ahref="https://en.wikipedia.org/wiki/Markdown"class="external-link"target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
@ -70,7 +70,7 @@ It will be used in the interactive docs:
You can specify the response description with the parameter `response_description`:
You can specify the response description with the parameter `response_description`:
@ -90,9 +90,9 @@ So, if you don't provide one, **FastAPI** will automatically generate one of "Su
## Deprecate a *path operation* { #deprecate-a-path-operation }
## Deprecate a *path operation* { #deprecate-a-path-operation }
If you need to mark a *path operation* as <abbrtitle="obsolete, recommended not to use it">deprecated</abbr>, but without removing it, pass the parameter `deprecated`:
If you need to mark a *path operation* as <dfntitle="obsolete, recommended not to use it">deprecated</dfn>, but without removing it, pass the parameter `deprecated`:
But keep in mind that if you use `Annotated`, you won't have this problem, it won't matter as you're not using the function parameter default values for `Query()` or `Path()`.
But keep in mind that if you use `Annotated`, you won't have this problem, it won't matter as you're not using the function parameter default values for `Query()` or `Path()`.
## Order the parameters as you need, tricks { #order-the-parameters-as-you-need-tricks }
## Order the parameters as you need, tricks { #order-the-parameters-as-you-need-tricks }
@ -83,13 +83,13 @@ Pass `*`, as the first parameter of the function.
Python won't do anything with that `*`, but it will know that all the following parameters should be called as keyword arguments (key-value pairs), also known as <abbrtitle="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Even if they don't have a default value.
Python won't do anything with that `*`, but it will know that all the following parameters should be called as keyword arguments (key-value pairs), also known as <abbrtitle="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Even if they don't have a default value.
### Better with `Annotated` { #better-with-annotated }
### Better with `Annotated` { #better-with-annotated }
Keep in mind that if you use `Annotated`, as you are not using function parameter default values, you won't have this problem, and you probably won't need to use `*`.
Keep in mind that if you use `Annotated`, as you are not using function parameter default values, you won't have this problem, and you probably won't need to use `*`.
In this case, `item_id` is declared to be an `int`.
In this case, `item_id` is declared to be an `int`.
@ -26,7 +26,7 @@ This will give you editor support inside of your function, with error checks, co
///
///
## Data <abbrtitle="also known as: serialization, parsing, marshalling">conversion</abbr> { #data-conversion }
## Data <dfntitle="also known as: serialization, parsing, marshalling">conversion</dfn> { #data-conversion }
If you run this example and open your browser at <ahref="http://127.0.0.1:8000/items/3"class="external-link"target="_blank">http://127.0.0.1:8000/items/3</a>, you will see a response of:
If you run this example and open your browser at <ahref="http://127.0.0.1:8000/items/3"class="external-link"target="_blank">http://127.0.0.1:8000/items/3</a>, you will see a response of:
@ -38,7 +38,7 @@ If you run this example and open your browser at <a href="http://127.0.0.1:8000/
Notice that the value your function received (and returned) is `3`, as a Python `int`, not a string `"3"`.
Notice that the value your function received (and returned) is `3`, as a Python `int`, not a string `"3"`.
So, with that type declaration, **FastAPI** gives you automatic request <abbrtitle="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
So, with that type declaration, **FastAPI** gives you automatic request <dfntitle="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>.
///
///
@ -118,13 +118,13 @@ And then you can also have a path `/users/{user_id}` to get data about a specifi
Because *path operations* are evaluated in order, you need to make sure that the path for `/users/me` is declared before the one for `/users/{user_id}`:
Because *path operations* are evaluated in order, you need to make sure that the path for `/users/me` is declared before the one for `/users/{user_id}`:
Otherwise, the path for `/users/{user_id}` would match also for `/users/me`, "thinking" that it's receiving a parameter `user_id` with a value of `"me"`.
Otherwise, the path for `/users/{user_id}` would match also for `/users/me`, "thinking" that it's receiving a parameter `user_id` with a value of `"me"`.
If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Learning <abbrtitle="Technically, Deep Learning model architectures">models</abbr>.
If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Learning <dfntitle="Technically, Deep Learning model architectures">models</dfn>.
///
///
@ -152,7 +152,7 @@ If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine
Then create a *path parameter* with a type annotation using the enum class you created (`ModelName`):
Then create a *path parameter* with a type annotation using the enum class you created (`ModelName`):
@ -47,40 +47,16 @@ Now it's the time to use it with FastAPI. 🚀
We had this type annotation:
We had this type annotation:
//// tab | Python 3.10+
```Python
```Python
q: str | None = None
q: str | None = None
```
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
What we will do is wrap that with `Annotated`, so it becomes:
What we will do is wrap that with `Annotated`, so it becomes:
//// tab | Python 3.10+
```Python
```Python
q: Annotated[str | None] = None
q: Annotated[str | None] = None
```
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
Both of those versions mean the same thing, `q` is a parameter that can be a `str` or `None`, and by default, it is `None`.
Both of those versions mean the same thing, `q` is a parameter that can be a `str` or `None`, and by default, it is `None`.
Now let's jump to the fun stuff. 🎉
Now let's jump to the fun stuff. 🎉
@ -109,7 +85,7 @@ FastAPI will now:
## Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }
## Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }
Previous versions of FastAPI (before <abbrtitle="before 2023-03">0.95.0</abbr>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.
Previous versions of FastAPI (before <dfntitle="before 2023-03">0.95.0</dfn>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.
/// tip
/// tip
@ -192,7 +168,7 @@ You can also add a parameter `min_length`:
You can define a <abbrtitle="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr>`pattern` that the parameter should match:
You can define a <dfntitle="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</dfn>`pattern` that the parameter should match:
@ -372,7 +348,7 @@ Then you can declare an `alias`, and that alias is what will be used to find the
Now let's say you don't like this parameter anymore.
Now let's say you don't like this parameter anymore.
You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <abbrtitle="obsolete, recommended not to use it">deprecated</abbr>.
You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <dfntitle="obsolete, recommended not to use it">deprecated</dfn>.
Then pass the parameter `deprecated=True` to `Query`:
Then pass the parameter `deprecated=True` to `Query`:
@ -402,7 +378,7 @@ Pydantic also has <a href="https://docs.pydantic.dev/latest/concepts/validators/
///
///
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbrtitle="ISBN means International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbrtitle="IMDB (Internet Movie Database) is a website with information about movies">IMDB</abbr> movie URL ID:
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbrtitle="International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbrtitle="Internet Movie Database: a website with information about movies">IMDB</abbr> movie URL ID:
@ -436,7 +412,7 @@ Did you notice? a string using `value.startswith()` can take a tuple, and it wil
#### A Random Item { #a-random-item }
#### A Random Item { #a-random-item }
With `data.items()` we get an <abbrtitle="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</abbr> with tuples containing the key and value for each dictionary item.
With `data.items()` we get an <dfntitle="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</dfn> with tuples containing the key and value for each dictionary item.
We convert this iterable object into a proper `list` with `list(data.items())`.
We convert this iterable object into a proper `list` with `list(data.items())`.
For example, in one of the ways the OAuth2 specification can be used (called "password flow") it is required to send a `username` and `password` as form fields.
For example, in one of the ways the OAuth2 specification can be used (called "password flow") it is required to send a `username` and `password` as form fields.
The <abbrtitle="specification">spec</abbr> requires the fields to be exactly named `username` and `password`, and to be sent as form fields, not JSON.
The <dfntitle="specification">spec</dfn> requires the fields to be exactly named `username` and `password`, and to be sent as form fields, not JSON.
With `Form` you can declare the same configurations as with `Body` (and `Query`, `Path`, `Cookie`), including validation, examples, an alias (e.g. `user-name` instead of `username`), etc.
With `Form` you can declare the same configurations as with `Body` (and `Query`, `Path`, `Cookie`), including validation, examples, an alias (e.g. `user-name` instead of `username`), etc.
@ -183,7 +183,7 @@ There might be cases where you return something that is not a valid Pydantic fie
The most common case would be [returning a Response directly as explained later in the advanced docs](../advanced/response-directly.md){.internal-link target=_blank}.
The most common case would be [returning a Response directly as explained later in the advanced docs](../advanced/response-directly.md){.internal-link target=_blank}.
This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case.
This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case.
@ -201,7 +201,7 @@ This will also work because `RedirectResponse` is a subclass of `Response`, and
But when you return some other arbitrary object that is not a valid Pydantic type (e.g. a database object) and you annotate it like that in the function, FastAPI will try to create a Pydantic response model from that type annotation, and will fail.
But when you return some other arbitrary object that is not a valid Pydantic type (e.g. a database object) and you annotate it like that in the function, FastAPI will try to create a Pydantic response model from that type annotation, and will fail.
The same would happen if you had something like a <abbrtitle='A union between multiple types means "any of these types".'>union</abbr> between different types where one or more of them are not valid Pydantic types, for example this would fail 💥:
The same would happen if you had something like a <dfntitle='A union between multiple types means "any of these types".'>union</dfn> between different types where one or more of them are not valid Pydantic types, for example this would fail 💥:
@ -74,7 +74,7 @@ You can of course also pass multiple `examples`:
When you do this, the examples will be part of the internal **JSON Schema** for that body data.
When you do this, the examples will be part of the internal **JSON Schema** for that body data.
Nevertheless, at the <abbrtitle="2023-08-26">time of writing this</abbr>, Swagger UI, the tool in charge of showing the docs UI, doesn't support showing multiple examples for the data in **JSON Schema**. But read below for a workaround.
Nevertheless, at the <dfntitle="2023-08-26">time of writing this</dfn>, Swagger UI, the tool in charge of showing the docs UI, doesn't support showing multiple examples for the data in **JSON Schema**. But read below for a workaround.
@ -132,7 +132,7 @@ In that case, **FastAPI** also provides you with the tools to build it.
When we create an instance of the `OAuth2PasswordBearer` class we pass in the `tokenUrl` parameter. This parameter contains the URL that the client (the frontend running in the user's browser) will use to send the `username` and `password` in order to get a token.
When we create an instance of the `OAuth2PasswordBearer` class we pass in the `tokenUrl` parameter. This parameter contains the URL that the client (the frontend running in the user's browser) will use to send the `username` and `password` in order to get a token.
In the previous chapter the security system (which is based on the dependency injection system) was giving the *path operation function* a `token` as a `str`:
In the previous chapter the security system (which is based on the dependency injection system) was giving the *path operation function* a `token` as a `str`:
When `authenticate_user` is called with a username that doesn't exist in the database, we still run `verify_password` against a dummy hash.
This ensures the endpoint takes roughly the same amount of time to respond whether the username is valid or not, preventing **timing attacks** that could be used to enumerate existing usernames.
/// note
/// note
@ -152,7 +156,7 @@ Define a Pydantic Model that will be used in the token endpoint for the response
Create a utility function to generate a new access token.
Create a utility function to generate a new access token.