🌐 Update translations for pt (update-outdated) (#16653)

Co-authored-by: pr-submit[bot] <pr-submit[bot]@users.noreply.github.com>
Co-authored-by: pr-push[bot] <pr-push[bot]@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-11-02 12:25:04 +01:00
1 parent 7997cbcb3b
commit 3edf18a4f1
22 files changed
+324 -168

No files matched your search

@@ -13,17 +13,17 @@ from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
print(f"Hi {name}!")
```
O `typing` também tem um atalho para declarar que algo pode ser `None`, com `Optional`.
Aqui vai uma dica do meu ponto de vista bem subjetivo:
Aqui vai uma dica do meu ponto de vista bem **subjetivo**:
* 🚨 Evite usar `Optional[SomeType]`
* Em vez disso ✨ use **`Union[SomeType, None]`** ✨.
* Em vez disso ✨ **use `Union[SomeType, None]`** ✨.
Ambos são equivalentes e, por baixo, são a mesma coisa, mas eu recomendaria `Union` em vez de `Optional` porque a palavra "opcional" sugere que o valor é opcional; na verdade, significa "pode ser `None`", mesmo quando não é opcional e continua sendo obrigatório.
Ambos são equivalentes e, por baixo, são a mesma coisa, mas eu recomendaria `Union` em vez de `Optional` porque a palavra "**opcional**" sugere que o valor é opcional; na verdade, significa "pode ser `None`", mesmo quando não é opcional e continua sendo obrigatório.
Acho que `Union[SomeType, None]` é mais explícito quanto ao significado.
@@ -39,13 +39,13 @@ def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
O parâmetro `name` é definido como `Optional[str]`, mas não é opcional; não é possível chamar a função sem o parâmetro:
O parâmetro `name` é definido como `Optional[str]`, mas **não é opcional**; não é possível chamar a função sem o parâmetro:
```Python
say_hi() # Ah, não, isso gera um erro! 😱
```
O parâmetro `name` continua obrigatório (não é opcional) porque não tem valor padrão. Ainda assim, `name` aceita `None` como valor:
O parâmetro `name` **continua obrigatório** (não é *opcional*) porque não tem valor padrão. Ainda assim, `name` aceita `None` como valor:
```Python
say_hi(name=None) # Isso funciona, None é válido 🎉
+4 -4
View File
@@ -8,13 +8,13 @@ Vamos ver como nós podemos fazer isso funcionar.
## pytest.mark.anyio { #pytest-mark-anyio }
Se quisermos chamar funções assíncronas em nossos testes, as nossas funções de teste precisam ser assíncronas. O AnyIO oferece um plugin bem legal para isso, que nos permite especificar que algumas das nossas funções de teste precisam ser chamadas de forma assíncrona.
Se quisermos chamar funções assíncronas em nossos testes, as nossas funções de teste precisam ser assíncronas. O AnyIO oferece um plugin útil para isso, que nos permite especificar que algumas das nossas funções de teste precisam ser chamadas de forma assíncrona.
## HTTPX { #httpx }
Mesmo que a sua aplicação **FastAPI** utilize funções normais com `def` no lugar de `async def`, ela ainda é uma aplicação `async` por baixo dos panos.
O `TestClient` faz algumas mágicas para invocar a aplicação FastAPI assíncrona em suas funções `def` normais, utilizando o pytest padrão. Porém a mágica não acontece mais quando nós estamos utilizando dentro de funções assíncronas. Ao executar os nossos testes de forma assíncrona, nós não podemos mais utilizar o `TestClient` dentro das nossas funções de teste.
O `TestClient` faz algumas mágicas para invocar a aplicação FastAPI assíncrona em suas funções de teste `def` normais, utilizando o pytest padrão. Porém a mágica não acontece mais quando nós estamos utilizando dentro de funções assíncronas. Ao executar os nossos testes de forma assíncrona, nós não podemos mais utilizar o `TestClient` dentro das nossas funções de teste.
O `TestClient` é baseado no [HTTPX](https://www.python-httpx.org), e felizmente nós podemos utilizá-lo diretamente para testar a API.
@@ -38,7 +38,7 @@ O arquivo `test_main.py` teria os testes para o arquivo `main.py`, ele poderia f
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
## Executá-lo { #run-it }
## Execute { #run-it }
Você pode executar os seus testes normalmente via:
@@ -71,7 +71,7 @@ Então podemos criar um `AsyncClient` com a aplicação, e enviar requisições
Isso é equivalente a:
```Python
response = client.get('/')
response = client.get("/")
```
...que nós utilizamos para fazer as nossas requisições utilizando o `TestClient`.
+16 -45
View File
@@ -8,7 +8,7 @@ Esses proxies podem lidar com certificados HTTPS e outras coisas.
Um **proxy** na frente da sua aplicação normalmente definiria alguns headers dinamicamente antes de enviar as requisições para o seu **servidor**, para informar ao servidor que a requisição foi **encaminhada** pelo proxy, informando a URL original (pública), incluindo o domínio, que está usando HTTPS, etc.
O programa do **servidor** (por exemplo, **Uvicorn** via **CLI do FastAPI**) é capaz de interpretar esses headers e então repassar essas informações para a sua aplicação.
O **servidor** iniciado por `fastapi run` é capaz de interpretar esses headers e então repassar essas informações para a sua aplicação.
Mas, por segurança, como o servidor não sabe que está atrás de um proxy confiável, ele não interpretará esses headers.
@@ -34,8 +34,6 @@ Se o seu **servidor** estiver atrás de um **proxy** confiável e somente o prox
```console
$ uv run fastapi run --forwarded-allow-ips="*"
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
@@ -101,7 +99,7 @@ Quando a **CLI do FastAPI** é configurada com `--forwarded-allow-ips`, ela conf
Você pode ter um proxy que adiciona um prefixo de path à sua aplicação.
Nesses casos, você pode usar `root_path` para configurar sua aplicação.
Nesses casos, você pode configurar o servidor com `fastapi run --root-path`.
O `root_path` é um mecanismo fornecido pela especificação ASGI (na qual o FastAPI é construído, através do Starlette).
@@ -117,7 +115,7 @@ Embora todo o seu código esteja escrito assumindo que existe apenas `/app`.
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
E o proxy estaria **"removendo"** o **prefixo de path** dinamicamente antes de transmitir a requisição para o servidor da aplicação (provavelmente Uvicorn via CLI do FastAPI), mantendo sua aplicação convencida de que está sendo servida em `/app`, para que você não precise atualizar todo o seu código para incluir o prefixo `/api/v1`.
E o proxy estaria **"removendo"** o **prefixo de path** dinamicamente antes de transmitir a requisição para o servidor, mantendo sua aplicação convencida de que está sendo servida em `/app`, para que você não precise atualizar todo o seu código para incluir o prefixo `/api/v1`.
Até aqui, tudo funcionaria normalmente.
@@ -161,7 +159,7 @@ A interface de documentação também precisaria do OpenAPI schema para declarar
}
```
Neste exemplo, o "Proxy" poderia ser algo como **Traefik**. E o servidor seria algo como a CLI do FastAPI com **Uvicorn**, executando sua aplicação FastAPI.
Neste exemplo, o "Proxy" poderia ser algo como **Traefik**. E `fastapi run` iniciaria o servidor executando sua aplicação FastAPI.
### Fornecendo o `root_path` { #providing-the-root-path }
@@ -171,14 +169,10 @@ Para conseguir isso, você pode usar a opção de linha de comando `--root-path`
```console
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Se você usar Hypercorn, ele também tem a opção `--root-path`.
/// note | Detalhes Técnicos
A especificação ASGI define um `root_path` para esse caso de uso.
@@ -195,14 +189,12 @@ Aqui estamos incluindo-o na mensagem apenas para fins de demonstração.
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
Então, se você iniciar o Uvicorn com:
Então, se você iniciar o servidor com:
<div class="termy">
```console
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
@@ -216,30 +208,11 @@ A resposta seria algo como:
}
```
### Configurando o `root_path` na aplicação FastAPI { #setting-the-root-path-in-the-fastapi-app }
/// warning | Parâmetro `root_path` descontinuado
Alternativamente, se você não tiver uma maneira de fornecer uma opção de linha de comando como `--root-path` ou equivalente, você pode definir o parâmetro `root_path` ao criar sua aplicação FastAPI:
No FastAPI 0.145.0 e versões anteriores, `root_path` também podia ser configurado em `FastAPI()`. Esse parâmetro agora está descontinuado porque seu comportamento não era consistente com a configuração do servidor. Use `fastapi run --root-path /api/v1` em vez disso.
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
Passar o `root_path` para `FastAPI` seria o equivalente a passar a opção de linha de comando `--root-path` para Uvicorn ou Hypercorn.
### Sobre `root_path` { #about-root-path }
Tenha em mente que o servidor (Uvicorn) não usará esse `root_path` para nada além de passá-lo para a aplicação.
Mas se você acessar com seu navegador [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app) você verá a resposta normal:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
Portanto, ele não esperará ser acessado em `http://127.0.0.1:8000/api/v1/app`.
O Uvicorn esperará que o proxy acesse o Uvicorn em `http://127.0.0.1:8000/app`, e então seria responsabilidade do proxy adicionar o prefixo extra `/api/v1` no topo.
///
## Sobre proxies com um prefixo de path removido { #about-proxies-with-a-stripped-path-prefix }
@@ -247,7 +220,7 @@ Tenha em mente que um proxy com prefixo de path removido é apenas uma das manei
Provavelmente, em muitos casos, o padrão será que o proxy não tenha um prefixo de path removido.
Em um caso como esse (sem um prefixo de path removido), o proxy escutaria em algo como `https://myawesomeapp.com`, e então, se o navegador acessar `https://myawesomeapp.com/api/v1/app` e seu servidor (por exemplo, Uvicorn) escutar em `http://127.0.0.1:8000`, o proxy (sem um prefixo de path removido) acessaria o Uvicorn no mesmo path: `http://127.0.0.1:8000/api/v1/app`.
Em um caso como esse (sem um prefixo de path removido), o proxy escutaria em algo como `https://myawesomeapp.com`, e então, se o navegador acessar `https://myawesomeapp.com/api/v1/app` e seu servidor escutar em `http://127.0.0.1:8000`, o proxy (sem um prefixo de path removido) acessaria o servidor no mesmo path: `http://127.0.0.1:8000/api/v1/app`.
## Testando localmente com Traefik { #testing-locally-with-traefik }
@@ -302,7 +275,7 @@ Agora crie esse outro arquivo `routes.toml`:
Esse arquivo configura o Traefik para usar o prefixo de path `/api/v1`.
E então o Traefik redirecionará suas requisições para seu Uvicorn rodando em `http://127.0.0.1:8000`.
E então o Traefik encaminhará suas requisições para seu servidor rodando em `http://127.0.0.1:8000`.
Agora inicie o Traefik:
@@ -322,15 +295,13 @@ E agora inicie sua aplicação, usando a opção `--root-path`:
```console
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Verifique as respostas { #check-the-responses }
Agora, se você for ao URL com a porta para o Uvicorn: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), você verá a resposta normal:
Agora, se você for ao URL com a porta para o servidor: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), você verá a resposta normal:
```JSON
{
@@ -360,15 +331,15 @@ mas desta vez no URL com o prefixo de path fornecido pelo proxy: `/api/v1`.
Claro, a ideia aqui é que todos acessariam a aplicação através do proxy, então a versão com o prefixo de path `/api/v1` é a "correta".
E a versão sem o prefixo de path (`http://127.0.0.1:8000/app`), fornecida diretamente pelo Uvicorn, seria exclusivamente para o _proxy_ (Traefik) acessá-la.
E a versão sem o prefixo de path (`http://127.0.0.1:8000/app`), fornecida diretamente pelo servidor, seria exclusivamente para o _proxy_ (Traefik) acessá-la.
Isso demonstra como o Proxy (Traefik) usa o prefixo de path e como o servidor (Uvicorn) usa o `root_path` da opção `--root-path`.
Isso demonstra como o Proxy (Traefik) usa o prefixo de path e como o servidor usa o `root_path` da opção `--root-path`.
### Verifique a interface de documentação { #check-the-docs-ui }
Mas aqui está a parte divertida. ✨
A maneira "oficial" de acessar a aplicação seria através do proxy com o prefixo de path que definimos. Então, como esperaríamos, se você tentar a interface de documentação servida diretamente pelo Uvicorn, sem o prefixo de path no URL, ela não funcionará, porque espera ser acessada através do proxy.
A maneira "oficial" de acessar a aplicação seria através do proxy com o prefixo de path que definimos. Então, como esperaríamos, se você tentar a interface de documentação servida diretamente pelo servidor, sem o prefixo de path no URL, ela não funcionará, porque espera ser acessada através do proxy.
Você pode verificar em [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs):
@@ -398,7 +369,7 @@ Mas você também pode fornecer outros `servers` alternativos, por exemplo, se q
Se você passar uma lista personalizada de `servers` e houver um `root_path` (porque sua API está atrás de um proxy), o **FastAPI** inserirá um "server" com esse `root_path` no início da lista.
Por exemplo:
Por exemplo, usando a mesma configuração de servidor `fastapi run --root-path /api/v1`:
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
@@ -455,7 +426,7 @@ Se você não especificar o parâmetro `servers` e `root_path` for igual a `/`,
Se você não quiser que o **FastAPI** inclua um servidor automático usando o `root_path`, você pode usar o parâmetro `root_path_in_servers=False`:
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[8] *}
e então ele não será incluído no OpenAPI schema.
@@ -45,8 +45,10 @@ Então nós podemos utilizar o `secrets.compare_digest()` para garantir que o `c
Isso seria parecido com:
```Python
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
# Return some error
if not (credentials.username == "stanleyjobson") or not (
credentials.password == "swordfish"
):
# Retorne algum erro
...
```
+36 -10
View File
@@ -1,3 +1,7 @@
---
render_macros: false
---
# Templates { #templates }
Você pode usar qualquer template engine com o **FastAPI**.
@@ -6,7 +10,7 @@ Uma escolha comum é o Jinja2, o mesmo usado pelo Flask e outras ferramentas.
Existem utilitários para configurá-lo facilmente que você pode usar diretamente em sua aplicação **FastAPI** (fornecidos pelo Starlette).
## Instalar dependências { #install-dependencies }
## Instale dependências { #install-dependencies }
Adicione `jinja2` ao seu projeto:
@@ -63,14 +67,10 @@ Então você pode escrever um template em `templates/item.html` com, por exemplo
No código HTML que contém:
{% raw %}
```jinja
Item ID: {{ id }}
```
{% endraw %}
...aparecerá o `id` obtido do "context" `dict` que você passou:
```Python
@@ -89,22 +89,48 @@ Você também pode usar `url_for()` dentro do template, ele recebe como argument
Logo, a seção com:
{% raw %}
```jinja
<a href="{{ url_for('read_item', id=id) }}">
```
{% endraw %}
...irá gerar um link para a mesma URL que será tratada pela *função de operação de rota* `read_item(id=id)`.
Por exemplo, com um ID de `42`, isso renderizará:
`url_for()` retorna uma URL absoluta, incluindo o esquema e o host, com base no request atual.
Por exemplo, se sua aplicação for servida em `https://example.com`, com um ID de `42`, isso renderizará:
```html
<a href="https://example.com/items/42">
```
### Paths de URL em templates { #url-paths-in-templates }
Para links para o mesmo site, você pode usar o atributo `.path` para obter apenas o path da URL, por exemplo, em `templates/item_path.html`:
```jinja hl_lines="4 7"
{!../../docs_src/templates/templates/item_path.html!}
```
Passe o nome do template para `TemplateResponse`:
{* ../../docs_src/templates/tutorial002_py310.py ln[14:18] hl[17] *}
Com o mesmo exemplo, o link do item seria renderizado assim:
```html
<a href="/items/42">
```
A `/` inicial torna esse path relativo à raiz do site atual.
O atributo `.path` exclui o esquema, o host, os parâmetros de consulta e o fragmento. Use a URL completa para links para outro host.
/// tip | Dica
Se sua aplicação estiver atrás de um proxy, configure os cabeçalhos encaminhados e o `root_path` conforme descrito em [Atrás de um Proxy](behind-a-proxy.md).
///
## Templates e arquivos estáticos { #templates-and-static-files }
Você também pode usar `url_for()` dentro do template e usá-lo, por exemplo, com o `StaticFiles` que você montou com o `name="static"`.
+5 -5
View File
@@ -15,7 +15,7 @@ results = await some_library()
Então, declare suas *funções de operação de rota* com `async def` como:
```Python hl_lines="2"
@app.get('/')
@app.get("/")
async def read_results():
results = await some_library()
return results
@@ -32,7 +32,7 @@ Você só pode usar `await` dentro de funções criadas com `async def`.
Se você está usando uma biblioteca de terceiros que se comunica com alguma coisa (um banco de dados, uma API, o sistema de arquivos etc.) e não tem suporte para utilizar `await` (esse é atualmente o caso para a maioria das bibliotecas de banco de dados), então declare suas *funções de operação de rota* normalmente, com apenas `def`, como:
```Python hl_lines="2"
@app.get('/')
@app.get("/")
def results():
results = some_library()
return results
@@ -316,7 +316,7 @@ Para o `await` funcionar, tem que estar dentro de uma função que suporte essa
```Python hl_lines="1"
async def get_burgers(number: int):
# Faz alguma coisa assíncrona para criar os hambúrgueres
# Faça alguma coisa assíncrona para criar os hambúrgueres
return burgers
```
@@ -325,7 +325,7 @@ async def get_burgers(number: int):
```Python hl_lines="2"
# Isso não é assíncrono
def get_sequential_burgers(number: int):
# Faz alguma coisa sequencial para criar os hambúrgueres
# Faça alguma coisa sequencial para criar os hambúrgueres
return burgers
```
@@ -343,7 +343,7 @@ burgers = get_burgers(2)
Então, se você está usando uma biblioteca que diz que você pode chamá-la com `await`, você precisa criar as *funções de operação de rota* que a utilizam com `async def`, como em:
```Python hl_lines="2-3"
@app.get('/burgers')
@app.get("/burgers")
async def read_burgers():
burgers = await get_burgers(2)
return burgers
+12 -11
View File
@@ -27,7 +27,7 @@ Documentação interativa da API e navegação web da interface de usuário. Com
Tudo é baseado no padrão das declarações de **tipos do Python** (graças ao Pydantic). Nenhuma sintaxe nova para aprender. Apenas o padrão moderno do Python.
Se você precisa refrescar a memória rapidamente sobre como usar tipos do Python (mesmo que você não use o FastAPI), confira esse rápido tutorial: [Tipos do Python](python-types.md).
Se você precisa refrescar a memória em 2 minutos sobre como usar tipos do Python (mesmo que você não use o FastAPI), confira esse rápido tutorial: [Tipos do Python](python-types.md).
Você escreve Python padrão com tipos:
@@ -36,6 +36,7 @@ from datetime import date
from pydantic import BaseModel
# Declare uma variável como str
# e obtenha suporte do editor dentro da função
def main(user_id: str):
@@ -85,19 +86,19 @@ Aqui está como o editor poderá te ajudar:
* no [Visual Studio Code](https://code.visualstudio.com/):
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
![suporte do editor](https://fastapi.tiangolo.com/img/vscode-completion.png)
* no [PyCharm](https://www.jetbrains.com/pycharm/):
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
![suporte do editor](https://fastapi.tiangolo.com/img/pycharm-completion.png)
Você terá preenchimento automático no seu código que você poderia considerar impossível antes. Como por exemplo, a chave `price` dentro do corpo JSON (que poderia ter sido aninhado) que vem de uma requisição.
Sem a necessidade de digitar nomes de chaves erroneamente, ir e voltar entre documentações, ou rolar pela página para descobrir se você utilizou `username` ou `user_name`.
Chega de digitar nomes de chaves erroneamente, ir e voltar entre documentações, ou rolar pela página para descobrir se você utilizou `username` ou `user_name`.
### Breve { #short }
Há **valores padrão** sensíveis para tudo, com configurações adicionais em todos os lugares. Todos os parâmetros podem ser regulados para fazer o que você precisa e para definir a API que você necessita.
Há **valores padrão** sensatos para tudo, com configurações opcionais em todos os lugares. Todos os parâmetros podem ser regulados para fazer o que você precisa e para definir a API que você necessita.
Mas, por padrão, tudo **"simplesmente funciona"**.
@@ -167,7 +168,7 @@ Com **FastAPI**, você terá todas as funcionalidades do **Starlette** (já que
* Desempenho realmente impressionante. É [um dos frameworks Python disponíveis mais rápidos, a par com o **NodeJS** e **Go**](https://github.com/encode/starlette#performance).
* Suporte a **WebSocket**.
* Tarefas em processo background.
* Tarefas em segundo plano no mesmo processo.
* Eventos de inicialização e encerramento.
* Cliente de testes construído sobre HTTPX.
* Respostas **CORS**, GZip, Static Files, Streaming.
@@ -187,15 +188,15 @@ O mesmo se aplica no sentido inverso, em muitos casos você poderá simplesmente
Com **FastAPI** você terá todas as funcionalidades do **Pydantic** (já que FastAPI utiliza o Pydantic para todo o controle dos dados):
* **Sem pegadinhas**:
* **Sem complicações**:
* Sem novas definições de esquema de micro-linguagem para aprender.
* Se você conhece os tipos do Python, você sabe como usar o Pydantic.
* Vai bem com o/a seu/sua **<abbr title="Integrated Development Environment - Ambiente de Desenvolvimento Integrado: similar a um editor de código">IDE</abbr>/<dfn title="Um programa que confere erros de código">linter</dfn>/cérebro**:
* Como as estruturas de dados do Pydantic são apenas instâncias de classes que você define, o preenchimento automático, linting, mypy e a sua intuição devem funcionar corretamente com seus dados validados.
* Valida **estruturas complexas**:
* Valide **estruturas complexas**:
* Use modelos hierárquicos do Pydantic, `List` e `Dict` do `typing` do Python, etc.
* Validadores permitem que esquemas de dados complexos sejam limpos e facilmente definidos, conferidos e documentados como JSON Schema.
* Você pode ter **JSONs aninhados** profundamente e tê-los todos validados e anotados.
* E validadores permitem que esquemas de dados complexos sejam definidos, conferidos e documentados como JSON Schema de forma clara e fácil.
* Você pode ter **objetos JSON aninhados** profundamente e tê-los todos validados e anotados.
* **Extensível**:
* Pydantic permite que tipos de dados personalizados sejam definidos ou você pode estender a validação com métodos em um modelo decorado com seu decorador de validador.
* Pydantic permite que tipos de dados personalizados sejam definidos ou você pode estender a validação com métodos em um modelo decorados com seu decorador de validador.
* 100% de cobertura de testes.
+1 -1
View File
@@ -544,7 +544,7 @@ Utilizado pelo Pydantic:
Utilizado pelo Starlette:
* [`httpx`](https://www.python-httpx.org) - Obrigatório caso você queira utilizar o `TestClient`.
* [`httpx2`](https://pydantic.dev/docs/httpx2/) (ou `httpx`) - Utilizado pelo `TestClient`.
* [`jinja2`](https://jinja.palletsprojects.com) - Obrigatório se você quer utilizar a configuração padrão de templates.
* [`python-multipart`](https://github.com/Kludex/python-multipart) - Obrigatório se você deseja suporte a <dfn title="convertendo a string que vem de uma requisição HTTP em dados Python">"parsing"</dfn> de formulário, com `request.form()`.
+6 -7
View File
@@ -155,8 +155,7 @@ Como o path de cada *operação de rota* tem que começar com `/`, como em:
```Python hl_lines="1"
@router.get("/{item_id}")
async def read_item(item_id: str):
...
async def read_item(item_id: str): ...
```
...o prefixo não deve incluir um `/` final.
@@ -180,7 +179,7 @@ O resultado final é que os paths dos itens agora são:
...como pretendíamos.
* Elas serão marcadas com uma lista de tags que contêm uma única string `"items"`.
* Elas serão marcadas com uma list de tags que contêm uma única string `"items"`.
* Essas "tags" são especialmente úteis para os sistemas de documentação interativa automática (usando OpenAPI).
* Todas elas incluirão as `responses` predefinidas.
* Todas essas *operações de rota* terão a list de `dependencies` avaliada/executada antes delas.
@@ -196,7 +195,7 @@ Ter `dependencies` no `APIRouter` pode ser usado, por exemplo, para exigir auten
/// tip | Dica
Os parâmetros `prefix`, `tags`, `responses` e `dependencies` são (como em muitos outros casos) apenas um recurso do **FastAPI** para ajudar a evitar duplicação de código.
Os parâmetros `prefix`, `tags`, `responses` e `dependencies` são (como em muitos outros casos) apenas uma funcionalidade do **FastAPI** para ajudar a evitar duplicação de código.
///
@@ -390,7 +389,7 @@ E `items.router` contém o `APIRouter` dentro do arquivo `app/routers/items.py`.
///
Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo principal `FastAPI`.
Com `app.include_router()` podemos adicionar cada `APIRouter` à aplicação principal `FastAPI`.
Ele incluirá todas as rotas daquele router como parte dele.
@@ -443,7 +442,7 @@ Assim, por exemplo, outros projetos poderiam usar o mesmo `APIRouter` com um mé
### Inclua uma *operação de rota* { #include-a-path-operation }
Também podemos adicionar *operações de rota* diretamente ao aplicativo `FastAPI`.
Também podemos adicionar *operações de rota* diretamente à aplicação `FastAPI`.
Aqui fazemos isso... só para mostrar que podemos 🤷:
@@ -542,6 +541,6 @@ Evite mutar diretamente `router.routes` após incluir um router. O FastAPI trata
Use APIs documentadas como os decoradores de operações de rota e `.include_router()` para adicionar rotas e routers.
Trate `router.routes` como uma árvore de rotas de nível mais baixo que pode conter definições de rotas e routers incluídos, e evite depender dela como uma lista plana de operações de rota finais.
Trate `router.routes` como uma árvore de rotas de nível mais baixo que pode conter definições de rotas e routers incluídos, e evite depender dela como uma list plana de operações de rota finais.
///
+4 -3
View File
@@ -8,6 +8,7 @@ Primeiro, você tem que importá-lo:
{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
/// warning | Atenção
Note que `Field` é importado diretamente do `pydantic`, não do `fastapi` como todo o resto (`Query`, `Path`, `Body`, etc).
@@ -42,13 +43,13 @@ Note como cada atributo do modelo com um tipo, valor padrão e `Field` possuem a
## Adicione informações extras { #add-extra-information }
Você pode declarar informação extra em `Field`, `Query`, `Body`, etc. E isso será incluído no JSON Schema gerado.
Você pode declarar informação extra com `json_schema_extra` em `Field`, `Query`, `Body`, etc. E isso será incluído no JSON Schema gerado.
Você irá aprender mais sobre adicionar informações extras posteriormente nessa documentação, quando estiver aprendendo a declarar exemplos.
/// warning | Atenção
Chaves extras passadas para `Field` também estarão presentes no schema OpenAPI resultante da sua aplicação.
Chaves extras passadas em `json_schema_extra` também estarão presentes no schema OpenAPI resultante da sua aplicação.
Como essas chaves podem não fazer necessariamente parte da especificação OpenAPI, algumas ferramentas de OpenAPI, por exemplo [o validador do OpenAPI](https://validator.swagger.io/), podem não funcionar com o schema gerado.
///
@@ -57,4 +58,4 @@ Como essas chaves podem não fazer necessariamente parte da especificação Open
Você pode usar `Field` do Pydantic para declarar validações extras e metadados para atributos do modelo.
Você também pode usar os argumentos de palavras-chave extras para passar metadados do JSON Schema adicionais.
Você também pode usar `json_schema_extra` para passar metadados do JSON Schema adicionais.
+22 -6
View File
@@ -34,25 +34,25 @@ Você pode ver os cookies definidos na IU da documentação em `/docs`:
/// note | Nota
Tenha em mente que, como os **navegadores lidam com cookies** de maneira especial e por baixo dos panos, eles **não** permitem facilmente que o **JavaScript** lidem com eles.
Tenha em mente que, como os **navegadores lidam com cookies** de maneira especial e por baixo dos panos, eles **não** permitem facilmente que o **JavaScript** lide com eles.
Se você for na **IU da documentação da API** em `/docs` você poderá ver a **documentação** para cookies das suas *operações de rotas*.
Se você for na **IU da documentação da API** em `/docs` você poderá ver a **documentação** para cookies das suas *operações de rota*.
Mas mesmo que você **adicionar os dados** e clicar em "Executar", pelo motivo da IU da documentação trabalhar com **JavaScript**, os cookies não serão enviados, e você verá uma mensagem de **erro** como se você não tivesse escrito nenhum dado.
Mas mesmo que você **adicione os dados** e clique em "Executar", pelo motivo da IU da documentação trabalhar com **JavaScript**, os cookies não serão enviados, e você verá uma mensagem de **erro** como se você não tivesse escrito nenhum dado.
///
## Proibir Cookies Adicionais { #forbid-extra-cookies }
## Proíba Cookies Adicionais { #forbid-extra-cookies }
Em alguns casos especiais (provavelmente não muito comuns), você pode querer **restringir** os cookies que você deseja receber.
Agora a sua API possui o poder de controlar o seu próprio <dfn title="Isso é uma brincadeira, só por precaução. Isso não tem nada a ver com consentimentos de cookies, mas é engraçado que até a API consegue rejeitar os coitados dos cookies. Coma um biscoito. 🍪">consentimento de cookie</dfn>. 🤪🍪
Você pode utilizar a configuração do modelo Pydantic para `proibir` qualquer campo `extra`:
Você pode utilizar a configuração do modelo Pydantic para proibir com `forbid` qualquer campo `extra`:
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
Se o cliente tentar enviar alguns **cookies extras**, eles receberão um retorno de **erro**.
Se o cliente tentar enviar alguns **cookies extras**, ele receberá uma resposta de **erro**.
Coitados dos banners de cookies com todo o seu esforço para obter o seu consentimento para a <dfn title="Isso é uma outra piada. Não preste atenção em mim. Beba um café com o seu cookie. ☕">API rejeitá-lo</dfn>. 🍪
@@ -71,6 +71,22 @@ Por exemplo, se o cliente tentar enviar um cookie `santa_tracker` com o valor de
}
```
## Combine Modelos de Parâmetros { #combine-parameter-models }
Você pode combinar vários modelos de parâmetros de cookie com parâmetros de cookie individuais e dependências. Cada modelo é extraído e validado de forma independente, conforme explicado para [modelos de parâmetros de query](query-param-models.md#combine-parameter-models).
A configuração `extra` de cada modelo se aplica a todos os parâmetros de cookie, incluindo os declarados em outros modelos ou dependências. Com `extra="forbid"`, qualquer cookie fora desse modelo é rejeitado. Com `extra="allow"`, esses cookies são incluídos como campos extras do modelo.
## Modelos Opcionais de Parâmetros de Cookie { #optional-cookie-parameter-models }
Declare um modelo de parâmetros de cookie com `| None` e um valor padrão de `None` para tornar o grupo opcional.
{* ../../docs_src/cookie_param_models/tutorial003_an_py310.py hl[15] *}
Se nem `theme` nem `locale` forem enviados, `preferences` será `None`. Se qualquer um deles for enviado, o FastAPI validará o modelo e exigirá ambos os campos.
As mesmas regras para valores padrão, campos extras e OpenAPI se aplicam, assim como nos [modelos opcionais de parâmetros de query](query-param-models.md#optional-query-parameter-models).
## Resumo { #summary }
Você consegue utilizar **modelos Pydantic** para declarar <dfn title="Coma um último biscoito antes de você ir embora. 🍪">**cookies**</dfn> no **FastAPI**. 😎
@@ -29,7 +29,7 @@ Vamos focar nos parâmetros declarados:
* Ela também declara um cookie opcional `last_query`, do tipo `str`.
* Se o usuário não passou nenhuma consulta `q`, a última consulta é utilizada, que foi salva em um cookie anteriormente.
## Utilizando a dependência { #use-the-dependency }
## Utilize a dependência { #use-the-dependency }
Então podemos utilizar a dependência com:
@@ -60,12 +60,14 @@ Se uma de suas dependências é declarada várias vezes para a mesma *operação
E o valor retornado é salvo em um <dfn title="Um utilitário/sistema para armazenar valores calculados/gerados para serem reutilizados em vez de computá-los novamente.">"cache"</dfn> e repassado para todos os "dependentes" que precisam dele em uma requisição específica, em vez de chamar a dependência múltiplas vezes para uma mesma requisição.
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`:
Em um cenário avançado onde você precise que a dependência seja chamada 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`:
//// tab | Python 3.10+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
```Python hl_lines="2"
async def needy_dependency(
fresh_value: Annotated[str, Depends(get_value, use_cache=False)],
):
return {"fresh_value": fresh_value}
```
@@ -100,6 +102,6 @@ Tudo isso pode não parecer muito útil com esses exemplos.
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.
E você também verá a quantidade de código que você não precisará escrever.
///
+14 -14
View File
@@ -54,10 +54,10 @@ teríamos um `dict` Python com:
```Python
{
'username': 'john',
'password': 'secret',
'email': 'john.doe@example.com',
'full_name': None,
"username": "john",
"password": "secret",
"email": "john.doe@example.com",
"full_name": None,
}
```
@@ -86,10 +86,10 @@ Ou mais exatamente, usando `user_dict` diretamente, com qualquer conteúdo que e
```Python
UserInDB(
username = user_dict["username"],
password = user_dict["password"],
email = user_dict["email"],
full_name = user_dict["full_name"],
username=user_dict["username"],
password=user_dict["password"],
email=user_dict["email"],
full_name=user_dict["full_name"],
)
```
@@ -124,11 +124,11 @@ UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
```Python
UserInDB(
username = user_dict["username"],
password = user_dict["password"],
email = user_dict["email"],
full_name = user_dict["full_name"],
hashed_password = hashed_password,
username=user_dict["username"],
password=user_dict["password"],
email=user_dict["email"],
full_name=user_dict["full_name"],
hashed_password=hashed_password,
)
```
@@ -138,7 +138,7 @@ As funções adicionais de suporte `fake_password_hasher` e `fake_save_user` ser
///
## Reduzir duplicação { #reduce-duplication }
## Reduza a duplicação { #reduce-duplication }
Reduzir a duplicação de código é uma das ideias principais no **FastAPI**.
+24 -4
View File
@@ -18,7 +18,7 @@ Declare os **parâmetros de cabeçalho** que você precisa em um **modelo do Pyd
O **FastAPI** irá **extrair** os dados de **cada campo** a partir dos **cabeçalhos** da requisição e te retornará o modelo do Pydantic que você definiu.
## Checando a documentação { #check-the-docs }
## Confira a documentação { #check-the-docs }
Você pode ver os headers necessários na interface gráfica da documentação em `/docs`:
@@ -26,11 +26,11 @@ Você pode ver os headers necessários na interface gráfica da documentação e
<img src="/img/tutorial/header-param-models/image01.png">
</div>
## Proibindo Cabeçalhos adicionais { #forbid-extra-headers }
## Proíba Cabeçalhos adicionais { #forbid-extra-headers }
Em alguns casos de uso especiais (provavelmente não muito comuns), você pode querer **restringir** os cabeçalhos que você quer receber.
Você pode usar a configuração dos modelos do Pydantic para proibir (`forbid`) quaisquer campos `extra`:
Você pode usar a configuração dos modelos do Pydantic para proibir quaisquer campos `extra` com `forbid`:
{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
@@ -51,7 +51,7 @@ Por exemplo, se o cliente tentar enviar um cabeçalho `tool` com o valor `plumbu
}
```
## Desativar conversão de underscores { #disable-convert-underscores }
## Desative a conversão de underscores { #disable-convert-underscores }
Da mesma forma que com parâmetros de cabeçalho normais, quando você tem caracteres de sublinhado nos nomes dos parâmetros, eles são **automaticamente convertidos em hifens**.
@@ -67,6 +67,26 @@ Antes de definir `convert_underscores` como `False`, tenha em mente que alguns p
///
## Combine Modelos de Parâmetros { #combine-parameter-models }
Você pode combinar múltiplos modelos de parâmetros de cabeçalho com parâmetros de cabeçalho individuais e dependências. Cada modelo é extraído e validado de forma independente, conforme explicado para [modelos de parâmetros de consulta](query-param-models.md#combine-parameter-models).
A configuração `extra` de cada modelo se aplica a todos os parâmetros de cabeçalho, incluindo aqueles declarados em outros modelos ou dependências. Com `extra="forbid"`, qualquer cabeçalho fora desse modelo é rejeitado. Com `extra="allow"`, esses cabeçalhos são incluídos como campos extras do modelo.
Cada modelo usa sua própria configuração `Header(convert_underscores=...)`, tanto ao ler a requisição quanto ao gerar o OpenAPI. Aliases explícitos de campos permanecem como nomes literais de cabeçalhos.
## Modelos Opcionais de Parâmetros de Cabeçalho { #optional-header-parameter-models }
Declare um modelo de parâmetros de cabeçalho com `| None` e um valor padrão de `None` para tornar o grupo opcional.
{* ../../docs_src/header_param_models/tutorial004_an_py310.py hl[15] *}
Se nem `x-client-name` nem `x-client-version` forem enviados, `client` será `None`. Se qualquer um deles for enviado, o FastAPI validará o modelo e exigirá ambos os campos.
As mesmas regras para valores padrão, campos extras e OpenAPI se aplicam aos [modelos opcionais de parâmetros de consulta](query-param-models.md#optional-query-parameter-models).
Cabeçalhos como `Host` também seguem a configuração `extra` do modelo. Com `extra="allow"`, eles tornam o modelo presente mesmo que nenhum dos campos declarados seja fornecido.
## Resumo { #summary }
Você pode utilizar **modelos do Pydantic** para declarar **cabeçalhos** no **FastAPI**. 😎
@@ -28,7 +28,7 @@ Por exemplo, para declarar um valor de metadado `title` para o parâmetro de pat
/// note | Nota
Um parâmetro de path é sempre obrigatório, pois precisa fazer parte do path. Mesmo que você o declare como `None` ou defina um valor padrão, isso não afetaria nada, ele ainda seria sempre obrigatório.
Um parâmetro de path é sempre obrigatório, pois precisa fazer parte do path da URL. Adicionar `None` ao seu tipo não o torna opcional. Um parâmetro declarado com `Path` não pode ter um valor padrão.
///
@@ -68,7 +68,7 @@ Isso provavelmente não é tão importante ou necessário se você usar `Annotat
///
Aqui vai um pequeno truque que pode ser útil, mas você não vai precisar dele com frequência.
Aqui vai um **pequeno truque** que pode ser útil, mas você não vai precisar dele com frequência.
Se você quiser:
@@ -81,7 +81,7 @@ Se você quiser:
Passe `*`, como o primeiro parâmetro da função.
O Python não fará nada com esse `*`, mas saberá que todos os parâmetros seguintes devem ser chamados como argumentos nomeados (pares chave-valor), também conhecidos como <abbr title="De: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Mesmo que eles não tenham um valor padrão.
O Python não fará nada com esse `*`, mas saberá que todos os parâmetros seguintes devem ser chamados como argumentos nomeados (pares chave-valor), também conhecidos como <abbr title="De: K-ey W-ord Arg-uments - argumentos nomeados"><code>kwargs</code></abbr>. Mesmo que eles não tenham um valor padrão.
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
@@ -95,7 +95,7 @@ Tenha em mente que, se você usar `Annotated`, como você não está usando valo
Com `Query` e `Path` (e outras que você verá depois) você pode declarar restrições numéricas.
Aqui, com `ge=1`, `item_id` precisará ser um número inteiro “`g`reater than or `e`qual” a `1`.
Aqui, com `ge=1`, `item_id` precisará ser um número inteiro “maior que ou igual” — `g`reater than or `e`qual — a `1`.
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
@@ -103,8 +103,8 @@ Aqui, com `ge=1`, `item_id` precisará ser um número inteiro “`g`reater than
O mesmo se aplica a:
* `gt`: maior que (`g`reater `t`han)
* `le`: menor que ou igual (`l`ess than or `e`qual)
* `gt`: maior que — `g`reater `t`han
* `le`: menor que ou igual — `l`ess than or `e`qual
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
@@ -112,11 +112,11 @@ O mesmo se aplica a:
Validações numéricas também funcionam para valores `float`.
Aqui é onde se torna importante poder declarar <abbr title="greater than – maior que"><code>gt</code></abbr> e não apenas <abbr title="greater than or equal – maior que ou igual"><code>ge</code></abbr>. Com isso você pode exigir, por exemplo, que um valor seja maior que `0`, mesmo que seja menor que `1`.
Aqui é onde se torna importante poder declarar <abbr title="greater than - maior que"><code>gt</code></abbr> e não apenas <abbr title="greater than or equal - maior que ou igual"><code>ge</code></abbr>. Com isso você pode exigir, por exemplo, que um valor seja maior que `0`, mesmo que seja menor que `1`.
Assim, `0.5` seria um valor válido. Mas `0.0` ou `0` não seriam.
E o mesmo para <abbr title="less than – menor que"><code>lt</code></abbr>.
E o mesmo para <abbr title="less than - menor que"><code>lt</code></abbr>.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
@@ -126,10 +126,10 @@ Com `Query`, `Path` (e outras que você ainda não viu) você pode declarar meta
E você também pode declarar validações numéricas:
* `gt`: maior que (`g`reater `t`han)
* `ge`: maior que ou igual (`g`reater than or `e`qual)
* `lt`: menor que (`l`ess `t`han)
* `le`: menor que ou igual (`l`ess than or `e`qual)
* `gt`: maior que — `g`reater `t`han
* `ge`: maior que ou igual — `g`reater than or `e`qual
* `lt`: menor que — `l`ess `t`han
* `le`: menor que ou igual — `l`ess than or `e`qual
/// note | Nota
+37 -1
View File
@@ -28,7 +28,7 @@ Você pode ver os parâmetros de consulta na IU da documentação em `/docs`:
## Restrinja Parâmetros de Consulta Extras { #forbid-extra-query-parameters }
Em alguns casos especiais (provavelmente não muito comuns), você queira **restringir** os parâmetros de consulta que deseja receber.
Em alguns casos especiais (provavelmente não muito comuns), você pode querer **restringir** os parâmetros de consulta que deseja receber.
Você pode usar a configuração do modelo Pydantic para `forbid` qualquer campo `extra`:
@@ -57,6 +57,42 @@ Eles receberão um retorno de **erro** informando-os que o parâmetro de consult
}
```
## Combine Modelos de Parâmetros { #combine-parameter-models }
Você pode declarar vários modelos de parâmetros de consulta e combiná-los com parâmetros de consulta individuais ou dependências.
{* ../../docs_src/query_param_models/tutorial003_an_py310.py hl[9:15,20:22] *}
Os parâmetros da requisição permanecem no mesmo nível.
```http
https://example.com/items/?limit=5&offset=10&tags=red&tags=blue&search=shirt
```
Não há chaves `pagination` ou `filters` na string de consulta. Cada modelo valida os parâmetros de consulta de forma independente, com seus próprios valores padrão, validadores de campo e de modelo. O mesmo se aplica quando os modelos ou parâmetros individuais são declarados em dependências.
Se os modelos compartilham um nome ou alias de parâmetro, cada modelo valida esse parâmetro da requisição de forma independente. Use nomes ou aliases distintos para valores independentes. O OpenAPI lista um parâmetro compartilhado apenas uma vez, assim como faz com parâmetros compartilhados com dependências, portanto as declarações compartilhadas deveriam descrever o mesmo tipo e as mesmas restrições.
A configuração `extra` de cada modelo se aplica a todos os parâmetros de consulta, incluindo os declarados em outros modelos ou dependências. Com `extra="forbid"`, qualquer parâmetro fora desse modelo é rejeitado. Com `extra="allow"`, esses parâmetros são incluídos como extras do modelo.
Isso também funciona para modelos `Header` e `Cookie`.
## Modelos Opcionais de Parâmetros de Consulta { #optional-query-parameter-models }
Declare um modelo de parâmetros de consulta com `| None` e um valor padrão de `None` para tornar o grupo opcional.
{* ../../docs_src/query_param_models/tutorial004_an_py310.py hl[18] *}
Se nem `start` nem `end` forem enviados, `date_range` será `None`. Se qualquer um deles for enviado, o FastAPI validará o modelo e exigirá ambos os campos.
Usar `| None` sem um valor padrão ainda torna o parâmetro obrigatório.
Parâmetros extras seguem a configuração `extra` do modelo. Extras ignorados não fazem com que o modelo seja considerado presente.
O OpenAPI lista os campos do grupo individualmente e os marca como opcionais.
Você também pode declarar [modelos de parâmetros de cabeçalho](header-param-models.md#optional-header-parameter-models) e [modelos de parâmetros de cookie](cookie-param-models.md#optional-cookie-parameter-models) opcionais.
## Resumo { #summary }
Você pode utilizar **modelos Pydantic** para declarar **parâmetros de consulta** no **FastAPI**. 😎
@@ -220,14 +220,22 @@ Então, quando você precisa declarar um valor como obrigatório usando `Query`,
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### Obrigatório, pode ser `None` { #required-can-be-none }
### Parâmetros obrigatórios e `None` { #required-parameters-and-none }
Você pode declarar que um parâmetro pode aceitar `None`, mas que ainda assim é obrigatório. Isso forçaria os clientes a enviarem um valor, mesmo que o valor seja `None`.
Para isso, você pode declarar que `None` é um tipo válido, mas simplesmente não declarar um valor padrão:
O tipo `str | None` permite `None` como valor Python, mas não torna um parâmetro de consulta opcional. Sem um valor padrão, o parâmetro continua obrigatório:
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
Os valores dos parâmetros de consulta chegam como strings e não têm uma representação nativa de `None`. Enviar `?q=None` ou `?q=null` envia as strings `"None"` e `"null"`, respectivamente. Enviar `?q=` envia uma string vazia, que falha na validação `min_length=3` neste exemplo.
Para permitir que os clientes omitam `q` e usem `None` como seu valor, atribua a ele o valor padrão `None`:
```Python
q: Annotated[str | None, Query(min_length=3)] = None
```
Corpos de requisição JSON, ao contrário dos parâmetros de consulta, podem conter um valor `null` explícito.
## Lista de parâmetros de consulta / múltiplos valores { #query-parameter-list-multiple-values }
Quando você define explicitamente um parâmetro de consulta com `Query`, você também pode declará-lo para receber uma lista de valores, ou seja, receber múltiplos valores.
@@ -296,9 +304,9 @@ Você também pode usar `list` diretamente em vez de `list[str]`:
/// note | Nota
Tenha em mente que, neste caso, o FastAPI não verificará o conteúdo da lista.
Tenha em mente que, neste caso, o FastAPI não verificará o conteúdo da list.
Por exemplo, `list[int]` verificaria (e documentaria) que os conteúdos da lista são inteiros. Mas `list` sozinho não.
Por exemplo, `list[int]` verificaria (e documentaria) que os conteúdos da list são inteiros. Mas `list` sozinho não.
///
@@ -358,7 +366,7 @@ A documentação vai mostrar assim:
<img src="/img/tutorial/query-params-str-validations/image01.png">
## Excluir parâmetros do OpenAPI { #exclude-parameters-from-openapi }
## Exclua parâmetros do OpenAPI { #exclude-parameters-from-openapi }
Para excluir um parâmetro de consulta do esquema OpenAPI gerado (e portanto, dos sistemas de documentação automáticos), defina o parâmetro `include_in_schema` de `Query` como `False`:
@@ -416,7 +424,7 @@ Com `data.items()` obtemos um <dfn title="Algo que podemos iterar com um laço f
Convertemos esse objeto iterável em uma `list` adequada com `list(data.items())`.
Em seguida, com `random.choice()` podemos obter um **valor aleatório** da lista, então obtemos uma tupla com `(id, name)`. Será algo como `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Em seguida, com `random.choice()` podemos obter um **valor aleatório** da list, então obtemos uma tupla com `(id, name)`. Será algo como `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Depois **atribuímos esses dois valores** da tupla às variáveis `id` e `name`.
+9 -3
View File
@@ -30,7 +30,7 @@ Todo o processo que era aplicado para parâmetros de rota também é aplicado pa
## Valores padrão { #defaults }
Como os parâmetros de consulta não são uma parte fixa da rota, eles podem ser opcionais e podem ter valores padrão.
Como os parâmetros de consulta não são uma parte fixa de um path, eles podem ser opcionais e podem ter valores padrão.
No exemplo acima eles tem valores padrão de `skip=0` e `limit=10`.
@@ -107,7 +107,13 @@ ou
http://127.0.0.1:8000/items/foo?short=yes
```
ou qualquer outra variação (tudo em maiúscula, primeira letra em maiúscula, etc), a sua função vai ver o parâmetro `short` com um valor `bool` de `True`. Caso contrário `False`.
ou qualquer outra variação (tudo em maiúscula, primeira letra em maiúscula, etc), a sua função vai ver o parâmetro `short` com um valor `bool` de `True`.
Valores como `0`, `false`, `off` e `no` (incluindo variações de maiúsculas e minúsculas) são convertidos para `False`.
Se `short` for omitido, o **FastAPI** usa seu valor padrão, que é `False` neste exemplo.
Um valor vazio (`?short=`) ou não reconhecido (por exemplo, `?short=maybe`) produz um erro de validação `422`.
## Múltiplos parâmetros de rota e consulta { #multiple-path-and-query-parameters }
@@ -126,7 +132,7 @@ Quando você declara um valor padrão para parâmetros que não são de rota (at
Caso você não queira adicionar um valor específico mas queira apenas torná-lo opcional, defina o valor padrão como `None`.
Porém, quando você quiser fazer com que o parâmetro de consulta seja obrigatório, você pode simplesmente não declarar nenhum valor como padrão.
Porém, quando você quiser fazer com que o parâmetro de consulta seja obrigatório, você pode simplesmente não declarar nenhum valor como padrão:
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
+56 -2
View File
@@ -28,6 +28,8 @@ Você precisa apenas declarar um **modelo Pydantic** com os campos que deseja re
O **FastAPI** irá **extrair** as informações para **cada campo** dos **dados do formulário** na requisição e dar para você o modelo Pydantic que você definiu.
Para [caixas de seleção HTML](request-forms.md#boolean-form-fields), declare campos booleanos com o valor padrão `False`.
## Confira a Documentação { #check-the-docs }
Você pode verificar na UI de documentação em `/docs`:
@@ -36,7 +38,7 @@ Você pode verificar na UI de documentação em `/docs`:
<img src="/img/tutorial/request-form-models/image01.png">
</div>
## Proibir Campos Extras de Formulários { #forbid-extra-form-fields }
## Proíba Campos Extras de Formulários { #forbid-extra-form-fields }
Em alguns casos de uso especiais (provavelmente não muito comum), você pode desejar **restringir** os campos do formulário para aceitar apenas os declarados no modelo Pydantic. E **proibir** qualquer campo **extra**.
@@ -46,7 +48,7 @@ Isso é suportado desde a versão `0.114.0` do FastAPI. 🤓
///
Você pode utilizar a configuração de modelo do Pydantic para `proibir` qualquer campo `extra`:
Você pode utilizar a configuração de modelo do Pydantic para definir `forbid` para qualquer campo `extra`:
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
@@ -73,6 +75,58 @@ Ele receberá um retorno de erro informando-o que o campo `extra` não é permit
}
```
## Combine Modelos de Formulários { #combine-form-models }
Você pode combinar vários modelos de formulários com parâmetros `Form` individuais.
{* ../../docs_src/request_form_models/tutorial003_an_py310.py hl[9:14,19:21] *}
O cliente envia `name`, `tags` e `token` como campos de formulário. Cada modelo valida os campos do formulário de forma independente.
A configuração `extra` de cada modelo se aplica a todos os campos do formulário, incluindo campos e arquivos declarados em outros parâmetros ou dependências. Com `extra="forbid"`, qualquer campo fora desse modelo é rejeitado. Com `extra="allow"`, esses campos são incluídos como extras do modelo.
Se várias declarações usarem o mesmo nome de campo de formulário, cada uma validará o valor desse campo. Use tipos e restrições compatíveis para campos compartilhados, para que o esquema OpenAPI possa descrevê-los de forma consistente.
## Modelos de Formulários Opcionais { #optional-form-models }
Declare um modelo de formulário com `| None` e um valor padrão `None` para tornar o grupo opcional.
{* ../../docs_src/request_form_models/tutorial005_an_py310.py hl[17] *}
Se nem `name` nem `age` forem enviados, `profile` será `None`. Se qualquer um deles for enviado, o FastAPI validará o modelo e exigirá ambos os campos. Um valor vazio enviado também conta como fornecimento de um campo.
Usar `| None` sem um valor padrão ainda torna o parâmetro obrigatório.
Campos extras seguem a configuração `extra` do modelo. Extras ignorados não fazem com que o modelo seja considerado presente.
Um modelo opcional que contenha apenas caixas de seleção desmarcadas é omitido. Envie um valor como `enabled=false` para fornecê-lo explicitamente.
## Uniões Opcionais de Modelos de Formulários { #optional-unions-of-form-models }
Você também pode usar uma união opcional de modelos.
{* ../../docs_src/request_form_models/tutorial006_an_py310.py hl[9:16,21] *}
Se nenhum campo de formulário for enviado, `contact` será `None`. Envie `kind=person` com `name`, ou `kind=company` com `company_name`. O discriminador seleciona qual modelo validar.
## Combine Uniões de Modelos de Formulários { #combine-unions-of-form-models }
Você pode combinar uniões com outros modelos de formulários, parâmetros `Form` individuais e parâmetros `File`. Cada união é validada de forma independente.
{* ../../docs_src/request_form_models/tutorial007_an_py310.py hl[31:35] *}
Envie todos os campos no mesmo formulário. Por exemplo, envie `contact_type=person`, `name=Rick`, `notification_type=email`, `email=rick@example.com` e `token=secret`.
Omita os campos de notificação para deixar `notification` como `None`.
## Modelos de Formulários e Arquivos { #form-models-and-files }
Você também pode combinar um modelo de formulário com [parâmetros de arquivo](request-files.md).
{* ../../docs_src/request_form_models/tutorial004_an_py310.py hl[14] *}
Aqui, o cliente envia o campo `name` e o arquivo `avatar` usando `multipart/form-data`.
## Resumo { #summary }
Você pode utilizar modelos Pydantic para declarar campos de formulários no FastAPI. 😎
+10
View File
@@ -44,6 +44,14 @@ Para declarar corpos de formulário, você precisa usar `Form` explicitamente, p
///
## Campos booleanos de formulário { #boolean-form-fields }
Os navegadores omitem caixas de seleção desmarcadas ao enviar formulários HTML. Declare um parâmetro booleano de formulário com o valor padrão `False` para receber `False` quando a caixa estiver desmarcada:
{* ../../docs_src/request_forms/tutorial002_an_py310.py hl[9] *}
Uma caixa de seleção marcada envia seu valor, que por padrão é `"on"`. O **FastAPI** aceita `"on"` como `True`.
## Sobre "Campos de formulário" { #about-form-fields }
A forma como os formulários HTML (`<form></form>`) enviam os dados para o servidor normalmente usa uma codificação "especial" para esses dados, é diferente do JSON.
@@ -56,6 +64,8 @@ Os dados dos formulários são normalmente codificados usando o "media type" `ap
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.
Você pode usar `Form(media_type="multipart/form-data")` para descrever um formulário multipart no OpenAPI. Configurá-lo em um parâmetro é suficiente ao combinar parâmetros de formulário ou modelos.
Se você quiser ler mais sobre essas codificações e campos de formulário, vá para a [documentação web da <abbr title="Mozilla Developer Network - Rede de Desenvolvedores da Mozilla">MDN</abbr> para `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
///
+9 -5
View File
@@ -2,7 +2,7 @@
Você pode declarar o tipo usado para a resposta anotando o **tipo de retorno** da *função de operação de rota*.
Você pode usar **anotações de tipo** da mesma forma que usaria para dados de entrada em **parâmetros** de função, você pode usar modelos Pydantic, listas, dicionários, valores escalares como inteiros, booleanos, etc.
Você pode usar **anotações de tipo** da mesma forma que usaria para dados de entrada em **parâmetros** de função, você pode usar modelos Pydantic, lists, dicionários, valores escalares como inteiros, booleanos, etc.
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
@@ -156,7 +156,7 @@ Primeiro, vamos ver como editores, mypy e outras ferramentas veriam isso.
Anotamos o tipo de retorno da função como `BaseUser`, mas na verdade estamos retornando uma instância `UserIn`.
O editor, mypy e outras ferramentas não reclamarão disso porque, em termos de digitação, `UserIn` é uma subclasse de `BaseUser`, o que significa que é um tipo *válido* quando o que é esperado é qualquer coisa que seja um `BaseUser`.
O editor, mypy e outras ferramentas não reclamarão disso porque, em termos de tipagem, `UserIn` é uma subclasse de `BaseUser`, o que significa que é um tipo *válido* quando o que é esperado é qualquer coisa que seja um `BaseUser`.
### Filtragem de dados FastAPI { #fastapi-data-filtering }
@@ -168,7 +168,7 @@ Dessa forma, você pode obter o melhor dos dois mundos: anotações de tipo com
## Veja na documentação { #see-it-in-the-docs }
Quando você vê a documentação automática, pode verificar se o modelo de entrada e o modelo de saída terão seus próprios esquemas JSON:
Quando você vê a documentação automática, pode verificar se o modelo de entrada e o modelo de saída terão seus próprios JSON Schema:
<img src="/img/tutorial/response-model/image01.png">
@@ -228,7 +228,7 @@ Seu modelo de resposta pode ter valores padrão, como:
* `description: Union[str, None] = None` (ou `str | None = None` no Python 3.10) tem um padrão de `None`.
* `tax: float = 10.5` tem um padrão de `10.5`.
* `tags: List[str] = []` tem um padrão de uma lista vazia: `[]`.
* `tags: List[str] = []` tem um padrão de uma list vazia: `[]`.
mas você pode querer omiti-los do resultado se eles não foram realmente armazenados.
@@ -266,6 +266,7 @@ conforme descrito na [documentação do Pydantic](https://pydantic.dev/docs/vali
Mas se seus dados tiverem valores para os campos do modelo com valores padrões, como o item com ID `bar`:
<!-- fmt:off -->
```Python hl_lines="3 5"
{
"name": "Bar",
@@ -274,6 +275,7 @@ Mas se seus dados tiverem valores para os campos do modelo com valores padrões,
"tax": 20.2
}
```
<!-- fmt:on -->
eles serão incluídos na resposta.
@@ -281,6 +283,7 @@ eles serão incluídos na resposta.
Se os dados tiverem os mesmos valores que os padrões, como o item com ID `baz`:
<!-- fmt:off -->
```Python hl_lines="3 5-6"
{
"name": "Baz",
@@ -290,6 +293,7 @@ Se os dados tiverem os mesmos valores que os padrões, como o item com ID `baz`:
"tags": []
}
```
<!-- fmt:on -->
O FastAPI é inteligente o suficiente (na verdade, o Pydantic é inteligente o suficiente) para perceber que, embora `description`, `tax` e `tags` tenham os mesmos valores que os padrões, eles foram definidos explicitamente (em vez de retirados dos padrões).
@@ -299,7 +303,7 @@ Portanto, eles serão incluídos na resposta JSON.
Observe que os valores padrão podem ser qualquer coisa, não apenas `None`.
Eles podem ser uma lista (`[]`), um `float` de `10.5`, etc.
Eles podem ser uma list (`[]`), um `float` de `10.5`, etc.
///
+14 -14
View File
@@ -96,7 +96,7 @@ Não estamos usando `scopes` neste exemplo, mas a funcionalidade está disponív
Agora, obtenha os dados do usuário do banco de dados (falso), usando o `username` do campo do formulário.
Se não existir tal usuário, retornaremos um erro dizendo "Incorrect username or password".
Se não existir tal usuário, retornaremos um erro dizendo "Nome de usuário ou senha incorretos".
Para o erro, usamos a exceção `HTTPException`:
@@ -136,17 +136,17 @@ Assim, o ladrão não poderá tentar usar essas mesmas senhas em outro sistema (
```Python
UserInDB(
username = user_dict["username"],
email = user_dict["email"],
full_name = user_dict["full_name"],
disabled = user_dict["disabled"],
hashed_password = user_dict["hashed_password"],
username=user_dict["username"],
email=user_dict["email"],
full_name=user_dict["full_name"],
disabled=user_dict["disabled"],
hashed_password=user_dict["hashed_password"],
)
```
/// note | Nota
Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Extra Models**](../extra-models.md#about-user-in-model-dump).
Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Modelos Extras**](../extra-models.md#about-user-in-model-dump).
///
@@ -158,11 +158,11 @@ Deve ter um `token_type`. No nosso caso, como estamos usando tokens "Bearer", o
E deve ter um `access_token`, com uma string contendo nosso token de acesso.
Para este exemplo simples, seremos completamente inseguros e retornaremos o mesmo `username` do token.
Para este exemplo simples, seremos completamente inseguros e retornaremos o mesmo `username` como token.
/// tip | Dica
No próximo capítulo, você verá uma implementação realmente segura, com hash de senha e tokens <abbr title="JSON Web Tokens">JWT</abbr>.
No próximo capítulo, você verá uma implementação realmente segura, com hash de senha e tokens <abbr title="JSON Web Tokens - Tokens Web JSON">JWT</abbr>.
Mas, por enquanto, vamos nos concentrar nos detalhes específicos de que precisamos.
@@ -224,9 +224,9 @@ Clique no botão "Authorize".
Use as credenciais:
User: `johndoe`
Usuário: `johndoe`
Password: `secret`
Senha: `secret`
<img src="/img/tutorial/security/image04.png">
@@ -264,9 +264,9 @@ Se você clicar no ícone de cadeado, sair e tentar a mesma operação novamente
Agora tente com um usuário inativo, autentique-se com:
User: `alice`
Usuário: `alice`
Password: `secret2`
Senha: `secret2`
E tente usar a operação `GET` com o caminho `/users/me`.
@@ -286,4 +286,4 @@ Usando essas ferramentas, você pode tornar o sistema de segurança compatível
O único detalhe que falta é que ainda não é realmente "seguro".
No próximo capítulo você verá como usar uma biblioteca de hashing de senha segura e tokens <abbr title="JSON Web Tokens">JWT</abbr>.
No próximo capítulo você verá como usar uma biblioteca de hashing de senha segura e tokens <abbr title="JSON Web Tokens - Tokens Web JSON">JWT</abbr>.