Sync fastapi docs from 50fa3f7c on 2026-01-11
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.).
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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,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] *}
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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. 🤓
|
||||
@@ -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.
|
||||
|
||||
///
|
||||
@@ -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"`.
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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] *}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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
@@ -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). (*)
|
||||
|
||||
@@ -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
@@ -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,3 +1,3 @@
|
||||
# Recursos { #resources }
|
||||
|
||||
Material complementar, links externos, artigos e muito mais. ✈️
|
||||
Material complementar, links externos e mais. ✈️
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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()`.
|
||||
|
||||
|
||||
@@ -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]
|
||||
```
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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**.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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*.
|
||||
|
||||
@@ -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] *}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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,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`.
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user