Sync fastapi docs from 50fa3f7c on 2026-01-11

This commit is contained in:
The Librarian
2026-01-11 04:00:07 +00:00
parent a42b1ff04e
commit 95d1a394e6
1611 changed files with 12193 additions and 123004 deletions
+4 -4
View File
@@ -15,7 +15,7 @@ Use da seguinte forma:
Os testes:
## Trechos de código { #code-snippets}
## Trechos de código { #code-snippets }
//// tab | Teste
@@ -53,7 +53,7 @@ Veja, por exemplo, a seção `### Quotes` em `docs/de/llm-prompt.md`.
////
## Citações em trechos de código { #quotes-in-code-snippets}
## Citações em trechos de código { #quotes-in-code-snippets }
//// tab | Teste
@@ -205,7 +205,7 @@ Aqui estão algumas coisas envolvidas em elementos HTML "abbr" (algumas são inv
### O abbr fornece uma explicação { #the-abbr-gives-an-explanation }
* <abbr title="Um grupo de máquinas configuradas para estarem conectadas e trabalharem juntas de alguma forma.">cluster</abbr>
* <abbr title="Um método de aprendizado de máquina que usa redes neurais artificiais com numerosas camadas ocultas entre as camadas de entrada e saída, desenvolvendo assim uma estrutura interna abrangente">Aprendizado Profundo</abbr>
* <abbr title="Um método de aprendizado de máquina que usa redes neurais artificiais com numerosas camadas ocultas entre as camadas de entrada e saída, desenvolvendo assim uma estrutura interna abrangente">Deep Learning</abbr>
### O abbr fornece uma frase completa e uma explicação { #the-abbr-gives-a-full-phrase-and-an-explanation }
@@ -273,7 +273,7 @@ Para algumas instruções específicas do idioma, veja, por exemplo, a seção `
* a documentação automática
* Ciência de Dados
* Aprendizado Profundo
* Deep Learning
* Aprendizado de Máquina
* Injeção de Dependências
* autenticação HTTP Basic
@@ -26,7 +26,7 @@ O **FastAPI** pegará este modelo, gerará o esquema JSON dele e incluirá no lo
Por exemplo, para declarar um outro retorno com o status code `404` e um modelo do Pydantic chamado `Message`, você pode escrever:
{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
/// note | Nota
@@ -175,7 +175,7 @@ Você pode utilizar o mesmo parâmetro `responses` para adicionar diferentes med
Por exemplo, você pode adicionar um media type adicional de `image/png`, declarando que a sua *operação de rota* pode retornar um objeto JSON (com o media type `application/json`) ou uma imagem PNG:
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
/// note | Nota
@@ -203,7 +203,7 @@ Por exemplo, você pode declarar um retorno com o código de status `404` que ut
E um retorno com o código de status `200` que utiliza o seu `response_model`, porém inclui um `example` customizado:
{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
Isso será combinado e incluído em seu OpenAPI, e disponibilizado na documentação da sua API:
@@ -237,7 +237,7 @@ Você pode utilizar essa técnica para reutilizar alguns retornos predefinidos n
Por exemplo:
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
## Mais informações sobre retornos OpenAPI { #more-information-about-openapi-responses }
@@ -144,7 +144,7 @@ Isso foi alterado na versão 0.110.0 para corrigir consumo de memória não trat
### Tarefas em Segundo Plano e Dependências com `yield`, Detalhes Técnicos { #background-tasks-and-dependencies-with-yield-technical-details }
Antes do FastAPI 0.106.0, lançar exceções após o `yield` não era possível, o código de saída em dependências com `yield` era executado depois que a resposta era enviada, então [Tratadores de Exceções](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} já teriam sido executados.
Antes do FastAPI 0.106.0, lançar exceções após o `yield` não era possível, o código de saída em dependências com `yield` era executado depois que a resposta era enviada, então [Tratadores de Exceções](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} já teriam sido executados.
Isso foi projetado assim principalmente para permitir o uso dos mesmos objetos "yielded" por dependências dentro de tarefas em segundo plano, porque o código de saída seria executado depois que as tarefas em segundo plano fossem concluídas.
+4 -4
View File
@@ -32,11 +32,11 @@ Para um exemplos simples, vamos considerar uma estrutura de arquivos semelhante
O arquivo `main.py` teria:
{* ../../docs_src/async_tests/main.py *}
{* ../../docs_src/async_tests/app_a_py39/main.py *}
O arquivo `test_main.py` teria os testes para para o arquivo `main.py`, ele poderia ficar assim:
{* ../../docs_src/async_tests/test_main.py *}
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
## Executá-lo { #run-it }
@@ -56,7 +56,7 @@ $ pytest
O marcador `@pytest.mark.anyio` informa ao pytest que esta função de teste deve ser invocada de maneira assíncrona:
{* ../../docs_src/async_tests/test_main.py hl[7] *}
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
/// tip | Dica
@@ -66,7 +66,7 @@ Note que a função de teste é `async def` agora, no lugar de apenas `def` como
Então podemos criar um `AsyncClient` com a aplicação, e enviar requisições assíncronas para ela utilizando `await`.
{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
Isso é equivalente a:
+15 -7
View File
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
Por exemplo, suponha que você defina uma *operação de rota* `/items/`:
{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
Se o cliente tentar ir para `/items`, por padrão, ele seria redirecionado para `/items/`.
@@ -115,7 +115,7 @@ Nesse caso, o path original `/app` seria servido em `/api/v1/app`.
Embora todo o seu código esteja escrito assumindo que existe apenas `/app`.
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
E o proxy estaria **"removendo"** o **prefixo de path** dinamicamente antes de transmitir a solicitaçã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`.
@@ -193,7 +193,7 @@ Você pode obter o `root_path` atual usado pela sua aplicação para cada solici
Aqui estamos incluindo-o na mensagem apenas para fins de demonstração.
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
Então, se você iniciar o Uvicorn com:
@@ -220,7 +220,7 @@ A resposta seria algo como:
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:
{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
{* ../../docs_src/behind_a_proxy/tutorial002_py39.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.
@@ -228,7 +228,7 @@ Passar o `root_path` para `FastAPI` seria o equivalente a passar a opção de li
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 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> você verá a resposta normal:
Mas se você acessar com seu navegador <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> você verá a resposta normal:
```JSON
{
@@ -400,7 +400,7 @@ Se você passar uma lista personalizada de `servers` e houver um `root_path` (po
Por exemplo:
{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
Gerará um OpenAPI schema como:
@@ -443,11 +443,19 @@ A interface de documentação interagirá com o servidor que você selecionar.
///
/// note | Detalhes Técnicos
A propriedade `servers` na especificação OpenAPI é opcional.
Se você não especificar o parâmetro `servers` e `root_path` for igual a `/`, a propriedade `servers` no OpenAPI gerado será totalmente omitida por padrão, o que equivale a um único servidor com valor de `url` igual a `/`.
///
### Desabilitar servidor automático de `root_path` { #disable-automatic-server-from-root-path }
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.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
e então ele não será incluído no OpenAPI schema.
+16 -16
View File
@@ -30,7 +30,7 @@ Isso ocorre por que, por padrão, o FastAPI irá verificar cada item dentro do d
Mas se você tem certeza que o conteúdo que você está retornando é **serializável com JSON**, você pode passá-lo diretamente para a classe de resposta e evitar o trabalho extra que o FastAPI teria ao passar o conteúdo pelo `jsonable_encoder` antes de passar para a classe de resposta.
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
/// info | Informação
@@ -55,7 +55,7 @@ Para retornar uma resposta com HTML diretamente do **FastAPI**, utilize `HTMLRes
* Importe `HTMLResponse`
* Passe `HTMLResponse` como o parâmetro de `response_class` do seu *decorador de operação de rota*.
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
/// info | Informação
@@ -73,7 +73,7 @@ Como visto em [Retornando uma Resposta Diretamente](response-directly.md){.inter
O mesmo exemplo de antes, retornando uma `HTMLResponse`, poderia parecer com:
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
/// warning | Atenção
@@ -97,7 +97,7 @@ A `response_class` será usada apenas para documentar o OpenAPI da *operação d
Por exemplo, poderia ser algo como:
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
Neste exemplo, a função `generate_html_response()` já cria e retorna uma `Response` em vez de retornar o HTML em uma `str`.
@@ -136,7 +136,7 @@ Ela aceita os seguintes parâmetros:
O FastAPI (Starlette, na verdade) irá incluir o cabeçalho Content-Length automaticamente. Ele também irá incluir o cabeçalho Content-Type, baseado no `media_type` e acrescentando uma codificação para tipos textuais.
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@@ -146,7 +146,7 @@ Usa algum texto ou sequência de bytes e retorna uma resposta HTML. Como você l
Usa algum texto ou sequência de bytes para retornar uma resposta de texto não formatado.
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@@ -180,7 +180,7 @@ Essa resposta requer a instalação do pacote `ujson`, com o comando `pip instal
///
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
/// tip | Dica
@@ -194,13 +194,13 @@ Retorna um redirecionamento HTTP. Utiliza o código de status 307 (Redirecioname
Você pode retornar uma `RedirectResponse` diretamente:
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
---
Ou você pode utilizá-la no parâmetro `response_class`:
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
Se você fizer isso, então você pode retornar a URL diretamente da sua *função de operação de rota*
@@ -210,13 +210,13 @@ Neste caso, o `status_code` utilizada será o padrão de `RedirectResponse`, que
Você também pode utilizar o parâmetro `status_code` combinado com o parâmetro `response_class`:
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
Recebe um gerador assíncrono ou um gerador/iterador comum e retorna o corpo da resposta de forma contínua (stream).
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
#### Utilizando `StreamingResponse` com objetos semelhantes a arquivos { #using-streamingresponse-with-file-like-objects }
@@ -226,7 +226,7 @@ Dessa forma, você não precisa ler todo o arquivo na memória primeiro, e você
Isso inclui muitas bibliotecas que interagem com armazenamento em nuvem, processamento de vídeos, entre outras.
{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
1. Essa é a função geradora. É definida como "função geradora" porque contém declarações `yield` nela.
2. Ao utilizar o bloco `with`, nós garantimos que o objeto semelhante a um arquivo é fechado após a função geradora ser finalizada. Isto é, após a resposta terminar de ser enviada.
@@ -255,11 +255,11 @@ Recebe um conjunto de argumentos do construtor diferente dos outros tipos de res
Respostas de Arquivos incluem o tamanho do arquivo, data da última modificação e ETags apropriados, nos cabeçalhos `Content-Length`, `Last-Modified` e `ETag`, respectivamente.
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
Você também pode usar o parâmetro `response_class`:
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
Nesse caso, você pode retornar o caminho do arquivo diretamente da sua *função de operação de rota*.
@@ -273,7 +273,7 @@ Vamos supor também que você queira retornar um JSON indentado e formatado, ent
Você poderia criar uma classe `CustomORJSONResponse`. A principal coisa a ser feita é sobrecarregar o método render da classe Response, `Response.render(content)`, que retorna o conteúdo em bytes:
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
Agora em vez de retornar:
@@ -299,7 +299,7 @@ O padrão que define isso é o `default_response_class`.
No exemplo abaixo, o **FastAPI** irá utilizar `ORJSONResponse` por padrão, em todas as *operações de rota*, em vez de `JSONResponse`.
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
/// tip | Dica
+3 -3
View File
@@ -4,7 +4,7 @@ FastAPI é construído em cima do **Pydantic**, e eu tenho mostrado como usar mo
Mas o FastAPI também suporta o uso de <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> da mesma forma:
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
Isso ainda é suportado graças ao **Pydantic**, pois ele tem <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">suporte interno para `dataclasses`</a>.
@@ -32,7 +32,7 @@ Mas se você tem um monte de dataclasses por aí, este é um truque legal para u
Você também pode usar `dataclasses` no parâmetro `response_model`:
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
A dataclass será automaticamente convertida para uma dataclass Pydantic.
@@ -48,7 +48,7 @@ Em alguns casos, você ainda pode ter que usar a versão do Pydantic das `datacl
Nesse caso, você pode simplesmente trocar as `dataclasses` padrão por `pydantic.dataclasses`, que é um substituto direto:
{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. Ainda importamos `field` das `dataclasses` padrão.
+6 -6
View File
@@ -30,7 +30,7 @@ Vamos começar com um exemplo e depois ver em detalhes.
Nós criamos uma função assíncrona `lifespan()` com `yield` assim:
{* ../../docs_src/events/tutorial003.py hl[16,19] *}
{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
Aqui estamos simulando a operação de *inicialização* custosa de carregar o modelo, colocando a (falsa) função do modelo no dicionário com modelos de machine learning antes do `yield`. Esse código será executado **antes** de a aplicação **começar a receber requisições**, durante a *inicialização*.
@@ -48,7 +48,7 @@ Talvez você precise iniciar uma nova versão, ou apenas cansou de executá-la.
A primeira coisa a notar é que estamos definindo uma função assíncrona com `yield`. Isso é muito semelhante a Dependências com `yield`.
{* ../../docs_src/events/tutorial003.py hl[14:19] *}
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
A primeira parte da função, antes do `yield`, será executada **antes** de a aplicação iniciar.
@@ -60,7 +60,7 @@ Se você verificar, a função está decorada com um `@asynccontextmanager`.
Isso converte a função em algo chamado "**gerenciador de contexto assíncrono**".
{* ../../docs_src/events/tutorial003.py hl[1,13] *}
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
Um **gerenciador de contexto** em Python é algo que você pode usar em uma declaração `with`, por exemplo, `open()` pode ser usado como um gerenciador de contexto:
@@ -82,7 +82,7 @@ No nosso exemplo de código acima, não o usamos diretamente, mas passamos para
O parâmetro `lifespan` da aplicação `FastAPI` aceita um **gerenciador de contexto assíncrono**, então podemos passar para ele nosso novo gerenciador de contexto assíncrono `lifespan`.
{* ../../docs_src/events/tutorial003.py hl[22] *}
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
## Eventos alternativos (descontinuados) { #alternative-events-deprecated }
@@ -104,7 +104,7 @@ Essas funções podem ser declaradas com `async def` ou `def` normal.
Para adicionar uma função que deve rodar antes de a aplicação iniciar, declare-a com o evento `"startup"`:
{* ../../docs_src/events/tutorial001.py hl[8] *}
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
Nesse caso, a função de manipulador do evento `startup` inicializará os itens do "banco de dados" (apenas um `dict`) com alguns valores.
@@ -116,7 +116,7 @@ E sua aplicação não começará a receber requisições até que todos os mani
Para adicionar uma função que deve ser executada quando a aplicação estiver encerrando, declare-a com o evento `"shutdown"`:
{* ../../docs_src/events/tutorial002.py hl[6] *}
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
Aqui, a função de manipulador do evento `shutdown` escreverá uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
+1 -1
View File
@@ -167,7 +167,7 @@ Mas para o cliente gerado, poderíamos **modificar** os IDs de operação do Ope
Poderíamos baixar o JSON do OpenAPI para um arquivo `openapi.json` e então poderíamos **remover essa tag prefixada** com um script como este:
{* ../../docs_src/generate_clients/tutorial004.py *}
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
//// tab | Node.js
+3 -3
View File
@@ -57,13 +57,13 @@ Garante que todas as requisições devem ser `https` ou `wss`.
Qualquer requisição para `http` ou `ws` será redirecionada para o esquema seguro.
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
Garante que todas as requisições recebidas tenham um cabeçalho `Host` corretamente configurado, a fim de proteger contra ataques de cabeçalho de host HTTP.
{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
Os seguintes argumentos são suportados:
@@ -78,7 +78,7 @@ Gerencia respostas GZip para qualquer requisição que inclua `"gzip"` no cabeç
O middleware lidará com respostas padrão e de streaming.
{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
Os seguintes argumentos são suportados:
+12 -12
View File
@@ -1,8 +1,8 @@
# Callbacks na OpenAPI { #openapi-callbacks }
Você poderia criar uma API com uma *operação de rota* que poderia acionar uma solicitação a uma *API externa* criada por outra pessoa (provavelmente o mesmo desenvolvedor que estaria *usando* sua API).
Você poderia criar uma API com uma *operação de rota* que poderia acionar um request a uma *API externa* criada por outra pessoa (provavelmente o mesmo desenvolvedor que estaria *usando* sua API).
O processo que acontece quando sua aplicação de API chama a *API externa* é chamado de "callback". Porque o software que o desenvolvedor externo escreveu envia uma solicitação para sua API e então sua API *chama de volta*, enviando uma solicitação para uma *API externa* (que provavelmente foi criada pelo mesmo desenvolvedor).
O processo que acontece quando sua aplicação de API chama a *API externa* é chamado de "callback". Porque o software que o desenvolvedor externo escreveu envia um request para sua API e então sua API *chama de volta*, enviando um request para uma *API externa* (que provavelmente foi criada pelo mesmo desenvolvedor).
Nesse caso, você poderia querer documentar como essa API externa *deveria* ser. Que *operação de rota* ela deveria ter, que corpo ela deveria esperar, que resposta ela deveria retornar, etc.
@@ -14,14 +14,14 @@ Imagine que você desenvolve um aplicativo que permite criar faturas.
Essas faturas terão um `id`, `title` (opcional), `customer` e `total`.
O usuário da sua API (um desenvolvedor externo) criará uma fatura na sua API com uma solicitação POST.
O usuário da sua API (um desenvolvedor externo) criará uma fatura na sua API com um request POST.
Então sua API irá (vamos imaginar):
* Enviar a fatura para algum cliente do desenvolvedor externo.
* Coletar o dinheiro.
* Enviar a notificação de volta para o usuário da API (o desenvolvedor externo).
* Isso será feito enviando uma solicitação POST (de *sua API*) para alguma *API externa* fornecida por esse desenvolvedor externo (este é o "callback").
* Isso será feito enviando um request POST (de *sua API*) para alguma *API externa* fornecida por esse desenvolvedor externo (este é o "callback").
## O aplicativo **FastAPI** normal { #the-normal-fastapi-app }
@@ -31,7 +31,7 @@ Ele terá uma *operação de rota* que receberá um corpo `Invoice`, e um parâm
Essa parte é bastante normal, a maior parte do código provavelmente já é familiar para você:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
/// tip | Dica
@@ -54,7 +54,7 @@ callback_url = "https://example.com/api/v1/invoices/events/"
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
```
Mas possivelmente a parte mais importante do callback é garantir que o usuário da sua API (o desenvolvedor externo) implemente a *API externa* corretamente, de acordo com os dados que *sua API* vai enviar no corpo da solicitação do callback, etc.
Mas possivelmente a parte mais importante do callback é garantir que o usuário da sua API (o desenvolvedor externo) implemente a *API externa* corretamente, de acordo com os dados que *sua API* vai enviar no corpo do request do callback, etc.
Então, o que faremos a seguir é adicionar o código para documentar como essa *API externa* deve ser para receber o callback de *sua API*.
@@ -64,7 +64,7 @@ Esse exemplo não implementa o callback em si (que poderia ser apenas uma linha
/// tip | Dica
O callback real é apenas uma solicitação HTTP.
O callback real é apenas um request HTTP.
Ao implementar o callback por conta própria, você pode usar algo como <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> ou <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">Requests</a>.
@@ -90,7 +90,7 @@ Adotar temporariamente esse ponto de vista (do *desenvolvedor externo*) pode aju
Primeiro crie um novo `APIRouter` que conterá um ou mais callbacks.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
### Crie a *operação de rota* do callback { #create-the-callback-path-operation }
@@ -101,7 +101,7 @@ Ela deve parecer exatamente como uma *operação de rota* normal do FastAPI:
* Ela provavelmente deveria ter uma declaração do corpo que deveria receber, por exemplo, `body: InvoiceEvent`.
* E também poderia ter uma declaração da resposta que deveria retornar, por exemplo, `response_model=InvoiceEventReceived`.
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
Há 2 diferenças principais de uma *operação de rota* normal:
@@ -118,7 +118,7 @@ Nesse caso, é a `str`:
"{$callback_url}/invoices/{$request.body.id}"
```
Então, se o usuário da sua API (o desenvolvedor externo) enviar uma solicitação para *sua API* para:
Então, se o usuário da sua API (o desenvolvedor externo) enviar um request para *sua API* para:
```
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
@@ -134,7 +134,7 @@ com um corpo JSON de:
}
```
então *sua API* processará a fatura e, em algum momento posterior, enviará uma solicitação de callback para o `callback_url` (a *API externa*):
então *sua API* processará a fatura e, em algum momento posterior, enviará um request de callback para o `callback_url` (a *API externa*):
```
https://www.external.org/events/invoices/2expen51ve
@@ -169,7 +169,7 @@ Nesse ponto você tem a(s) *operação(ões) de rota de callback* necessária(s)
Agora use o parâmetro `callbacks` no decorador da *operação de rota da sua API* para passar o atributo `.routes` (que é na verdade apenas uma `list` de rotas/*operações de path*) do roteador de callback:
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
/// tip | Dica
+1 -1
View File
@@ -32,7 +32,7 @@ Webhooks estão disponíveis a partir do OpenAPI 3.1.0, e possui suporte do Fast
Quando você cria uma aplicação com o **FastAPI**, existe um atributo chamado `webhooks`, que você utilizar para defini-los da mesma maneira que você definiria as suas **operações de rotas**, utilizando por exemplo `@app.webhooks.post()`.
{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
Os webhooks que você define aparecerão no esquema do **OpenAPI** e na **página de documentação** gerada automaticamente.
@@ -12,15 +12,15 @@ Você pode definir o `operationId` do OpenAPI que será utilizado na sua *opera
Você precisa ter certeza que ele é único para cada operação.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
### Utilizando o nome da *função de operação de rota* como o operationId { #using-the-path-operation-function-name-as-the-operationid }
Se você quiser utilizar o nome das funções da sua API como `operationId`s, você pode iterar sobre todos esses nomes e sobrescrever o `operationId` em cada *operação de rota* utilizando o `APIRoute.name` dela.
Se você quiser utilizar o nome das funções da sua API como `operationId`s, você pode iterar sobre todos esses nomes e sobrescrever o `operation_id` em cada *operação de rota* utilizando o `APIRoute.name` dela.
Você deve fazer isso depois de adicionar todas as suas *operações de rota*.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
/// tip | Dica
@@ -40,7 +40,7 @@ Mesmo que elas estejam em módulos (arquivos Python) diferentes.
Para excluir uma *operação de rota* do esquema OpenAPI gerado (e por consequência, dos sistemas de documentação automáticos), utilize o parâmetro `include_in_schema` e defina ele como `False`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
## Descrição avançada a partir de docstring { #advanced-description-from-docstring }
@@ -50,7 +50,7 @@ Adicionar um `\f` (um caractere de escape para alimentação de formulário) faz
Ele não será mostrado na documentação, mas outras ferramentas (como o Sphinx) serão capazes de utilizar o resto do texto.
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
## Respostas Adicionais { #additional-responses }
@@ -92,7 +92,7 @@ Você pode estender o esquema do OpenAPI para uma *operação de rota* utilizand
Esse parâmetro `openapi_extra` pode ser útil, por exemplo, para declarar [Extensões do OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
Se você abrir os documentos criados automaticamente para a API, sua extensão aparecerá no final da *operação de rota* específica.
@@ -139,7 +139,7 @@ Por exemplo, você poderia optar por ler e validar a requisição com seu própr
Você pode fazer isso com `openapi_extra`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo <abbr title="convertido de um formato plano, como bytes, para objetos Python">analisado</abbr> como JSON, ele é lido diretamente como `bytes` e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma.
@@ -155,13 +155,13 @@ Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao Fa
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
////
@@ -179,13 +179,13 @@ E então no nosso código, nós analisamos o conteúdo YAML diretamente, e estam
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
////
@@ -20,7 +20,7 @@ Você pode declarar um parâmetro do tipo `Response` em sua *função de operaç
E então você pode definir o `status_code` neste objeto de retorno temporal.
{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
E então você pode retornar qualquer objeto que você precise, como você faria normalmente (um `dict`, um modelo de banco de dados, etc.).
+2 -2
View File
@@ -6,7 +6,7 @@ Você pode declarar um parâmetro do tipo `Response` na sua *função de operaç
E então você pode definir cookies nesse objeto de resposta *temporário*.
{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
Em seguida, você pode retornar qualquer objeto que precise, como normalmente faria (um `dict`, um modelo de banco de dados, etc).
@@ -24,7 +24,7 @@ Para fazer isso, você pode criar uma resposta como descrito em [Retorne uma Res
Então, defina os cookies nela e a retorne:
{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
/// tip | Dica
+2 -2
View File
@@ -34,7 +34,7 @@ Por exemplo, você não pode colocar um modelo do Pydantic em uma `JSONResponse`
Para esses casos, você pode usar o `jsonable_encoder` para converter seus dados antes de repassá-los para a resposta:
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | Detalhes Técnicos
@@ -54,7 +54,7 @@ Vamos dizer que você quer retornar uma resposta <a href="https://en.wikipedia.o
Você pode colocar o seu conteúdo XML em uma string, colocar em uma `Response`, e retorná-lo:
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
## Notas { #notes }
+2 -2
View File
@@ -6,7 +6,7 @@ Você pode declarar um parâmetro do tipo `Response` na sua *função de operaç
Então você pode definir os cabeçalhos nesse objeto de resposta *temporário*.
{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
Em seguida você pode retornar qualquer objeto que precisar, da maneira que faria normalmente (um `dict`, um modelo de banco de dados, etc.).
@@ -22,7 +22,7 @@ Você também pode adicionar cabeçalhos quando retornar uma `Response` diretame
Crie uma resposta conforme descrito em [Retornar uma resposta diretamente](response-directly.md){.internal-link target=_blank} e passe os cabeçalhos como um parâmetro adicional:
{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
/// note | Detalhes Técnicos
+9 -9
View File
@@ -62,7 +62,7 @@ Você pode usar as mesmas funcionalidades e ferramentas de validação que usa e
//// tab | Pydantic v2
{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
////
@@ -74,7 +74,7 @@ No Pydantic v1 você importaria `BaseSettings` diretamente de `pydantic` em vez
///
{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
////
@@ -92,7 +92,7 @@ Em seguida, ele converterá e validará os dados. Assim, quando você usar esse
Depois você pode usar o novo objeto `settings` na sua aplicação:
{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
### Executar o servidor { #run-the-server }
@@ -126,11 +126,11 @@ Você pode colocar essas configurações em outro arquivo de módulo como visto
Por exemplo, você poderia ter um arquivo `config.py` com:
{* ../../docs_src/settings/app01/config.py *}
{* ../../docs_src/settings/app01_py39/config.py *}
E então usá-lo em um arquivo `main.py`:
{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
/// tip | Dica
@@ -148,7 +148,7 @@ Isso pode ser especialmente útil durante os testes, pois é muito fácil sobres
Vindo do exemplo anterior, seu arquivo `config.py` poderia ser assim:
{* ../../docs_src/settings/app02/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
Perceba que agora não criamos uma instância padrão `settings = Settings()`.
@@ -174,7 +174,7 @@ E então podemos exigi-la na *função de operação de rota* como dependência
Então seria muito fácil fornecer um objeto de configurações diferente durante os testes criando uma sobrescrita de dependência para `get_settings`:
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
Na sobrescrita da dependência definimos um novo valor para `admin_email` ao criar o novo objeto `Settings`, e então retornamos esse novo objeto.
@@ -217,7 +217,7 @@ E então atualizar seu `config.py` com:
//// tab | Pydantic v2
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip | Dica
@@ -229,7 +229,7 @@ O atributo `model_config` é usado apenas para configuração do Pydantic. Você
//// tab | Pydantic v1
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
/// tip | Dica
+3 -3
View File
@@ -10,7 +10,7 @@ Se você precisar ter duas aplicações FastAPI independentes, cada uma com seu
Primeiro, crie a aplicação principal, de nível superior, **FastAPI**, e suas *operações de rota*:
{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
### Sub-aplicação { #sub-application }
@@ -18,7 +18,7 @@ Em seguida, crie sua sub-aplicação e suas *operações de rota*.
Essa sub-aplicação é apenas outra aplicação FastAPI padrão, mas esta é a que será "montada":
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
### Monte a sub-aplicação { #mount-the-sub-application }
@@ -26,7 +26,7 @@ Na sua aplicação de nível superior, `app`, monte a sub-aplicação, `subapi`.
Neste caso, ela será montada no path `/subapi`:
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
### Verifique a documentação automática da API { #check-the-automatic-api-docs }
+1 -1
View File
@@ -27,7 +27,7 @@ $ pip install jinja2
* Declare um parâmetro `Request` no *path operation* que retornará um template.
* Use o `templates` que você criou para renderizar e retornar uma `TemplateResponse`, passe o nome do template, o objeto `request` e um dicionário "context" com pares chave-valor a serem usados dentro do template do Jinja2.
{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
/// note | Nota
+2 -2
View File
@@ -2,10 +2,10 @@
Quando você precisa que o `lifespan` seja executado em seus testes, você pode utilizar o `TestClient` com a instrução `with`:
{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
Você pode ler mais detalhes sobre o ["Executando lifespan em testes no site oficial da documentação do Starlette."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
Para os eventos `startup` e `shutdown` descontinuados, você pode usar o `TestClient` da seguinte forma:
{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
+1 -1
View File
@@ -4,7 +4,7 @@ Você pode usar o mesmo `TestClient` para testar WebSockets.
Para isso, você utiliza o `TestClient` dentro de uma instrução `with`, conectando com o WebSocket:
{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
/// note | Nota
@@ -29,7 +29,7 @@ Vamos imaginar que você deseja obter o endereço de IP/host do cliente dentro d
Para isso você precisa acessar a requisição diretamente.
{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
Ao declarar o parâmetro com o tipo sendo um `Request` em sua *função de operação de rota*, o **FastAPI** saberá como passar o `Request` neste parâmetro.
+3 -3
View File
@@ -38,13 +38,13 @@ Na produção, você teria uma das opções acima.
Mas é a maneira mais simples de focar no lado do servidor de WebSockets e ter um exemplo funcional:
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
## Crie um `websocket` { #create-a-websocket }
Em sua aplicação **FastAPI**, crie um `websocket`:
{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
/// note | Detalhes Técnicos
@@ -58,7 +58,7 @@ A **FastAPI** fornece o mesmo `WebSocket` diretamente apenas como uma conveniên
Em sua rota WebSocket você pode esperar (`await`) por mensagens e enviar mensagens.
{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
Você pode receber e enviar dados binários, de texto e JSON.
+1 -1
View File
@@ -12,7 +12,7 @@ Em seguida, encapsule a aplicação WSGI (e.g. Flask) com o middleware.
E então monte isso sob um path.
{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
## Confira { #check-it }
+12 -4
View File
@@ -4,13 +4,21 @@ Você pode usar praticamente **qualquer provedor de nuvem** para implantar seu a
Na maioria dos casos, os principais provedores de nuvem têm tutoriais para implantar o FastAPI com eles.
## FastAPI Cloud { #fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** é desenvolvido pelo mesmo autor e equipe por trás do **FastAPI**.
Ele simplifica o processo de **criar**, **implantar** e **acessar** uma API com o mínimo de esforço.
Traz a mesma **experiência do desenvolvedor** de criar aplicações com FastAPI para **implantá-las** na nuvem. 🎉
FastAPI Cloud é o patrocinador principal e provedor de financiamento dos projetos de código aberto *FastAPI and friends*. ✨
## Provedores de Nuvem - Patrocinadores { #cloud-providers-sponsors }
Alguns provedores de nuvem ✨ [**patrocinam o FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, o que garante o **desenvolvimento** contínuo e saudável do FastAPI e seu **ecossistema**.
Alguns outros provedores de nuvem ✨ [**patrocinam o FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ também. 🙇
E isso mostra seu verdadeiro comprometimento com o FastAPI e sua **comunidade** (você), pois eles não querem apenas fornecer a você um **bom serviço**, mas também querem ter certeza de que você tenha um **framework bom e saudável**, o FastAPI. 🙇
Talvez você queira experimentar os serviços deles e seguir os tutoriais:
Você também pode considerá-los para seguir seus tutoriais e experimentar seus serviços:
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
+65
View File
@@ -0,0 +1,65 @@
# FastAPI Cloud { #fastapi-cloud }
Você pode implantar sua aplicação FastAPI no <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> com um **único comando**; entre na lista de espera, caso ainda não tenha feito isso. 🚀
## Login { #login }
Certifique-se de que você já tem uma conta no **FastAPI Cloud** (nós convidamos você a partir da lista de espera 😉).
Depois, faça login:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
## Implantar { #deploy }
Agora, implante sua aplicação, com **um único comando**:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
É isso! Agora você pode acessar sua aplicação nesse URL. ✨
## Sobre o FastAPI Cloud { #about-fastapi-cloud }
O **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** é desenvolvido pelo mesmo autor e equipe por trás do **FastAPI**.
Ele simplifica o processo de **criar**, **implantar** e **acessar** uma API com esforço mínimo.
Traz a mesma **experiência do desenvolvedor** de criar aplicações com FastAPI para **implantá-las** na nuvem. 🎉
Ele também cuidará da maioria das coisas de que você precisaria ao implantar uma aplicação, como:
* HTTPS
* Replicação, com dimensionamento automático baseado em requests
* etc.
O FastAPI Cloud é o patrocinador principal e provedor de financiamento dos projetos open source do ecossistema *FastAPI and friends*. ✨
## Implantar em outros provedores de nuvem { #deploy-to-other-cloud-providers }
FastAPI é open source e baseado em padrões. Você pode implantar aplicações FastAPI em qualquer provedor de nuvem que escolher.
Siga os tutoriais do seu provedor de nuvem para implantar aplicações FastAPI com esse provedor. 🤓
## Implantar no seu próprio servidor { #deploy-your-own-server }
Também vou lhe ensinar, mais adiante neste guia de **Implantação**, todos os detalhes, para que você possa entender o que está acontecendo, o que precisa acontecer, ou como implantar aplicações FastAPI por conta própria, inclusive nos seus próprios servidores. 🤓
+2
View File
@@ -16,6 +16,8 @@ Há várias maneiras de fazer isso, dependendo do seu caso de uso específico e
Você pode **implantar um servidor** por conta própria usando uma combinação de ferramentas, pode usar um **serviço em nuvem** que faça parte do trabalho por você, entre outras opções.
Por exemplo, nós, a equipe por trás do FastAPI, criamos <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, para tornar a implantação de aplicações FastAPI na nuvem o mais simples possível, com a mesma experiência de desenvolvimento de trabalhar com o FastAPI.
Vou mostrar alguns dos principais conceitos que você provavelmente deve ter em mente ao implantar uma aplicação **FastAPI** (embora a maior parte se aplique a qualquer outro tipo de aplicação web).
Você verá mais detalhes para ter em mente e algumas das técnicas para fazer isso nas próximas seções. ✨
@@ -0,0 +1,17 @@
# Usar antigos códigos de status de erro de autenticação 403 { #use-old-403-authentication-error-status-codes }
Antes da versão `0.122.0` do FastAPI, quando os utilitários de segurança integrados retornavam um erro ao cliente após uma falha na autenticação, eles usavam o código de status HTTP `403 Forbidden`.
A partir da versão `0.122.0` do FastAPI, eles usam o código de status HTTP `401 Unauthorized`, mais apropriado, e retornam um cabeçalho `WWW-Authenticate` adequado na response, seguindo as especificações HTTP, <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>, <a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>.
Mas, se por algum motivo seus clientes dependem do comportamento antigo, você pode voltar a ele sobrescrevendo o método `make_not_authenticated_error` nas suas classes de segurança.
Por exemplo, você pode criar uma subclasse de `HTTPBearer` que retorne um erro `403 Forbidden` em vez do erro padrão `401 Unauthorized`:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
/// tip | Dica
Perceba que a função retorna a instância da exceção, ela não a lança. O lançamento é feito no restante do código interno.
///
+1 -1
View File
@@ -29,7 +29,7 @@ Você pode usar facilmente as mesmas configurações do Pydantic para configurar
Por exemplo:
{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
Aqui declaramos a configuração `openapi_url` com o mesmo padrão de `"/openapi.json"`.
+4 -4
View File
@@ -18,7 +18,7 @@ Sem alterar as configurações, o destaque de sintaxe é habilitado por padrão:
Mas você pode desabilitá-lo definindo `syntaxHighlight` como `False`:
{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
...e então o Swagger UI não mostrará mais o destaque de sintaxe:
@@ -28,7 +28,7 @@ Mas você pode desabilitá-lo definindo `syntaxHighlight` como `False`:
Da mesma forma que você pode definir o tema de destaque de sintaxe com a chave `"syntaxHighlight.theme"` (observe que há um ponto no meio):
{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
Essa configuração alteraria o tema de cores de destaque de sintaxe:
@@ -40,13 +40,13 @@ O FastAPI inclui alguns parâmetros de configuração padrão apropriados para a
Inclui estas configurações padrão:
{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
Você pode substituir qualquer um deles definindo um valor diferente no argumento `swagger_ui_parameters`.
Por exemplo, para desabilitar `deepLinking` você pode passar essas configurações para `swagger_ui_parameters`:
{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
## Outros parâmetros da UI do Swagger { #other-swagger-ui-parameters }
+7 -7
View File
@@ -18,7 +18,7 @@ O primeiro passo é desativar a documentação automática, pois por padrão, el
Para desativá-los, defina suas URLs como `None` ao criar sua aplicação FastAPI:
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
### Incluir a documentação personalizada { #include-the-custom-docs }
@@ -34,7 +34,7 @@ Você pode reutilizar as funções internas do FastAPI para criar as páginas HT
E de forma semelhante para o ReDoc...
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
/// tip | Dica
@@ -50,7 +50,7 @@ Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse aux
Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
### Teste { #test-it }
@@ -118,7 +118,7 @@ Depois disso, sua estrutura de arquivos deve se parecer com:
* Importe `StaticFiles`.
* "Monte" a instância `StaticFiles()` em um caminho específico.
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
### Teste os arquivos estáticos { #test-the-static-files }
@@ -144,7 +144,7 @@ Da mesma forma que ao usar um CDN personalizado, o primeiro passo é desativar a
Para desativá-los, defina suas URLs como `None` ao criar sua aplicação FastAPI:
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
### Incluir a documentação personalizada para arquivos estáticos { #include-the-custom-docs-for-static-files }
@@ -160,7 +160,7 @@ Novamente, você pode reutilizar as funções internas do FastAPI para criar as
E de forma semelhante para o ReDoc...
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
/// tip | Dica
@@ -176,7 +176,7 @@ Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse aux
Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
### Teste a UI de Arquivos Estáticos { #test-static-files-ui }
@@ -42,7 +42,7 @@ Se não houver `gzip` no cabeçalho, ele não tentará descomprimir o corpo.
Dessa forma, a mesma classe de rota pode lidar com requisições comprimidas ou não comprimidas.
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
### Criar uma classe `GzipRoute` personalizada { #create-a-custom-gziproute-class }
@@ -54,7 +54,7 @@ Esse método retorna uma função. E essa função é o que irá receber uma req
Aqui nós usamos para criar um `GzipRequest` a partir da requisição original.
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
/// note | Detalhes Técnicos
@@ -92,18 +92,18 @@ Também podemos usar essa mesma abordagem para acessar o corpo da requisição e
Tudo que precisamos fazer é manipular a requisição dentro de um bloco `try`/`except`:
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
Se uma exceção ocorrer, a instância `Request` ainda estará em escopo, então podemos ler e fazer uso do corpo da requisição ao lidar com o erro:
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
## Classe `APIRoute` personalizada em um router { #custom-apiroute-class-in-a-router }
Você também pode definir o parâmetro `route_class` de uma `APIRouter`:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
Nesse exemplo, as *operações de rota* sob o `router` irão usar a classe `TimedRoute` personalizada, e terão um cabeçalho extra `X-Response-Time` na resposta com o tempo que levou para gerar a resposta:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
+5 -5
View File
@@ -43,19 +43,19 @@ Por exemplo, vamos adicionar <a href="https://github.com/Rebilly/ReDoc/blob/mast
Primeiro, escreva toda a sua aplicação **FastAPI** normalmente:
{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
### Gerar o esquema OpenAPI { #generate-the-openapi-schema }
Em seguida, use a mesma função utilitária para gerar o esquema OpenAPI, dentro de uma função `custom_openapi()`:
{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
### Modificar o esquema OpenAPI { #modify-the-openapi-schema }
Agora, você pode adicionar a extensão do ReDoc, incluindo um `x-logo` personalizado ao "objeto" `info` no esquema OpenAPI:
{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
### Armazenar em cache o esquema OpenAPI { #cache-the-openapi-schema }
@@ -65,13 +65,13 @@ Dessa forma, sua aplicação não precisará gerar o esquema toda vez que um usu
Ele será gerado apenas uma vez, e o mesmo esquema armazenado em cache será utilizado nas próximas requisições.
{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
### Sobrescrever o método { #override-the-method }
Agora, você pode substituir o método `.openapi()` pela sua nova função.
{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
### Verificar { #check-it }
+1 -1
View File
@@ -35,7 +35,7 @@ Dependendo do seu caso de uso, você pode preferir usar uma biblioteca diferente
Aqui está uma pequena prévia de como você poderia integrar Strawberry com FastAPI:
{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
Você pode aprender mais sobre Strawberry na <a href="https://strawberry.rocks/" class="external-link" target="_blank">documentação do Strawberry</a>.
+60 -2
View File
@@ -52,14 +52,20 @@ Os recursos chave são:
<!-- sponsors -->
{% if sponsors %}
### Patrocinador Keystone { #keystone-sponsor }
{% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
### Patrocinadores Ouro e Prata { #gold-and-silver-sponsors }
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
<!-- /sponsors -->
@@ -444,6 +450,58 @@ Para um exemplo mais completo incluindo mais recursos, veja <a href="https://fas
* **Cookie Sessions**
* ...e mais.
### Implemente sua aplicação (opcional) { #deploy-your-app-optional }
Você pode opcionalmente implantar sua aplicação FastAPI na <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, inscreva-se na lista de espera se ainda não o fez. 🚀
Se você já tem uma conta na **FastAPI Cloud** (nós convidamos você da lista de espera 😉), pode implantar sua aplicação com um único comando.
Antes de implantar, certifique-se de que está autenticado:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
Depois, implemente sua aplicação:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
É isso! Agora você pode acessar sua aplicação nesse URL. ✨
#### Sobre a FastAPI Cloud { #about-fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** é construída pelo mesmo autor e equipe por trás do **FastAPI**.
Ela simplifica o processo de **construir**, **implantar** e **acessar** uma API com esforço mínimo.
Traz a mesma **experiência do desenvolvedor** de construir aplicações com FastAPI para **implantá-las** na nuvem. 🎉
A FastAPI Cloud é a principal patrocinadora e financiadora dos projetos open source do ecossistema *FastAPI and friends*. ✨
#### Implante em outros provedores de nuvem { #deploy-to-other-cloud-providers }
FastAPI é open source e baseado em padrões. Você pode implantar aplicações FastAPI em qualquer provedor de nuvem que escolher.
Siga os tutoriais do seu provedor de nuvem para implantar aplicações FastAPI com eles. 🤓
## Performance { #performance }
Testes de performance da _Independent TechEmpower_ mostram aplicações **FastAPI** rodando sob Uvicorn como <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">um dos _frameworks_ Python mais rápidos disponíveis</a>, somente atrás de Starlette e Uvicorn (utilizados internamente pelo FastAPI). (*)
+2 -2
View File
@@ -13,8 +13,8 @@ Repositório GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-tem
- 🔍 [Pydantic](https://docs.pydantic.dev), usado pelo FastAPI, para validação de dados e gerenciamento de configurações.
- 💾 [PostgreSQL](https://www.postgresql.org) como banco de dados SQL.
- 🚀 [React](https://react.dev) para o frontend.
- 💃 Usando TypeScript, hooks, [Vite](https://vitejs.dev), e outras partes de uma _stack_ frontend moderna.
- 🎨 [Chakra UI](https://chakra-ui.com) para os componentes de frontend.
- 💃 Usando TypeScript, hooks, Vite, e outras partes de uma _stack_ frontend moderna.
- 🎨 [Tailwind CSS](https://tailwindcss.com) e [shadcn/ui](https://ui.shadcn.com) para os componentes de frontend.
- 🤖 Um cliente frontend automaticamente gerado.
- 🧪 [Playwright](https://playwright.dev) para testes Ponta-a-Ponta.
- 🦇 Suporte para modo escuro.
+31 -143
View File
@@ -22,7 +22,7 @@ Se você é um especialista em Python e já sabe tudo sobre type hints, pule par
Vamos começar com um exemplo simples:
{* ../../docs_src/python_types/tutorial001.py *}
{* ../../docs_src/python_types/tutorial001_py39.py *}
A chamada deste programa gera:
@@ -36,7 +36,7 @@ A função faz o seguinte:
* Converte a primeira letra de cada uma em maiúsculas com `title()`.
* <abbr title = "Agrupa-os, como um. Com o conteúdo de um após o outro.">Concatena</abbr> com um espaço no meio.
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
### Edite-o { #edit-it }
@@ -78,7 +78,7 @@ para:
Esses são os "type hints":
{* ../../docs_src/python_types/tutorial002.py hl[1] *}
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
Isso não é o mesmo que declarar valores padrão como seria com:
@@ -106,7 +106,7 @@ Com isso, você pode rolar, vendo as opções, até encontrar o que "soa familia
Verifique esta função, ela já possui type hints:
{* ../../docs_src/python_types/tutorial003.py hl[1] *}
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
Como o editor conhece os tipos de variáveis, você não obtém apenas o preenchimento automático, mas também as verificações de erro:
@@ -114,7 +114,7 @@ Como o editor conhece os tipos de variáveis, você não obtém apenas o preench
Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`:
{* ../../docs_src/python_types/tutorial004.py hl[2] *}
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
## Declarando Tipos { #declaring-types }
@@ -133,7 +133,7 @@ Você pode usar, por exemplo:
* `bool`
* `bytes`
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
### Tipos genéricos com parâmetros de tipo { #generic-types-with-type-parameters }
@@ -161,56 +161,24 @@ Se você pode utilizar a **versão mais recente do Python**, utilize os exemplos
Por exemplo, vamos definir uma variável para ser uma `list` de `str`.
//// tab | Python 3.9+
Declare a variável, com a mesma sintaxe com dois pontos (`:`).
Declare uma variável com a mesma sintaxe com dois pontos (`:`)
Como o tipo, coloque `list`.
Como tipo, coloque `list`.
Como a lista é um tipo que contém tipos internos, você os coloca entre colchetes:
Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial006_py39.py!}
```
////
//// tab | Python 3.8+
De `typing`, importe `List` (com o `L` maiúsculo):
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial006.py!}
```
Declare uma variável com a mesma sintaxe com dois pontos (`:`)
Como tipo, coloque o `List` que você importou de `typing`.
Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
```Python hl_lines="4"
{!> ../../docs_src/python_types/tutorial006.py!}
```
////
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
/// info | Informação
Estes tipos internos dentro dos colchetes são chamados "parâmetros de tipo" (type parameters).
Neste caso, `str` é o parâmetro de tipo passado para `List` (ou `list` no Python 3.9 ou superior).
Neste caso, `str` é o parâmetro de tipo passado para `list`.
///
Isso significa: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`".
/// tip | Dica
Se você usa o Python 3.9 ou superior, você não precisa importar `List` de `typing`. Você pode utilizar o mesmo tipo `list` no lugar.
///
Ao fazer isso, seu editor pode fornecer suporte mesmo durante o processamento de itens da lista:
<img src="/img/python-types/image05.png">
@@ -225,21 +193,7 @@ E, ainda assim, o editor sabe que é um `str` e fornece suporte para isso.
Você faria o mesmo para declarar `tuple`s e `set`s:
//// tab | Python 3.9+
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial007_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial007.py!}
```
////
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
Isso significa que:
@@ -254,21 +208,7 @@ O primeiro parâmetro de tipo é para as chaves do `dict`.
O segundo parâmetro de tipo é para os valores do `dict`:
//// tab | Python 3.9+
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008_py39.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008.py!}
```
////
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
Isso significa que:
@@ -292,10 +232,10 @@ No Python 3.10 também existe uma **nova sintaxe** onde você pode colocar os po
////
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008b.py!}
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
```
////
@@ -309,7 +249,7 @@ Você pode declarar que um valor pode ter um tipo, como `str`, mas que ele tamb
No Python 3.6 e superior (incluindo o Python 3.10) você pode declará-lo importando e utilizando `Optional` do módulo `typing`.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009.py!}
{!../../docs_src/python_types/tutorial009_py39.py!}
```
O uso de `Optional[str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
@@ -326,18 +266,18 @@ Isso também significa que no Python 3.10, você pode utilizar `Something | None
////
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009.py!}
{!> ../../docs_src/python_types/tutorial009_py39.py!}
```
////
//// tab | Python 3.8+ alternativa
//// tab | Python 3.9+ alternativa
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009b.py!}
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
```
////
@@ -357,7 +297,7 @@ Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os s
Por exemplo, vamos pegar esta função:
{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
O parâmetro `name` é definido como `Optional[str]`, mas ele **não é opcional**, você não pode chamar a função sem o parâmetro:
@@ -390,10 +330,10 @@ Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e ti
* `set`
* `dict`
E o mesmo como no Python 3.8, do módulo `typing`:
E o mesmo que com versões anteriores do Python, do módulo `typing`:
* `Union`
* `Optional` (o mesmo que com o 3.8)
* `Optional`
* ...entre outros.
No Python 3.10, como uma alternativa para a utilização dos genéricos `Union` e `Optional`, você pode usar a <abbr title='também chamado de "bitwise ou operador", mas o significado não é relevante aqui'>barra vertical (`|`)</abbr> para declarar uniões de tipos. Isso é muito melhor e mais simples.
@@ -409,7 +349,7 @@ Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e ti
* `set`
* `dict`
E o mesmo como no Python 3.8, do módulo `typing`:
E genéricos do módulo `typing`:
* `Union`
* `Optional`
@@ -417,31 +357,19 @@ E o mesmo como no Python 3.8, do módulo `typing`:
////
//// tab | Python 3.8+
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Union`
* `Optional`
* ...entre outros.
////
### Classes como tipos { #classes-as-types }
Você também pode declarar uma classe como o tipo de uma variável.
Digamos que você tenha uma classe `Person`, com um nome:
{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
Então você pode declarar que uma variável é do tipo `Person`:
{* ../../docs_src/python_types/tutorial010.py hl[6] *}
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
E então, novamente, você recebe todo o suporte do editor:
E então, novamente, você recebe todo o apoio do editor:
<img src="/img/python-types/image06.png">
@@ -461,31 +389,9 @@ Em seguida, você cria uma instância dessa classe com alguns valores e ela os v
E você recebe todo o suporte do editor com esse objeto resultante.
Retirado dos documentos oficiais dos Pydantic:
Um exemplo da documentação oficial do Pydantic:
//// tab | Python 3.10+
```Python
{!> ../../docs_src/python_types/tutorial011_py310.py!}
```
////
//// tab | Python 3.9+
```Python
{!> ../../docs_src/python_types/tutorial011_py39.py!}
```
////
//// tab | Python 3.8+
```Python
{!> ../../docs_src/python_types/tutorial011.py!}
```
////
{* ../../docs_src/python_types/tutorial011_py310.py *}
/// info | Informação
@@ -507,27 +413,9 @@ O Pydantic tem um comportamento especial quando você usa `Optional` ou `Union[S
O Python possui uma funcionalidade que nos permite incluir **<abbr title="Informação sobre a informação, neste caso, informação sobre o tipo, e.g. uma descrição.">metadados</abbr> adicionais** nos type hints utilizando `Annotated`.
//// tab | Python 3.9+
Desde o Python 3.9, `Annotated` faz parte da biblioteca padrão, então você pode importá-lo de `typing`.
No Python 3.9, `Annotated` é parte da biblioteca padrão, então você pode importá-lo de `typing`.
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial013_py39.py!}
```
////
//// tab | Python 3.8+
Em versões abaixo do Python 3.9, você importa `Annotated` de `typing_extensions`.
Ele já estará instalado com o **FastAPI**.
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial013.py!}
```
////
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
O Python em si não faz nada com este `Annotated`. E para editores e outras ferramentas, o tipo ainda é `str`.
+1 -1
View File
@@ -1,3 +1,3 @@
# Recursos { #resources }
Material complementar, links externos, artigos e muito mais. ✈️
Material complementar, links externos e mais. ✈️
+3 -3
View File
@@ -15,7 +15,7 @@ Isso inclui, por exemplo:
Primeiro, importe `BackgroundTasks` e defina um parâmetro na sua *função de operação de rota* com uma declaração de tipo `BackgroundTasks`:
{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
O **FastAPI** criará o objeto do tipo `BackgroundTasks` para você e o passará como esse parâmetro.
@@ -31,13 +31,13 @@ Neste caso, a função da tarefa escreverá em um arquivo (simulando o envio de
E como a operação de escrita não usa `async` e `await`, definimos a função com um `def` normal:
{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
## Adicione a tarefa em segundo plano { #add-the-background-task }
Dentro da sua *função de operação de rota*, passe sua função de tarefa para o objeto de *tarefas em segundo plano* com o método `.add_task()`:
{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
O `.add_task()` recebe como argumentos:
+14 -66
View File
@@ -85,9 +85,7 @@ Você pode criar as *operações de rotas* para esse módulo usando o `APIRouter
você o importa e cria uma "instância" da mesma maneira que faria com a classe `FastAPI`:
```Python hl_lines="1 3" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### *Operações de Rota* com `APIRouter` { #path-operations-with-apirouter }
@@ -95,9 +93,7 @@ E então você o utiliza para declarar suas *operações de rota*.
Utilize-o da mesma maneira que utilizaria a classe `FastAPI`:
```Python hl_lines="6 11 16" title="app/routers/users.py"
{!../../docs_src/bigger_applications/app/routers/users.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
Você pode pensar em `APIRouter` como uma classe "mini `FastAPI`".
@@ -121,35 +117,7 @@ Então, as colocamos em seu próprio módulo de `dependencies` (`app/dependencie
Agora usaremos uma dependência simples para ler um cabeçalho `X-Token` personalizado:
//// tab | Python 3.9+
```Python hl_lines="3 6-8" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
```
////
//// tab | Python 3.8+
```Python hl_lines="1 5-7" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip | Dica
Prefira usar a versão `Annotated` se possível.
///
```Python hl_lines="1 4-6" title="app/dependencies.py"
{!> ../../docs_src/bigger_applications/app/dependencies.py!}
```
////
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip | Dica
@@ -181,9 +149,7 @@ Sabemos que todas as *operações de rota* neste módulo têm o mesmo:
Então, em vez de adicionar tudo isso a cada *operação de rota*, podemos adicioná-lo ao `APIRouter`.
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
Como o caminho de cada *operação de rota* deve começar com `/`, como em:
@@ -199,7 +165,7 @@ Então, o prefixo neste caso é `/items`.
Também podemos adicionar uma lista de `tags` e `responses` extras que serão aplicadas a todas as *operações de rota* incluídas neste roteador.
E podemos adicionar uma lista de `dependencies` que serão adicionadas a todas as *operações de rota* no roteador e serão executadas/resolvidas para cada solicitação feita a elas.
E podemos adicionar uma lista de `dependencies` que serão adicionadas a todas as *operações de rota* no roteador e serão executadas/resolvidas para cada request feita a elas.
/// tip | Dica
@@ -242,9 +208,7 @@ E precisamos obter a função de dependência do módulo `app.dependencies`, o a
Então usamos uma importação relativa com `..` para as dependências:
```Python hl_lines="3" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
#### Como funcionam as importações relativas { #how-relative-imports-work }
@@ -315,9 +279,7 @@ Não estamos adicionando o prefixo `/items` nem `tags=["items"]` a cada *operaç
Mas ainda podemos adicionar _mais_ `tags` que serão aplicadas a uma *operação de rota* específica, e também algumas `responses` extras específicas para essa *operação de rota*:
```Python hl_lines="30-31" title="app/routers/items.py"
{!../../docs_src/bigger_applications/app/routers/items.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip | Dica
@@ -343,17 +305,13 @@ Você importa e cria uma classe `FastAPI` normalmente.
E podemos até declarar [dependências globais](dependencies/global-dependencies.md){.internal-link target=_blank} que serão combinadas com as dependências para cada `APIRouter`:
```Python hl_lines="1 3 7" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
### Importe o `APIRouter` { #import-the-apirouter }
Agora importamos os outros submódulos que possuem `APIRouter`s:
```Python hl_lines="4-5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
Como os arquivos `app/routers/users.py` e `app/routers/items.py` são submódulos que fazem parte do mesmo pacote Python `app`, podemos usar um único ponto `.` para importá-los usando "importações relativas".
@@ -416,17 +374,13 @@ o `router` de `users` sobrescreveria o de `items` e não poderíamos usá-los ao
Então, para poder usar ambos no mesmo arquivo, importamos os submódulos diretamente:
```Python hl_lines="5" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
### Inclua os `APIRouter`s para `usuários` e `itens` { #include-the-apirouters-for-users-and-items }
Agora, vamos incluir os `router`s dos submódulos `users` e `items`:
```Python hl_lines="10-11" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
/// info | Informação
@@ -466,17 +420,13 @@ Ele contém um `APIRouter` com algumas *operações de rota* de administração
Para este exemplo, será super simples. Mas digamos que, como ele é compartilhado com outros projetos na organização, não podemos modificá-lo e adicionar um `prefix`, `dependencies`, `tags`, etc. diretamente ao `APIRouter`:
```Python hl_lines="3" title="app/internal/admin.py"
{!../../docs_src/bigger_applications/app/internal/admin.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
Mas ainda queremos definir um `prefix` personalizado ao incluir o `APIRouter` para que todas as suas *operações de rota* comecem com `/admin`, queremos protegê-lo com as `dependencies` que já temos para este projeto e queremos incluir `tags` e `responses`.
Podemos declarar tudo isso sem precisar modificar o `APIRouter` original passando esses parâmetros para `app.include_router()`:
```Python hl_lines="14-17" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
Dessa forma, o `APIRouter` original permanecerá inalterado, para que possamos compartilhar o mesmo arquivo `app/internal/admin.py` com outros projetos na organização.
@@ -497,9 +447,7 @@ Também podemos adicionar *operações de rota* diretamente ao aplicativo `FastA
Aqui fazemos isso... só para mostrar que podemos 🤷:
```Python hl_lines="21-23" title="app/main.py"
{!../../docs_src/bigger_applications/app/main.py!}
```
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
e funcionará corretamente, junto com todas as outras *operações de rota* adicionadas com `app.include_router()`.
+2 -28
View File
@@ -14,35 +14,15 @@ Isso fará com que tags seja uma lista de itens mesmo sem declarar o tipo dos el
Mas o Python tem uma maneira específica de declarar listas com tipos internos ou "parâmetros de tipo":
### Importe `List` do typing { #import-typings-list }
No Python 3.9 e superior você pode usar a `list` padrão para declarar essas anotações de tipo, como veremos abaixo. 💡
Mas nas versões do Python anteriores à 3.9 (3.6 e superiores), primeiro é necessário importar `List` do módulo padrão `typing` do Python:
{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
### Declare uma `list` com um parâmetro de tipo { #declare-a-list-with-a-type-parameter }
Para declarar tipos que têm parâmetros de tipo (tipos internos), como `list`, `dict`, `tuple`:
* Se você estiver em uma versão do Python inferior a 3.9, importe a versão equivalente do módulo `typing`
* Passe o(s) tipo(s) interno(s) como "parâmetros de tipo" usando colchetes: `[` e `]`
No Python 3.9, seria:
Para declarar tipos que têm parâmetros de tipo (tipos internos), como `list`, `dict`, `tuple`,
passe o(s) tipo(s) interno(s) como "parâmetros de tipo" usando colchetes: `[` e `]`
```Python
my_list: list[str]
```
Em versões do Python anteriores à 3.9, seria:
```Python
from typing import List
my_list: List[str]
```
Essa é a sintaxe padrão do Python para declarações de tipo.
Use a mesma sintaxe padrão para atributos de modelo com tipos internos.
@@ -178,12 +158,6 @@ Observe como `Offer` tem uma lista de `Item`s, que por sua vez têm uma lista op
Se o valor de primeiro nível do corpo JSON que você espera for um `array` do JSON (uma` lista` do Python), você pode declarar o tipo no parâmetro da função, da mesma forma que nos modelos do Pydantic:
```Python
images: List[Image]
```
ou no Python 3.9 e superior:
```Python
images: list[Image]
```
+1 -1
View File
@@ -161,7 +161,7 @@ Os parâmetros da função serão reconhecidos conforme abaixo:
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
O `str | None` (Python 3.10+) ou o `Union` em `Union[str, None]` (Python 3.8+) não é utilizado pelo FastAPI para determinar que o valor não é obrigatório, ele saberá que não é obrigatório porque tem um valor padrão `= None`.
O `str | None` (Python 3.10+) ou o `Union` em `Union[str, None]` (Python 3.9+) não é utilizado pelo FastAPI para determinar que o valor não é obrigatório, ele saberá que não é obrigatório porque tem um valor padrão `= None`.
Mas adicionar as anotações de tipo permitirá ao seu editor oferecer um suporte melhor e detectar erros.
+2 -4
View File
@@ -48,11 +48,9 @@ Em alguns casos especiais (provavelmente não muito comuns), você pode querer *
Agora a sua API possui o poder de controlar o seu próprio <abbr 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</abbr>. 🤪🍪
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` qualquer campo `extra`.
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
{* ../../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**.
+1 -1
View File
@@ -46,7 +46,7 @@ Você também pode especificar se o seu backend permite:
* Métodos HTTP específicos (`POST`, `PUT`) ou todos eles com o curinga `"*"`.
* Cabeçalhos HTTP específicos ou todos eles com o curinga `"*"`.
{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
Os parâmetros padrão usados pela implementação `CORSMiddleware` são restritivos por padrão, então você precisará habilitar explicitamente as origens, métodos ou cabeçalhos específicos para que os navegadores tenham permissão para usá-los em um contexto cross domain.
+1 -1
View File
@@ -6,7 +6,7 @@ Você pode conectar o depurador no seu editor, por exemplo, com o Visual Studio
Em sua aplicação FastAPI, importe e execute `uvicorn` diretamente:
{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
### Sobre `__name__ == "__main__"` { #about-name-main }
@@ -101,7 +101,7 @@ O **FastAPI** chama a classe `CommonQueryParams`. Isso cria uma "instância" des
Perceba como escrevemos `CommonQueryParams` duas vezes no código abaixo:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.8+ non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
@@ -137,7 +137,7 @@ O último `CommonQueryParams`, em:
Nesse caso, o primeiro `CommonQueryParams`, em:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
////
//// tab | Python 3.8+ non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
Na verdade você poderia escrever apenas:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
////
//// tab | Python 3.8+ non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
@@ -197,7 +197,7 @@ Mas declarar o tipo é encorajado por que é a forma que o seu editor de texto s
Mas você pode ver que temos uma repetição do código neste exemplo, escrevendo `CommonQueryParams` duas vezes:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.8+ non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
@@ -225,7 +225,7 @@ Para esses casos específicos, você pode fazer o seguinte:
Em vez de escrever:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.8+ non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
...escreva:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
////
//// tab | Python 3.8 non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
@@ -29,15 +29,15 @@ Por exemplo, você poderia utilizar isso para criar uma sessão do banco de dado
Apenas o código anterior à declaração com `yield` e o código contendo essa declaração são executados antes de criar uma resposta:
{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
O valor gerado (yielded) é o que é injetado nas *operações de rota* e outras dependências:
{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
O código após o `yield` é executado após a resposta:
{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
/// tip | Dica
@@ -57,7 +57,7 @@ Então, você pode procurar por essa exceção específica dentro da dependênci
Da mesma forma, você pode utilizar `finally` para garantir que os passos de saída são executados, com ou sem exceções.
{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
## Subdependências com `yield` { #sub-dependencies-with-yield }
@@ -269,7 +269,7 @@ Em Python, você pode criar Gerenciadores de Contexto ao <a href="https://docs.p
Você também pode usá-los dentro de dependências com `yield` do **FastAPI** ao utilizar
`with` ou `async with` dentro da função da dependência:
{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
/// tip | Dica
@@ -6,7 +6,7 @@ De forma semelhante a [adicionar `dependencies` aos *decoradores de operação d
Nesse caso, elas serão aplicadas a todas as *operações de rota* da aplicação:
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
E todos os conceitos apresentados na seção sobre [adicionar `dependencies` aos *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} ainda se aplicam, mas nesse caso, para todas as *operações de rota* da aplicação.
@@ -62,7 +62,7 @@ E o valor retornado é salvo em um <abbr title="Um utilitário/sistema para arma
Em um cenário avançado onde você precise que a dependência seja calculada em cada passo (possivelmente várias vezes) de uma requisição em vez de utilizar o valor em "cache", você pode definir o parâmetro `use_cache=False` em `Depends`:
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
////
//// tab | Python 3.8+ non-Annotated
//// tab | Python 3.9+ non-Annotated
/// tip | Dica
+65 -8
View File
@@ -2,7 +2,7 @@
O arquivo FastAPI mais simples pode se parecer com:
{* ../../docs_src/first_steps/tutorial001.py *}
{* ../../docs_src/first_steps/tutorial001_py39.py *}
Copie o conteúdo para um arquivo `main.py`.
@@ -143,11 +143,47 @@ E existem dezenas de alternativas, todas baseadas em OpenAPI. Você pode facilme
Você também pode usá-lo para gerar código automaticamente para clientes que se comunicam com sua API. Por exemplo, aplicativos front-end, móveis ou IoT.
### Faça o deploy da sua aplicação (opcional) { #deploy-your-app-optional }
Você pode, opcionalmente, fazer o deploy da sua aplicação FastAPI na <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>; acesse e entre na lista de espera, se ainda não entrou. 🚀
Se você já tem uma conta na **FastAPI Cloud** (nós convidamos você da lista de espera 😉), pode fazer o deploy da sua aplicação com um único comando.
Antes do deploy, certifique-se de que está autenticado:
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
Em seguida, faça o deploy da sua aplicação:
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
É isso! Agora você pode acessar sua aplicação nessa URL. ✨
## Recapitulando, passo a passo { #recap-step-by-step }
### Passo 1: importe `FastAPI` { #step-1-import-fastapi }
{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
`FastAPI` é uma classe Python que fornece todas as funcionalidades para sua API.
@@ -161,7 +197,7 @@ Você pode usar todas as funcionalidades do <a href="https://www.starlette.dev/"
### Passo 2: crie uma "instância" de `FastAPI` { #step-2-create-a-fastapi-instance }
{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
Aqui, a variável `app` será uma "instância" da classe `FastAPI`.
@@ -230,7 +266,7 @@ Vamos chamá-los de "**operações**" também.
#### Defina um decorador de operação de rota { #define-a-path-operation-decorator }
{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
O `@app.get("/")` diz ao **FastAPI** que a função logo abaixo é responsável por tratar as requisições que vão para:
@@ -284,7 +320,7 @@ Esta é a nossa "**função de operação de rota**":
* **operação**: é `get`.
* **função**: é a função abaixo do "decorador" (abaixo do `@app.get("/")`).
{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
Esta é uma função Python.
@@ -296,7 +332,7 @@ Neste caso, é uma função `async`.
Você também pode defini-la como uma função normal em vez de `async def`:
{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
/// note | Nota
@@ -306,14 +342,34 @@ Se você não sabe a diferença, verifique o [Async: *"Com pressa?"*](../async.m
### Passo 5: retorne o conteúdo { #step-5-return-the-content }
{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
Você pode retornar um `dict`, `list` e valores singulares como `str`, `int`, etc.
Você também pode devolver modelos Pydantic (você verá mais sobre isso mais tarde).
Você também pode devolver modelos Pydantic ( você verá mais sobre isso mais tarde).
Existem muitos outros objetos e modelos que serão convertidos automaticamente para JSON (incluindo ORMs, etc). Tente usar seus favoritos, é altamente provável que já sejam compatíveis.
### Passo 6: Faça o deploy { #step-6-deploy-it }
Faça o deploy da sua aplicação para a **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** com um comando: `fastapi deploy`. 🎉
#### Sobre o FastAPI Cloud { #about-fastapi-cloud }
A **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** é construída pelo mesmo autor e equipe por trás do **FastAPI**.
Ela simplifica o processo de **construir**, **fazer deploy** e **acessar** uma API com o mínimo de esforço.
Traz a mesma **experiência do desenvolvedor** de criar aplicações com FastAPI para **fazer o deploy** delas na nuvem. 🎉
A FastAPI Cloud é a principal patrocinadora e financiadora dos projetos open source do ecossistema *FastAPI and friends*. ✨
#### Faça o deploy em outros provedores de nuvem { #deploy-to-other-cloud-providers }
FastAPI é open source e baseado em padrões. Você pode fazer deploy de aplicações FastAPI em qualquer provedor de nuvem que preferir.
Siga os tutoriais do seu provedor de nuvem para fazer deploy de aplicações FastAPI com eles. 🤓
## Recapitulando { #recap }
* Importe `FastAPI`.
@@ -321,3 +377,4 @@ Existem muitos outros objetos e modelos que serão convertidos automaticamente p
* Escreva um **decorador de operação de rota** usando decoradores como `@app.get("/")`.
* Defina uma **função de operação de rota**; por exemplo, `def root(): ...`.
* Execute o servidor de desenvolvimento usando o comando `fastapi dev`.
* Opcionalmente, faça o deploy da sua aplicação com `fastapi deploy`.
+25 -37
View File
@@ -11,7 +11,6 @@ Pode ser que você precise comunicar ao cliente que:
* O item que o cliente está tentando acessar não existe.
* etc.
Nesses casos, você normalmente retornaria um **HTTP status code** próximo ao status code na faixa do status code **400** (do 400 ao 499).
Isso é bastante similar ao caso do HTTP status code 200 (do 200 ao 299). Esses "200" status codes significam que, de algum modo, houve sucesso na requisição.
@@ -26,9 +25,9 @@ Para retornar ao cliente *responses* HTTP com erros, use o `HTTPException`.
### Import `HTTPException` { #import-httpexception }
{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
### Lance o `HTTPException` no seu código. { #raise-an-httpexception-in-your-code }
### Lance o `HTTPException` no seu código { #raise-an-httpexception-in-your-code }
`HTTPException`, ao fundo, nada mais é do que a conjunção entre uma exceção comum do Python e informações adicionais relevantes para APIs.
@@ -40,7 +39,7 @@ O benefício de lançar uma exceção em vez de retornar um valor ficará mais e
Neste exemplo, quando o cliente pede, na requisição, por um item cujo ID não existe, a exceção com o status code `404` é lançada:
{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
### A response resultante { #the-resulting-response }
@@ -78,17 +77,17 @@ Você provavelmente não precisará utilizar esses headers diretamente no seu c
Mas caso você precise, para um cenário mais complexo, você pode adicionar headers customizados:
{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
## Instale manipuladores de exceções customizados { #install-custom-exception-handlers }
Você pode adicionar manipuladores de exceção customizados com <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">a mesma seção de utilidade de exceções presentes no Starlette</a>
Você pode adicionar manipuladores de exceção customizados com <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">a mesma seção de utilidade de exceções presentes no Starlette</a>.
Digamos que você tenha uma exceção customizada `UnicornException` que você (ou uma biblioteca que você use) precise lançar (`raise`).
Nesse cenário, se você precisa manipular essa exceção de modo global com o FastAPI, você pode adicionar um manipulador de exceção customizada com `@app.exception_handler()`.
{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
Nesse cenário, se você fizer uma requisição para `/unicorns/yolo`, a *operação de caminho* vai lançar (`raise`) o `UnicornException`.
@@ -102,7 +101,7 @@ Dessa forma você receberá um erro "limpo", com o HTTP status code `418` e um J
/// note | Detalhes Técnicos
Você também pode usar `from starlette.requests import Request` and `from starlette.responses import JSONResponse`.
Você também pode usar `from starlette.requests import Request` e `from starlette.responses import JSONResponse`.
**FastAPI** disponibiliza o mesmo `starlette.responses` através do `fastapi.responses` por conveniência ao desenvolvedor. Contudo, a maior parte das respostas disponíveis vem diretamente do Starlette. O mesmo acontece com o `Request`.
@@ -112,7 +111,7 @@ Você também pode usar `from starlette.requests import Request` and `from starl
**FastAPI** tem alguns manipuladores padrão de exceções.
Esses manipuladores são os responsáveis por retornar o JSON padrão de respostas quando você lança (`raise`) o `HTTPException` e quando a requisição tem dados invalidos.
Esses manipuladores são os responsáveis por retornar o JSON padrão de respostas quando você lança (`raise`) o `HTTPException` e quando a requisição tem dados inválidos.
Você pode sobrescrever esses manipuladores de exceção com os seus próprios manipuladores.
@@ -126,7 +125,7 @@ Para sobrescrevê-lo, importe o `RequestValidationError` e use-o com o `@app.exc
O manipulador de exceções receberá um `Request` e a exceção.
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
Se você for ao `/items/foo`, em vez de receber o JSON padrão com o erro:
@@ -148,36 +147,17 @@ Se você for ao `/items/foo`, em vez de receber o JSON padrão com o erro:
você receberá a versão em texto:
```
1 validation error
path -> item_id
value is not a valid integer (type=type_error.integer)
Validation errors:
Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
```
#### `RequestValidationError` vs `ValidationError` { #requestvalidationerror-vs-validationerror }
/// warning | Atenção
Você pode pular estes detalhes técnicos caso eles não sejam importantes para você neste momento.
///
`RequestValidationError` é uma subclasse do <a href="https://docs.pydantic.dev/latest/concepts/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a> existente no Pydantic.
**FastAPI** faz uso dele para que você veja o erro no seu log, caso você utilize um modelo de Pydantic em `response_model`, e seus dados tenham erro.
Contudo, o cliente ou usuário não terão acesso a ele. Ao contrário, o cliente receberá um "Internal Server Error" com o HTTP status code `500`.
E assim deve ser porque seria um bug no seu código ter o `ValidationError` do Pydantic na sua *response*, ou em qualquer outro lugar do seu código (que não na requisição do cliente).
E enquanto você conserta o bug, os clientes / usuários não deveriam ter acesso às informações internas do erro, porque, desse modo, haveria exposição de uma vulnerabilidade de segurança.
### Sobrescreva o manipulador de erro `HTTPException` { #override-the-httpexception-error-handler }
Do mesmo modo, você pode sobreescrever o `HTTPException`.
Do mesmo modo, você pode sobrescrever o `HTTPException`.
Por exemplo, você pode querer retornar uma *response* em *plain text* ao invés de um JSON para os seguintes erros:
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
/// note | Detalhes Técnicos
@@ -187,13 +167,21 @@ Você pode usar `from starlette.responses import PlainTextResponse`.
///
### Use o body do `RequestValidationError`. { #use-the-requestvalidationerror-body }
/// warning | Atenção
Tenha em mente que o `RequestValidationError` contém as informações do nome do arquivo e da linha onde o erro de validação acontece, para que você possa mostrá-las nos seus logs com as informações relevantes, se quiser.
Mas isso significa que, se você simplesmente convertê-lo para uma string e retornar essa informação diretamente, você pode acabar vazando um pouco de informação sobre o seu sistema; por isso, aqui o código extrai e mostra cada erro de forma independente.
///
### Use o body do `RequestValidationError` { #use-the-requestvalidationerror-body }
O `RequestValidationError` contém o `body` que ele recebeu de dados inválidos.
Você pode utilizá-lo enquanto desenvolve seu app para conectar o *body* e debugá-lo, e assim retorná-lo ao usuário, etc.
Você pode utilizá-lo enquanto desenvolve seu app para registrar o *body* e debugá-lo, e assim retorná-lo ao usuário, etc.
{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
Tente enviar um item inválido como este:
@@ -249,6 +237,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
Se você quer usar a exceção em conjunto com o mesmo manipulador de exceção *default* do **FastAPI**, você pode importar e re-usar esses manipuladores de exceção do `fastapi.exception_handlers`:
{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
Nesse exemplo você apenas imprime (`print`) o erro com uma mensagem expressiva. Mesmo assim, dá para pegar a ideia. Você pode usar a exceção e então apenas re-usar o manipulador de exceção *default*.
+6 -6
View File
@@ -18,7 +18,7 @@ Você pode definir os seguintes campos que são usados na especificação OpenAP
Você pode defini-los da seguinte maneira:
{* ../../docs_src/metadata/tutorial001.py hl[3:16,19:32] *}
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
/// tip | Dica
@@ -36,7 +36,7 @@ Desde o OpenAPI 3.1.0 e FastAPI 0.99.0, você também pode definir o license_inf
Por exemplo:
{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
## Metadados para tags { #metadata-for-tags }
@@ -58,7 +58,7 @@ Vamos tentar isso em um exemplo com tags para `users` e `items`.
Crie metadados para suas tags e passe-os para o parâmetro `openapi_tags`:
{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
Observe que você pode usar Markdown dentro das descrições. Por exemplo, "login" será exibido em negrito (**login**) e "fancy" será exibido em itálico (_fancy_).
@@ -72,7 +72,7 @@ Você não precisa adicionar metadados para todas as tags que você usa.
Use o parâmetro `tags` com suas *operações de rota* (e `APIRouter`s) para atribuí-los a diferentes tags:
{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
/// info | Informação
@@ -100,7 +100,7 @@ Mas você pode configurá-lo com o parâmetro `openapi_url`.
Por exemplo, para defini-lo para ser servido em `/api/v1/openapi.json`:
{* ../../docs_src/metadata/tutorial002.py hl[3] *}
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
Se você quiser desativar completamente o esquema OpenAPI, pode definir `openapi_url=None`, o que também desativará as interfaces de documentação que o utilizam.
@@ -117,4 +117,4 @@ Você pode configurar as duas interfaces de documentação incluídas:
Por exemplo, para definir o Swagger UI para ser servido em `/documentation` e desativar o ReDoc:
{* ../../docs_src/metadata/tutorial003.py hl[3] *}
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
+2 -2
View File
@@ -31,7 +31,7 @@ A função middleware recebe:
* Então ela retorna a `response` gerada pela *operação de rota* correspondente.
* Você pode então modificar ainda mais o `response` antes de retorná-lo.
{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
/// tip | Dica
@@ -57,7 +57,7 @@ E também depois que a `response` é gerada, antes de retorná-la.
Por exemplo, você pode adicionar um cabeçalho personalizado `X-Process-Time` contendo o tempo em segundos que levou para processar a solicitação e gerar uma resposta:
{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
/// tip | Dica
@@ -46,7 +46,7 @@ Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
**FastAPI** suporta isso da mesma maneira que com strings simples:
{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
## Resumo e descrição { #summary-and-description }
@@ -92,7 +92,7 @@ Então, se você não fornecer uma, o **FastAPI** irá gerar automaticamente uma
Se você precisar marcar uma *operação de rota* como <abbr title="obsoleta, recomendada não usá-la">descontinuada</abbr>, mas sem removê-la, passe o parâmetro `deprecated`:
{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
Ela será claramente marcada como descontinuada nas documentações interativas:
@@ -54,7 +54,7 @@ Isso não faz diferença para o **FastAPI**. Ele vai detectar os parâmetros pel
Então, você pode declarar sua função assim:
{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
Mas tenha em mente que, se você usar `Annotated`, você não terá esse problema, não fará diferença, pois você não está usando valores padrão de parâmetros de função para `Query()` ou `Path()`.
@@ -83,7 +83,7 @@ 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="Do inglês: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Mesmo que eles não tenham um valor padrão.
{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
### Melhor com `Annotated` { #better-with-annotated }
+10 -14
View File
@@ -2,7 +2,7 @@
Você pode declarar "parâmetros" ou "variáveis" de path com a mesma sintaxe usada por strings de formatação do Python:
{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
O valor do parâmetro de path `item_id` será passado para a sua função como o argumento `item_id`.
@@ -16,7 +16,7 @@ Então, se você executar este exemplo e acessar <a href="http://127.0.0.1:8000/
Você pode declarar o tipo de um parâmetro de path na função, usando as anotações de tipo padrão do Python:
{* ../../docs_src/path_params/tutorial002.py hl[7] *}
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
Neste caso, `item_id` é declarado como um `int`.
@@ -110,13 +110,13 @@ E então você também pode ter um path `/users/{user_id}` para obter dados sobr
Como as *operações de rota* são avaliadas em ordem, você precisa garantir que o path para `/users/me` seja declarado antes do de `/users/{user_id}`:
{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
Caso contrário, o path para `/users/{user_id}` também corresponderia a `/users/me`, "achando" que está recebendo um parâmetro `user_id` com o valor `"me"`.
Da mesma forma, você não pode redefinir uma operação de rota:
{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
A primeira sempre será usada, já que o path corresponde primeiro.
@@ -132,11 +132,7 @@ Ao herdar de `str`, a documentação da API saberá que os valores devem ser do
Em seguida, crie atributos de classe com valores fixos, que serão os valores válidos disponíveis:
{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
/// info | Informação
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerations (ou enums) estão disponíveis no Python</a> desde a versão 3.4.
///
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
/// tip | Dica
Se você está se perguntando, "AlexNet", "ResNet" e "LeNet" são apenas nomes de <abbr title="Tecnicamente, arquiteturas de modelos de Deep Learning">modelos</abbr> de Aprendizado de Máquina.
@@ -146,7 +142,7 @@ Se você está se perguntando, "AlexNet", "ResNet" e "LeNet" são apenas nomes d
Em seguida, crie um *parâmetro de path* com anotação de tipo usando a classe enum que você criou (`ModelName`):
{* ../../docs_src/path_params/tutorial005.py hl[16] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
### Verifique a documentação { #check-the-docs }
@@ -162,13 +158,13 @@ O valor do *parâmetro de path* será um *membro de enumeração*.
Você pode compará-lo com o *membro de enumeração* no seu enum `ModelName` criado:
{* ../../docs_src/path_params/tutorial005.py hl[17] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
#### Obtenha o valor da enumeração { #get-the-enumeration-value }
Você pode obter o valor real (um `str` neste caso) usando `model_name.value`, ou, em geral, `your_enum_member.value`:
{* ../../docs_src/path_params/tutorial005.py hl[20] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
/// tip | Dica
Você também pode acessar o valor `"lenet"` com `ModelName.lenet.value`.
@@ -180,7 +176,7 @@ Você pode retornar *membros de enum* da sua *operação de rota*, até mesmo an
Eles serão convertidos para seus valores correspondentes (strings neste caso) antes de serem retornados ao cliente:
{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
No seu cliente, você receberá uma resposta JSON como:
@@ -219,7 +215,7 @@ Nesse caso, o nome do parâmetro é `file_path`, e a última parte, `:path`, diz
Então, você pode usá-lo com:
{* ../../docs_src/path_params/tutorial004.py hl[6] *}
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
/// tip | Dica
Você pode precisar que o parâmetro contenha `/home/johndoe/myfile.txt`, com uma barra inicial (`/`).
@@ -55,7 +55,7 @@ q: str | None = None
////
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
////
//// tab | Python 3.8+
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
+2 -2
View File
@@ -2,7 +2,7 @@
Quando você declara outros parâmetros na função que não fazem parte dos parâmetros da rota, esses parâmetros são automaticamente interpretados como parâmetros de "consulta".
{* ../../docs_src/query_params/tutorial001.py hl[9] *}
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
A consulta é o conjunto de pares chave-valor que vai depois de `?` na URL, separado pelo caractere `&`.
@@ -127,7 +127,7 @@ Caso você não queira adicionar um valor específico mas queira apenas torná-l
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.py hl[6:7] *}
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
Aqui o parâmetro de consulta `needy` é um valor obrigatório, do tipo `str`.
+2 -2
View File
@@ -183,7 +183,7 @@ Pode haver casos em que você retorna algo que não é um campo Pydantic válido
O caso mais comum seria [retornar uma Response diretamente, conforme explicado posteriormente na documentação avançada](../advanced/response-directly.md){.internal-link target=_blank}.
{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
Este caso simples é tratado automaticamente pelo FastAPI porque a anotação do tipo de retorno é a classe (ou uma subclasse de) `Response`.
@@ -193,7 +193,7 @@ E as ferramentas também ficarão felizes porque `RedirectResponse` e `JSO
Você também pode usar uma subclasse de `Response` na anotação de tipo:
{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
Isso também funcionará porque `RedirectResponse` é uma subclasse de `Response`, e o FastAPI tratará automaticamente este caso simples.
@@ -8,7 +8,7 @@ Da mesma forma que você pode especificar um modelo de resposta, você também p
* `@app.delete()`
* etc.
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
/// note | Nota
@@ -74,7 +74,7 @@ Para saber mais sobre cada código de status e qual código serve para quê, ver
Vamos ver o exemplo anterior novamente:
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
`201` é o código de status para "Criado".
@@ -82,7 +82,7 @@ Mas você não precisa memorizar o que cada um desses códigos significa.
Você pode usar as variáveis de conveniência de `fastapi.status`.
{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
Eles são apenas uma conveniência, eles possuem o mesmo número, mas dessa forma você pode usar o preenchimento automático do editor para encontrá-los:
+8 -8
View File
@@ -1,4 +1,4 @@
# Segurança
# Segurança { #security }
Há várias formas de lidar segurança, autenticação e autorização.
@@ -10,11 +10,11 @@ Em muitos frameworks e sistemas, apenas lidar com segurança e autenticação ex
Mas primeiro, vamos verificar alguns pequenos conceitos.
## Está com pressa?
## Está com pressa? { #in-a-hurry }
Se você não se importa com qualquer um desses termos e só precisa adicionar segurança com autenticação baseada em usuário e senha _agora_, pule para os próximos capítulos.
## OAuth2
## OAuth2 { #oauth2 }
OAuth2 é uma especificação que define várias formas para lidar com autenticação e autorização.
@@ -24,7 +24,7 @@ Ela inclui uma forma para autenticação usando “third party”/aplicações d
Isso é o que todos os sistemas com “Login with Facebook, Google, X (Twitter), GitHub” usam por baixo.
### OAuth 1
### OAuth 1 { #oauth-1 }
Havia um OAuth 1, que é bem diferente do OAuth2, e mais complexo, isso incluía diretamente as especificações de como criptografar a comunicação.
@@ -38,7 +38,7 @@ Na seção sobre **deployment** você irá ver como configurar HTTPS de modo gra
///
## OpenID Connect
## OpenID Connect { #openid-connect }
OpenID Connect é outra especificação, baseada em **OAuth2**.
@@ -48,7 +48,7 @@ Por exemplo, o login do Google usa OpenID Connect (que por baixo dos panos usa O
Mas o login do Facebook não tem suporte para OpenID Connect. Ele tem a própria implementação do OAuth2.
### OpenID (não "OpenID Connect")
### OpenID (não "OpenID Connect") { #openid-not-openid-connect }
Houve também uma especificação “OpenID”. Ela tentou resolver a mesma coisa que a **OpenID Connect**, mas não baseada em OAuth2.
@@ -56,7 +56,7 @@ Então, ela foi um sistema adicional completo.
Ela não é muito popular ou usada nos dias de hoje.
## OpenAPI
## OpenAPI { #openapi }
OpenAPI (anteriormente conhecido como Swagger) é a especificação aberta para a criação de APIs (agora parte da Linux Foundation).
@@ -97,7 +97,7 @@ O problema mais complexo é criar um provedor de autenticação/autorização co
///
## **FastAPI** utilitários
## **FastAPI** utilitários { #fastapi-utilities }
**FastAPI** fornece várias ferramentas para cada um desses esquemas de segurança no módulo `fastapi.security` que simplesmente usa esses mecanismos de segurança.
+1 -1
View File
@@ -65,7 +65,7 @@ Existem algumas diferenças:
* `Field(primary_key=True)` informa ao SQLModel que o `id` é a **chave primária** no banco de dados SQL (você pode aprender mais sobre chaves primárias SQL na documentação do SQLModel).
Ao ter o tipo como `int | None`, o SQLModel saberá que essa coluna deve ser um `INTEGER` no banco de dados SQL e que ela deve ser `NULLABLE`.
**Nota:** Usamos `int | None` para o campo de chave primária para que, no código Python, possamos *criar um objeto sem um `id`* (`id=None`), assumindo que o banco de dados irá *gerá-lo ao salvar*. O SQLModel entende que o banco de dados fornecerá o `id` e *define a coluna como um `INTEGER` não nulo* no esquema do banco de dados. Veja a <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">documentação do SQLModel sobre chaves primárias</a> para detalhes.
* `Field(index=True)` informa ao SQLModel que ele deve criar um **índice SQL** para essa coluna, o que permitirá buscas mais rápidas no banco de dados ao ler dados filtrados por essa coluna.
+1 -1
View File
@@ -7,7 +7,7 @@ Você pode servir arquivos estáticos automaticamente a partir de um diretório
* Importe `StaticFiles`.
* "Monte" uma instância de `StaticFiles()` em um path específico.
{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
/// note | Detalhes Técnicos
+13 -63
View File
@@ -1,6 +1,6 @@
# Testando { #testing }
Graças ao <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>, testar aplicativos **FastAPI** é fácil e agradável.
Graças ao <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>, testar aplicações **FastAPI** é fácil e agradável.
Ele é baseado no <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>, que por sua vez é projetado com base em Requests, por isso é muito familiar e intuitivo.
@@ -22,7 +22,7 @@ $ pip install httpx
Importe `TestClient`.
Crie um `TestClient` passando seu aplicativo **FastAPI** para ele.
Crie um `TestClient` passando sua aplicação **FastAPI** para ele.
Crie funções com um nome que comece com `test_` (essa é a convenção padrão do `pytest`).
@@ -30,7 +30,7 @@ Use o objeto `TestClient` da mesma forma que você faz com `httpx`.
Escreva instruções `assert` simples com as expressões Python padrão que você precisa verificar (novamente, `pytest` padrão).
{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
/// tip | Dica
@@ -52,7 +52,7 @@ Você também pode usar `from starlette.testclient import TestClient`.
/// tip | Dica
Se você quiser chamar funções `async` em seus testes além de enviar solicitações ao seu aplicativo FastAPI (por exemplo, funções de banco de dados assíncronas), dê uma olhada em [Testes assíncronos](../advanced/async-tests.md){.internal-link target=_blank} no tutorial avançado.
Se você quiser chamar funções `async` em seus testes além de enviar solicitações à sua aplicação FastAPI (por exemplo, funções de banco de dados assíncronas), dê uma olhada em [Testes assíncronos](../advanced/async-tests.md){.internal-link target=_blank} no tutorial avançado.
///
@@ -60,9 +60,9 @@ Se você quiser chamar funções `async` em seus testes além de enviar solicita
Em uma aplicação real, você provavelmente teria seus testes em um arquivo diferente.
E seu aplicativo **FastAPI** também pode ser composto de vários arquivos/módulos, etc.
E sua aplicação **FastAPI** também pode ser composta de vários arquivos/módulos, etc.
### Arquivo do aplicativo **FastAPI** { #fastapi-app-file }
### Arquivo da aplicação **FastAPI** { #fastapi-app-file }
Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicações maiores](bigger-applications.md){.internal-link target=_blank}:
@@ -73,10 +73,10 @@ Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicaç
│   └── main.py
```
No arquivo `main.py` você tem seu aplicativo **FastAPI**:
No arquivo `main.py` você tem sua aplicação **FastAPI**:
{* ../../docs_src/app_testing/main.py *}
{* ../../docs_src/app_testing/app_a_py39/main.py *}
### Arquivo de teste { #testing-file }
@@ -92,7 +92,7 @@ Então você poderia ter um arquivo `test_main.py` com seus testes. Ele poderia
Como esse arquivo está no mesmo pacote, você pode usar importações relativas para importar o objeto `app` do módulo `main` (`main.py`):
{* ../../docs_src/app_testing/test_main.py hl[3] *}
{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
...e ter o código para os testes como antes.
@@ -100,7 +100,7 @@ Como esse arquivo está no mesmo pacote, você pode usar importações relativas
Agora vamos estender este exemplo e adicionar mais detalhes para ver como testar diferentes partes.
### Arquivo de aplicativo **FastAPI** estendido { #extended-fastapi-app-file }
### Arquivo de aplicação **FastAPI** estendido { #extended-fastapi-app-file }
Vamos continuar com a mesma estrutura de arquivo de antes:
@@ -112,7 +112,7 @@ Vamos continuar com a mesma estrutura de arquivo de antes:
│   └── test_main.py
```
Digamos que agora o arquivo `main.py` com seu aplicativo **FastAPI** tenha algumas outras **operações de rotas**.
Digamos que agora o arquivo `main.py` com sua aplicação **FastAPI** tenha algumas outras **operações de rotas**.
Ele tem uma operação `GET` que pode retornar um erro.
@@ -120,63 +120,13 @@ Ele tem uma operação `POST` que pode retornar vários erros.
Ambas as *operações de rotas* requerem um cabeçalho `X-Token`.
//// tab | Python 3.10+
```Python
{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
```
////
//// tab | Python 3.9+
```Python
{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
```
////
//// tab | Python 3.8+
```Python
{!> ../../docs_src/app_testing/app_b_an/main.py!}
```
////
//// tab | Python 3.10+ non-Annotated
/// tip | Dica
Prefira usar a versão `Annotated` se possível.
///
```Python
{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip | Dica
Prefira usar a versão `Annotated` se possível.
///
```Python
{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
### Arquivo de teste estendido { #extended-testing-file }
Você pode então atualizar `test_main.py` com os testes estendidos:
{* ../../docs_src/app_testing/app_b/test_main.py *}
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
Sempre que você precisar que o cliente passe informações na requisição e não souber como, você pode pesquisar (no Google) como fazer isso no `httpx`, ou até mesmo como fazer isso com `requests`, já que o design do HTTPX é baseado no design do Requests.
+20
View File
@@ -242,6 +242,26 @@ $ python -m pip install --upgrade pip
</div>
/// tip | Dica
Às vezes, você pode receber um erro **`No module named pip`** ao tentar atualizar o pip.
Se isso acontecer, instale e atualize o pip usando o comando abaixo:
<div class="termy">
```console
$ python -m ensurepip --upgrade
---> 100%
```
</div>
Esse comando instalará o pip caso ele ainda não esteja instalado e também garante que a versão instalada do pip seja pelo menos tão recente quanto a disponível em `ensurepip`.
///
## Adicionar `.gitignore` { #add-gitignore }
Se você estiver usando **Git** (você deveria), adicione um arquivo `.gitignore` para excluir tudo em seu `.venv` do Git.
+10 -10
View File
@@ -14,15 +14,15 @@ When translating documentation into Portuguese, use neutral and widely understan
For the next terms, use the following translations:
* «/// check»: «/// check | Verifique»
* «/// danger»: «/// danger | Cuidado»
* «/// info»: «/// info | Informação»
* «/// note | Technical Details»: «/// note | Detalhes Técnicos»
* «/// info | Very Technical Details»: «/// note | Detalhes Técnicos Avançados»
* «/// note»: «/// note | Nota»
* «/// tip»: «/// tip | Dica»
* «/// warning»: «/// warning | Atenção»
* «(you should)»: «(você deveria)»
* /// check: /// check | Verifique
* /// danger: /// danger | Cuidado
* /// info: /// info | Informação
* /// note | Technical Details: /// note | Detalhes Técnicos
* /// info | Very Technical Details: /// note | Detalhes Técnicos Avançados
* /// note: /// note | Nota
* /// tip: /// tip | Dica
* /// warning: /// warning | Atenção
* (you should): (você deveria)
* async context manager: gerenciador de contexto assíncrono
* autocomplete: autocompletar
* autocompletion: preenchimento automático
@@ -47,7 +47,7 @@ For the next terms, use the following translations:
* list (as in Python list): list
* Machine Learning: Aprendizado de Máquina
* media type: media type (do not translate to "tipo de mídia")
* non-Annotated: non-Annotated (do not translate non-Annotated when it comes after a Python version.e.g., “Python 3.8+ non-Annotated”)
* non-Annotated: non-Annotated (do not translate non-Annotated when it comes after a Python version.e.g., “Python 3.10+ non-Annotated”)
* operation IDs: IDs de operação
* path (as in URL path): path
* path operation: operação de rota