Browse Source

Merge branch 'master' into deferred-init

pull/10589/head
Jan Vollmer 7 months ago
committed by GitHub
parent
commit
42ea3b22c4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      .github/workflows/deploy-docs.yml
  2. 2
      .pre-commit-config.yaml
  3. 4
      docs/en/data/external_links.yml
  4. 90
      docs/en/docs/advanced/security/http-basic-auth.md
  5. 16
      docs/en/docs/how-to/configure-swagger-ui.md
  6. 162
      docs/en/docs/how-to/separate-openapi-schemas.md
  7. 40
      docs/en/docs/python-types.md
  8. 32
      docs/en/docs/release-notes.md
  9. 28
      docs/en/docs/tutorial/first-steps.md
  10. 2
      docs/en/docs/tutorial/security/oauth2-jwt.md
  11. 1
      docs/en/mkdocs.yml
  12. 101
      docs/pt/docs/advanced/dataclasses.md
  13. 121
      docs/pt/docs/how-to/custom-request-and-route.md
  14. 91
      docs/pt/docs/how-to/extending-openapi.md
  15. 258
      docs/pt/docs/how-to/separate-openapi-schemas.md
  16. 184
      docs/pt/docs/tutorial/header-param-models.md
  17. 13
      docs/zh-hant/docs/how-to/index.md
  18. 102
      docs/zh-hant/docs/tutorial/index.md
  19. 2
      fastapi/param_functions.py
  20. 4
      fastapi/security/oauth2.py

5
.github/workflows/deploy-docs.yml

@ -62,7 +62,10 @@ jobs:
env: env:
PROJECT_NAME: fastapitiangolo PROJECT_NAME: fastapitiangolo
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }} BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
uses: cloudflare/wrangler-action@v3 # TODO: Use v3 when it's fixed, probably in v3.11
# https://github.com/cloudflare/wrangler-action/issues/307
uses: cloudflare/[email protected]
# uses: cloudflare/wrangler-action@v3
with: with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

2
.pre-commit-config.yaml

@ -14,7 +14,7 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9 rev: v0.7.0
hooks: hooks:
- id: ruff - id: ruff
args: args:

4
docs/en/data/external_links.yml

@ -339,6 +339,10 @@ Articles:
link: https://qiita.com/mtitg/items/47770e9a562dd150631d link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築 title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築
Portuguese: Portuguese:
- author: Eduardo Mendes
author_link: https://bolha.us/@dunossauro
link: https://fastapidozero.dunossauro.com/
title: FastAPI do ZERO
- author: Jessica Temporal - author: Jessica Temporal
author_link: https://jtemporal.com/socials author_link: https://jtemporal.com/socials
link: https://jtemporal.com/dicas-para-migrar-de-flask-para-fastapi-e-vice-versa/ link: https://jtemporal.com/dicas-para-migrar-de-flask-para-fastapi-e-vice-versa/

90
docs/en/docs/advanced/security/http-basic-auth.md

@ -20,35 +20,7 @@ Then, when you type that username and password, the browser sends them in the he
* It returns an object of type `HTTPBasicCredentials`: * It returns an object of type `HTTPBasicCredentials`:
* It contains the `username` and `password` sent. * It contains the `username` and `password` sent.
//// tab | Python 3.9+ {* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
```Python hl_lines="4 8 12"
{!> ../../docs_src/security/tutorial006_an_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="2 7 11"
{!> ../../docs_src/security/tutorial006_an.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip
Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="2 6 10"
{!> ../../docs_src/security/tutorial006.py!}
```
////
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:
@ -68,35 +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"`.
//// tab | Python 3.9+ {* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
```Python hl_lines="1 12-24"
{!> ../../docs_src/security/tutorial007_an_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="1 12-24"
{!> ../../docs_src/security/tutorial007_an.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip
Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="1 11-21"
{!> ../../docs_src/security/tutorial007.py!}
```
////
This would be similar to: This would be similar to:
@ -160,32 +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:
//// tab | Python 3.9+ {* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
```Python hl_lines="26-30"
{!> ../../docs_src/security/tutorial007_an_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="26-30"
{!> ../../docs_src/security/tutorial007_an.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip
Prefer to use the `Annotated` version if possible.
///
```Python hl_lines="23-27"
{!> ../../docs_src/security/tutorial007.py!}
```
////

16
docs/en/docs/how-to/configure-swagger-ui.md

@ -18,9 +18,7 @@ Without changing the settings, syntax highlighting is enabled by default:
But you can disable it by setting `syntaxHighlight` to `False`: But you can disable it by setting `syntaxHighlight` to `False`:
```Python hl_lines="3" {* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
{!../../docs_src/configure_swagger_ui/tutorial001.py!}
```
...and then Swagger UI won't show the syntax highlighting anymore: ...and then Swagger UI won't show the syntax highlighting anymore:
@ -30,9 +28,7 @@ But you can disable it by setting `syntaxHighlight` to `False`:
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle): The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
```Python hl_lines="3" {* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
{!../../docs_src/configure_swagger_ui/tutorial002.py!}
```
That configuration would change the syntax highlighting color theme: That configuration would change the syntax highlighting color theme:
@ -44,17 +40,13 @@ FastAPI includes some default configuration parameters appropriate for most of t
It includes these default configurations: It includes these default configurations:
```Python {* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
{!../../fastapi/openapi/docs.py[ln:7-23]!}
```
You can override any of them by setting a different value in the argument `swagger_ui_parameters`. You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`: For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
```Python hl_lines="3" {* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
{!../../docs_src/configure_swagger_ui/tutorial003.py!}
```
## Other Swagger UI Parameters ## Other Swagger UI Parameters

162
docs/en/docs/how-to/separate-openapi-schemas.md

@ -10,123 +10,13 @@ Let's see how that works and how to change it if you need to do that.
Let's say you have a Pydantic model with default values, like this one: Let's say you have a Pydantic model with default values, like this one:
//// tab | Python 3.10+ {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *}
```Python hl_lines="7"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
# Code below omitted 👇
```
<details>
<summary>👀 Full file preview</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
```
</details>
////
//// tab | Python 3.9+
```Python hl_lines="9"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-9]!}
# Code below omitted 👇
```
<details>
<summary>👀 Full file preview</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
```
</details>
////
//// tab | Python 3.8+
```Python hl_lines="9"
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-9]!}
# Code below omitted 👇
```
<details>
<summary>👀 Full file preview</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
```
</details>
////
### Model for Input ### Model for Input
If you use this model as an input like here: If you use this model as an input like here:
//// tab | Python 3.10+ {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *}
```Python hl_lines="14"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-15]!}
# Code below omitted 👇
```
<details>
<summary>👀 Full file preview</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
```
</details>
////
//// tab | Python 3.9+
```Python hl_lines="16"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-17]!}
# Code below omitted 👇
```
<details>
<summary>👀 Full file preview</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
```
</details>
////
//// tab | Python 3.8+
```Python hl_lines="16"
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-17]!}
# Code below omitted 👇
```
<details>
<summary>👀 Full file preview</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
```
</details>
////
...then the `description` field will **not be required**. Because it has a default value of `None`. ...then the `description` field will **not be required**. Because it has a default value of `None`.
@ -142,29 +32,7 @@ You can confirm that in the docs, the `description` field doesn't have a **red a
But if you use the same model as an output, like here: But if you use the same model as an output, like here:
//// tab | Python 3.10+ {* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
```Python hl_lines="19"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="21"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="21"
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
```
////
...then because `description` has a default value, if you **don't return anything** for that field, it will still have that **default value**. ...then because `description` has a default value, if you **don't return anything** for that field, it will still have that **default value**.
@ -223,29 +91,7 @@ Support for `separate_input_output_schemas` was added in FastAPI `0.102.0`. 🤓
/// ///
//// tab | Python 3.10+ {* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *}
```Python hl_lines="10"
{!> ../../docs_src/separate_openapi_schemas/tutorial002_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="12"
{!> ../../docs_src/separate_openapi_schemas/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="12"
{!> ../../docs_src/separate_openapi_schemas/tutorial002.py!}
```
////
### Same Schema for Input and Output Models in Docs ### Same Schema for Input and Output Models in Docs

40
docs/en/docs/python-types.md

@ -22,9 +22,7 @@ If you are a Python expert, and you already know everything about type hints, sk
Let's start with a simple example: Let's start with a simple example:
```Python {* ../../docs_src/python_types/tutorial001.py *}
{!../../docs_src/python_types/tutorial001.py!}
```
Calling this program outputs: Calling this program outputs:
@ -38,9 +36,7 @@ The function does the following:
* Converts the first letter of each one to upper case with `title()`. * Converts the first letter of each one to upper case with `title()`.
* <abbr title="Puts them together, as one. With the contents of one after the other.">Concatenates</abbr> them with a space in the middle. * <abbr title="Puts them together, as one. With the contents of one after the other.">Concatenates</abbr> them with a space in the middle.
```Python hl_lines="2" {* ../../docs_src/python_types/tutorial001.py hl[2] *}
{!../../docs_src/python_types/tutorial001.py!}
```
### Edit it ### Edit it
@ -82,9 +78,7 @@ That's it.
Those are the "type hints": Those are the "type hints":
```Python hl_lines="1" {* ../../docs_src/python_types/tutorial002.py hl[1] *}
{!../../docs_src/python_types/tutorial002.py!}
```
That is not the same as declaring default values like would be with: That is not the same as declaring default values like would be with:
@ -112,9 +106,7 @@ With that, you can scroll, seeing the options, until you find the one that "ring
Check this function, it already has type hints: Check this function, it already has type hints:
```Python hl_lines="1" {* ../../docs_src/python_types/tutorial003.py hl[1] *}
{!../../docs_src/python_types/tutorial003.py!}
```
Because the editor knows the types of the variables, you don't only get completion, you also get error checks: Because the editor knows the types of the variables, you don't only get completion, you also get error checks:
@ -122,9 +114,7 @@ Because the editor knows the types of the variables, you don't only get completi
Now you know that you have to fix it, convert `age` to a string with `str(age)`: Now you know that you have to fix it, convert `age` to a string with `str(age)`:
```Python hl_lines="2" {* ../../docs_src/python_types/tutorial004.py hl[2] *}
{!../../docs_src/python_types/tutorial004.py!}
```
## Declaring types ## Declaring types
@ -143,9 +133,7 @@ You can use, for example:
* `bool` * `bool`
* `bytes` * `bytes`
```Python hl_lines="1" {* ../../docs_src/python_types/tutorial005.py hl[1] *}
{!../../docs_src/python_types/tutorial005.py!}
```
### Generic types with type parameters ### Generic types with type parameters
@ -369,9 +357,7 @@ It's just about the words and names. But those words can affect how you and your
As an example, let's take this function: As an example, let's take this function:
```Python hl_lines="1 4" {* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
{!../../docs_src/python_types/tutorial009c.py!}
```
The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter: The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:
@ -387,9 +373,7 @@ say_hi(name=None) # This works, None is valid 🎉
The good news is, once you are on Python 3.10 you won't have to worry about that, as you will be able to simply use `|` to define unions of types: The good news is, once you are on Python 3.10 you won't have to worry about that, as you will be able to simply use `|` to define unions of types:
```Python hl_lines="1 4" {* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
{!../../docs_src/python_types/tutorial009c_py310.py!}
```
And then you won't have to worry about names like `Optional` and `Union`. 😎 And then you won't have to worry about names like `Optional` and `Union`. 😎
@ -451,15 +435,11 @@ You can also declare a class as the type of a variable.
Let's say you have a class `Person`, with a name: Let's say you have a class `Person`, with a name:
```Python hl_lines="1-3" {* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
{!../../docs_src/python_types/tutorial010.py!}
```
Then you can declare a variable to be of type `Person`: Then you can declare a variable to be of type `Person`:
```Python hl_lines="6" {* ../../docs_src/python_types/tutorial010.py hl[6] *}
{!../../docs_src/python_types/tutorial010.py!}
```
And then, again, you get all the editor support: And then, again, you get all the editor support:

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

@ -7,6 +7,38 @@ hide:
## Latest Changes ## Latest Changes
### Docs
* 📝 Update includes for `docs/en/docs/how-to/configure-swagger-ui.md`. PR [#12556](https://github.com/fastapi/fastapi/pull/12556) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update includes for `docs/en/docs/how-to/separate-openapi-schemas.md`. PR [#12555](https://github.com/fastapi/fastapi/pull/12555) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update includes for `docs/en/docs/advanced/security/http-basic-auth.md`. PR [#12553](https://github.com/fastapi/fastapi/pull/12553) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update includes in `docs/en/docs/tutorial/first-steps.md`. PR [#12552](https://github.com/fastapi/fastapi/pull/12552) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update includes in `docs/en/docs/python-types.md`. PR [#12551](https://github.com/fastapi/fastapi/pull/12551) by [@tiangolo](https://github.com/tiangolo).
* 📝 Fix link in OAuth2 docs. PR [#12550](https://github.com/fastapi/fastapi/pull/12550) by [@tiangolo](https://github.com/tiangolo).
* 📝 Add External Link: FastAPI do Zero. PR [#12533](https://github.com/fastapi/fastapi/pull/12533) by [@rennerocha](https://github.com/rennerocha).
* 📝 Fix minor typos. PR [#12516](https://github.com/fastapi/fastapi/pull/12516) by [@kkirsche](https://github.com/kkirsche).
* 🌐 Fix rendering issue in translations. PR [#12509](https://github.com/fastapi/fastapi/pull/12509) by [@alejsdev](https://github.com/alejsdev).
### Translations
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/separate-openapi-schemas.md`. PR [#12518](https://github.com/fastapi/fastapi/pull/12518) by [@ilacftemp](https://github.com/ilacftemp).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/deployment/index.md`. PR [#12521](https://github.com/fastapi/fastapi/pull/12521) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/deployment/cloud.md`. PR [#12522](https://github.com/fastapi/fastapi/pull/12522) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/how-to/index.md`. PR [#12523](https://github.com/fastapi/fastapi/pull/12523) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/tutorial/index.md`. PR [#12524](https://github.com/fastapi/fastapi/pull/12524) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/how-to/index.md`. PR [#12468](https://github.com/fastapi/fastapi/pull/12468) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/tutorial/index.md`. PR [#12466](https://github.com/fastapi/fastapi/pull/12466) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/header-param-models.md`. PR [#12437](https://github.com/fastapi/fastapi/pull/12437) by [@Joao-Pedro-P-Holanda](https://github.com/Joao-Pedro-P-Holanda).
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/extending-openapi.md`. PR [#12470](https://github.com/fastapi/fastapi/pull/12470) by [@ilacftemp](https://github.com/ilacftemp).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/dataclasses.md`. PR [#12475](https://github.com/fastapi/fastapi/pull/12475) by [@leoscarlato](https://github.com/leoscarlato).
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/custom-request-and-route.md`. PR [#12483](https://github.com/fastapi/fastapi/pull/12483) by [@devfernandoa](https://github.com/devfernandoa).
### Internal
* ⬆ Bump cloudflare/wrangler-action from 3.9 to 3.11. PR [#12544](https://github.com/fastapi/fastapi/pull/12544) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Update GitHub Action to deploy docs previews to handle missing deploy comments. PR [#12527](https://github.com/fastapi/fastapi/pull/12527) by [@tiangolo](https://github.com/tiangolo).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#12505](https://github.com/fastapi/fastapi/pull/12505) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
## 0.115.3 ## 0.115.3
### Upgrades ### Upgrades

28
docs/en/docs/tutorial/first-steps.md

@ -2,9 +2,7 @@
The simplest FastAPI file could look like this: The simplest FastAPI file could look like this:
```Python {* ../../docs_src/first_steps/tutorial001.py *}
{!../../docs_src/first_steps/tutorial001.py!}
```
Copy that to a file `main.py`. Copy that to a file `main.py`.
@ -157,9 +155,7 @@ You could also use it to generate code automatically, for clients that communica
### Step 1: import `FastAPI` ### Step 1: import `FastAPI`
```Python hl_lines="1" {* ../../docs_src/first_steps/tutorial001.py hl[1] *}
{!../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` is a Python class that provides all the functionality for your API. `FastAPI` is a Python class that provides all the functionality for your API.
@ -173,9 +169,7 @@ You can use all the <a href="https://www.starlette.io/" class="external-link" ta
### Step 2: create a `FastAPI` "instance" ### Step 2: create a `FastAPI` "instance"
```Python hl_lines="3" {* ../../docs_src/first_steps/tutorial001.py hl[3] *}
{!../../docs_src/first_steps/tutorial001.py!}
```
Here the `app` variable will be an "instance" of the class `FastAPI`. Here the `app` variable will be an "instance" of the class `FastAPI`.
@ -244,9 +238,7 @@ We are going to call them "**operations**" too.
#### Define a *path operation decorator* #### Define a *path operation decorator*
```Python hl_lines="6" {* ../../docs_src/first_steps/tutorial001.py hl[6] *}
{!../../docs_src/first_steps/tutorial001.py!}
```
The `@app.get("/")` tells **FastAPI** that the function right below is in charge of handling requests that go to: The `@app.get("/")` tells **FastAPI** that the function right below is in charge of handling requests that go to:
@ -300,9 +292,7 @@ This is our "**path operation function**":
* **operation**: is `get`. * **operation**: is `get`.
* **function**: is the function below the "decorator" (below `@app.get("/")`). * **function**: is the function below the "decorator" (below `@app.get("/")`).
```Python hl_lines="7" {* ../../docs_src/first_steps/tutorial001.py hl[7] *}
{!../../docs_src/first_steps/tutorial001.py!}
```
This is a Python function. This is a Python function.
@ -314,9 +304,7 @@ In this case, it is an `async` function.
You could also define it as a normal function instead of `async def`: You could also define it as a normal function instead of `async def`:
```Python hl_lines="7" {* ../../docs_src/first_steps/tutorial003.py hl[7] *}
{!../../docs_src/first_steps/tutorial003.py!}
```
/// note /// note
@ -326,9 +314,7 @@ If you don't know the difference, check the [Async: *"In a hurry?"*](../async.md
### Step 5: return the content ### Step 5: return the content
```Python hl_lines="8" {* ../../docs_src/first_steps/tutorial001.py hl[8] *}
{!../../docs_src/first_steps/tutorial001.py!}
```
You can return a `dict`, `list`, singular values as `str`, `int`, etc. You can return a `dict`, `list`, singular values as `str`, `int`, etc.

2
docs/en/docs/tutorial/security/oauth2-jwt.md

@ -72,7 +72,7 @@ It supports many secure hashing algorithms and utilities to work with them.
The recommended algorithm is "Bcrypt". The recommended algorithm is "Bcrypt".
Make sure you create a [virtual environment](../virtual-environments.md){.internal-link target=_blank}, activate it, and then install PassLib with Bcrypt: Make sure you create a [virtual environment](../../virtual-environments.md){.internal-link target=_blank}, activate it, and then install PassLib with Bcrypt:
<div class="termy"> <div class="termy">

1
docs/en/mkdocs.yml

@ -266,7 +266,6 @@ markdown_extensions:
# Python Markdown Extensions # Python Markdown Extensions
pymdownx.betterem: pymdownx.betterem:
smart_enable: all
pymdownx.caret: pymdownx.caret:
pymdownx.highlight: pymdownx.highlight:
line_spans: __span line_spans: __span

101
docs/pt/docs/advanced/dataclasses.md

@ -0,0 +1,101 @@
# Usando Dataclasses
FastAPI é construído em cima do **Pydantic**, e eu tenho mostrado como usar modelos Pydantic para declarar requisições e respostas.
Mas o FastAPI também suporta o uso de <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> da mesma forma:
```Python hl_lines="1 7-12 19-20"
{!../../docs_src/dataclasses/tutorial001.py!}
```
Isso ainda é suportado graças ao **Pydantic**, pois ele tem <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">suporte interno para `dataclasses`</a>.
Então, mesmo com o código acima que não usa Pydantic explicitamente, o FastAPI está usando Pydantic para converter essas dataclasses padrão para a versão do Pydantic.
E claro, ele suporta o mesmo:
* validação de dados
* serialização de dados
* documentação de dados, etc.
Isso funciona da mesma forma que com os modelos Pydantic. E na verdade é alcançado da mesma maneira por baixo dos panos, usando Pydantic.
/// info | Informação
Lembre-se de que dataclasses não podem fazer tudo o que os modelos Pydantic podem fazer.
Então, você ainda pode precisar usar modelos Pydantic.
Mas se você tem um monte de dataclasses por aí, este é um truque legal para usá-las para alimentar uma API web usando FastAPI. 🤓
///
## Dataclasses em `response_model`
Você também pode usar `dataclasses` no parâmetro `response_model`:
```Python hl_lines="1 7-13 19"
{!../../docs_src/dataclasses/tutorial002.py!}
```
A dataclass será automaticamente convertida para uma dataclass Pydantic.
Dessa forma, seu esquema aparecerá na interface de documentação da API:
<img src="/img/tutorial/dataclasses/image01.png">
## Dataclasses em Estruturas de Dados Aninhadas
Você também pode combinar `dataclasses` com outras anotações de tipo para criar estruturas de dados aninhadas.
Em alguns casos, você ainda pode ter que usar a versão do Pydantic das `dataclasses`. Por exemplo, se você tiver erros com a documentação da API gerada automaticamente.
Nesse caso, você pode simplesmente trocar as `dataclasses` padrão por `pydantic.dataclasses`, que é um substituto direto:
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
{!../../docs_src/dataclasses/tutorial003.py!}
```
1. Ainda importamos `field` das `dataclasses` padrão.
2. `pydantic.dataclasses` é um substituto direto para `dataclasses`.
3. A dataclass `Author` inclui uma lista de dataclasses `Item`.
4. A dataclass `Author` é usada como o parâmetro `response_model`.
5. Você pode usar outras anotações de tipo padrão com dataclasses como o corpo da requisição.
Neste caso, é uma lista de dataclasses `Item`.
6. Aqui estamos retornando um dicionário que contém `items`, que é uma lista de dataclasses.
O FastAPI ainda é capaz de <abbr title="converter os dados para um formato que pode ser transmitido">serializar</abbr> os dados para JSON.
7. Aqui o `response_model` está usando uma anotação de tipo de uma lista de dataclasses `Author`.
Novamente, você pode combinar `dataclasses` com anotações de tipo padrão.
8. Note que esta *função de operação de rota* usa `def` regular em vez de `async def`.
Como sempre, no FastAPI você pode combinar `def` e `async def` conforme necessário.
Se você precisar de uma atualização sobre quando usar qual, confira a seção _"Com pressa?"_ na documentação sobre [`async` e `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
9. Esta *função de operação de rota* não está retornando dataclasses (embora pudesse), mas uma lista de dicionários com dados internos.
O FastAPI usará o parâmetro `response_model` (que inclui dataclasses) para converter a resposta.
Você pode combinar `dataclasses` com outras anotações de tipo em muitas combinações diferentes para formar estruturas de dados complexas.
Confira as dicas de anotação no código acima para ver mais detalhes específicos.
## Saiba Mais
Você também pode combinar `dataclasses` com outros modelos Pydantic, herdar deles, incluí-los em seus próprios modelos, etc.
Para saber mais, confira a <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">documentação do Pydantic sobre dataclasses</a>.
## Versão
Isso está disponível desde a versão `0.67.0` do FastAPI. 🔖

121
docs/pt/docs/how-to/custom-request-and-route.md

@ -0,0 +1,121 @@
# Requisições Personalizadas e Classes da APIRoute
Em algum casos, você pode querer sobreescrever a lógica usada pelas classes `Request`e `APIRoute`.
Em particular, isso pode ser uma boa alternativa para uma lógica em um middleware
Por exemplo, se você quiser ler ou manipular o corpo da requisição antes que ele seja processado pela sua aplicação.
/// danger | Perigo
Isso é um recurso "avançado".
Se você for um iniciante em **FastAPI** você deve considerar pular essa seção.
///
## Casos de Uso
Alguns casos de uso incluem:
* Converter requisições não-JSON para JSON (por exemplo, <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>).
* Descomprimir corpos de requisição comprimidos com gzip.
* Registrar automaticamente todos os corpos de requisição.
## Manipulando codificações de corpo de requisição personalizadas
Vamos ver como usar uma subclasse personalizada de `Request` para descomprimir requisições gzip.
E uma subclasse de `APIRoute` para usar essa classe de requisição personalizada.
### Criar uma classe `GzipRequest` personalizada
/// tip | Dica
Isso é um exemplo de brincadeira para demonstrar como funciona, se você precisar de suporte para Gzip, você pode usar o [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank} fornecido.
///
Primeiro, criamos uma classe `GzipRequest`, que irá sobrescrever o método `Request.body()` para descomprimir o corpo na presença de um cabeçalho apropriado.
Se não houver `gzip` no cabeçalho, ele não tentará descomprimir o corpo.
Dessa forma, a mesma classe de rota pode lidar com requisições comprimidas ou não comprimidas.
```Python hl_lines="8-15"
{!../../docs_src/custom_request_and_route/tutorial001.py!}
```
### Criar uma classe `GzipRoute` personalizada
Em seguida, criamos uma subclasse personalizada de `fastapi.routing.APIRoute` que fará uso do `GzipRequest`.
Dessa vez, ele irá sobrescrever o método `APIRoute.get_route_handler()`.
Esse método retorna uma função. E essa função é o que irá receber uma requisição e retornar uma resposta.
Aqui nós usamos para criar um `GzipRequest` a partir da requisição original.
```Python hl_lines="18-26"
{!../../docs_src/custom_request_and_route/tutorial001.py!}
```
/// note | Detalhes Técnicos
Um `Request` também tem um `request.receive`, que é uma função para "receber" o corpo da requisição.
Um `Request` também tem um `request.receive`, que é uma função para "receber" o corpo da requisição.
O dicionário `scope` e a função `receive` são ambos parte da especificação ASGI.
E essas duas coisas, `scope` e `receive`, são o que é necessário para criar uma nova instância de `Request`.
Para aprender mais sobre o `Request` confira a <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">documentação do Starlette sobre Requests</a>.
///
A única coisa que a função retornada por `GzipRequest.get_route_handler` faz de diferente é converter o `Request` para um `GzipRequest`.
Fazendo isso, nosso `GzipRequest` irá cuidar de descomprimir os dados (se necessário) antes de passá-los para nossas *operações de rota*.
Depois disso, toda a lógica de processamento é a mesma.
Mas por causa das nossas mudanças em `GzipRequest.body`, o corpo da requisição será automaticamente descomprimido quando for carregado pelo **FastAPI** quando necessário.
## Acessando o corpo da requisição em um manipulador de exceção
/// tip | Dica
Para resolver esse mesmo problema, é provavelmente muito mais fácil usar o `body` em um manipulador personalizado para `RequestValidationError` ([Tratando Erros](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
Mas esse exemplo ainda é valido e mostra como interagir com os componentes internos.
///
Também podemos usar essa mesma abordagem para acessar o corpo da requisição em um manipulador de exceção.
Tudo que precisamos fazer é manipular a requisição dentro de um bloco `try`/`except`:
```Python hl_lines="13 15"
{!../../docs_src/custom_request_and_route/tutorial002.py!}
```
Se uma exceção ocorrer, a instância `Request` ainda estará em escopo, então podemos ler e fazer uso do corpo da requisição ao lidar com o erro:
```Python hl_lines="16-18"
{!../../docs_src/custom_request_and_route/tutorial002.py!}
```
## Classe `APIRoute` personalizada em um router
você também pode definir o parametro `route_class` de uma `APIRouter`;
```Python hl_lines="26"
{!../../docs_src/custom_request_and_route/tutorial003.py!}
```
Nesse exemplo, as *operações de rota* sob o `router` irão usar a classe `TimedRoute` personalizada, e terão um cabeçalho extra `X-Response-Time` na resposta com o tempo que levou para gerar a resposta:
```Python hl_lines="13-20"
{!../../docs_src/custom_request_and_route/tutorial003.py!}
```

91
docs/pt/docs/how-to/extending-openapi.md

@ -0,0 +1,91 @@
# Extendendo o OpenAPI
Existem alguns casos em que pode ser necessário modificar o esquema OpenAPI gerado.
Nesta seção, você verá como fazer isso.
## O processo normal
O processo normal (padrão) é o seguinte:
Uma aplicação (instância) do `FastAPI` possui um método `.openapi()` que deve retornar o esquema OpenAPI.
Como parte da criação do objeto de aplicação, uma *operação de rota* para `/openapi.json` (ou para o que você definir como `openapi_url`) é registrada.
Ela apenas retorna uma resposta JSON com o resultado do método `.openapi()` da aplicação.
Por padrão, o que o método `.openapi()` faz é verificar se a propriedade `.openapi_schema` tem conteúdo e retorná-lo.
Se não tiver, ele gera o conteúdo usando a função utilitária em `fastapi.openapi.utils.get_openapi`.
E essa função `get_openapi()` recebe como parâmetros:
* `title`: O título do OpenAPI, exibido na documentação.
* `version`: A versão da sua API, por exemplo, `2.5.0`.
* `openapi_version`: A versão da especificação OpenAPI utilizada. Por padrão, a mais recente: `3.1.0`.
* `summary`: Um resumo curto da API.
* `description`: A descrição da sua API, que pode incluir markdown e será exibida na documentação.
* `routes`: Uma lista de rotas, que são cada uma das *operações de rota* registradas. Elas são obtidas de `app.routes`.
/// info | Informação
O parâmetro `summary` está disponível no OpenAPI 3.1.0 e superior, suportado pelo FastAPI 0.99.0 e superior.
///
## Sobrescrevendo os padrões
Com as informações acima, você pode usar a mesma função utilitária para gerar o esquema OpenAPI e sobrescrever cada parte que precisar.
Por exemplo, vamos adicionar <a href="https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo" class="external-link" target="_blank">Extensão OpenAPI do ReDoc para incluir um logo personalizado</a>.
### **FastAPI** Normal
Primeiro, escreva toda a sua aplicação **FastAPI** normalmente:
```Python hl_lines="1 4 7-9"
{!../../docs_src/extending_openapi/tutorial001.py!}
```
### Gerar o esquema OpenAPI
Em seguida, use a mesma função utilitária para gerar o esquema OpenAPI, dentro de uma função `custom_openapi()`:
```Python hl_lines="2 15-21"
{!../../docs_src/extending_openapi/tutorial001.py!}
```
### Modificar o esquema OpenAPI
Agora, você pode adicionar a extensão do ReDoc, incluindo um `x-logo` personalizado ao "objeto" `info` no esquema OpenAPI:
```Python hl_lines="22-24"
{!../../docs_src/extending_openapi/tutorial001.py!}
```
### Armazenar em cache o esquema OpenAPI
Você pode usar a propriedade `.openapi_schema` como um "cache" para armazenar o esquema gerado.
Dessa forma, sua aplicação não precisará gerar o esquema toda vez que um usuário abrir a documentação da sua API.
Ele será gerado apenas uma vez, e o mesmo esquema armazenado em cache será utilizado nas próximas requisições.
```Python hl_lines="13-14 25-26"
{!../../docs_src/extending_openapi/tutorial001.py!}
```
### Sobrescrever o método
Agora, você pode substituir o método `.openapi()` pela sua nova função.
```Python hl_lines="29"
{!../../docs_src/extending_openapi/tutorial001.py!}
```
### Verificar
Uma vez que você acessar <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>, verá que está usando seu logo personalizado (neste exemplo, o logo do **FastAPI**):
<img src="/docs/en/docs/img/tutorial/extending-openapi/image01.png">

258
docs/pt/docs/how-to/separate-openapi-schemas.md

@ -0,0 +1,258 @@
# Esquemas OpenAPI Separados para Entrada e Saída ou Não
Ao usar **Pydantic v2**, o OpenAPI gerado é um pouco mais exato e **correto** do que antes. 😎
Inclusive, em alguns casos, ele terá até **dois JSON Schemas** no OpenAPI para o mesmo modelo Pydantic, para entrada e saída, dependendo se eles possuem **valores padrão**.
Vamos ver como isso funciona e como alterar se for necessário.
## Modelos Pydantic para Entrada e Saída
Digamos que você tenha um modelo Pydantic com valores padrão, como este:
//// tab | Python 3.10+
```Python hl_lines="7"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
# Code below omitted 👇
```
<details>
<summary>👀 Visualização completa do arquivo</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
```
</details>
////
//// tab | Python 3.9+
```Python hl_lines="9"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-9]!}
# Code below omitted 👇
```
<details>
<summary>👀 Visualização completa do arquivo</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
```
</details>
////
//// tab | Python 3.8+
```Python hl_lines="9"
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-9]!}
# Code below omitted 👇
```
<details>
<summary>👀 Visualização completa do arquivo</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
```
</details>
////
### Modelo para Entrada
Se você usar esse modelo como entrada, como aqui:
//// tab | Python 3.10+
```Python hl_lines="14"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-15]!}
# Code below omitted 👇
```
<details>
<summary>👀 Visualização completa do arquivo</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
```
</details>
////
//// tab | Python 3.9+
```Python hl_lines="16"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-17]!}
# Code below omitted 👇
```
<details>
<summary>👀 Visualização completa do arquivo</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
```
</details>
////
//// tab | Python 3.8+
```Python hl_lines="16"
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-17]!}
# Code below omitted 👇
```
<details>
<summary>👀 Visualização completa do arquivo</summary>
```Python
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
```
</details>
////
... então o campo `description` não será obrigatório. Porque ele tem um valor padrão de `None`.
### Modelo de Entrada na Documentação
Você pode confirmar que na documentação, o campo `description` não tem um **asterisco vermelho**, não é marcado como obrigatório:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image01.png">
</div>
### Modelo para Saída
Mas se você usar o mesmo modelo como saída, como aqui:
//// tab | Python 3.10+
```Python hl_lines="19"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="21"
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="21"
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
```
////
... então, como `description` tem um valor padrão, se você **não retornar nada** para esse campo, ele ainda terá o **valor padrão**.
### Modelo para Dados de Resposta de Saída
Se você interagir com a documentação e verificar a resposta, mesmo que o código não tenha adicionado nada em um dos campos `description`, a resposta JSON contém o valor padrão (`null`):
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image02.png">
</div>
Isso significa que ele **sempre terá um valor**, só que às vezes o valor pode ser `None` (ou `null` em termos de JSON).
Isso quer dizer que, os clientes que usam sua API não precisam verificar se o valor existe ou não, eles podem **assumir que o campo sempre estará lá**, mas que em alguns casos terá o valor padrão de `None`.
A maneira de descrever isso no OpenAPI é marcar esse campo como **obrigatório**, porque ele sempre estará lá.
Por causa disso, o JSON Schema para um modelo pode ser diferente dependendo se ele é usado para **entrada ou saída**:
* para **entrada**, o `description` **não será obrigatório**
* para **saída**, ele será **obrigatório** (e possivelmente `None`, ou em termos de JSON, `null`)
### Modelo para Saída na Documentação
Você pode verificar o modelo de saída na documentação também, ambos `name` e `description` são marcados como **obrigatórios** com um **asterisco vermelho**:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image03.png">
</div>
### Modelo para Entrada e Saída na Documentação
E se você verificar todos os Schemas disponíveis (JSON Schemas) no OpenAPI, verá que há dois, um `Item-Input` e um `Item-Output`.
Para `Item-Input`, `description` **não é obrigatório**, não tem um asterisco vermelho.
Mas para `Item-Output`, `description` **é obrigatório**, tem um asterisco vermelho.
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image04.png">
</div>
Com esse recurso do **Pydantic v2**, sua documentação da API fica mais **precisa**, e se você tiver clientes e SDKs gerados automaticamente, eles serão mais precisos também, proporcionando uma melhor **experiência para desenvolvedores** e consistência. 🎉
## Não Separe Schemas
Agora, há alguns casos em que você pode querer ter o **mesmo esquema para entrada e saída**.
Provavelmente, o principal caso de uso para isso é se você já tem algum código de cliente/SDK gerado automaticamente e não quer atualizar todo o código de cliente/SDK gerado ainda, você provavelmente vai querer fazer isso em algum momento, mas talvez não agora.
Nesse caso, você pode desativar esse recurso no **FastAPI**, com o parâmetro `separate_input_output_schemas=False`.
/// info | Informação
O suporte para `separate_input_output_schemas` foi adicionado no FastAPI `0.102.0`. 🤓
///
//// tab | Python 3.10+
```Python hl_lines="10"
{!> ../../docs_src/separate_openapi_schemas/tutorial002_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="12"
{!> ../../docs_src/separate_openapi_schemas/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="12"
{!> ../../docs_src/separate_openapi_schemas/tutorial002.py!}
```
////
### Mesmo Esquema para Modelos de Entrada e Saída na Documentação
E agora haverá um único esquema para entrada e saída para o modelo, apenas `Item`, e `description` **não será obrigatório**:
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
</div>
Esse é o mesmo comportamento do Pydantic v1. 🤓

184
docs/pt/docs/tutorial/header-param-models.md

@ -0,0 +1,184 @@
# Modelos de Parâmetros do Cabeçalho
Se você possui um grupo de **parâmetros de cabeçalho** relacionados, você pode criar um **modelo do Pydantic** para declará-los.
Isso vai lhe permitir **reusar o modelo** em **múltiplos lugares** e também declarar validações e metadadados para todos os parâmetros de uma vez. 😎
/// note | Nota
Isso é possível desde a versão `0.115.0` do FastAPI. 🤓
///
## Parâmetros do Cabeçalho com um Modelo Pydantic
Declare os **parâmetros de cabeçalho** que você precisa em um **modelo do Pydantic**, e então declare o parâmetro como `Header`:
//// tab | Python 3.10+
```Python hl_lines="9-14 18"
{!> ../../docs_src/header_param_models/tutorial001_an_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="9-14 18"
{!> ../../docs_src/header_param_models/tutorial001_an_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="10-15 19"
{!> ../../docs_src/header_param_models/tutorial001_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="7-12 16"
{!> ../../docs_src/header_param_models/tutorial001_py310.py!}
```
////
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="9-14 18"
{!> ../../docs_src/header_param_models/tutorial001_py39.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="7-12 16"
{!> ../../docs_src/header_param_models/tutorial001_py310.py!}
```
////
O **FastAPI** irá **extrair** os dados de **cada campo** a partir dos **cabeçalhos** da requisição e te retornará o modelo do Pydantic que você definiu.
### Checando a documentação
Você pode ver os headers necessários na interface gráfica da documentação em `/docs`:
<div class="screenshot">
<img src="/img/tutorial/header-param-models/image01.png">
</div>
### Proibindo Cabeçalhos adicionais
Em alguns casos de uso especiais (provavelmente não muito comuns), você pode querer **restringir** os cabeçalhos que você quer receber.
Você pode usar a configuração dos modelos do Pydantic para proibir (`forbid`) quaisquer campos `extra`:
//// tab | Python 3.10+
```Python hl_lines="10"
{!> ../../docs_src/header_param_models/tutorial002_an_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="10"
{!> ../../docs_src/header_param_models/tutorial002_an_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="11"
{!> ../../docs_src/header_param_models/tutorial002_an.py!}
```
////
//// tab | Python 3.10+ non-Annotated
/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="8"
{!> ../../docs_src/header_param_models/tutorial002_py310.py!}
```
////
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="10"
{!> ../../docs_src/header_param_models/tutorial002_py39.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip | Dica
Utilize a versão com `Annotated` se possível.
///
```Python hl_lines="10"
{!> ../../docs_src/header_param_models/tutorial002.py!}
```
////
Se um cliente tentar enviar alguns **cabeçalhos extra**, eles irão receber uma resposta de **erro**.
Por exemplo, se o cliente tentar enviar um cabeçalho `tool` com o valor `plumbus`, ele irá receber uma resposta de **erro** informando que o parâmetro do cabeçalho `tool` não é permitido:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["header", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus",
}
]
}
```
## Resumo
Você pode utilizar **modelos do Pydantic** para declarar **cabeçalhos** no **FastAPI**. 😎

13
docs/zh-hant/docs/how-to/index.md

@ -0,0 +1,13 @@
# 使用指南 - 範例集
在這裡,你將會看到**不同主題**的範例或「如何使用」的指南。
大多數這些想法都是**獨立**的,在大多數情況下,你只需要研究那些直接適用於**你的專案**的東西。
如果有些東西看起來很有趣且對你的專案很有用的話再去讀它,否則你可能可以跳過它們。
/// tip
如果你想要以結構化的方式**學習 FastAPI**(推薦),請前往[教學 - 使用者指南](../tutorial/index.md){.internal-link target=_blank}逐章閱讀。
///

102
docs/zh-hant/docs/tutorial/index.md

@ -0,0 +1,102 @@
# 教學 - 使用者指南
本教學將一步一步展示如何使用 **FastAPI** 及其大多數功能。
每個部分都是在前一部分的基礎上逐步建置的,但內容結構是按主題分開的,因此你可以直接跳到任何特定的部分,解決你具體的 API 需求。
它也被設計成可作為未來的參考,讓你隨時回來查看所需的內容。
## 運行程式碼
所有程式碼區塊都可以直接複製和使用(它們實際上是經過測試的 Python 檔案)。
要運行任何範例,請將程式碼複製到 `main.py` 檔案,並使用以下命令啟動 `fastapi dev`
<div class="termy">
```console
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:single">main.py</u>
<font color="#3465A4">INFO </font> Using path <font color="#3465A4">main.py</font>
<font color="#3465A4">INFO </font> Resolved absolute path <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font>
<font color="#3465A4">INFO </font> Searching for package file structure from directories with <font color="#3465A4">__init__.py</font> files
<font color="#3465A4">INFO </font> Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
╭─ <font color="#8AE234"><b>Python module file</b></font> ─╮
│ │
│ 🐍 main.py │
│ │
╰──────────────────────╯
<font color="#3465A4">INFO </font> Importing module <font color="#4E9A06">main</font>
<font color="#3465A4">INFO </font> Found importable FastAPI app
╭─ <font color="#8AE234"><b>Importable FastAPI app</b></font> ─╮
│ │
<span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822"> </span>
│ │
╰──────────────────────────╯
<font color="#3465A4">INFO </font> Using import string <font color="#8AE234"><b>main:app</b></font>
<span style="background-color:#C4A000"><font color="#2E3436">╭────────── FastAPI CLI - Development mode ───────────╮</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ Serving at: http://127.0.0.1:8000 │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ API docs: http://127.0.0.1:8000/docs │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ Running in development mode, for production use: │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436"></font></span><span style="background-color:#C4A000"><font color="#555753"><b>fastapi run</b></font></span><span style="background-color:#C4A000"><font color="#2E3436"></font></span>
<span style="background-color:#C4A000"><font color="#2E3436">│ │</font></span>
<span style="background-color:#C4A000"><font color="#2E3436">╰─────────────────────────────────────────────────────╯</font></span>
<font color="#4E9A06">INFO</font>: Will watch for changes in these directories: [&apos;/home/user/code/awesomeapp&apos;]
<font color="#4E9A06">INFO</font>: Uvicorn running on <b>http://127.0.0.1:8000</b> (Press CTRL+C to quit)
<font color="#4E9A06">INFO</font>: Started reloader process [<font color="#34E2E2"><b>2265862</b></font>] using <font color="#34E2E2"><b>WatchFiles</b></font>
<font color="#4E9A06">INFO</font>: Started server process [<font color="#06989A">2265873</font>]
<font color="#4E9A06">INFO</font>: Waiting for application startup.
<font color="#4E9A06">INFO</font>: Application startup complete.
</pre>
```
</div>
**強烈建議**你編寫或複製程式碼、進行修改並在本地端運行。
在編輯器中使用它,才能真正體會到 FastAPI 的好處,可以看到你只需編寫少量程式碼,以及所有的型別檢查、自動補齊等功能。
---
## 安裝 FastAPI
第一步是安裝 FastAPI。
確保你建立一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},啟用它,然後**安裝 FastAPI**:
<div class="termy">
```console
$ pip install "fastapi[standard]"
---> 100%
```
</div>
/// note
當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準相依項。
如果你不想包含那些可選的相依項,你可以使用 `pip install fastapi` 來安裝。
///
## 進階使用者指南
還有一個**進階使用者指南**你可以稍後閱讀。
**進階使用者指南**建立在這個教學之上,使用相同的概念,並教你一些額外的功能。
但首先你應該閱讀**教學 - 使用者指南**(你正在閱讀的內容)。
它被設計成你可以使用**教學 - 使用者指南**來建立一個完整的應用程式,然後根據你的需求,使用一些額外的想法來擴展它。

2
fastapi/param_functions.py

@ -2298,7 +2298,7 @@ def Security( # noqa: N802
dependency. dependency.
The term "scope" comes from the OAuth2 specification, it seems to be The term "scope" comes from the OAuth2 specification, it seems to be
intentionaly vague and interpretable. It normally refers to permissions, intentionally vague and interpretable. It normally refers to permissions,
in cases to roles. in cases to roles.
These scopes are integrated with OpenAPI (and the API docs at `/docs`). These scopes are integrated with OpenAPI (and the API docs at `/docs`).

4
fastapi/security/oauth2.py

@ -52,7 +52,7 @@ class OAuth2PasswordRequestForm:
``` ```
Note that for OAuth2 the scope `items:read` is a single scope in an opaque string. Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
You could have custom internal logic to separate it by colon caracters (`:`) or You could have custom internal logic to separate it by colon characters (`:`) or
similar, and get the two parts `items` and `read`. Many applications do that to similar, and get the two parts `items` and `read`. Many applications do that to
group and organize permissions, you could do it as well in your application, just group and organize permissions, you could do it as well in your application, just
know that that it is application specific, it's not part of the specification. know that that it is application specific, it's not part of the specification.
@ -194,7 +194,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
``` ```
Note that for OAuth2 the scope `items:read` is a single scope in an opaque string. Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
You could have custom internal logic to separate it by colon caracters (`:`) or You could have custom internal logic to separate it by colon characters (`:`) or
similar, and get the two parts `items` and `read`. Many applications do that to similar, and get the two parts `items` and `read`. Many applications do that to
group and organize permissions, you could do it as well in your application, just group and organize permissions, you could do it as well in your application, just
know that that it is application specific, it's not part of the specification. know that that it is application specific, it's not part of the specification.

Loading…
Cancel
Save