* Updated .py files with Optional tag (up to body_nested_models)
* Update optionals
* docs_src/ all updates, few I was unsure of
* Updated markdown files with Optional param
* es: Add Optional typing to index.md
* Last of markdown files updated with Optional param
* Update highlight lines
* it: Add Optional typings
* README.md: Update with Optional typings
* Update more highlight increments
* Update highlights
* schema-extra-example.md: Update highlights
* updating highlighting on website to reflect .py changes
* Update highlighting for query-params & response-directly
* Address PR comments
* Get rid of unnecessary comment
* ⏪ Revert Optional in Chinese docs as it probably also requires changes in text
* 🎨 Apply format
* ⏪ Revert modified example
* ♻️ Simplify example in docs
* 📝 Update OpenAPI callback example to use Optional
* ✨ Add Optional types to tests
* 📝 Update docs about query params, default to using Optional
* 🎨 Update code examples line highlighting
* 📝 Update nested models docs to use "type parameters" instead of "subtypes"
* 📝 Add notes about FastAPI usage of None
including:
= None
and
= Query(None)
and clarify relationship with Optional[str]
* 📝 Add note about response_model_by_alias
* ♻️ Simplify query param list example
* 🔥 Remove test for removed example
* ✅ Update test for updated example
Co-authored-by: Christopher Nguyen <[email protected]>
Co-authored-by: yk396 <[email protected]>
Co-authored-by: Kai Chen <[email protected]>
@ -168,7 +168,7 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
@ -172,7 +172,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that
Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:
@ -57,7 +57,7 @@ Using `BackgroundTasks` also works with the dependency injection system, you can
**FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards:
@ -17,7 +17,7 @@ To declare a **request** body, you use <a href="https://pydantic-docs.helpmanual
First, you need to import `BaseModel` from `pydantic`:
```Python hl_lines="2"
```Python hl_lines="4"
{!../../../docs_src/body/tutorial001.py!}
```
@ -27,7 +27,7 @@ Then you declare your data model as a class that inherits from `BaseModel`.
Use standard Python types for all the attributes:
```Python hl_lines="5 6 7 8 9"
```Python hl_lines="7 8 9 10 11"
{!../../../docs_src/body/tutorial001.py!}
```
@ -57,7 +57,7 @@ For example, this model above declares a JSON "`object`" (or Python `dict`) like
To add it to your *path operation*, declare it the same way you declared path and query parameters:
```Python hl_lines="16"
```Python hl_lines="18"
{!../../../docs_src/body/tutorial001.py!}
```
@ -123,7 +123,7 @@ But you would get the same editor support with <a href="https://www.jetbrains.co
Inside of the function, you can access all the attributes of the model object directly:
```Python hl_lines="19"
```Python hl_lines="21"
{!../../../docs_src/body/tutorial002.py!}
```
@ -133,7 +133,7 @@ You can declare path parameters and body requests at the same time.
**FastAPI** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared to be Pydantic models should be **taken from the request body**.
```Python hl_lines="15 16"
```Python hl_lines="17 18"
{!../../../docs_src/body/tutorial003.py!}
```
@ -143,7 +143,7 @@ You can also declare **body**, **path** and **query** parameters, all at the sam
**FastAPI** will recognize each of them and take the data from the correct place.
```Python hl_lines="16"
```Python hl_lines="18"
{!../../../docs_src/body/tutorial004.py!}
```
@ -153,6 +153,11 @@ The function parameters will be recognized as follows:
* If the parameter is of a **singular type** (like `int`, `float`, `str`, `bool`, etc) it will be interpreted as a **query** parameter.
* If the parameter is declared to be of the type of a **Pydantic model**, it will be interpreted as a request **body**.
!!! note
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI, but will allow your editor to give you better support and detect errors.
## Without Pydantic
If you don't want to use Pydantic models, you can also use **Body** parameters. See the docs for [Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
@ -6,7 +6,7 @@ Before diving deeper into the **Dependency Injection** system, let's upgrade the
In the previous example, we were returning a `dict` from our dependency ("dependable"):
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/dependencies/tutorial001.py!}
```
@ -71,19 +71,19 @@ That also applies to callables with no parameters at all. The same as it would b
Then, we can change the dependency "dependable" `common_parameters` from above to the class `CommonQueryParameters`:
```Python hl_lines="9 10 11 12 13"
```Python hl_lines="11 12 13 14 15"
{!../../../docs_src/dependencies/tutorial002.py!}
```
Pay attention to the `__init__` method used to create the instance of the class:
```Python hl_lines="10"
```Python hl_lines="12"
{!../../../docs_src/dependencies/tutorial002.py!}
```
...it has the same parameters as our previous `common_parameters`:
```Python hl_lines="6"
```Python hl_lines="8"
{!../../../docs_src/dependencies/tutorial001.py!}
```
@ -103,7 +103,7 @@ Now you can declare your dependency using this class.
And as when **FastAPI** calls that class the value that will be passed as `commons` to your function will be an "instance" of the class, you can declare that parameter `commons` to be of type of the class, `CommonQueryParams`.
The query parameter `q` is of type `str`, and by default is `None`, so it is optional.
The query parameter `q` is of type `Optional[str]`, that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
!!! note
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI, but will allow your editor to give you better support and detect errors.
## Additional validation
@ -18,7 +23,7 @@ We are going to enforce that even though `q` is optional, whenever it is provide
To achieve that, first import `Query` from `fastapi`:
@ -66,7 +88,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> that the parameter should match:
@ -63,7 +63,7 @@ The parameter values in your function will be:
The same way, you can declare optional query parameters, by setting their default to `None`:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial002.py!}
```
@ -72,11 +72,16 @@ In this case, the function parameter `q` will be optional, and will be `None` by
!!! check
Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.
!!! note
FastAPI will know that `q` is optional because of the `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI (FastAPI will only use the `str` part), but the `Optional[str]` will let your editor help you finding errors in your code.
## Query parameter type conversion
You can also declare `bool` types, and they will be converted:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial003.py!}
```
@ -121,7 +126,7 @@ And you don't have to declare them in any specific order.
* `description: str = None` has a default of `None`.
* `description: Optional[str] = None` has a default of `None`.
* `tax: float = 10.5` has a default of `10.5`.
* `tags: List[str] = []`has a default of an empty list: `[]`.
* `tags: List[str] = []` as a default of an empty list: `[]`.
but you might want to omit them from the result if they were not actually stored.
@ -183,7 +183,9 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
This is because the JSON Schema generated in your app's OpenAPI (and the docs) will still be the one for the complete model, even if you use `response_model_include` or `response_model_exclude` to omit some attributes.
```Python hl_lines="29 35"
This also applies to `response_model_by_alias` that works similarly.
@ -10,7 +10,7 @@ There are several ways you can declare extra JSON Schema information.
You can declare an example for a Pydantic model using `Config` and `schema_extra`, as described in <ahref="https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization"class="external-link"target="_blank">Pydantic's docs: Schema customization</a>:
@ -20,7 +20,7 @@ That extra info will be added as-is to the output JSON Schema.
In `Field`, `Path`, `Query`, `Body` and others you'll see later, you can also declare extra info for the JSON Schema by passing any other arbitrary arguments to the function, for example, to add an `example`:
@ -49,7 +49,7 @@ Now let's use the utilities provided by **FastAPI** to handle this.
First, import `OAuth2PasswordRequestForm`, and use it as a dependency with `Depends` for the path `/token`:
```Python hl_lines="2 74"
```Python hl_lines="4 76"
{!../../../docs_src/security/tutorial003.py!}
```
@ -90,7 +90,7 @@ If there is no such user, we return an error saying "incorrect username or passw
For the error, we use the exception `HTTPException`:
```Python hl_lines="1 75 76 77"
```Python hl_lines="3 77 78 79"
{!../../../docs_src/security/tutorial003.py!}
```
@ -118,7 +118,7 @@ If your database is stolen, the thief won't have your users' plaintext passwords
So, the thief won't be able to try to use those same passwords in another system (as many users use the same password everywhere, this would be dangerous).
```Python hl_lines="78 79 80 81"
```Python hl_lines="80 81 82 83"
{!../../../docs_src/security/tutorial003.py!}
```
@ -156,7 +156,7 @@ For this simple example, we are going to just be completely insecure and return
But for now, let's focus on the specific details we need.
```Python hl_lines="83"
```Python hl_lines="85"
{!../../../docs_src/security/tutorial003.py!}
```
@ -181,7 +181,7 @@ Both of these dependencies will just return an HTTP error if the user doesn't ex
So, in our endpoint, we will only get a user if the user exists, was correctly authenticated, and is active: