mirror of
https://github.com/fastapi/fastapi.git
synced 2026-05-18 13:27:45 -04:00
🔧 Update docs setup with latest configs and plugins (#11953)
This commit is contained in:
committed by
GitHub
parent
af1a07052a
commit
0cd844d387
@@ -10,8 +10,11 @@ Primeiro, você tem que importá-lo:
|
||||
{!../../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! warning "Aviso"
|
||||
Note que `Field` é importado diretamente do `pydantic`, não do `fastapi` como todo o resto (`Query`, `Path`, `Body`, etc).
|
||||
/// warning | "Aviso"
|
||||
|
||||
Note que `Field` é importado diretamente do `pydantic`, não do `fastapi` como todo o resto (`Query`, `Path`, `Body`, etc).
|
||||
|
||||
///
|
||||
|
||||
## Declare atributos do modelo
|
||||
|
||||
@@ -23,17 +26,23 @@ Você pode então utilizar `Field` com atributos do modelo:
|
||||
|
||||
`Field` funciona da mesma forma que `Query`, `Path` e `Body`, ele possui todos os mesmos parâmetros, etc.
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Na realidade, `Query`, `Path` e outros que você verá em seguida, criam objetos de subclasses de uma classe `Param` comum, que é ela mesma uma subclasse da classe `FieldInfo` do Pydantic.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
E `Field` do Pydantic retorna uma instância de `FieldInfo` também.
|
||||
Na realidade, `Query`, `Path` e outros que você verá em seguida, criam objetos de subclasses de uma classe `Param` comum, que é ela mesma uma subclasse da classe `FieldInfo` do Pydantic.
|
||||
|
||||
`Body` também retorna objetos de uma subclasse de `FieldInfo` diretamente. E tem outras que você verá mais tarde que são subclasses da classe `Body`.
|
||||
E `Field` do Pydantic retorna uma instância de `FieldInfo` também.
|
||||
|
||||
Lembre-se que quando você importa `Query`, `Path`, e outros de `fastapi`, esse são na realidade funções que retornam classes especiais.
|
||||
`Body` também retorna objetos de uma subclasse de `FieldInfo` diretamente. E tem outras que você verá mais tarde que são subclasses da classe `Body`.
|
||||
|
||||
!!! tip "Dica"
|
||||
Note como cada atributo do modelo com um tipo, valor padrão e `Field` possuem a mesma estrutura que parâmetros de *funções de operações de rota*, com `Field` ao invés de `Path`, `Query` e `Body`.
|
||||
Lembre-se que quando você importa `Query`, `Path`, e outros de `fastapi`, esse são na realidade funções que retornam classes especiais.
|
||||
|
||||
///
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Note como cada atributo do modelo com um tipo, valor padrão e `Field` possuem a mesma estrutura que parâmetros de *funções de operações de rota*, com `Field` ao invés de `Path`, `Query` e `Body`.
|
||||
|
||||
///
|
||||
|
||||
## Adicione informações extras
|
||||
|
||||
|
||||
@@ -8,20 +8,27 @@ Primeiro, é claro, você pode misturar `Path`, `Query` e declarações de parâ
|
||||
|
||||
E você também pode declarar parâmetros de corpo como opcionais, definindo o valor padrão com `None`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="17-19"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
|
||||
```
|
||||
```Python hl_lines="17-19"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="19-21"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! note "Nota"
|
||||
Repare que, neste caso, o `item` que seria capturado a partir do corpo é opcional. Visto que ele possui `None` como valor padrão.
|
||||
```Python hl_lines="19-21"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// note | "Nota"
|
||||
|
||||
Repare que, neste caso, o `item` que seria capturado a partir do corpo é opcional. Visto que ele possui `None` como valor padrão.
|
||||
|
||||
///
|
||||
|
||||
## Múltiplos parâmetros de corpo
|
||||
|
||||
@@ -38,17 +45,21 @@ No exemplo anterior, as *operações de rota* esperariam um JSON no corpo conten
|
||||
|
||||
Mas você pode também declarar múltiplos parâmetros de corpo, por exemplo, `item` e `user`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
|
||||
```
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Neste caso, o **FastAPI** perceberá que existe mais de um parâmetro de corpo na função (dois parâmetros que são modelos Pydantic).
|
||||
|
||||
@@ -69,9 +80,11 @@ Então, ele usará o nome dos parâmetros como chaves (nome dos campos) no corpo
|
||||
}
|
||||
```
|
||||
|
||||
!!! note "Nota"
|
||||
Repare que mesmo que o `item` esteja declarado da mesma maneira que antes, agora é esperado que ele esteja dentro do corpo com uma chave `item`.
|
||||
/// note | "Nota"
|
||||
|
||||
Repare que mesmo que o `item` esteja declarado da mesma maneira que antes, agora é esperado que ele esteja dentro do corpo com uma chave `item`.
|
||||
|
||||
///
|
||||
|
||||
O **FastAPI** fará a conversão automática a partir da requisição, assim esse parâmetro `item` receberá seu respectivo conteúdo e o mesmo ocorrerá com `user`.
|
||||
|
||||
@@ -87,17 +100,21 @@ Se você declará-lo como é, porque é um valor singular, o **FastAPI** assumir
|
||||
|
||||
Mas você pode instruir o **FastAPI** para tratá-lo como outra chave do corpo usando `Body`:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
|
||||
```
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+"
|
||||
////
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Neste caso, o **FastAPI** esperará um corpo como:
|
||||
|
||||
@@ -137,20 +154,27 @@ q: str | None = None
|
||||
|
||||
Por exemplo:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="26"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
|
||||
```
|
||||
```Python hl_lines="26"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="27"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! info "Informação"
|
||||
`Body` também possui todas as validações adicionais e metadados de parâmetros como em `Query`,`Path` e outras que você verá depois.
|
||||
```Python hl_lines="27"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info | "Informação"
|
||||
|
||||
`Body` também possui todas as validações adicionais e metadados de parâmetros como em `Query`,`Path` e outras que você verá depois.
|
||||
|
||||
///
|
||||
|
||||
## Declare um único parâmetro de corpo indicando sua chave
|
||||
|
||||
@@ -166,17 +190,21 @@ item: Item = Body(embed=True)
|
||||
|
||||
como em:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
|
||||
```
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Neste caso o **FastAPI** esperará um corpo como:
|
||||
|
||||
|
||||
@@ -165,8 +165,11 @@ Isso vai esperar(converter, validar, documentar, etc) um corpo JSON tal qual:
|
||||
}
|
||||
```
|
||||
|
||||
!!! info "informação"
|
||||
Note como o campo `images` agora tem uma lista de objetos de image.
|
||||
/// info | "informação"
|
||||
|
||||
Note como o campo `images` agora tem uma lista de objetos de image.
|
||||
|
||||
///
|
||||
|
||||
## Modelos profundamente aninhados
|
||||
|
||||
@@ -176,8 +179,11 @@ Você pode definir modelos profundamente aninhados de forma arbitrária:
|
||||
{!../../../docs_src/body_nested_models/tutorial007.py!}
|
||||
```
|
||||
|
||||
!!! info "informação"
|
||||
Note como `Offer` tem uma lista de `Item`s, que por sua vez possui opcionalmente uma lista `Image`s
|
||||
/// info | "informação"
|
||||
|
||||
Note como `Offer` tem uma lista de `Item`s, que por sua vez possui opcionalmente uma lista `Image`s
|
||||
|
||||
///
|
||||
|
||||
## Corpos de listas puras
|
||||
|
||||
@@ -226,14 +232,17 @@ Neste caso, você aceitaria qualquer `dict`, desde que tenha chaves` int` com va
|
||||
{!../../../docs_src/body_nested_models/tutorial009.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Leve em condideração que o JSON só suporta `str` como chaves.
|
||||
/// tip | "Dica"
|
||||
|
||||
Mas o Pydantic tem conversão automática de dados.
|
||||
Leve em condideração que o JSON só suporta `str` como chaves.
|
||||
|
||||
Isso significa que, embora os clientes da API só possam enviar strings como chaves, desde que essas strings contenham inteiros puros, o Pydantic irá convertê-los e validá-los.
|
||||
Mas o Pydantic tem conversão automática de dados.
|
||||
|
||||
E o `dict` que você recebe como `weights` terá, na verdade, chaves `int` e valores` float`.
|
||||
Isso significa que, embora os clientes da API só possam enviar strings como chaves, desde que essas strings contenham inteiros puros, o Pydantic irá convertê-los e validá-los.
|
||||
|
||||
E o `dict` que você recebe como `weights` terá, na verdade, chaves `int` e valores` float`.
|
||||
|
||||
///
|
||||
|
||||
## Recapitulação
|
||||
|
||||
|
||||
@@ -8,12 +8,15 @@ Sua API quase sempre irá enviar um corpo na **resposta**. Mas os clientes não
|
||||
|
||||
Para declarar um corpo da **requisição**, você utiliza os modelos do <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> com todos os seus poderes e benefícios.
|
||||
|
||||
!!! info "Informação"
|
||||
Para enviar dados, você deve usar utilizar um dos métodos: `POST` (Mais comum), `PUT`, `DELETE` ou `PATCH`.
|
||||
/// info | "Informação"
|
||||
|
||||
Enviar um corpo em uma requisição `GET` não tem um comportamento definido nas especificações, porém é suportado pelo FastAPI, apenas para casos de uso bem complexos/extremos.
|
||||
Para enviar dados, você deve usar utilizar um dos métodos: `POST` (Mais comum), `PUT`, `DELETE` ou `PATCH`.
|
||||
|
||||
Como é desencorajado, a documentação interativa com Swagger UI não irá mostrar a documentação para o corpo da requisição para um `GET`, e proxies que intermediarem podem não suportar o corpo da requisição.
|
||||
Enviar um corpo em uma requisição `GET` não tem um comportamento definido nas especificações, porém é suportado pelo FastAPI, apenas para casos de uso bem complexos/extremos.
|
||||
|
||||
Como é desencorajado, a documentação interativa com Swagger UI não irá mostrar a documentação para o corpo da requisição para um `GET`, e proxies que intermediarem podem não suportar o corpo da requisição.
|
||||
|
||||
///
|
||||
|
||||
## Importe o `BaseModel` do Pydantic
|
||||
|
||||
@@ -110,16 +113,19 @@ Mas você terá o mesmo suporte do editor no <a href="https://www.jetbrains.com/
|
||||
|
||||
<img src="/img/tutorial/body/image05.png">
|
||||
|
||||
!!! tip "Dica"
|
||||
Se você utiliza o <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> como editor, você pode utilizar o <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Plugin do Pydantic para o PyCharm </a>.
|
||||
/// tip | "Dica"
|
||||
|
||||
Melhora o suporte do editor para seus modelos Pydantic com::
|
||||
Se você utiliza o <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> como editor, você pode utilizar o <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Plugin do Pydantic para o PyCharm </a>.
|
||||
|
||||
* completação automática
|
||||
* verificação de tipos
|
||||
* refatoração
|
||||
* buscas
|
||||
* inspeções
|
||||
Melhora o suporte do editor para seus modelos Pydantic com::
|
||||
|
||||
* completação automática
|
||||
* verificação de tipos
|
||||
* refatoração
|
||||
* buscas
|
||||
* inspeções
|
||||
|
||||
///
|
||||
|
||||
## Use o modelo
|
||||
|
||||
@@ -155,10 +161,13 @@ Os parâmetros da função serão reconhecidos conforme abaixo:
|
||||
* Se o parâmetro é de um **tipo único** (como `int`, `float`, `str`, `bool`, etc) será interpretado como um parâmetro de **consulta**.
|
||||
* Se o parâmetro é declarado como um **modelo Pydantic**, será interpretado como o **corpo** da requisição.
|
||||
|
||||
!!! note "Observação"
|
||||
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
|
||||
/// note | "Observação"
|
||||
|
||||
O `Union` em `Union[str, None]` não é utilizado pelo FastAPI, mas permite ao seu editor de texto lhe dar um suporte melhor e detectar erros.
|
||||
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
|
||||
|
||||
O `Union` em `Union[str, None]` não é utilizado pelo FastAPI, mas permite ao seu editor de texto lhe dar um suporte melhor e detectar erros.
|
||||
|
||||
///
|
||||
|
||||
## Sem o Pydantic
|
||||
|
||||
|
||||
@@ -20,13 +20,19 @@ O primeiro valor é o valor padrão, você pode passar todas as validações adi
|
||||
{!../../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
`Cookie` é uma classe "irmã" de `Path` e `Query`. Ela também herda da mesma classe em comum `Param`.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
Mas lembre-se que quando você importa `Query`, `Path`, `Cookie` e outras de `fastapi`, elas são na verdade funções que retornam classes especiais.
|
||||
`Cookie` é uma classe "irmã" de `Path` e `Query`. Ela também herda da mesma classe em comum `Param`.
|
||||
|
||||
!!! info "Informação"
|
||||
Para declarar cookies, você precisa usar `Cookie`, caso contrário, os parâmetros seriam interpretados como parâmetros de consulta.
|
||||
Mas lembre-se que quando você importa `Query`, `Path`, `Cookie` e outras de `fastapi`, elas são na verdade funções que retornam classes especiais.
|
||||
|
||||
///
|
||||
|
||||
/// info | "Informação"
|
||||
|
||||
Para declarar cookies, você precisa usar `Cookie`, caso contrário, os parâmetros seriam interpretados como parâmetros de consulta.
|
||||
|
||||
///
|
||||
|
||||
## Recapitulando
|
||||
|
||||
|
||||
@@ -78,7 +78,10 @@ Qualquer solicitação com um cabeçalho `Origin`. Neste caso, o middleware pass
|
||||
|
||||
Para mais informações <abbr title="Cross-Origin Resource Sharing">CORS</abbr>, acesse <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS documentation</a>.
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Você também pode usar `from starlette.middleware.cors import CORSMiddleware`.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
**FastAPI** fornece vários middlewares em `fastapi.middleware` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria dos middlewares disponíveis vêm diretamente da Starlette.
|
||||
Você também pode usar `from starlette.middleware.cors import CORSMiddleware`.
|
||||
|
||||
**FastAPI** fornece vários middlewares em `fastapi.middleware` apenas como uma conveniência para você, o desenvolvedor. Mas a maioria dos middlewares disponíveis vêm diretamente da Starlette.
|
||||
|
||||
///
|
||||
|
||||
@@ -6,41 +6,57 @@ Antes de nos aprofundarmos no sistema de **Injeção de Dependência**, vamos me
|
||||
|
||||
No exemplo anterior, nós retornávamos um `dict` da nossa dependência ("injetável"):
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Mas assim obtemos um `dict` como valor do parâmetro `commons` na *função de operação de rota*.
|
||||
|
||||
@@ -103,123 +119,165 @@ Isso também se aplica a objetos chamáveis que não recebem nenhum parâmetro.
|
||||
|
||||
Então, podemos mudar o "injetável" na dependência `common_parameters` acima para a classe `CommonQueryParams`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="12-16"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="12-16"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="9-13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
```Python hl_lines="9-13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Observe o método `__init__` usado para criar uma instância da classe:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
...ele possui os mesmos parâmetros que nosso `common_parameters` anterior:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Esses parâmetros são utilizados pelo **FastAPI** para "definir" a dependência.
|
||||
|
||||
@@ -235,43 +293,57 @@ Os dados serão convertidos, validados, documentados no esquema da OpenAPI e etc
|
||||
|
||||
Agora você pode declarar sua dependência utilizando essa classe.
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
O **FastAPI** chama a classe `CommonQueryParams`. Isso cria uma "instância" dessa classe e é a instância que será passada para o parâmetro `commons` na sua função.
|
||||
|
||||
@@ -279,21 +351,27 @@ O **FastAPI** chama a classe `CommonQueryParams`. Isso cria uma "instância" des
|
||||
|
||||
Perceba como escrevemos `CommonQueryParams` duas vezes no código abaixo:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
O último `CommonQueryParams`, em:
|
||||
|
||||
@@ -309,81 +387,107 @@ O último `CommonQueryParams`, em:
|
||||
|
||||
Nesse caso, o primeiro `CommonQueryParams`, em:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, ...
|
||||
```
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, ...
|
||||
```
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams ...
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams ...
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
...não tem nenhum signficado especial para o **FastAPI**. O FastAPI não irá utilizá-lo para conversão dos dados, validação, etc (já que ele utiliza `Depends(CommonQueryParams)` para isso).
|
||||
|
||||
Na verdade você poderia escrever apenas:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
```
|
||||
```Python
|
||||
commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python
|
||||
commons = Depends(CommonQueryParams)
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
commons = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
...como em:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Mas declarar o tipo é encorajado por que é a forma que o seu editor de texto sabe o que será passado como valor do parâmetro `commons`.
|
||||
|
||||
@@ -393,20 +497,27 @@ Mas declarar o tipo é encorajado por que é a forma que o seu editor de texto s
|
||||
|
||||
Mas você pode ver que temos uma repetição do código neste exemplo, escrevendo `CommonQueryParams` duas vezes:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
O **FastAPI** nos fornece um atalho para esses casos, onde a dependência é *especificamente* uma classe que o **FastAPI** irá "chamar" para criar uma instância da própria classe.
|
||||
|
||||
@@ -414,84 +525,114 @@ Para esses casos específicos, você pode fazer o seguinte:
|
||||
|
||||
Em vez de escrever:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
```
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
...escreva:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends()]
|
||||
```
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends()]
|
||||
```
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends()
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
commons: CommonQueryParams = Depends()
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Você declara a dependência como o tipo do parâmetro, e utiliza `Depends()` sem nenhum parâmetro, em vez de ter que escrever a classe *novamente* dentro de `Depends(CommonQueryParams)`.
|
||||
|
||||
O mesmo exemplo ficaria então dessa forma:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
...e o **FastAPI** saberá o que fazer.
|
||||
|
||||
!!! tip "Dica"
|
||||
Se isso parece mais confuso do que útil, não utilize, você não *precisa* disso.
|
||||
/// tip | "Dica"
|
||||
|
||||
É apenas um atalho. Por que o **FastAPI** se preocupa em ajudar a minimizar a repetição de código.
|
||||
Se isso parece mais confuso do que útil, não utilize, você não *precisa* disso.
|
||||
|
||||
É apenas um atalho. Por que o **FastAPI** se preocupa em ajudar a minimizar a repetição de código.
|
||||
|
||||
///
|
||||
|
||||
@@ -14,39 +14,55 @@ O *decorador da operação de rota* recebe um argumento opcional `dependencies`.
|
||||
|
||||
Ele deve ser uma lista de `Depends()`:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
Essas dependências serão executadas/resolvidas da mesma forma que dependências comuns. Mas o valor delas (se existir algum) não será passado para a sua *função de operação de rota*.
|
||||
|
||||
!!! tip "Dica"
|
||||
Alguns editores de texto checam parâmetros de funções não utilizados, e os mostram como erros.
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilizando `dependencies` no *decorador da operação de rota* você pode garantir que elas serão executadas enquanto evita errors de editores/ferramentas.
|
||||
Alguns editores de texto checam parâmetros de funções não utilizados, e os mostram como erros.
|
||||
|
||||
Isso também pode ser útil para evitar confundir novos desenvolvedores que ao ver um parâmetro não usado no seu código podem pensar que ele é desnecessário.
|
||||
Utilizando `dependencies` no *decorador da operação de rota* você pode garantir que elas serão executadas enquanto evita errors de editores/ferramentas.
|
||||
|
||||
!!! info "Informação"
|
||||
Neste exemplo utilizamos cabeçalhos personalizados inventados `X-Keys` e `X-Token`.
|
||||
Isso também pode ser útil para evitar confundir novos desenvolvedores que ao ver um parâmetro não usado no seu código podem pensar que ele é desnecessário.
|
||||
|
||||
Mas em situações reais, como implementações de segurança, você pode obter mais vantagens em usar as [Ferramentas de segurança integradas (o próximo capítulo)](../security/index.md){.internal-link target=_blank}.
|
||||
///
|
||||
|
||||
/// info | "Informação"
|
||||
|
||||
Neste exemplo utilizamos cabeçalhos personalizados inventados `X-Keys` e `X-Token`.
|
||||
|
||||
Mas em situações reais, como implementações de segurança, você pode obter mais vantagens em usar as [Ferramentas de segurança integradas (o próximo capítulo)](../security/index.md){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
|
||||
## Erros das dependências e valores de retorno
|
||||
|
||||
@@ -56,51 +72,69 @@ Você pode utilizar as mesmas *funções* de dependências que você usaria norm
|
||||
|
||||
Dependências podem declarar requisitos de requisições (como cabeçalhos) ou outras subdependências:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="7 12"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
```Python hl_lines="7 12"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível
|
||||
////
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### Levantando exceções
|
||||
|
||||
Essas dependências podem levantar exceções, da mesma forma que dependências comuns:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
```Python hl_lines="9 14"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível
|
||||
////
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### Valores de retorno
|
||||
|
||||
@@ -108,26 +142,37 @@ E elas também podem ou não retornar valores, eles não serão utilizados.
|
||||
|
||||
Então, você pode reutilizar uma dependência comum (que retorna um valor) que já seja utilizada em outro lugar, e mesmo que o valor não seja utilizado, a dependência será executada:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível
|
||||
////
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Utilize a versão com `Annotated` se possível
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
{!> ../../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Dependências para um grupo de *operações de rota*
|
||||
|
||||
|
||||
@@ -4,18 +4,24 @@ O FastAPI possui suporte para dependências que realizam <abbr title='também ch
|
||||
|
||||
Para fazer isso, utilize `yield` em vez de `return`, e escreva os passos extras (código) depois.
|
||||
|
||||
!!! tip "Dica"
|
||||
Garanta que `yield` é utilizado apenas uma vez.
|
||||
/// tip | "Dica"
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
Qualquer função que possa ser utilizada com:
|
||||
Garanta que `yield` é utilizado apenas uma vez.
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> ou
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
///
|
||||
|
||||
pode ser utilizada como uma dependência do **FastAPI**.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
Na realidade, o FastAPI utiliza esses dois decoradores internamente.
|
||||
Qualquer função que possa ser utilizada com:
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> ou
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
|
||||
pode ser utilizada como uma dependência do **FastAPI**.
|
||||
|
||||
Na realidade, o FastAPI utiliza esses dois decoradores internamente.
|
||||
|
||||
///
|
||||
|
||||
## Uma dependência de banco de dados com `yield`
|
||||
|
||||
@@ -39,10 +45,13 @@ O código após o `yield` é executado após a resposta ser entregue:
|
||||
{!../../../docs_src/dependencies/tutorial007.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Você pode usar funções assíncronas (`async`) ou funções comuns.
|
||||
/// tip | "Dica"
|
||||
|
||||
O **FastAPI** saberá o que fazer com cada uma, da mesma forma que as dependências comuns.
|
||||
Você pode usar funções assíncronas (`async`) ou funções comuns.
|
||||
|
||||
O **FastAPI** saberá o que fazer com cada uma, da mesma forma que as dependências comuns.
|
||||
|
||||
///
|
||||
|
||||
## Uma dependência com `yield` e `try`
|
||||
|
||||
@@ -66,26 +75,35 @@ O **FastAPI** garantirá que o "código de saída" em cada dependência com `yie
|
||||
|
||||
Por exemplo, `dependency_c` pode depender de `dependency_b`, e `dependency_b` depender de `dependency_a`:
|
||||
|
||||
=== "python 3.9+"
|
||||
//// tab | python 3.9+
|
||||
|
||||
```python hl_lines="6 14 22"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
|
||||
```
|
||||
```python hl_lines="6 14 22"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "python 3.8+"
|
||||
////
|
||||
|
||||
```python hl_lines="5 13 21"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an.py!}
|
||||
```
|
||||
//// tab | python 3.8+
|
||||
|
||||
=== "python 3.8+ non-annotated"
|
||||
```python hl_lines="5 13 21"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
////
|
||||
|
||||
```python hl_lines="4 12 20"
|
||||
{!> ../../../docs_src/dependencies/tutorial008.py!}
|
||||
```
|
||||
//// tab | python 3.8+ non-annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```python hl_lines="4 12 20"
|
||||
{!> ../../../docs_src/dependencies/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
E todas elas podem utilizar `yield`.
|
||||
|
||||
@@ -93,26 +111,35 @@ Neste caso, `dependency_c` precisa que o valor de `dependency_b` (nomeada de `de
|
||||
|
||||
E, por outro lado, `dependency_b` precisa que o valor de `dependency_a` (nomeada de `dep_a`) continue disponível para executar seu código de saída.
|
||||
|
||||
=== "python 3.9+"
|
||||
//// tab | python 3.9+
|
||||
|
||||
```python hl_lines="18-19 26-27"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
|
||||
```
|
||||
```python hl_lines="18-19 26-27"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "python 3.8+"
|
||||
////
|
||||
|
||||
```python hl_lines="17-18 25-26"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an.py!}
|
||||
```
|
||||
//// tab | python 3.8+
|
||||
|
||||
=== "python 3.8+ non-annotated"
|
||||
```python hl_lines="17-18 25-26"
|
||||
{!> ../../../docs_src/dependencies/tutorial008_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
////
|
||||
|
||||
```python hl_lines="16-17 24-25"
|
||||
{!> ../../../docs_src/dependencies/tutorial008.py!}
|
||||
```
|
||||
//// tab | python 3.8+ non-annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```python hl_lines="16-17 24-25"
|
||||
{!> ../../../docs_src/dependencies/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Da mesma forma, você pode ter algumas dependências com `yield` e outras com `return` e ter uma relação de dependência entre algumas dos dois tipos.
|
||||
|
||||
@@ -122,10 +149,13 @@ Você pode ter qualquer combinação de dependências que você quiser.
|
||||
|
||||
O **FastAPI** se encarrega de executá-las na ordem certa.
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
Tudo isso funciona graças aos <a href="https://docs.python.org/3/library/contextlib.html" class="external-link" target="_blank">gerenciadores de contexto</a> do Python.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
O **FastAPI** utiliza eles internamente para alcançar isso.
|
||||
Tudo isso funciona graças aos <a href="https://docs.python.org/3/library/contextlib.html" class="external-link" target="_blank">gerenciadores de contexto</a> do Python.
|
||||
|
||||
O **FastAPI** utiliza eles internamente para alcançar isso.
|
||||
|
||||
///
|
||||
|
||||
## Dependências com `yield` e `httpexception`
|
||||
|
||||
@@ -133,32 +163,43 @@ Você viu que dependências podem ser utilizadas com `yield` e podem incluir blo
|
||||
|
||||
Da mesma forma, você pode lançar uma `httpexception` ou algo parecido no código de saída, após o `yield`
|
||||
|
||||
!!! tip "Dica"
|
||||
/// tip | "Dica"
|
||||
|
||||
Essa é uma técnica relativamente avançada, e na maioria dos casos você não precisa dela totalmente, já que você pode lançar exceções (incluindo `httpexception`) dentro do resto do código da sua aplicação, por exemplo, em uma *função de operação de rota*.
|
||||
Essa é uma técnica relativamente avançada, e na maioria dos casos você não precisa dela totalmente, já que você pode lançar exceções (incluindo `httpexception`) dentro do resto do código da sua aplicação, por exemplo, em uma *função de operação de rota*.
|
||||
|
||||
Mas ela existe para ser utilizada caso você precise. 🤓
|
||||
Mas ela existe para ser utilizada caso você precise. 🤓
|
||||
|
||||
=== "python 3.9+"
|
||||
///
|
||||
|
||||
```python hl_lines="18-22 31"
|
||||
{!> ../../../docs_src/dependencies/tutorial008b_an_py39.py!}
|
||||
```
|
||||
//// tab | python 3.9+
|
||||
|
||||
=== "python 3.8+"
|
||||
```python hl_lines="18-22 31"
|
||||
{!> ../../../docs_src/dependencies/tutorial008b_an_py39.py!}
|
||||
```
|
||||
|
||||
```python hl_lines="17-21 30"
|
||||
{!> ../../../docs_src/dependencies/tutorial008b_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "python 3.8+ non-annotated"
|
||||
//// tab | python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```python hl_lines="17-21 30"
|
||||
{!> ../../../docs_src/dependencies/tutorial008b_an.py!}
|
||||
```
|
||||
|
||||
```python hl_lines="16-20 29"
|
||||
{!> ../../../docs_src/dependencies/tutorial008b.py!}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | python 3.8+ non-annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```python hl_lines="16-20 29"
|
||||
{!> ../../../docs_src/dependencies/tutorial008b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Uma alternativa que você pode utilizar para capturar exceções (e possivelmente lançar outra HTTPException) é criar um [Manipulador de Exceções Customizado](../handling-errors.md#instalando-manipuladores-de-excecoes-customizados){.internal-link target=_blank}.
|
||||
|
||||
@@ -166,26 +207,35 @@ Uma alternativa que você pode utilizar para capturar exceções (e possivelment
|
||||
|
||||
Se você capturar uma exceção com `except` em uma dependência que utilize `yield` e ela não for levantada novamente (ou uma nova exceção for levantada), o FastAPI não será capaz de identifcar que houve uma exceção, da mesma forma que aconteceria com Python puro:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="15-16"
|
||||
{!> ../../../docs_src/dependencies/tutorial008c_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="15-16"
|
||||
{!> ../../../docs_src/dependencies/tutorial008c_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="14-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial008c_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "Python 3.8+ non-annotated"
|
||||
```Python hl_lines="14-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial008c_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "dica"
|
||||
utilize a versão com `Annotated` se possível.
|
||||
////
|
||||
|
||||
```Python hl_lines="13-14"
|
||||
{!> ../../../docs_src/dependencies/tutorial008c.py!}
|
||||
```
|
||||
//// tab | Python 3.8+ non-annotated
|
||||
|
||||
/// tip | "dica"
|
||||
|
||||
utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="13-14"
|
||||
{!> ../../../docs_src/dependencies/tutorial008c.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Neste caso, o cliente irá ver uma resposta *HTTP 500 Internal Server Error* como deveria acontecer, já que não estamos levantando nenhuma `HTTPException` ou coisa parecida, mas o servidor **não terá nenhum log** ou qualquer outra indicação de qual foi o erro. 😱
|
||||
|
||||
@@ -195,26 +245,35 @@ Se você capturar uma exceção em uma dependência com `yield`, a menos que voc
|
||||
|
||||
Você pode relançar a mesma exceção utilizando `raise`:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial008d_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial008d_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/dependencies/tutorial008d_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "python 3.8+ non-annotated"
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/dependencies/tutorial008d_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
////
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/dependencies/tutorial008d.py!}
|
||||
```
|
||||
//// tab | python 3.8+ non-annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/dependencies/tutorial008d.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Agora o cliente irá receber a mesma resposta *HTTP 500 Internal Server Error*, mas o servidor terá nosso `InternalError` personalizado nos logs. 😎
|
||||
|
||||
@@ -257,22 +316,31 @@ participant tasks as Tarefas de Background
|
||||
end
|
||||
```
|
||||
|
||||
!!! info "Informação"
|
||||
Apenas **uma resposta** será enviada para o cliente. Ela pode ser uma das respostas de erro, ou então a resposta da *operação de rota*.
|
||||
/// info | "Informação"
|
||||
|
||||
Após uma dessas respostas ser enviada, nenhuma outra resposta pode ser enviada
|
||||
Apenas **uma resposta** será enviada para o cliente. Ela pode ser uma das respostas de erro, ou então a resposta da *operação de rota*.
|
||||
|
||||
!!! tip "Dica"
|
||||
Esse diagrama mostra `HttpException`, mas você pode levantar qualquer outra exceção que você capture em uma dependência com `yield` ou um [Manipulador de exceções personalizado](../handling-errors.md#instalando-manipuladores-de-excecoes-customizados){.internal-link target=_blank}.
|
||||
Após uma dessas respostas ser enviada, nenhuma outra resposta pode ser enviada
|
||||
|
||||
Se você lançar qualquer exceção, ela será passada para as dependências com yield, inlcuindo a `HTTPException`. Na maioria dos casos você vai querer relançar essa mesma exceção ou uma nova a partir da dependência com `yield` para garantir que ela seja tratada adequadamente.
|
||||
///
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Esse diagrama mostra `HttpException`, mas você pode levantar qualquer outra exceção que você capture em uma dependência com `yield` ou um [Manipulador de exceções personalizado](../handling-errors.md#instalando-manipuladores-de-excecoes-customizados){.internal-link target=_blank}.
|
||||
|
||||
Se você lançar qualquer exceção, ela será passada para as dependências com yield, inlcuindo a `HTTPException`. Na maioria dos casos você vai querer relançar essa mesma exceção ou uma nova a partir da dependência com `yield` para garantir que ela seja tratada adequadamente.
|
||||
|
||||
///
|
||||
|
||||
## Dependências com `yield`, `HTTPException`, `except` e Tarefas de Background
|
||||
|
||||
!!! warning "Aviso"
|
||||
Você provavelmente não precisa desses detalhes técnicos, você pode pular essa seção e continuar na próxima seção abaixo.
|
||||
/// warning | "Aviso"
|
||||
|
||||
Esses detalhes são úteis principalmente se você estiver usando uma versão do FastAPI anterior à 0.106.0 e utilizando recursos de dependências com `yield` em tarefas de background.
|
||||
Você provavelmente não precisa desses detalhes técnicos, você pode pular essa seção e continuar na próxima seção abaixo.
|
||||
|
||||
Esses detalhes são úteis principalmente se você estiver usando uma versão do FastAPI anterior à 0.106.0 e utilizando recursos de dependências com `yield` em tarefas de background.
|
||||
|
||||
///
|
||||
|
||||
### Dependências com `yield` e `except`, Detalhes Técnicos
|
||||
|
||||
@@ -288,11 +356,13 @@ Isso foi implementado dessa forma principalmente para permitir que os mesmos obj
|
||||
|
||||
Ainda assim, como isso exigiria esperar que a resposta navegasse pela rede enquanto mantia ativo um recurso desnecessário na dependência com yield (por exemplo, uma conexão com banco de dados), isso mudou na versão 0.106.0 do FastAPI.
|
||||
|
||||
!!! tip "Dica"
|
||||
/// tip | "Dica"
|
||||
|
||||
Adicionalmente, uma tarefa de background é, normalmente, um conjunto de lógicas independentes que devem ser manipuladas separadamente, com seus próprios recursos (e.g. sua própria conexão com banco de dados).
|
||||
Adicionalmente, uma tarefa de background é, normalmente, um conjunto de lógicas independentes que devem ser manipuladas separadamente, com seus próprios recursos (e.g. sua própria conexão com banco de dados).
|
||||
|
||||
Então, dessa forma você provavelmente terá um código mais limpo.
|
||||
Então, dessa forma você provavelmente terá um código mais limpo.
|
||||
|
||||
///
|
||||
|
||||
Se você costumava depender desse comportamento, agora você precisa criar os recursos para uma tarefa de background dentro dela mesma, e usar internamente apenas dados que não dependam de recursos de dependências com `yield`.
|
||||
|
||||
@@ -320,10 +390,13 @@ Quando você cria uma dependência com `yield`, o **FastAPI** irá criar um gere
|
||||
|
||||
### Utilizando gerenciadores de contexto em dependências com `yield`
|
||||
|
||||
!!! warning "Aviso"
|
||||
Isso é uma ideia mais ou menos "avançada".
|
||||
/// warning | "Aviso"
|
||||
|
||||
Se você está apenas iniciando com o **FastAPI** você pode querer pular isso por enquanto.
|
||||
Isso é uma ideia mais ou menos "avançada".
|
||||
|
||||
Se você está apenas iniciando com o **FastAPI** você pode querer pular isso por enquanto.
|
||||
|
||||
///
|
||||
|
||||
Em python, você pode criar Gerenciadores de Contexto ao <a href="https://docs.python.org/3/reference/datamodel.html#context-managers" class="external-link" target="_blank"> criar uma classe com dois métodos: `__enter__()` e `__exit__()`</a>.
|
||||
|
||||
@@ -333,17 +406,20 @@ Você também pode usá-los dentro de dependências com `yield` do **FastAPI** a
|
||||
{!../../../docs_src/dependencies/tutorial010.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Outra forma de criar um gerenciador de contexto é utilizando:
|
||||
/// tip | "Dica"
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> ou
|
||||
Outra forma de criar um gerenciador de contexto é utilizando:
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> ou
|
||||
|
||||
Para decorar uma função com um único `yield`.
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
|
||||
Isso é o que o **FastAPI** usa internamente para dependências com `yield`.
|
||||
Para decorar uma função com um único `yield`.
|
||||
|
||||
Mas você não precisa usar esses decoradores para as dependências do FastAPI (e você não deveria).
|
||||
Isso é o que o **FastAPI** usa internamente para dependências com `yield`.
|
||||
|
||||
O FastAPI irá fazer isso para você internamente.
|
||||
Mas você não precisa usar esses decoradores para as dependências do FastAPI (e você não deveria).
|
||||
|
||||
O FastAPI irá fazer isso para você internamente.
|
||||
|
||||
///
|
||||
|
||||
@@ -6,26 +6,35 @@ De forma semelhante a [adicionar dependências (`dependencies`) em *decoradores
|
||||
|
||||
Nesse caso, elas serão aplicadas a todas as *operações de rota* da aplicação:
|
||||
|
||||
=== "Python 3.9+"
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/dependencies/tutorial012_an_py39.py!}
|
||||
```
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/dependencies/tutorial012_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/dependencies/tutorial012_an.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/dependencies/tutorial012_an.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
////
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/dependencies/tutorial012.py!}
|
||||
```
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/dependencies/tutorial012.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
E todos os conceitos apresentados na sessão sobre [adicionar dependências em *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} ainda se aplicam, mas nesse caso, para todas as *operações de rota* da aplicação.
|
||||
|
||||
|
||||
@@ -31,41 +31,57 @@ Primeiro vamos focar na dependência.
|
||||
|
||||
Ela é apenas uma função que pode receber os mesmos parâmetros de uma *função de operação de rota*:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="8-11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="8-11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="9-12"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="9-12"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="8-11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8-11"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
E pronto.
|
||||
|
||||
@@ -85,90 +101,125 @@ Neste caso, a dependência espera por:
|
||||
|
||||
E então retorna um `dict` contendo esses valores.
|
||||
|
||||
!!! info "Informação"
|
||||
FastAPI passou a suportar a notação `Annotated` (e começou a recomendá-la) na versão 0.95.0.
|
||||
/// info | "Informação"
|
||||
|
||||
Se você utiliza uma versão anterior, ocorrerão erros ao tentar utilizar `Annotated`.
|
||||
FastAPI passou a suportar a notação `Annotated` (e começou a recomendá-la) na versão 0.95.0.
|
||||
|
||||
Certifique-se de [Atualizar a versão do FastAPI](../../deployment/versions.md#atualizando-as-versoes-do-fastapi){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
|
||||
Se você utiliza uma versão anterior, ocorrerão erros ao tentar utilizar `Annotated`.
|
||||
|
||||
Certifique-se de [Atualizar a versão do FastAPI](../../deployment/versions.md#atualizando-as-versoes-do-fastapi){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
|
||||
|
||||
///
|
||||
|
||||
### Importando `Depends`
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### Declarando a dependência, no "dependente"
|
||||
|
||||
Da mesma forma que você utiliza `Body`, `Query`, etc. Como parâmetros de sua *função de operação de rota*, utilize `Depends` com um novo parâmetro:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="13 18"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="13 18"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="15 20"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="15 20"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="16 21"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="16 21"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
//// tab | Python 3.10+ non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="15 20"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="15 20"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Ainda que `Depends` seja utilizado nos parâmetros da função da mesma forma que `Body`, `Query`, etc, `Depends` funciona de uma forma um pouco diferente.
|
||||
|
||||
@@ -180,8 +231,11 @@ Você **não chama a função** diretamente (não adicione os parênteses no fin
|
||||
|
||||
E essa função vai receber os parâmetros da mesma forma que uma *função de operação de rota*.
|
||||
|
||||
!!! tip "Dica"
|
||||
Você verá quais outras "coisas", além de funções, podem ser usadas como dependências no próximo capítulo.
|
||||
/// tip | "Dica"
|
||||
|
||||
Você verá quais outras "coisas", além de funções, podem ser usadas como dependências no próximo capítulo.
|
||||
|
||||
///
|
||||
|
||||
Sempre que uma nova requisição for realizada, o **FastAPI** se encarrega de:
|
||||
|
||||
@@ -202,10 +256,13 @@ common_parameters --> read_users
|
||||
|
||||
Assim, você escreve um código compartilhado apenas uma vez e o **FastAPI** se encarrega de chamá-lo em suas *operações de rota*.
|
||||
|
||||
!!! check "Checando"
|
||||
Perceba que você não precisa criar uma classe especial e enviar a dependência para algum outro lugar em que o **FastAPI** a "registre" ou realize qualquer operação similar.
|
||||
/// check | "Checando"
|
||||
|
||||
Você apenas envia para `Depends` e o **FastAPI** sabe como fazer o resto.
|
||||
Perceba que você não precisa criar uma classe especial e enviar a dependência para algum outro lugar em que o **FastAPI** a "registre" ou realize qualquer operação similar.
|
||||
|
||||
Você apenas envia para `Depends` e o **FastAPI** sabe como fazer o resto.
|
||||
|
||||
///
|
||||
|
||||
## Compartilhando dependências `Annotated`
|
||||
|
||||
@@ -219,28 +276,37 @@ commons: Annotated[dict, Depends(common_parameters)]
|
||||
|
||||
Mas como estamos utilizando `Annotated`, podemos guardar esse valor `Annotated` em uma variável e utilizá-la em múltiplos locais:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12 16 21"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="12 16 21"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="14 18 23"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="14 18 23"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="15 19 24"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_02_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Isso é apenas Python padrão, essa funcionalidade é chamada de "type alias", e na verdade não é específica ao **FastAPI**.
|
||||
//// tab | Python 3.8+
|
||||
|
||||
Mas como o **FastAPI** se baseia em convenções do Python, incluindo `Annotated`, você pode incluir esse truque no seu código. 😎
|
||||
```Python hl_lines="15 19 24"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_02_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Isso é apenas Python padrão, essa funcionalidade é chamada de "type alias", e na verdade não é específica ao **FastAPI**.
|
||||
|
||||
Mas como o **FastAPI** se baseia em convenções do Python, incluindo `Annotated`, você pode incluir esse truque no seu código. 😎
|
||||
|
||||
///
|
||||
|
||||
As dependências continuarão funcionando como esperado, e a **melhor parte** é que a **informação sobre o tipo é preservada**, o que signfica que seu editor de texto ainda irá incluir **preenchimento automático**, **visualização de erros**, etc. O mesmo vale para ferramentas como `mypy`.
|
||||
|
||||
@@ -256,8 +322,11 @@ E você pode declarar dependências utilizando `async def` dentro de *funções
|
||||
|
||||
Não faz diferença. O **FastAPI** sabe o que fazer.
|
||||
|
||||
!!! note "Nota"
|
||||
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#com-pressa){.internal-link target=_blank} a sessão acerca de `async` e `await` na documentação.
|
||||
/// note | "Nota"
|
||||
|
||||
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#com-pressa){.internal-link target=_blank} a sessão acerca de `async` e `await` na documentação.
|
||||
|
||||
///
|
||||
|
||||
## Integrando com OpenAPI
|
||||
|
||||
|
||||
@@ -10,41 +10,57 @@ O **FastAPI** se encarrega de resolver essas dependências.
|
||||
|
||||
Você pode criar uma primeira dependência (injetável) dessa forma:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="9-10"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10 non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="9-10"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
//// tab | Python 3.10 non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Esse código declara um parâmetro de consulta opcional, `q`, com o tipo `str`, e então retorna esse parâmetro.
|
||||
|
||||
@@ -54,41 +70,57 @@ Isso é bastante simples (e não muito útil), mas irá nos ajudar a focar em co
|
||||
|
||||
Então, você pode criar uma outra função para uma dependência (um "injetável") que ao mesmo tempo declara sua própria dependência (o que faz dela um "dependente" também):
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10 non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
//// tab | Python 3.10 non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Vamos focar nos parâmetros declarados:
|
||||
|
||||
@@ -101,46 +133,65 @@ Vamos focar nos parâmetros declarados:
|
||||
|
||||
Então podemos utilizar a dependência com:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.10 non-Annotated"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
```Python hl_lines="24"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
=== "Python 3.8 non-Annotated"
|
||||
//// tab | Python 3.10 non-Annotated
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
/// tip | "Dica"
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
!!! info "Informação"
|
||||
Perceba que nós estamos declarando apenas uma dependência na *função de operação de rota*, em `query_or_cookie_extractor`.
|
||||
///
|
||||
|
||||
Mas o **FastAPI** saberá que precisa solucionar `query_extractor` primeiro, para passar o resultado para `query_or_cookie_extractor` enquanto chama a função.
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 non-Annotated
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info | "Informação"
|
||||
|
||||
Perceba que nós estamos declarando apenas uma dependência na *função de operação de rota*, em `query_or_cookie_extractor`.
|
||||
|
||||
Mas o **FastAPI** saberá que precisa solucionar `query_extractor` primeiro, para passar o resultado para `query_or_cookie_extractor` enquanto chama a função.
|
||||
|
||||
///
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
@@ -161,22 +212,29 @@ E o valor retornado é salvo em um <abbr title="Um utilitário/sistema para arma
|
||||
|
||||
Em um cenário avançado onde você precise que a dependência seja calculada em cada passo (possivelmente várias vezes) de uma requisição em vez de utilizar o valor em "cache", você pode definir o parâmetro `use_cache=False` em `Depends`:
|
||||
|
||||
=== "Python 3.8+"
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
|
||||
return {"fresh_value": fresh_value}
|
||||
```
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
|
||||
return {"fresh_value": fresh_value}
|
||||
```
|
||||
|
||||
=== "Python 3.8+ non-Annotated"
|
||||
////
|
||||
|
||||
!!! tip "Dica"
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
//// tab | Python 3.8+ non-Annotated
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
|
||||
return {"fresh_value": fresh_value}
|
||||
```
|
||||
/// tip | "Dica"
|
||||
|
||||
Utilize a versão com `Annotated` se possível.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
|
||||
return {"fresh_value": fresh_value}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Recapitulando
|
||||
|
||||
@@ -186,9 +244,12 @@ Consiste apenas de funções que parecem idênticas a *funções de operação d
|
||||
|
||||
Mas ainda assim, é bastante poderoso, e permite que você declare grafos (árvores) de dependências com uma profundidade arbitrária.
|
||||
|
||||
!!! tip "Dica"
|
||||
Tudo isso pode não parecer muito útil com esses exemplos.
|
||||
/// tip | "Dica"
|
||||
|
||||
Mas você verá o quão útil isso é nos capítulos sobre **segurança**.
|
||||
Tudo isso pode não parecer muito útil com esses exemplos.
|
||||
|
||||
E você também verá a quantidade de código que você não precisara escrever.
|
||||
Mas você verá o quão útil isso é nos capítulos sobre **segurança**.
|
||||
|
||||
E você também verá a quantidade de código que você não precisara escrever.
|
||||
|
||||
///
|
||||
|
||||
@@ -20,17 +20,21 @@ Você pode usar a função `jsonable_encoder` para resolver isso.
|
||||
|
||||
A função recebe um objeto, como um modelo Pydantic e retorna uma versão compatível com JSON:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="4 21"
|
||||
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
|
||||
```
|
||||
```Python hl_lines="4 21"
|
||||
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="5 22"
|
||||
{!> ../../../docs_src/encoder/tutorial001.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="5 22"
|
||||
{!> ../../../docs_src/encoder/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Neste exemplo, ele converteria o modelo Pydantic em um `dict`, e o `datetime` em um `str`.
|
||||
|
||||
@@ -38,5 +42,8 @@ O resultado de chamar a função é algo que pode ser codificado com o padrão d
|
||||
|
||||
A função não retorna um grande `str` contendo os dados no formato JSON (como uma string). Mas sim, retorna uma estrutura de dados padrão do Python (por exemplo, um `dict`) com valores e subvalores compatíveis com JSON.
|
||||
|
||||
!!! note "Nota"
|
||||
`jsonable_encoder` é realmente usado pelo **FastAPI** internamente para converter dados. Mas também é útil em muitos outros cenários.
|
||||
/// note | "Nota"
|
||||
|
||||
`jsonable_encoder` é realmente usado pelo **FastAPI** internamente para converter dados. Mas também é útil em muitos outros cenários.
|
||||
|
||||
///
|
||||
|
||||
@@ -8,26 +8,33 @@ Isso é especialmente o caso para modelos de usuários, porque:
|
||||
* O **modelo de saída** não deve ter uma senha.
|
||||
* O **modelo de banco de dados** provavelmente precisaria ter uma senha criptografada.
|
||||
|
||||
!!! danger
|
||||
Nunca armazene senhas em texto simples dos usuários. Sempre armazene uma "hash segura" que você pode verificar depois.
|
||||
/// danger
|
||||
|
||||
Se não souber, você aprenderá o que é uma "senha hash" nos [capítulos de segurança](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
|
||||
Nunca armazene senhas em texto simples dos usuários. Sempre armazene uma "hash segura" que você pode verificar depois.
|
||||
|
||||
Se não souber, você aprenderá o que é uma "senha hash" nos [capítulos de segurança](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
|
||||
## Múltiplos modelos
|
||||
|
||||
Aqui está uma ideia geral de como os modelos poderiam parecer com seus campos de senha e os lugares onde são usados:
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
|
||||
{!> ../../../docs_src/extra_models/tutorial001.py!}
|
||||
```
|
||||
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
|
||||
{!> ../../../docs_src/extra_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
|
||||
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
|
||||
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### Sobre `**user_in.dict()`
|
||||
|
||||
@@ -139,8 +146,11 @@ UserInDB(
|
||||
)
|
||||
```
|
||||
|
||||
!!! warning
|
||||
As funções adicionais de suporte são apenas para demonstração de um fluxo possível dos dados, mas é claro que elas não fornecem segurança real.
|
||||
/// warning
|
||||
|
||||
As funções adicionais de suporte são apenas para demonstração de um fluxo possível dos dados, mas é claro que elas não fornecem segurança real.
|
||||
|
||||
///
|
||||
|
||||
## Reduzir duplicação
|
||||
|
||||
@@ -158,17 +168,21 @@ Toda conversão de dados, validação, documentação, etc. ainda funcionará no
|
||||
|
||||
Dessa forma, podemos declarar apenas as diferenças entre os modelos (com `password` em texto claro, com `hashed_password` e sem senha):
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="9 15-16 19-20 23-24"
|
||||
{!> ../../../docs_src/extra_models/tutorial002.py!}
|
||||
```
|
||||
```Python hl_lines="9 15-16 19-20 23-24"
|
||||
{!> ../../../docs_src/extra_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="7 13-14 17-18 21-22"
|
||||
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
|
||||
```
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="7 13-14 17-18 21-22"
|
||||
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## `Union` ou `anyOf`
|
||||
|
||||
@@ -178,20 +192,27 @@ Isso será definido no OpenAPI com `anyOf`.
|
||||
|
||||
Para fazer isso, use a dica de tipo padrão do Python <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>:
|
||||
|
||||
!!! note
|
||||
Ao definir um <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>, inclua o tipo mais específico primeiro, seguido pelo tipo menos específico. No exemplo abaixo, o tipo mais específico `PlaneItem` vem antes de `CarItem` em `Union[PlaneItem, CarItem]`.
|
||||
/// note
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
Ao definir um <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>, inclua o tipo mais específico primeiro, seguido pelo tipo menos específico. No exemplo abaixo, o tipo mais específico `PlaneItem` vem antes de `CarItem` em `Union[PlaneItem, CarItem]`.
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003.py!}
|
||||
```
|
||||
///
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
|
||||
```
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
### `Union` no Python 3.10
|
||||
|
||||
@@ -213,17 +234,21 @@ Da mesma forma, você pode declarar respostas de listas de objetos.
|
||||
|
||||
Para isso, use o padrão Python `typing.List` (ou simplesmente `list` no Python 3.9 e superior):
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="1 20"
|
||||
{!> ../../../docs_src/extra_models/tutorial004.py!}
|
||||
```
|
||||
```Python hl_lines="1 20"
|
||||
{!> ../../../docs_src/extra_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Resposta com `dict` arbitrário
|
||||
|
||||
@@ -233,17 +258,21 @@ Isso é útil se você não souber os nomes de campo / atributo válidos (que se
|
||||
|
||||
Neste caso, você pode usar `typing.Dict` (ou simplesmente dict no Python 3.9 e superior):
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="1 8"
|
||||
{!> ../../../docs_src/extra_models/tutorial005.py!}
|
||||
```
|
||||
```Python hl_lines="1 8"
|
||||
{!> ../../../docs_src/extra_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Em resumo
|
||||
|
||||
|
||||
@@ -24,12 +24,15 @@ $ uvicorn main:app --reload
|
||||
|
||||
</div>
|
||||
|
||||
!!! note "Nota"
|
||||
O comando `uvicorn main:app` se refere a:
|
||||
/// note | "Nota"
|
||||
|
||||
* `main`: o arquivo `main.py` (o "módulo" Python).
|
||||
* `app`: o objeto criado no arquivo `main.py` com a linha `app = FastAPI()`.
|
||||
* `--reload`: faz o servidor reiniciar após mudanças de código. Use apenas para desenvolvimento.
|
||||
O comando `uvicorn main:app` se refere a:
|
||||
|
||||
* `main`: o arquivo `main.py` (o "módulo" Python).
|
||||
* `app`: o objeto criado no arquivo `main.py` com a linha `app = FastAPI()`.
|
||||
* `--reload`: faz o servidor reiniciar após mudanças de código. Use apenas para desenvolvimento.
|
||||
|
||||
///
|
||||
|
||||
Na saída, temos:
|
||||
|
||||
@@ -136,10 +139,13 @@ Você também pode usá-lo para gerar código automaticamente para clientes que
|
||||
|
||||
`FastAPI` é uma classe Python que fornece todas as funcionalidades para sua API.
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
`FastAPI` é uma classe que herda diretamente de `Starlette`.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
Você pode usar todas as funcionalidades do <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> com `FastAPI` também.
|
||||
`FastAPI` é uma classe que herda diretamente de `Starlette`.
|
||||
|
||||
Você pode usar todas as funcionalidades do <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> com `FastAPI` também.
|
||||
|
||||
///
|
||||
|
||||
### Passo 2: crie uma "instância" de `FastAPI`
|
||||
|
||||
@@ -199,8 +205,11 @@ https://example.com/items/foo
|
||||
/items/foo
|
||||
```
|
||||
|
||||
!!! info "Informação"
|
||||
Uma "rota" também é comumente chamada de "endpoint".
|
||||
/// info | "Informação"
|
||||
|
||||
Uma "rota" também é comumente chamada de "endpoint".
|
||||
|
||||
///
|
||||
|
||||
Ao construir uma API, a "rota" é a principal forma de separar "preocupações" e "recursos".
|
||||
|
||||
@@ -250,16 +259,19 @@ O `@app.get("/")` diz ao **FastAPI** que a função logo abaixo é responsável
|
||||
* a rota `/`
|
||||
* usando o <abbr title="o método HTTP GET">operador <code>get</code></abbr>
|
||||
|
||||
!!! info "`@decorador`"
|
||||
Essa sintaxe `@alguma_coisa` em Python é chamada de "decorador".
|
||||
/// info | "`@decorador`"
|
||||
|
||||
Você o coloca em cima de uma função. Como um chapéu decorativo (acho que é daí que vem o termo).
|
||||
Essa sintaxe `@alguma_coisa` em Python é chamada de "decorador".
|
||||
|
||||
Um "decorador" pega a função abaixo e faz algo com ela.
|
||||
Você o coloca em cima de uma função. Como um chapéu decorativo (acho que é daí que vem o termo).
|
||||
|
||||
Em nosso caso, este decorador informa ao **FastAPI** que a função abaixo corresponde a **rota** `/` com uma **operação** `get`.
|
||||
Um "decorador" pega a função abaixo e faz algo com ela.
|
||||
|
||||
É o "**decorador de rota**".
|
||||
Em nosso caso, este decorador informa ao **FastAPI** que a função abaixo corresponde a **rota** `/` com uma **operação** `get`.
|
||||
|
||||
É o "**decorador de rota**".
|
||||
|
||||
///
|
||||
|
||||
Você também pode usar as outras operações:
|
||||
|
||||
@@ -274,14 +286,17 @@ E os mais exóticos:
|
||||
* `@app.patch()`
|
||||
* `@app.trace()`
|
||||
|
||||
!!! tip "Dica"
|
||||
Você está livre para usar cada operação (método HTTP) como desejar.
|
||||
/// tip | "Dica"
|
||||
|
||||
O **FastAPI** não impõe nenhum significado específico.
|
||||
Você está livre para usar cada operação (método HTTP) como desejar.
|
||||
|
||||
As informações aqui são apresentadas como uma orientação, não uma exigência.
|
||||
O **FastAPI** não impõe nenhum significado específico.
|
||||
|
||||
Por exemplo, ao usar GraphQL, você normalmente executa todas as ações usando apenas operações `POST`.
|
||||
As informações aqui são apresentadas como uma orientação, não uma exigência.
|
||||
|
||||
Por exemplo, ao usar GraphQL, você normalmente executa todas as ações usando apenas operações `POST`.
|
||||
|
||||
///
|
||||
|
||||
### Passo 4: defina uma **função de rota**
|
||||
|
||||
@@ -309,8 +324,11 @@ Você também pode defini-la como uma função normal em vez de `async def`:
|
||||
{!../../../docs_src/first_steps/tutorial003.py!}
|
||||
```
|
||||
|
||||
!!! note "Nota"
|
||||
Se você não sabe a diferença, verifique o [Async: *"Com pressa?"*](../async.md#com-pressa){.internal-link target=_blank}.
|
||||
/// note | "Nota"
|
||||
|
||||
Se você não sabe a diferença, verifique o [Async: *"Com pressa?"*](../async.md#com-pressa){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
|
||||
### Passo 5: retorne o conteúdo
|
||||
|
||||
|
||||
@@ -66,12 +66,14 @@ Mas se o cliente faz uma requisição para `http://example.com/items/bar` (ou se
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Quando você lançar um `HTTPException`, você pode passar qualquer valor convertível em JSON como parâmetro de `detail`, e não apenas `str`.
|
||||
/// tip | "Dica"
|
||||
|
||||
Você pode passar um `dict` ou um `list`, etc.
|
||||
Esses tipos de dados são manipulados automaticamente pelo **FastAPI** e convertidos em JSON.
|
||||
Quando você lançar um `HTTPException`, você pode passar qualquer valor convertível em JSON como parâmetro de `detail`, e não apenas `str`.
|
||||
|
||||
Você pode passar um `dict` ou um `list`, etc.
|
||||
Esses tipos de dados são manipulados automaticamente pelo **FastAPI** e convertidos em JSON.
|
||||
|
||||
///
|
||||
|
||||
## Adicione headers customizados
|
||||
|
||||
@@ -107,10 +109,13 @@ Dessa forma você receberá um erro "limpo", com o HTTP status code `418` e um J
|
||||
{"message": "Oops! yolo did something. There goes a rainbow..."}
|
||||
```
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
Você também pode usar `from starlette.requests import Request` and `from starlette.responses import JSONResponse`.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
**FastAPI** disponibiliza o mesmo `starlette.responses` através do `fastapi.responses` por conveniência ao desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette. O mesmo acontece com o `Request`.
|
||||
Você também pode usar `from starlette.requests import Request` and `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** disponibiliza o mesmo `starlette.responses` através do `fastapi.responses` por conveniência ao desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette. O mesmo acontece com o `Request`.
|
||||
|
||||
///
|
||||
|
||||
## Sobrescreva o manipulador padrão de exceções
|
||||
|
||||
@@ -157,8 +162,11 @@ path -> item_id
|
||||
|
||||
### `RequestValidationError` vs `ValidationError`
|
||||
|
||||
!!! warning "Aviso"
|
||||
Você pode pular estes detalhes técnicos caso eles não sejam importantes para você neste momento.
|
||||
/// warning | "Aviso"
|
||||
|
||||
Você pode pular estes detalhes técnicos caso eles não sejam importantes para você neste momento.
|
||||
|
||||
///
|
||||
|
||||
`RequestValidationError` é uma subclasse do <a href="https://docs.pydantic.dev/latest/#error-handling" class="external-link" target="_blank">`ValidationError`</a> existente no Pydantic.
|
||||
|
||||
@@ -178,11 +186,13 @@ Por exemplo, você pode querer retornar uma *response* em *plain text* ao invés
|
||||
{!../../../docs_src/handling_errors/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
Você pode usar `from starlette.responses import PlainTextResponse`.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
**FastAPI** disponibiliza o mesmo `starlette.responses` como `fastapi.responses`, como conveniência a você, desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette.
|
||||
Você pode usar `from starlette.responses import PlainTextResponse`.
|
||||
|
||||
**FastAPI** disponibiliza o mesmo `starlette.responses` como `fastapi.responses`, como conveniência a você, desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette.
|
||||
|
||||
///
|
||||
|
||||
### Use o body do `RequestValidationError`.
|
||||
|
||||
|
||||
@@ -6,17 +6,21 @@ Você pode definir parâmetros de Cabeçalho da mesma maneira que define paramê
|
||||
|
||||
Primeiro importe `Header`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Declare parâmetros de `Header`
|
||||
|
||||
@@ -24,25 +28,35 @@ Então declare os paramêtros de cabeçalho usando a mesma estrutura que em `Pat
|
||||
|
||||
O primeiro valor é o valor padrão, você pode passar todas as validações adicionais ou parâmetros de anotação:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
`Header` é uma classe "irmã" de `Path`, `Query` e `Cookie`. Ela também herda da mesma classe em comum `Param`.
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
Mas lembre-se que quando você importa `Query`, `Path`, `Header`, e outras de `fastapi`, elas são na verdade funções que retornam classes especiais.
|
||||
////
|
||||
|
||||
!!! info
|
||||
Para declarar headers, você precisa usar `Header`, caso contrário, os parâmetros seriam interpretados como parâmetros de consulta.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
`Header` é uma classe "irmã" de `Path`, `Query` e `Cookie`. Ela também herda da mesma classe em comum `Param`.
|
||||
|
||||
Mas lembre-se que quando você importa `Query`, `Path`, `Header`, e outras de `fastapi`, elas são na verdade funções que retornam classes especiais.
|
||||
|
||||
///
|
||||
|
||||
/// info
|
||||
|
||||
Para declarar headers, você precisa usar `Header`, caso contrário, os parâmetros seriam interpretados como parâmetros de consulta.
|
||||
|
||||
///
|
||||
|
||||
## Conversão automática
|
||||
|
||||
@@ -60,20 +74,27 @@ Portanto, você pode usar `user_agent` como faria normalmente no código Python,
|
||||
|
||||
Se por algum motivo você precisar desabilitar a conversão automática de sublinhados para hífens, defina o parâmetro `convert_underscores` de `Header` para `False`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/header_params/tutorial002_py310.py!}
|
||||
```
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/header_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/header_params/tutorial002.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! warning "Aviso"
|
||||
Antes de definir `convert_underscores` como `False`, lembre-se de que alguns proxies e servidores HTTP não permitem o uso de cabeçalhos com sublinhados.
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/header_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// warning | "Aviso"
|
||||
|
||||
Antes de definir `convert_underscores` como `False`, lembre-se de que alguns proxies e servidores HTTP não permitem o uso de cabeçalhos com sublinhados.
|
||||
|
||||
///
|
||||
|
||||
## Cabeçalhos duplicados
|
||||
|
||||
@@ -85,23 +106,29 @@ Você receberá todos os valores do cabeçalho duplicado como uma `list` Python.
|
||||
|
||||
Por exemplo, para declarar um cabeçalho de `X-Token` que pode aparecer mais de uma vez, você pode escrever:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/header_params/tutorial003_py310.py!}
|
||||
```
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/header_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
////
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial003_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9+
|
||||
|
||||
=== "Python 3.8+"
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial003.py!}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Se você se comunicar com essa *operação de caminho* enviando dois cabeçalhos HTTP como:
|
||||
|
||||
|
||||
@@ -52,22 +52,25 @@ $ pip install "fastapi[all]"
|
||||
|
||||
...isso também inclui o `uvicorn`, que você pode usar como o servidor que rodará seu código.
|
||||
|
||||
!!! note "Nota"
|
||||
Você também pode instalar parte por parte.
|
||||
/// note | "Nota"
|
||||
|
||||
Isso é provavelmente o que você faria quando você quisesse lançar sua aplicação em produção:
|
||||
Você também pode instalar parte por parte.
|
||||
|
||||
```
|
||||
pip install fastapi
|
||||
```
|
||||
Isso é provavelmente o que você faria quando você quisesse lançar sua aplicação em produção:
|
||||
|
||||
Também instale o `uvicorn` para funcionar como servidor:
|
||||
```
|
||||
pip install fastapi
|
||||
```
|
||||
|
||||
```
|
||||
pip install "uvicorn[standard]"
|
||||
```
|
||||
Também instale o `uvicorn` para funcionar como servidor:
|
||||
|
||||
E o mesmo para cada dependência opcional que você quiser usar.
|
||||
```
|
||||
pip install "uvicorn[standard]"
|
||||
```
|
||||
|
||||
E o mesmo para cada dependência opcional que você quiser usar.
|
||||
|
||||
///
|
||||
|
||||
## Guia Avançado de Usuário
|
||||
|
||||
|
||||
@@ -11,10 +11,13 @@ Um "middleware" é uma função que manipula cada **requisição** antes de ser
|
||||
* Ele pode fazer algo com essa **resposta** ou executar qualquer código necessário.
|
||||
* Então ele retorna a **resposta**.
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Se você tiver dependências com `yield`, o código de saída será executado *depois* do middleware.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
Se houver alguma tarefa em segundo plano (documentada posteriormente), ela será executada *depois* de todo o middleware.
|
||||
Se você tiver dependências com `yield`, o código de saída será executado *depois* do middleware.
|
||||
|
||||
Se houver alguma tarefa em segundo plano (documentada posteriormente), ela será executada *depois* de todo o middleware.
|
||||
|
||||
///
|
||||
|
||||
## Criar um middleware
|
||||
|
||||
@@ -32,15 +35,21 @@ A função middleware recebe:
|
||||
{!../../../docs_src/middleware/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Tenha em mente que cabeçalhos proprietários personalizados podem ser adicionados <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando o prefixo 'X-'</a>.
|
||||
/// tip | "Dica"
|
||||
|
||||
Mas se você tiver cabeçalhos personalizados desejando que um cliente em um navegador esteja apto a ver, você precisa adicioná-los às suas configurações CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) usando o parâmetro `expose_headers` documentado em <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">Documentos CORS da Starlette</a>.
|
||||
Tenha em mente que cabeçalhos proprietários personalizados podem ser adicionados <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando o prefixo 'X-'</a>.
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Você também pode usar `from starlette.requests import Request`.
|
||||
Mas se você tiver cabeçalhos personalizados desejando que um cliente em um navegador esteja apto a ver, você precisa adicioná-los às suas configurações CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) usando o parâmetro `expose_headers` documentado em <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">Documentos CORS da Starlette</a>.
|
||||
|
||||
**FastAPI** fornece isso como uma conveniência para você, o desenvolvedor. Mas vem diretamente da Starlette.
|
||||
///
|
||||
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
Você também pode usar `from starlette.requests import Request`.
|
||||
|
||||
**FastAPI** fornece isso como uma conveniência para você, o desenvolvedor. Mas vem diretamente da Starlette.
|
||||
|
||||
///
|
||||
|
||||
### Antes e depois da `response`
|
||||
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
|
||||
Existem vários parâmetros que você pode passar para o seu *decorador de operação de rota* para configurá-lo.
|
||||
|
||||
!!! warning "Aviso"
|
||||
Observe que esses parâmetros são passados diretamente para o *decorador de operação de rota*, não para a sua *função de operação de rota*.
|
||||
/// warning | "Aviso"
|
||||
|
||||
Observe que esses parâmetros são passados diretamente para o *decorador de operação de rota*, não para a sua *função de operação de rota*.
|
||||
|
||||
///
|
||||
|
||||
## Código de Status da Resposta
|
||||
|
||||
@@ -13,52 +16,67 @@ Você pode passar diretamente o código `int`, como `404`.
|
||||
|
||||
Mas se você não se lembrar o que cada código numérico significa, pode usar as constantes de atalho em `status`:
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
|
||||
```
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="1 15"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="1 15"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Esse código de status será usado na resposta e será adicionado ao esquema OpenAPI.
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
Você também poderia usar `from starlette import status`.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
**FastAPI** fornece o mesmo `starlette.status` como `fastapi.status` apenas como uma conveniência para você, o desenvolvedor. Mas vem diretamente do Starlette.
|
||||
Você também poderia usar `from starlette import status`.
|
||||
|
||||
**FastAPI** fornece o mesmo `starlette.status` como `fastapi.status` apenas como uma conveniência para você, o desenvolvedor. Mas vem diretamente do Starlette.
|
||||
|
||||
///
|
||||
|
||||
## Tags
|
||||
|
||||
Você pode adicionar tags para sua *operação de rota*, passe o parâmetro `tags` com uma `list` de `str` (comumente apenas um `str`):
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
|
||||
```
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="15 20 25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="15 20 25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Eles serão adicionados ao esquema OpenAPI e usados pelas interfaces de documentação automática:
|
||||
|
||||
@@ -80,23 +98,29 @@ Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
|
||||
|
||||
Você pode adicionar um `summary` e uma `description`:
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
|
||||
```
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Descrição do docstring
|
||||
|
||||
@@ -104,23 +128,29 @@ Como as descrições tendem a ser longas e cobrir várias linhas, você pode dec
|
||||
|
||||
Você pode escrever <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> na docstring, ele será interpretado e exibido corretamente (levando em conta a indentação da docstring).
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
|
||||
```
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="17-25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
```Python hl_lines="17-25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Ela será usada nas documentações interativas:
|
||||
|
||||
@@ -131,31 +161,43 @@ Ela será usada nas documentações interativas:
|
||||
|
||||
Você pode especificar a descrição da resposta com o parâmetro `response_description`:
|
||||
|
||||
=== "Python 3.8 and above"
|
||||
//// tab | Python 3.8 and above
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
|
||||
```
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
////
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
|
||||
```
|
||||
//// tab | Python 3.9 and above
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
|
||||
```
|
||||
////
|
||||
|
||||
!!! info "Informação"
|
||||
Note que `response_description` se refere especificamente à resposta, a `description` se refere à *operação de rota* em geral.
|
||||
//// tab | Python 3.10 and above
|
||||
|
||||
!!! check
|
||||
OpenAPI especifica que cada *operação de rota* requer uma descrição de resposta.
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
Então, se você não fornecer uma, o **FastAPI** irá gerar automaticamente uma de "Resposta bem-sucedida".
|
||||
////
|
||||
|
||||
/// info | "Informação"
|
||||
|
||||
Note que `response_description` se refere especificamente à resposta, a `description` se refere à *operação de rota* em geral.
|
||||
|
||||
///
|
||||
|
||||
/// check
|
||||
|
||||
OpenAPI especifica que cada *operação de rota* requer uma descrição de resposta.
|
||||
|
||||
Então, se você não fornecer uma, o **FastAPI** irá gerar automaticamente uma de "Resposta bem-sucedida".
|
||||
|
||||
///
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image03.png">
|
||||
|
||||
|
||||
@@ -6,17 +6,21 @@ Do mesmo modo que você pode declarar mais validações e metadados para parâme
|
||||
|
||||
Primeiro, importe `Path` de `fastapi`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Declare metadados
|
||||
|
||||
@@ -24,24 +28,31 @@ Você pode declarar todos os parâmetros da mesma maneira que na `Query`.
|
||||
|
||||
Por exemplo para declarar um valor de metadado `title` para o parâmetro de rota `item_id` você pode digitar:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
!!! note "Nota"
|
||||
Um parâmetro de rota é sempre obrigatório, como se fizesse parte da rota.
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
Então, você deve declará-lo com `...` para marcá-lo como obrigatório.
|
||||
////
|
||||
|
||||
Mesmo que você declare-o como `None` ou defina um valor padrão, isso não teria efeito algum, o parâmetro ainda seria obrigatório.
|
||||
/// note | "Nota"
|
||||
|
||||
Um parâmetro de rota é sempre obrigatório, como se fizesse parte da rota.
|
||||
|
||||
Então, você deve declará-lo com `...` para marcá-lo como obrigatório.
|
||||
|
||||
Mesmo que você declare-o como `None` ou defina um valor padrão, isso não teria efeito algum, o parâmetro ainda seria obrigatório.
|
||||
|
||||
///
|
||||
|
||||
## Ordene os parâmetros de acordo com sua necessidade
|
||||
|
||||
@@ -121,18 +132,24 @@ E você também pode declarar validações numéricas:
|
||||
* `lt`: menor que (`l`ess `t`han)
|
||||
* `le`: menor que ou igual (`l`ess than or `e`qual)
|
||||
|
||||
!!! info "Informação"
|
||||
`Query`, `Path` e outras classes que você verá a frente são subclasses de uma classe comum `Param`.
|
||||
/// info | "Informação"
|
||||
|
||||
Todas elas compartilham os mesmos parâmetros para validação adicional e metadados que você viu.
|
||||
`Query`, `Path` e outras classes que você verá a frente são subclasses de uma classe comum `Param`.
|
||||
|
||||
!!! note "Detalhes Técnicos"
|
||||
Quando você importa `Query`, `Path` e outras de `fastapi`, elas são na verdade funções.
|
||||
Todas elas compartilham os mesmos parâmetros para validação adicional e metadados que você viu.
|
||||
|
||||
Que quando chamadas, retornam instâncias de classes de mesmo nome.
|
||||
///
|
||||
|
||||
Então, você importa `Query`, que é uma função. E quando você a chama, ela retorna uma instância de uma classe também chamada `Query`.
|
||||
/// note | "Detalhes Técnicos"
|
||||
|
||||
Estas funções são assim (ao invés de apenas usar as classes diretamente) para que seu editor não acuse erros sobre seus tipos.
|
||||
Quando você importa `Query`, `Path` e outras de `fastapi`, elas são na verdade funções.
|
||||
|
||||
Dessa maneira você pode user seu editor e ferramentas de desenvolvimento sem precisar adicionar configurações customizadas para ignorar estes erros.
|
||||
Que quando chamadas, retornam instâncias de classes de mesmo nome.
|
||||
|
||||
Então, você importa `Query`, que é uma função. E quando você a chama, ela retorna uma instância de uma classe também chamada `Query`.
|
||||
|
||||
Estas funções são assim (ao invés de apenas usar as classes diretamente) para que seu editor não acuse erros sobre seus tipos.
|
||||
|
||||
Dessa maneira você pode user seu editor e ferramentas de desenvolvimento sem precisar adicionar configurações customizadas para ignorar estes erros.
|
||||
|
||||
///
|
||||
|
||||
@@ -24,7 +24,12 @@ Você pode declarar o tipo de um parâmetro na função usando as anotações pa
|
||||
|
||||
Nesse caso, `item_id` está sendo declarado como um `int`.
|
||||
|
||||
!!! check "Verifique"
|
||||
/// check | "Verifique"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Isso vai dar à você suporte do seu editor dentro das funções, com verificações de erros, autocompletar, etc.
|
||||
|
||||
## Conversão de <abbr title="também conhecido como: serialização, parsing, marshalling">dados</abbr>
|
||||
@@ -35,7 +40,12 @@ Se você rodar esse exemplo e abrir o seu navegador em <a href="http://127.0.0.1
|
||||
{"item_id":3}
|
||||
```
|
||||
|
||||
!!! check "Verifique"
|
||||
/// check | "Verifique"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Observe que o valor recebido pela função (e também retornado por ela) é `3`, como um Python `int`, não como uma string `"3"`.
|
||||
|
||||
Então, com essa declaração de tipo, o **FastAPI** dá pra você um <abbr title="convertendo a string que veio do request HTTP em um dado Python">"parsing"</abbr> automático no request .
|
||||
@@ -63,7 +73,12 @@ devido ao parâmetro da rota `item_id` ter um valor `"foo"`, que não é um `int
|
||||
|
||||
O mesmo erro apareceria se você tivesse fornecido um `float` ao invés de um `int`, como em: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
|
||||
|
||||
!!! check "Verifique"
|
||||
/// check | "Verifique"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Então, com a mesma declaração de tipo do Python, o **FastAPI** dá pra você validação de dados.
|
||||
|
||||
Observe que o erro também mostra claramente o ponto exato onde a validação não passou.
|
||||
@@ -76,7 +91,12 @@ Quando você abrir o seu navegador em <a href="http://127.0.0.1:8000/docs" class
|
||||
|
||||
<img src="/img/tutorial/path-params/image01.png">
|
||||
|
||||
!!! check "Verifique"
|
||||
/// check | "Verifique"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Novamente, apenas com a mesma declaração de tipo do Python, o **FastAPI** te dá de forma automática e interativa a documentação (integrada com o Swagger UI).
|
||||
|
||||
Veja que o parâmetro de rota está declarado como sendo um inteiro (int).
|
||||
@@ -131,10 +151,18 @@ Assim, crie atributos de classe com valores fixos, que serão os valores válido
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! info "informação"
|
||||
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerations (ou enums) estão disponíveis no Python</a> desde a versão 3.4.
|
||||
/// info | "informação"
|
||||
|
||||
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerations (ou enums) estão disponíveis no Python</a> desde a versão 3.4.
|
||||
|
||||
///
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
!!! tip "Dica"
|
||||
Se você está se perguntando, "AlexNet", "ResNet", e "LeNet" são apenas nomes de <abbr title="técnicamente, modelos de arquitetura de Deep Learning">modelos</abbr> de Machine Learning (aprendizado de máquina).
|
||||
|
||||
### Declare um *parâmetro de rota*
|
||||
@@ -171,7 +199,12 @@ Você pode ter o valor exato de enumerate (um `str` nesse caso) usando `model_na
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
/// tip | "Dica"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Você também poderia acessar o valor `"lenet"` com `ModelName.lenet.value`
|
||||
|
||||
#### Retorne *membros de enumeration*
|
||||
@@ -225,7 +258,12 @@ Então, você poderia usar ele com:
|
||||
{!../../../docs_src/path_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
/// tip | "Dica"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Você poderia precisar que o parâmetro contivesse `/home/johndoe/myfile.txt`, com uma barra no inicio (`/`).
|
||||
|
||||
Neste caso, a URL deveria ser: `/files//home/johndoe/myfile.txt`, com barra dupla (`//`) entre `files` e `home`.
|
||||
|
||||
@@ -10,10 +10,13 @@ Vamos utilizar essa aplicação como exemplo:
|
||||
|
||||
O parâmetro de consulta `q` é do tipo `Union[str, None]`, o que significa que é do tipo `str` mas que também pode ser `None`, e de fato, o valor padrão é `None`, então o FastAPI saberá que não é obrigatório.
|
||||
|
||||
!!! note "Observação"
|
||||
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
|
||||
/// note | "Observação"
|
||||
|
||||
O `Union` em `Union[str, None]` não é usado pelo FastAPI, mas permitirá que seu editor lhe dê um melhor suporte e detecte erros.
|
||||
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
|
||||
|
||||
O `Union` em `Union[str, None]` não é usado pelo FastAPI, mas permitirá que seu editor lhe dê um melhor suporte e detecte erros.
|
||||
|
||||
///
|
||||
|
||||
## Validação adicional
|
||||
|
||||
@@ -51,22 +54,25 @@ q: Union[str, None] = None
|
||||
|
||||
Mas o declara explicitamente como um parâmetro de consulta.
|
||||
|
||||
!!! info "Informação"
|
||||
Tenha em mente que o FastAPI se preocupa com a parte:
|
||||
/// info | "Informação"
|
||||
|
||||
```Python
|
||||
= None
|
||||
```
|
||||
Tenha em mente que o FastAPI se preocupa com a parte:
|
||||
|
||||
Ou com:
|
||||
```Python
|
||||
= None
|
||||
```
|
||||
|
||||
```Python
|
||||
= Query(default=None)
|
||||
```
|
||||
Ou com:
|
||||
|
||||
E irá utilizar o `None` para detectar que o parâmetro de consulta não é obrigatório.
|
||||
```Python
|
||||
= Query(default=None)
|
||||
```
|
||||
|
||||
O `Union` é apenas para permitir que seu editor de texto lhe dê um melhor suporte.
|
||||
E irá utilizar o `None` para detectar que o parâmetro de consulta não é obrigatório.
|
||||
|
||||
O `Union` é apenas para permitir que seu editor de texto lhe dê um melhor suporte.
|
||||
|
||||
///
|
||||
|
||||
Então, podemos passar mais parâmetros para `Query`. Neste caso, o parâmetro `max_length` que se aplica a textos:
|
||||
|
||||
@@ -112,8 +118,11 @@ Vamos dizer que você queira que o parâmetro de consulta `q` tenha um `min_leng
|
||||
{!../../../docs_src/query_params_str_validations/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! note "Observação"
|
||||
O parâmetro torna-se opcional quando possui um valor padrão.
|
||||
/// note | "Observação"
|
||||
|
||||
O parâmetro torna-se opcional quando possui um valor padrão.
|
||||
|
||||
///
|
||||
|
||||
## Torne-o obrigatório
|
||||
|
||||
@@ -141,8 +150,11 @@ Então, quando você precisa declarar um parâmetro obrigatório utilizando o `Q
|
||||
{!../../../docs_src/query_params_str_validations/tutorial006.py!}
|
||||
```
|
||||
|
||||
!!! info "Informação"
|
||||
Se você nunca viu os `...` antes: é um valor único especial, faz <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">parte do Python e é chamado "Ellipsis"</a>.
|
||||
/// info | "Informação"
|
||||
|
||||
Se você nunca viu os `...` antes: é um valor único especial, faz <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">parte do Python e é chamado "Ellipsis"</a>.
|
||||
|
||||
///
|
||||
|
||||
Dessa forma o **FastAPI** saberá que o parâmetro é obrigatório.
|
||||
|
||||
@@ -175,8 +187,11 @@ Assim, a resposta para essa URL seria:
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Para declarar um parâmetro de consulta com o tipo `list`, como no exemplo acima, você precisa usar explicitamente o `Query`, caso contrário será interpretado como um corpo da requisição.
|
||||
/// tip | "Dica"
|
||||
|
||||
Para declarar um parâmetro de consulta com o tipo `list`, como no exemplo acima, você precisa usar explicitamente o `Query`, caso contrário será interpretado como um corpo da requisição.
|
||||
|
||||
///
|
||||
|
||||
A documentação interativa da API irá atualizar de acordo, permitindo múltiplos valores:
|
||||
|
||||
@@ -215,10 +230,13 @@ Você também pode utilizar o tipo `list` diretamente em vez de `List[str]`:
|
||||
{!../../../docs_src/query_params_str_validations/tutorial013.py!}
|
||||
```
|
||||
|
||||
!!! note "Observação"
|
||||
Tenha em mente que neste caso, o FastAPI não irá validar os conteúdos da lista.
|
||||
/// note | "Observação"
|
||||
|
||||
Por exemplo, um `List[int]` iria validar (e documentar) que os contéudos da lista são números inteiros. Mas apenas `list` não.
|
||||
Tenha em mente que neste caso, o FastAPI não irá validar os conteúdos da lista.
|
||||
|
||||
Por exemplo, um `List[int]` iria validar (e documentar) que os contéudos da lista são números inteiros. Mas apenas `list` não.
|
||||
|
||||
///
|
||||
|
||||
## Declarando mais metadados
|
||||
|
||||
@@ -226,10 +244,13 @@ Você pode adicionar mais informações sobre o parâmetro.
|
||||
|
||||
Essa informações serão inclusas no esquema do OpenAPI e utilizado pela documentação interativa e ferramentas externas.
|
||||
|
||||
!!! note "Observação"
|
||||
Tenha em mente que cada ferramenta oferece diferentes níveis de suporte ao OpenAPI.
|
||||
/// note | "Observação"
|
||||
|
||||
Algumas delas não exibem todas as informações extras que declaramos, ainda que na maioria dos casos, esses recursos estão planejados para desenvolvimento.
|
||||
Tenha em mente que cada ferramenta oferece diferentes níveis de suporte ao OpenAPI.
|
||||
|
||||
Algumas delas não exibem todas as informações extras que declaramos, ainda que na maioria dos casos, esses recursos estão planejados para desenvolvimento.
|
||||
|
||||
///
|
||||
|
||||
Você pode adicionar um `title`:
|
||||
|
||||
|
||||
@@ -63,39 +63,49 @@ Os valores dos parâmetros na sua função serão:
|
||||
|
||||
Da mesma forma, você pode declarar parâmetros de consulta opcionais, definindo o valor padrão para `None`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
|
||||
```
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Nesse caso, o parâmetro da função `q` será opcional, e `None` será o padrão.
|
||||
|
||||
!!! check "Verificar"
|
||||
Você também pode notar que o **FastAPI** é esperto o suficiente para perceber que o parâmetro da rota `item_id` é um parâmetro da rota, e `q` não é, portanto, `q` é o parâmetro de consulta.
|
||||
/// check | "Verificar"
|
||||
|
||||
Você também pode notar que o **FastAPI** é esperto o suficiente para perceber que o parâmetro da rota `item_id` é um parâmetro da rota, e `q` não é, portanto, `q` é o parâmetro de consulta.
|
||||
|
||||
///
|
||||
|
||||
## Conversão dos tipos de parâmetros de consulta
|
||||
|
||||
Você também pode declarar tipos `bool`, e eles serão convertidos:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
|
||||
```
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Nesse caso, se você for para:
|
||||
|
||||
@@ -137,17 +147,21 @@ E você não precisa declarar eles em nenhuma ordem específica.
|
||||
|
||||
Eles serão detectados pelo nome:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="6 8"
|
||||
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
|
||||
```
|
||||
```Python hl_lines="6 8"
|
||||
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!> ../../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!> ../../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
## Parâmetros de consulta obrigatórios
|
||||
|
||||
@@ -203,17 +217,21 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
|
||||
E claro, você pode definir alguns parâmetros como obrigatórios, alguns possuindo um valor padrão, e outros sendo totalmente opcionais:
|
||||
|
||||
=== "Python 3.10+"
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
|
||||
```
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.8+"
|
||||
////
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Nesse caso, existem 3 parâmetros de consulta:
|
||||
|
||||
@@ -221,5 +239,8 @@ Nesse caso, existem 3 parâmetros de consulta:
|
||||
* `skip`, um `int` com o valor padrão `0`.
|
||||
* `limit`, um `int` opcional.
|
||||
|
||||
!!! tip "Dica"
|
||||
Você também poderia usar `Enum` da mesma forma que com [Path Parameters](path-params.md#valores-predefinidos){.internal-link target=_blank}.
|
||||
/// tip | "Dica"
|
||||
|
||||
Você também poderia usar `Enum` da mesma forma que com [Path Parameters](path-params.md#valores-predefinidos){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
Você pode definir arquivos e campos de formulário ao mesmo tempo usando `File` e `Form`.
|
||||
|
||||
!!! info "Informação"
|
||||
Para receber arquivos carregados e/ou dados de formulário, primeiro instale <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
|
||||
/// info | "Informação"
|
||||
|
||||
Por exemplo: `pip install python-multipart`.
|
||||
Para receber arquivos carregados e/ou dados de formulário, primeiro instale <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
|
||||
|
||||
Por exemplo: `pip install python-multipart`.
|
||||
|
||||
///
|
||||
|
||||
## Importe `File` e `Form`
|
||||
|
||||
@@ -26,10 +28,13 @@ Os arquivos e campos de formulário serão carregados como dados de formulário
|
||||
|
||||
E você pode declarar alguns dos arquivos como `bytes` e alguns como `UploadFile`.
|
||||
|
||||
!!! warning "Aviso"
|
||||
Você pode declarar vários parâmetros `File` e `Form` em uma *operação de caminho*, mas não é possível declarar campos `Body` para receber como JSON, pois a requisição terá o corpo codificado usando `multipart/form-data` ao invés de `application/json`.
|
||||
/// warning | "Aviso"
|
||||
|
||||
Isso não é uma limitação do **FastAPI** , é parte do protocolo HTTP.
|
||||
Você pode declarar vários parâmetros `File` e `Form` em uma *operação de caminho*, mas não é possível declarar campos `Body` para receber como JSON, pois a requisição terá o corpo codificado usando `multipart/form-data` ao invés de `application/json`.
|
||||
|
||||
Isso não é uma limitação do **FastAPI** , é parte do protocolo HTTP.
|
||||
|
||||
///
|
||||
|
||||
## Recapitulando
|
||||
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
Quando você precisar receber campos de formulário ao invés de JSON, você pode usar `Form`.
|
||||
|
||||
!!! info "Informação"
|
||||
Para usar formulários, primeiro instale <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
|
||||
/// info | "Informação"
|
||||
|
||||
Ex: `pip install python-multipart`.
|
||||
Para usar formulários, primeiro instale <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
|
||||
|
||||
Ex: `pip install python-multipart`.
|
||||
|
||||
///
|
||||
|
||||
## Importe `Form`
|
||||
|
||||
@@ -29,11 +32,17 @@ A <abbr title="especificação">spec</abbr> exige que os campos sejam exatamente
|
||||
|
||||
Com `Form` você pode declarar os mesmos metadados e validação que com `Body` (e `Query`, `Path`, `Cookie`).
|
||||
|
||||
!!! info "Informação"
|
||||
`Form` é uma classe que herda diretamente de `Body`.
|
||||
/// info | "Informação"
|
||||
|
||||
!!! tip "Dica"
|
||||
Para declarar corpos de formulário, você precisa usar `Form` explicitamente, porque sem ele os parâmetros seriam interpretados como parâmetros de consulta ou parâmetros de corpo (JSON).
|
||||
`Form` é uma classe que herda diretamente de `Body`.
|
||||
|
||||
///
|
||||
|
||||
/// tip | "Dica"
|
||||
|
||||
Para declarar corpos de formulário, você precisa usar `Form` explicitamente, porque sem ele os parâmetros seriam interpretados como parâmetros de consulta ou parâmetros de corpo (JSON).
|
||||
|
||||
///
|
||||
|
||||
## Sobre "Campos de formulário"
|
||||
|
||||
@@ -41,17 +50,23 @@ A forma como os formulários HTML (`<form></form>`) enviam os dados para o servi
|
||||
|
||||
O **FastAPI** fará a leitura desses dados no lugar certo em vez de JSON.
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Os dados dos formulários são normalmente codificados usando o "tipo de mídia" `application/x-www-form-urlencoded`.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
Mas quando o formulário inclui arquivos, ele é codificado como `multipart/form-data`. Você lerá sobre como lidar com arquivos no próximo capítulo.
|
||||
Os dados dos formulários são normalmente codificados usando o "tipo de mídia" `application/x-www-form-urlencoded`.
|
||||
|
||||
Se você quiser ler mais sobre essas codificações e campos de formulário, vá para o <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web docs para <code>POST</code></a>.
|
||||
Mas quando o formulário inclui arquivos, ele é codificado como `multipart/form-data`. Você lerá sobre como lidar com arquivos no próximo capítulo.
|
||||
|
||||
!!! warning "Aviso"
|
||||
Você pode declarar vários parâmetros `Form` em uma *operação de caminho*, mas não pode declarar campos `Body` que espera receber como JSON, pois a solicitação terá o corpo codificado usando `application/x-www- form-urlencoded` em vez de `application/json`.
|
||||
Se você quiser ler mais sobre essas codificações e campos de formulário, vá para o <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> web docs para <code>POST</code></a>.
|
||||
|
||||
Esta não é uma limitação do **FastAPI**, é parte do protocolo HTTP.
|
||||
///
|
||||
|
||||
/// warning | "Aviso"
|
||||
|
||||
Você pode declarar vários parâmetros `Form` em uma *operação de caminho*, mas não pode declarar campos `Body` que espera receber como JSON, pois a solicitação terá o corpo codificado usando `application/x-www- form-urlencoded` em vez de `application/json`.
|
||||
|
||||
Esta não é uma limitação do **FastAPI**, é parte do protocolo HTTP.
|
||||
|
||||
///
|
||||
|
||||
## Recapitulando
|
||||
|
||||
|
||||
@@ -12,13 +12,19 @@ Da mesma forma que você pode especificar um modelo de resposta, você também p
|
||||
{!../../../docs_src/response_status_code/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Nota"
|
||||
Observe que `status_code` é um parâmetro do método "decorador" (get, post, etc). Não da sua função de *operação de caminho*, como todos os parâmetros e corpo.
|
||||
/// note | "Nota"
|
||||
|
||||
Observe que `status_code` é um parâmetro do método "decorador" (get, post, etc). Não da sua função de *operação de caminho*, como todos os parâmetros e corpo.
|
||||
|
||||
///
|
||||
|
||||
O parâmetro `status_code` recebe um número com o código de status HTTP.
|
||||
|
||||
!!! info "Informação"
|
||||
`status_code` também pode receber um `IntEnum`, como o do Python <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>.
|
||||
/// info | "Informação"
|
||||
|
||||
`status_code` também pode receber um `IntEnum`, como o do Python <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>.
|
||||
|
||||
///
|
||||
|
||||
Dessa forma:
|
||||
|
||||
@@ -27,15 +33,21 @@ Dessa forma:
|
||||
|
||||
<img src="/img/tutorial/response-status-code/image01.png">
|
||||
|
||||
!!! note "Nota"
|
||||
Alguns códigos de resposta (consulte a próxima seção) indicam que a resposta não possui um corpo.
|
||||
/// note | "Nota"
|
||||
|
||||
O FastAPI sabe disso e produzirá documentos OpenAPI informando que não há corpo de resposta.
|
||||
Alguns códigos de resposta (consulte a próxima seção) indicam que a resposta não possui um corpo.
|
||||
|
||||
O FastAPI sabe disso e produzirá documentos OpenAPI informando que não há corpo de resposta.
|
||||
|
||||
///
|
||||
|
||||
## Sobre os códigos de status HTTP
|
||||
|
||||
!!! note "Nota"
|
||||
Se você já sabe o que são códigos de status HTTP, pule para a próxima seção.
|
||||
/// note | "Nota"
|
||||
|
||||
Se você já sabe o que são códigos de status HTTP, pule para a próxima seção.
|
||||
|
||||
///
|
||||
|
||||
Em HTTP, você envia um código de status numérico de 3 dígitos como parte da resposta.
|
||||
|
||||
@@ -55,8 +67,11 @@ Resumidamente:
|
||||
* Para erros genéricos do cliente, você pode usar apenas `400`.
|
||||
* `500` e acima são para erros do servidor. Você quase nunca os usa diretamente. Quando algo der errado em alguma parte do código do seu aplicativo ou servidor, ele retornará automaticamente um desses códigos de status.
|
||||
|
||||
!!! tip "Dica"
|
||||
Para saber mais sobre cada código de status e qual código serve para quê, verifique o <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> documentação sobre códigos de status HTTP</a>.
|
||||
/// tip | "Dica"
|
||||
|
||||
Para saber mais sobre cada código de status e qual código serve para quê, verifique o <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> documentação sobre códigos de status HTTP</a>.
|
||||
|
||||
///
|
||||
|
||||
## Atalho para lembrar os nomes
|
||||
|
||||
@@ -80,11 +95,13 @@ Eles são apenas uma conveniência, eles possuem o mesmo número, mas dessa form
|
||||
|
||||
<img src="/img/tutorial/response-status-code/image02.png">
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Você também pode usar `from starlette import status`.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
**FastAPI** fornece o mesmo `starlette.status` como `fastapi.status` apenas como uma conveniência para você, o desenvolvedor. Mas vem diretamente da Starlette.
|
||||
Você também pode usar `from starlette import status`.
|
||||
|
||||
**FastAPI** fornece o mesmo `starlette.status` como `fastapi.status` apenas como uma conveniência para você, o desenvolvedor. Mas vem diretamente da Starlette.
|
||||
|
||||
///
|
||||
|
||||
## Alterando o padrão
|
||||
|
||||
|
||||
@@ -14,10 +14,13 @@ Você pode declarar um `example` para um modelo Pydantic usando `Config` e `sche
|
||||
|
||||
Essas informações extras serão adicionadas como se encontram no **JSON Schema** de resposta desse modelo e serão usadas na documentação da API.
|
||||
|
||||
!!! tip "Dica"
|
||||
Você pode usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras de forma personalizada.
|
||||
/// tip | "Dica"
|
||||
|
||||
Por exemplo, você pode usar isso para adicionar metadados para uma interface de usuário de front-end, etc.
|
||||
Você pode usar a mesma técnica para estender o JSON Schema e adicionar suas próprias informações extras de forma personalizada.
|
||||
|
||||
Por exemplo, você pode usar isso para adicionar metadados para uma interface de usuário de front-end, etc.
|
||||
|
||||
///
|
||||
|
||||
## `Field` de argumentos adicionais
|
||||
|
||||
@@ -29,8 +32,11 @@ Você pode usar isso para adicionar um `example` para cada campo:
|
||||
{!../../../docs_src/schema_extra_example/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! warning "Atenção"
|
||||
Lembre-se de que esses argumentos extras passados não adicionarão nenhuma validação, apenas informações extras, para fins de documentação.
|
||||
/// warning | "Atenção"
|
||||
|
||||
Lembre-se de que esses argumentos extras passados não adicionarão nenhuma validação, apenas informações extras, para fins de documentação.
|
||||
|
||||
///
|
||||
|
||||
## `example` e `examples` no OpenAPI
|
||||
|
||||
@@ -85,10 +91,13 @@ Com `examples` adicionado a `Body()`, os `/docs` vão ficar assim:
|
||||
|
||||
## Detalhes técnicos
|
||||
|
||||
!!! warning "Atenção"
|
||||
Esses são detalhes muito técnicos sobre os padrões **JSON Schema** e **OpenAPI**.
|
||||
/// warning | "Atenção"
|
||||
|
||||
Se as ideias explicadas acima já funcionam para você, isso pode ser o suficiente, e você provavelmente não precisa desses detalhes, fique à vontade para pular.
|
||||
Esses são detalhes muito técnicos sobre os padrões **JSON Schema** e **OpenAPI**.
|
||||
|
||||
Se as ideias explicadas acima já funcionam para você, isso pode ser o suficiente, e você provavelmente não precisa desses detalhes, fique à vontade para pular.
|
||||
|
||||
///
|
||||
|
||||
Quando você adiciona um exemplo dentro de um modelo Pydantic, usando `schema_extra` ou` Field(example="something") `esse exemplo é adicionado ao **JSON Schema** para esse modelo Pydantic.
|
||||
|
||||
|
||||
@@ -25,7 +25,12 @@ Copie o exemplo em um arquivo `main.py`:
|
||||
|
||||
## Execute-o
|
||||
|
||||
!!! info "informação"
|
||||
/// info | "informação"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Primeiro, instale <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
|
||||
|
||||
Ex: `pip install python-multipart`.
|
||||
@@ -52,7 +57,12 @@ Você verá algo deste tipo:
|
||||
|
||||
<img src="/img/tutorial/security/image01.png">
|
||||
|
||||
!!! check "Botão de Autorizar!"
|
||||
/// check | "Botão de Autorizar!"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Você já tem um novo "botão de autorizar!".
|
||||
|
||||
E seu *path operation* tem um pequeno cadeado no canto superior direito que você pode clicar.
|
||||
@@ -61,7 +71,12 @@ E se você clicar, você terá um pequeno formulário de autorização para digi
|
||||
|
||||
<img src="/img/tutorial/security/image02.png">
|
||||
|
||||
!!! note "Nota"
|
||||
/// note | "Nota"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Não importa o que você digita no formulário, não vai funcionar ainda. Mas nós vamos chegar lá.
|
||||
|
||||
Claro que este não é o frontend para os usuários finais, mas é uma ótima ferramenta automática para documentar interativamente toda sua API.
|
||||
@@ -104,7 +119,12 @@ Então, vamos rever de um ponto de vista simplificado:
|
||||
|
||||
Neste exemplo, nós vamos usar o **OAuth2** com o fluxo de **Senha**, usando um token **Bearer**. Fazemos isso usando a classe `OAuth2PasswordBearer`.
|
||||
|
||||
!!! info "informação"
|
||||
/// info | "informação"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Um token "bearer" não é a única opção.
|
||||
|
||||
Mas é a melhor no nosso caso.
|
||||
@@ -119,7 +139,12 @@ Quando nós criamos uma instância da classe `OAuth2PasswordBearer`, nós passam
|
||||
{!../../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
/// tip | "Dica"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Esse `tokenUrl="token"` se refere a uma URL relativa que nós não criamos ainda. Como é uma URL relativa, é equivalente a `./token`.
|
||||
|
||||
Porque estamos usando uma URL relativa, se sua API estava localizada em `https://example.com/`, então irá referir-se à `https://example.com/token`. Mas se sua API estava localizada em `https://example.com/api/v1/`, então irá referir-se à `https://example.com/api/v1/token`.
|
||||
@@ -130,7 +155,12 @@ Esse parâmetro não cria um endpoint / *path operation*, mas declara que a URL
|
||||
|
||||
Em breve também criaremos o atual path operation.
|
||||
|
||||
!!! info "informação"
|
||||
/// info | "informação"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
Se você é um "Pythonista" muito rigoroso, você pode não gostar do estilo do nome do parâmetro `tokenUrl` em vez de `token_url`.
|
||||
|
||||
Isso ocorre porque está utilizando o mesmo nome que está nas especificações do OpenAPI. Então, se você precisa investigar mais sobre qualquer um desses esquemas de segurança, você pode simplesmente copiar e colar para encontrar mais informações sobre isso.
|
||||
@@ -157,7 +187,12 @@ Esse dependência vai fornecer uma `str` que é atribuído ao parâmetro `token
|
||||
|
||||
A **FastAPI** saberá que pode usar essa dependência para definir um "esquema de segurança" no esquema da OpenAPI (e na documentação da API automática).
|
||||
|
||||
!!! info "Detalhes técnicos"
|
||||
/// info | "Detalhes técnicos"
|
||||
|
||||
|
||||
|
||||
///
|
||||
|
||||
**FastAPI** saberá que pode usar a classe `OAuth2PasswordBearer` (declarada na dependência) para definir o esquema de segurança na OpenAPI porque herda de `fastapi.security.oauth2.OAuth2`, que por sua vez herda de `fastapi.security.base.Securitybase`.
|
||||
|
||||
Todos os utilitários de segurança que se integram com OpenAPI (e na documentação da API automática) herdam de `SecurityBase`, é assim que **FastAPI** pode saber como integrá-los no OpenAPI.
|
||||
|
||||
@@ -32,9 +32,11 @@ Não é muito popular ou usado nos dias atuais.
|
||||
|
||||
OAuth2 não especifica como criptografar a comunicação, ele espera que você tenha sua aplicação em um servidor HTTPS.
|
||||
|
||||
!!! tip "Dica"
|
||||
Na seção sobre **deployment** você irá ver como configurar HTTPS de modo gratuito, usando Traefik e Let’s Encrypt.
|
||||
/// tip | "Dica"
|
||||
|
||||
Na seção sobre **deployment** você irá ver como configurar HTTPS de modo gratuito, usando Traefik e Let’s Encrypt.
|
||||
|
||||
///
|
||||
|
||||
## OpenID Connect
|
||||
|
||||
@@ -87,10 +89,13 @@ OpenAPI define os seguintes esquemas de segurança:
|
||||
* Essa descoberta automática é o que é definido na especificação OpenID Connect.
|
||||
|
||||
|
||||
!!! tip "Dica"
|
||||
Integração com outros provedores de autenticação/autorização como Google, Facebook, Twitter, GitHub, etc. é bem possível e relativamente fácil.
|
||||
/// tip | "Dica"
|
||||
|
||||
O problema mais complexo é criar um provedor de autenticação/autorização como eles, mas o FastAPI dá a você ferramentas para fazer isso facilmente, enquanto faz o trabalho pesado para você.
|
||||
Integração com outros provedores de autenticação/autorização como Google, Facebook, Twitter, GitHub, etc. é bem possível e relativamente fácil.
|
||||
|
||||
O problema mais complexo é criar um provedor de autenticação/autorização como eles, mas o FastAPI dá a você ferramentas para fazer isso facilmente, enquanto faz o trabalho pesado para você.
|
||||
|
||||
///
|
||||
|
||||
## **FastAPI** utilitários
|
||||
|
||||
|
||||
@@ -11,10 +11,13 @@ Você pode servir arquivos estáticos automaticamente de um diretório usando `S
|
||||
{!../../../docs_src/static_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Detalhes técnicos"
|
||||
Você também pode usar `from starlette.staticfiles import StaticFiles`.
|
||||
/// note | "Detalhes técnicos"
|
||||
|
||||
O **FastAPI** fornece o mesmo que `starlette.staticfiles` como `fastapi.staticfiles` apenas como uma conveniência para você, o desenvolvedor. Mas na verdade vem diretamente da Starlette.
|
||||
Você também pode usar `from starlette.staticfiles import StaticFiles`.
|
||||
|
||||
O **FastAPI** fornece o mesmo que `starlette.staticfiles` como `fastapi.staticfiles` apenas como uma conveniência para você, o desenvolvedor. Mas na verdade vem diretamente da Starlette.
|
||||
|
||||
///
|
||||
|
||||
### O que é "Montagem"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user