diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 2fd46df6b..e46786a53 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -62,7 +62,10 @@ jobs: env: 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 ) }} - 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/wrangler-action@v3.11 + # uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a62acccfe..779018ff9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.9 + rev: v0.7.0 hooks: - id: ruff args: diff --git a/docs/en/data/external_links.yml b/docs/en/data/external_links.yml index dedbe87f4..9e411a631 100644 --- a/docs/en/data/external_links.yml +++ b/docs/en/data/external_links.yml @@ -339,6 +339,10 @@ Articles: link: https://qiita.com/mtitg/items/47770e9a562dd150631d title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築 Portuguese: + - author: Eduardo Mendes + author_link: https://bolha.us/@dunossauro + link: https://fastapidozero.dunossauro.com/ + title: FastAPI do ZERO - author: Jessica Temporal author_link: https://jtemporal.com/socials link: https://jtemporal.com/dicas-para-migrar-de-flask-para-fastapi-e-vice-versa/ diff --git a/docs/en/docs/advanced/security/http-basic-auth.md b/docs/en/docs/advanced/security/http-basic-auth.md index fa652c52b..234e2f940 100644 --- a/docs/en/docs/advanced/security/http-basic-auth.md +++ b/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 contains the `username` and `password` sent. -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *} 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"`. -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *} 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: -//// tab | Python 3.9+ - -```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!} -``` - -//// +{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *} diff --git a/docs/en/docs/how-to/configure-swagger-ui.md b/docs/en/docs/how-to/configure-swagger-ui.md index 2c649c152..a8a8de48f 100644 --- a/docs/en/docs/how-to/configure-swagger-ui.md +++ b/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`: -```Python hl_lines="3" -{!../../docs_src/configure_swagger_ui/tutorial001.py!} -``` +{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *} ...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): -```Python hl_lines="3" -{!../../docs_src/configure_swagger_ui/tutorial002.py!} -``` +{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *} 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: -```Python -{!../../fastapi/openapi/docs.py[ln:7-23]!} -``` +{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *} 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`: -```Python hl_lines="3" -{!../../docs_src/configure_swagger_ui/tutorial003.py!} -``` +{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *} ## Other Swagger UI Parameters diff --git a/docs/en/docs/how-to/separate-openapi-schemas.md b/docs/en/docs/how-to/separate-openapi-schemas.md index 75fd3f9b6..9a27638fe 100644 --- a/docs/en/docs/how-to/separate-openapi-schemas.md +++ b/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: -//// tab | Python 3.10+ - -```Python hl_lines="7" -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!} - -# Code below omitted 👇 -``` - -
-👀 Full file preview - -```Python -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!} -``` - -
- -//// - -//// tab | Python 3.9+ - -```Python hl_lines="9" -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-9]!} - -# Code below omitted 👇 -``` - -
-👀 Full file preview - -```Python -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!} -``` - -
- -//// - -//// tab | Python 3.8+ - -```Python hl_lines="9" -{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-9]!} - -# Code below omitted 👇 -``` - -
-👀 Full file preview - -```Python -{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!} -``` - -
- -//// +{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *} ### Model for Input If you use this model as an input like here: -//// tab | Python 3.10+ - -```Python hl_lines="14" -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-15]!} - -# Code below omitted 👇 -``` - -
-👀 Full file preview - -```Python -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!} -``` - -
- -//// - -//// tab | Python 3.9+ - -```Python hl_lines="16" -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-17]!} - -# Code below omitted 👇 -``` - -
-👀 Full file preview - -```Python -{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!} -``` - -
- -//// - -//// tab | Python 3.8+ - -```Python hl_lines="16" -{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-17]!} - -# Code below omitted 👇 -``` - -
-👀 Full file preview - -```Python -{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!} -``` - -
- -//// +{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *} ...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: -//// 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!} -``` - -//// +{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *} ...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+ - -```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!} -``` - -//// +{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *} ### Same Schema for Input and Output Models in Docs diff --git a/docs/en/docs/python-types.md b/docs/en/docs/python-types.md index ee192d8cb..6c28577cc 100644 --- a/docs/en/docs/python-types.md +++ b/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: -```Python -{!../../docs_src/python_types/tutorial001.py!} -``` +{* ../../docs_src/python_types/tutorial001.py *} 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()`. * Concatenates them with a space in the middle. -```Python hl_lines="2" -{!../../docs_src/python_types/tutorial001.py!} -``` +{* ../../docs_src/python_types/tutorial001.py hl[2] *} ### Edit it @@ -82,9 +78,7 @@ That's it. Those are the "type hints": -```Python hl_lines="1" -{!../../docs_src/python_types/tutorial002.py!} -``` +{* ../../docs_src/python_types/tutorial002.py hl[1] *} 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: -```Python hl_lines="1" -{!../../docs_src/python_types/tutorial003.py!} -``` +{* ../../docs_src/python_types/tutorial003.py hl[1] *} 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)`: -```Python hl_lines="2" -{!../../docs_src/python_types/tutorial004.py!} -``` +{* ../../docs_src/python_types/tutorial004.py hl[2] *} ## Declaring types @@ -143,9 +133,7 @@ You can use, for example: * `bool` * `bytes` -```Python hl_lines="1" -{!../../docs_src/python_types/tutorial005.py!} -``` +{* ../../docs_src/python_types/tutorial005.py hl[1] *} ### 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: -```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009c.py!} -``` +{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} 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: -```Python hl_lines="1 4" -{!../../docs_src/python_types/tutorial009c_py310.py!} -``` +{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *} 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: -```Python hl_lines="1-3" -{!../../docs_src/python_types/tutorial010.py!} -``` +{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} Then you can declare a variable to be of type `Person`: -```Python hl_lines="6" -{!../../docs_src/python_types/tutorial010.py!} -``` +{* ../../docs_src/python_types/tutorial010.py hl[6] *} And then, again, you get all the editor support: diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index be8f67ad6..d0bb66ee6 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,38 @@ hide: ## 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 ### Upgrades diff --git a/docs/en/docs/tutorial/first-steps.md b/docs/en/docs/tutorial/first-steps.md index 77728cebe..1c20b945a 100644 --- a/docs/en/docs/tutorial/first-steps.md +++ b/docs/en/docs/tutorial/first-steps.md @@ -2,9 +2,7 @@ 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`. @@ -157,9 +155,7 @@ You could also use it to generate code automatically, for clients that communica ### Step 1: import `FastAPI` -```Python hl_lines="1" -{!../../docs_src/first_steps/tutorial001.py!} -``` +{* ../../docs_src/first_steps/tutorial001.py hl[1] *} `FastAPI` is a Python class that provides all the functionality for your API. @@ -173,9 +169,7 @@ You can use all the diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml index 8e0f6765d..6443b290a 100644 --- a/docs/en/mkdocs.yml +++ b/docs/en/mkdocs.yml @@ -266,7 +266,6 @@ markdown_extensions: # Python Markdown Extensions pymdownx.betterem: - smart_enable: all pymdownx.caret: pymdownx.highlight: line_spans: __span diff --git a/docs/pt/docs/advanced/dataclasses.md b/docs/pt/docs/advanced/dataclasses.md new file mode 100644 index 000000000..af603ada7 --- /dev/null +++ b/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 `dataclasses` 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 suporte interno para `dataclasses`. + +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: + + + +## 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 serializar 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 documentação do Pydantic sobre dataclasses. + +## Versão + +Isso está disponível desde a versão `0.67.0` do FastAPI. 🔖 diff --git a/docs/pt/docs/how-to/custom-request-and-route.md b/docs/pt/docs/how-to/custom-request-and-route.md new file mode 100644 index 000000000..64325eed9 --- /dev/null +++ b/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, `msgpack`). +* 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 documentação do Starlette sobre Requests. + +/// + +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!} +``` diff --git a/docs/pt/docs/how-to/extending-openapi.md b/docs/pt/docs/how-to/extending-openapi.md new file mode 100644 index 000000000..40917325b --- /dev/null +++ b/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 Extensão OpenAPI do ReDoc para incluir um logo personalizado. + +### **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 http://127.0.0.1:8000/redoc, verá que está usando seu logo personalizado (neste exemplo, o logo do **FastAPI**): + + diff --git a/docs/pt/docs/how-to/separate-openapi-schemas.md b/docs/pt/docs/how-to/separate-openapi-schemas.md new file mode 100644 index 000000000..50d321d4c --- /dev/null +++ b/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 👇 +``` + +
+👀 Visualização completa do arquivo + +```Python +{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!} +``` + +
+ +//// + +//// tab | Python 3.9+ + +```Python hl_lines="9" +{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-9]!} + +# Code below omitted 👇 +``` + +
+👀 Visualização completa do arquivo + +```Python +{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!} +``` + +
+ +//// + +//// tab | Python 3.8+ + +```Python hl_lines="9" +{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-9]!} + +# Code below omitted 👇 +``` + +
+👀 Visualização completa do arquivo + +```Python +{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!} +``` + +
+ +//// + +### 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 👇 +``` + +
+👀 Visualização completa do arquivo + +```Python +{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!} +``` + +
+ +//// + +//// tab | Python 3.9+ + +```Python hl_lines="16" +{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-17]!} + +# Code below omitted 👇 +``` + +
+👀 Visualização completa do arquivo + +```Python +{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!} +``` + +
+ +//// + +//// tab | Python 3.8+ + +```Python hl_lines="16" +{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-17]!} + +# Code below omitted 👇 +``` + +
+👀 Visualização completa do arquivo + +```Python +{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!} +``` + +
+ +//// + +... 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: + +
+ +
+ +### 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`): + +
+ +
+ +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**: + +
+ +
+ +### 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. + +
+ +
+ +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**: + +
+ +
+ +Esse é o mesmo comportamento do Pydantic v1. 🤓 diff --git a/docs/pt/docs/tutorial/header-param-models.md b/docs/pt/docs/tutorial/header-param-models.md new file mode 100644 index 000000000..a42f77a2d --- /dev/null +++ b/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`: + +
+ +
+ +### 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**. 😎 diff --git a/docs/zh-hant/docs/deployment/cloud.md b/docs/zh-hant/docs/deployment/cloud.md index 5d645b6c2..29ebe3ff5 100644 --- a/docs/zh-hant/docs/deployment/cloud.md +++ b/docs/zh-hant/docs/deployment/cloud.md @@ -1,14 +1,14 @@ # 在雲端部署 FastAPI -你幾乎可以使用 **任何雲端供應商** 來部署你的 FastAPI 應用程式。 +你幾乎可以使用**任何雲端供應商**來部署你的 FastAPI 應用程式。 在大多數情況下,主要的雲端供應商都有部署 FastAPI 的指南。 ## 雲端供應商 - 贊助商 -一些雲端供應商 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這確保了 FastAPI 及其 **生態系統** 持續健康地 **發展**。 +一些雲端供應商 ✨ [**贊助 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨,這確保了 FastAPI 及其**生態系統**持續健康地**發展**。 -這也展現了他們對 FastAPI 和其 **社群**(包括你)的真正承諾,他們不僅希望為你提供 **優質的服務**,還希望確保你擁有一個 **良好且健康的框架**:FastAPI。🙇 +這也展現了他們對 FastAPI 和其**社群**(包括你)的真正承諾,他們不僅希望為你提供**優質的服務**,還希望確保你擁有一個**良好且健康的框架**:FastAPI。🙇 你可能會想嘗試他們的服務,以下有他們的指南: diff --git a/docs/zh-hant/docs/deployment/index.md b/docs/zh-hant/docs/deployment/index.md index e760b3d16..1726562b4 100644 --- a/docs/zh-hant/docs/deployment/index.md +++ b/docs/zh-hant/docs/deployment/index.md @@ -4,17 +4,17 @@ ## 部署是什麼意思 -**部署** 應用程式指的是執行一系列必要的步驟,使其能夠 **讓使用者存取和使用**。 +**部署**應用程式指的是執行一系列必要的步驟,使其能夠**讓使用者存取和使用**。 -對於一個 **Web API**,部署通常涉及將其放置在 **遠端伺服器** 上,並使用性能優良且穩定的 **伺服器程式**,確保使用者能夠高效、無中斷地存取應用程式,且不會遇到問題。 +對於一個 **Web API**,部署通常涉及將其放置在**遠端伺服器**上,並使用性能優良且穩定的**伺服器程式**,確保使用者能夠高效、無中斷地存取應用程式,且不會遇到問題。 -這與 **開發** 階段形成鮮明對比,在 **開發** 階段,你會不斷更改程式碼、破壞程式碼、修復程式碼,然後停止和重新啟動伺服器等。 +這與**開發**階段形成鮮明對比,在**開發**階段,你會不斷更改程式碼、破壞程式碼、修復程式碼,然後停止和重新啟動伺服器等。 ## 部署策略 根據你的使用場景和使用工具,有多種方法可以實現此目的。 -你可以使用一些工具自行 **部署伺服器**,你也可以使用能為你完成部分工作的 **雲端服務**,或其他可能的選項。 +你可以使用一些工具自行**部署伺服器**,你也可以使用能為你完成部分工作的**雲端服務**,或其他可能的選項。 我將向你展示在部署 **FastAPI** 應用程式時你可能應該記住的一些主要概念(儘管其中大部分適用於任何其他類型的 Web 應用程式)。 diff --git a/docs/zh-hant/docs/how-to/index.md b/docs/zh-hant/docs/how-to/index.md new file mode 100644 index 000000000..db740140d --- /dev/null +++ b/docs/zh-hant/docs/how-to/index.md @@ -0,0 +1,13 @@ +# 使用指南 - 範例集 + +在這裡,你將會看到**不同主題**的範例或「如何使用」的指南。 + +大多數這些想法都是**獨立**的,在大多數情況下,你只需要研究那些直接適用於**你的專案**的東西。 + +如果有些東西看起來很有趣且對你的專案很有用的話再去讀它,否則你可能可以跳過它們。 + +/// tip + +如果你想要以結構化的方式**學習 FastAPI**(推薦),請前往[教學 - 使用者指南](../tutorial/index.md){.internal-link target=_blank}逐章閱讀。 + +/// diff --git a/docs/zh-hant/docs/tutorial/index.md b/docs/zh-hant/docs/tutorial/index.md new file mode 100644 index 000000000..2aaa78b22 --- /dev/null +++ b/docs/zh-hant/docs/tutorial/index.md @@ -0,0 +1,102 @@ +# 教學 - 使用者指南 + +本教學將一步一步展示如何使用 **FastAPI** 及其大多數功能。 + +每個部分都是在前一部分的基礎上逐步建置的,但內容結構是按主題分開的,因此你可以直接跳到任何特定的部分,解決你具體的 API 需求。 + +它也被設計成可作為未來的參考,讓你隨時回來查看所需的內容。 + +## 運行程式碼 + +所有程式碼區塊都可以直接複製和使用(它們實際上是經過測試的 Python 檔案)。 + +要運行任何範例,請將程式碼複製到 `main.py` 檔案,並使用以下命令啟動 `fastapi dev`: + +
+ +```console +$ fastapi dev main.py +INFO Using path main.py +INFO Resolved absolute path /home/user/code/awesomeapp/main.py +INFO Searching for package file structure from directories with __init__.py files +INFO Importing from /home/user/code/awesomeapp + + ╭─ Python module file ─╮ + │ │ + │ 🐍 main.py │ + │ │ + ╰──────────────────────╯ + +INFO Importing module main +INFO Found importable FastAPI app + + ╭─ Importable FastAPI app ─╮ + │ │ + │ from main import app │ + │ │ + ╰──────────────────────────╯ + +INFO Using import string main:app + + ╭────────── FastAPI CLI - Development mode ───────────╮ + │ │ + │ Serving at: http://127.0.0.1:8000 │ + │ │ + │ API docs: http://127.0.0.1:8000/docs │ + │ │ + │ Running in development mode, for production use: │ + │ │ + fastapi run + │ │ + ╰─────────────────────────────────────────────────────╯ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +INFO: Started reloader process [2265862] using WatchFiles +INFO: Started server process [2265873] +INFO: Waiting for application startup. +INFO: Application startup complete. + +``` + +
+ +**強烈建議**你編寫或複製程式碼、進行修改並在本地端運行。 + +在編輯器中使用它,才能真正體會到 FastAPI 的好處,可以看到你只需編寫少量程式碼,以及所有的型別檢查、自動補齊等功能。 + +--- + +## 安裝 FastAPI + +第一步是安裝 FastAPI。 + +確保你建立一個[虛擬環境](../virtual-environments.md){.internal-link target=_blank},啟用它,然後**安裝 FastAPI**: + +
+ +```console +$ pip install "fastapi[standard]" + +---> 100% +``` + +
+ +/// note + +當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準相依項。 + +如果你不想包含那些可選的相依項,你可以使用 `pip install fastapi` 來安裝。 + +/// + +## 進階使用者指南 + +還有一個**進階使用者指南**你可以稍後閱讀。 + +**進階使用者指南**建立在這個教學之上,使用相同的概念,並教你一些額外的功能。 + +但首先你應該閱讀**教學 - 使用者指南**(你正在閱讀的內容)。 + +它被設計成你可以使用**教學 - 使用者指南**來建立一個完整的應用程式,然後根據你的需求,使用一些額外的想法來擴展它。 diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py index 7ddaace25..b3621626c 100644 --- a/fastapi/param_functions.py +++ b/fastapi/param_functions.py @@ -2298,7 +2298,7 @@ def Security( # noqa: N802 dependency. 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. These scopes are integrated with OpenAPI (and the API docs at `/docs`). diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py index 9720cace0..6adc55bfe 100644 --- a/fastapi/security/oauth2.py +++ b/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. - 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 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. @@ -194,7 +194,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): ``` 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 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.