mirror of
https://github.com/fastapi/fastapi.git
synced 2026-11-07 00:23:08 -05:00
🌐 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:
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 🎉
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
@@ -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"`.
|
||||
|
||||
@@ -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
@@ -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/):
|
||||
|
||||

|
||||

|
||||
|
||||
* no [PyCharm](https://www.jetbrains.com/pycharm/):
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
@@ -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()`.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
///
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||
///
|
||||
@@ -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**.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
@@ -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] *}
|
||||
|
||||
|
||||
@@ -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. 😎
|
||||
@@ -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).
|
||||
|
||||
///
|
||||
|
||||
@@ -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.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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>.
|
||||
Reference in new issue
Block a user