diff --git a/docs/pt/docs/advanced/advanced-python-types.md b/docs/pt/docs/advanced/advanced-python-types.md index f92a20bd46..6a0c2f97ac 100644 --- a/docs/pt/docs/advanced/advanced-python-types.md +++ b/docs/pt/docs/advanced/advanced-python-types.md @@ -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 🎉 diff --git a/docs/pt/docs/advanced/async-tests.md b/docs/pt/docs/advanced/async-tests.md index de4ecf9559..a074db43ad 100644 --- a/docs/pt/docs/advanced/async-tests.md +++ b/docs/pt/docs/advanced/async-tests.md @@ -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`. diff --git a/docs/pt/docs/advanced/behind-a-proxy.md b/docs/pt/docs/advanced/behind-a-proxy.md index 1bfe0bc4b2..3d348885a9 100644 --- a/docs/pt/docs/advanced/behind-a-proxy.md +++ b/docs/pt/docs/advanced/behind-a-proxy.md @@ -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="*" - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` @@ -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 - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` -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:
```console $ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1 - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ```
@@ -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 - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` ### 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. diff --git a/docs/pt/docs/advanced/security/http-basic-auth.md b/docs/pt/docs/advanced/security/http-basic-auth.md index 303d8480e1..cab126327d 100644 --- a/docs/pt/docs/advanced/security/http-basic-auth.md +++ b/docs/pt/docs/advanced/security/http-basic-auth.md @@ -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 ... ``` diff --git a/docs/pt/docs/advanced/templates.md b/docs/pt/docs/advanced/templates.md index dd71f59cfe..e49ce6c27a 100644 --- a/docs/pt/docs/advanced/templates.md +++ b/docs/pt/docs/advanced/templates.md @@ -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 ``` -{% 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 + +``` + +### 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 `/` 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"`. diff --git a/docs/pt/docs/async.md b/docs/pt/docs/async.md index 3fa92b085c..363b5374fb 100644 --- a/docs/pt/docs/async.md +++ b/docs/pt/docs/async.md @@ -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 diff --git a/docs/pt/docs/features.md b/docs/pt/docs/features.md index d010fc0985..e5988d63dd 100644 --- a/docs/pt/docs/features.md +++ b/docs/pt/docs/features.md @@ -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 **IDE/linter/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. diff --git a/docs/pt/docs/index.md b/docs/pt/docs/index.md index 03bb0063ab..bc2590b488 100644 --- a/docs/pt/docs/index.md +++ b/docs/pt/docs/index.md @@ -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 "parsing" de formulário, com `request.form()`. diff --git a/docs/pt/docs/tutorial/bigger-applications.md b/docs/pt/docs/tutorial/bigger-applications.md index 0eca9e8dbc..ce42677203 100644 --- a/docs/pt/docs/tutorial/bigger-applications.md +++ b/docs/pt/docs/tutorial/bigger-applications.md @@ -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. /// diff --git a/docs/pt/docs/tutorial/body-fields.md b/docs/pt/docs/tutorial/body-fields.md index 25e11189e7..654a7bd2c4 100644 --- a/docs/pt/docs/tutorial/body-fields.md +++ b/docs/pt/docs/tutorial/body-fields.md @@ -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. diff --git a/docs/pt/docs/tutorial/cookie-param-models.md b/docs/pt/docs/tutorial/cookie-param-models.md index b599159797..2e5b325dbb 100644 --- a/docs/pt/docs/tutorial/cookie-param-models.md +++ b/docs/pt/docs/tutorial/cookie-param-models.md @@ -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 consentimento de cookie. 🤪🍪 -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 API rejeitá-lo. 🍪 @@ -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 **cookies** no **FastAPI**. 😎 diff --git a/docs/pt/docs/tutorial/dependencies/sub-dependencies.md b/docs/pt/docs/tutorial/dependencies/sub-dependencies.md index da49f3b5bd..967199932e 100644 --- a/docs/pt/docs/tutorial/dependencies/sub-dependencies.md +++ b/docs/pt/docs/tutorial/dependencies/sub-dependencies.md @@ -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 "cache" 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. /// diff --git a/docs/pt/docs/tutorial/extra-models.md b/docs/pt/docs/tutorial/extra-models.md index 5fec38c145..08157ea2bb 100644 --- a/docs/pt/docs/tutorial/extra-models.md +++ b/docs/pt/docs/tutorial/extra-models.md @@ -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**. diff --git a/docs/pt/docs/tutorial/header-param-models.md b/docs/pt/docs/tutorial/header-param-models.md index 046c99c291..fd7aee4d9f 100644 --- a/docs/pt/docs/tutorial/header-param-models.md +++ b/docs/pt/docs/tutorial/header-param-models.md @@ -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 -## 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**. 😎 diff --git a/docs/pt/docs/tutorial/path-params-numeric-validations.md b/docs/pt/docs/tutorial/path-params-numeric-validations.md index 0a48c09e4d..52c2e846f6 100644 --- a/docs/pt/docs/tutorial/path-params-numeric-validations.md +++ b/docs/pt/docs/tutorial/path-params-numeric-validations.md @@ -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 kwargs. 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 kwargs. 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 gt e não apenas ge. 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 gt e não apenas ge. 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 lt. +E o mesmo para lt. {* ../../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 diff --git a/docs/pt/docs/tutorial/query-param-models.md b/docs/pt/docs/tutorial/query-param-models.md index 7fc59c0335..72f52c2d9d 100644 --- a/docs/pt/docs/tutorial/query-param-models.md +++ b/docs/pt/docs/tutorial/query-param-models.md @@ -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**. 😎 diff --git a/docs/pt/docs/tutorial/query-params-str-validations.md b/docs/pt/docs/tutorial/query-params-str-validations.md index 73171d3bdc..353aa59f5e 100644 --- a/docs/pt/docs/tutorial/query-params-str-validations.md +++ b/docs/pt/docs/tutorial/query-params-str-validations.md @@ -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: -## 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 -## 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. 😎 diff --git a/docs/pt/docs/tutorial/request-forms.md b/docs/pt/docs/tutorial/request-forms.md index f055157479..8dc704725a 100644 --- a/docs/pt/docs/tutorial/request-forms.md +++ b/docs/pt/docs/tutorial/request-forms.md @@ -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 (`
`) 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 MDN para `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST). /// diff --git a/docs/pt/docs/tutorial/response-model.md b/docs/pt/docs/tutorial/response-model.md index 2cbc50c025..dc124979c1 100644 --- a/docs/pt/docs/tutorial/response-model.md +++ b/docs/pt/docs/tutorial/response-model.md @@ -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: @@ -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`: + ```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 } ``` + 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`: + ```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": [] } ``` + 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. /// diff --git a/docs/pt/docs/tutorial/security/simple-oauth2.md b/docs/pt/docs/tutorial/security/simple-oauth2.md index 802879a53d..1a57750ded 100644 --- a/docs/pt/docs/tutorial/security/simple-oauth2.md +++ b/docs/pt/docs/tutorial/security/simple-oauth2.md @@ -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 JWT. +No próximo capítulo, você verá uma implementação realmente segura, com hash de senha e tokens JWT. 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` @@ -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 JWT. +No próximo capítulo você verá como usar uma biblioteca de hashing de senha segura e tokens JWT.