mirror of https://github.com/tiangolo/fastapi.git
🌐 Update translations for pt (update-outdated) (#14537)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
e5d0e78bd4
commit
9a03503542
|
|
@ -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 }
|
### 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 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 }
|
### 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
|
* a documentação automática
|
||||||
|
|
||||||
* Ciência de Dados
|
* Ciência de Dados
|
||||||
* Aprendizado Profundo
|
* Deep Learning
|
||||||
* Aprendizado de Máquina
|
* Aprendizado de Máquina
|
||||||
* Injeção de Dependências
|
* Injeção de Dependências
|
||||||
* autenticação HTTP Basic
|
* autenticação HTTP Basic
|
||||||
|
|
|
||||||
|
|
@ -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:
|
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
|
/// note | Nota
|
||||||
|
|
||||||
|
|
@ -237,7 +237,7 @@ Você pode utilizar essa técnica para reutilizar alguns retornos predefinidos n
|
||||||
|
|
||||||
Por exemplo:
|
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 }
|
## 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 }
|
### 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.
|
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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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
|
```JSON
|
||||||
{
|
{
|
||||||
|
|
@ -443,6 +443,14 @@ 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 }
|
### 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`:
|
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`:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
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>.
|
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`:
|
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.
|
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:
|
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.
|
1. Ainda importamos `field` das `dataclasses` padrão.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Callbacks na OpenAPI { #openapi-callbacks }
|
# 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.
|
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`.
|
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):
|
Então sua API irá (vamos imaginar):
|
||||||
|
|
||||||
* Enviar a fatura para algum cliente do desenvolvedor externo.
|
* Enviar a fatura para algum cliente do desenvolvedor externo.
|
||||||
* Coletar o dinheiro.
|
* Coletar o dinheiro.
|
||||||
* Enviar a notificação de volta para o usuário da API (o desenvolvedor externo).
|
* 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 }
|
## 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ê:
|
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
|
/// 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})
|
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*.
|
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
|
/// 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>.
|
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.
|
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 }
|
### 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`.
|
* 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`.
|
* 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:
|
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}"
|
"{$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
|
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
|
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:
|
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
|
/// tip | Dica
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ Você precisa ter certeza que ele é único para cada operação.
|
||||||
|
|
||||||
### Utilizando o nome da *função de operação de rota* como o operationId { #using-the-path-operation-function-name-as-the-operationid }
|
### 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*.
|
Você deve fazer isso depois de adicionar todas as suas *operações de rota*.
|
||||||
|
|
||||||
|
|
@ -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.
|
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 }
|
## Respostas Adicionais { #additional-responses }
|
||||||
|
|
||||||
|
|
@ -155,13 +155,13 @@ Por exemplo, nesta aplicação nós não usamos a funcionalidade integrada ao Fa
|
||||||
|
|
||||||
//// tab | Pydantic v2
|
//// 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
|
//// 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
|
//// 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
|
//// 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] *}
|
||||||
|
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
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
|
/// note | Detalhes Técnicos
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
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()`.
|
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`:
|
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.
|
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
|
//// tab | Pydantic v2
|
||||||
|
|
||||||
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
|
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
|
||||||
|
|
||||||
/// tip | Dica
|
/// tip | Dica
|
||||||
|
|
||||||
|
|
@ -229,7 +229,7 @@ O atributo `model_config` é usado apenas para configuração do Pydantic. Você
|
||||||
|
|
||||||
//// tab | Pydantic v1
|
//// 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
|
/// tip | Dica
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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 }
|
## 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. 🙇
|
Você também pode considerá-los para seguir seus tutoriais e experimentar seus serviços:
|
||||||
|
|
||||||
Talvez você queira experimentar os serviços deles e seguir os tutoriais:
|
|
||||||
|
|
||||||
* <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.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>
|
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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).
|
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. ✨
|
Você verá mais detalhes para ter em mente e algumas das técnicas para fazer isso nas próximas seções. ✨
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ O FastAPI inclui alguns parâmetros de configuração padrão apropriados para a
|
||||||
|
|
||||||
Inclui estas configurações padrão:
|
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`.
|
Você pode substituir qualquer um deles definindo um valor diferente no argumento `swagger_ui_parameters`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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 }
|
### 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.
|
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
|
/// 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`:
|
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:
|
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 }
|
## 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`:
|
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:
|
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] *}
|
||||||
|
|
|
||||||
|
|
@ -52,14 +52,20 @@ Os recursos chave são:
|
||||||
|
|
||||||
<!-- sponsors -->
|
<!-- 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 -%}
|
{% for sponsor in sponsors.gold -%}
|
||||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
{%- for sponsor in sponsors.silver -%}
|
{%- for sponsor in sponsors.silver -%}
|
||||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- /sponsors -->
|
<!-- /sponsors -->
|
||||||
|
|
||||||
|
|
@ -444,6 +450,58 @@ Para um exemplo mais completo incluindo mais recursos, veja <a href="https://fas
|
||||||
* **Cookie Sessions**
|
* **Cookie Sessions**
|
||||||
* ...e mais.
|
* ...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 }
|
## 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). (*)
|
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). (*)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Recursos { #resources }
|
# Recursos { #resources }
|
||||||
|
|
||||||
Material complementar, links externos, artigos e muito mais. ✈️
|
Material complementar, links externos e mais. ✈️
|
||||||
|
|
|
||||||
|
|
@ -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`:
|
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_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/users.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
### *Operações de Rota* com `APIRouter` { #path-operations-with-apirouter }
|
### *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`:
|
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_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/users.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Você pode pensar em `APIRouter` como uma classe "mini `FastAPI`".
|
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:
|
Agora usaremos uma dependência simples para ler um cabeçalho `X-Token` personalizado:
|
||||||
|
|
||||||
//// tab | Python 3.9+
|
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
|
||||||
|
|
||||||
```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!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
/// tip | Dica
|
/// 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`.
|
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_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
Como o caminho de cada *operação de rota* deve começar com `/`, como em:
|
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.
|
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
|
/// 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:
|
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_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Como funcionam as importações relativas { #how-relative-imports-work }
|
#### 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*:
|
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_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
/// tip | Dica
|
/// 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`:
|
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_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Importe o `APIRouter` { #import-the-apirouter }
|
### Importe o `APIRouter` { #import-the-apirouter }
|
||||||
|
|
||||||
Agora importamos os outros submódulos que possuem `APIRouter`s:
|
Agora importamos os outros submódulos que possuem `APIRouter`s:
|
||||||
|
|
||||||
```Python hl_lines="4-5" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/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".
|
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:
|
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_an_py39/main.py hl[5] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Inclua os `APIRouter`s para `usuários` e `itens` { #include-the-apirouters-for-users-and-items }
|
### 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`:
|
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_an_py39/main.py hl[10:11] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
/// info | Informação
|
/// 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`:
|
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_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
|
||||||
{!../../docs_src/bigger_applications/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`.
|
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()`:
|
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_an_py39/main.py hl[14:17] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/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.
|
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 🤷:
|
Aqui fazemos isso... só para mostrar que podemos 🤷:
|
||||||
|
|
||||||
```Python hl_lines="21-23" title="app/main.py"
|
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
|
||||||
{!../../docs_src/bigger_applications/app/main.py!}
|
|
||||||
```
|
|
||||||
|
|
||||||
e funcionará corretamente, junto com todas as outras *operações de rota* adicionadas com `app.include_router()`.
|
e funcionará corretamente, junto com todas as outras *operações de rota* adicionadas com `app.include_router()`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>. 🤪🍪
|
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_py310.py hl[10] *}
|
||||||
|
|
||||||
|
|
||||||
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
|
|
||||||
|
|
||||||
Se o cliente tentar enviar alguns **cookies extras**, eles receberão um retorno de **erro**.
|
Se o cliente tentar enviar alguns **cookies extras**, eles receberão um retorno de **erro**.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,42 @@ 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.
|
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 }
|
## Recapitulando, passo a passo { #recap-step-by-step }
|
||||||
|
|
||||||
### Passo 1: importe `FastAPI` { #step-1-import-fastapi }
|
### Passo 1: importe `FastAPI` { #step-1-import-fastapi }
|
||||||
|
|
@ -314,6 +350,26 @@ Você também pode devolver modelos Pydantic (você verá mais sobre isso mais t
|
||||||
|
|
||||||
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.
|
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 }
|
## Recapitulando { #recap }
|
||||||
|
|
||||||
* Importe `FastAPI`.
|
* 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("/")`.
|
* 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(): ...`.
|
* Defina uma **função de operação de rota**; por exemplo, `def root(): ...`.
|
||||||
* Execute o servidor de desenvolvimento usando o comando `fastapi dev`.
|
* 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.
|
* O item que o cliente está tentando acessar não existe.
|
||||||
* etc.
|
* 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).
|
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.
|
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.
|
||||||
|
|
@ -28,7 +27,7 @@ Para retornar ao cliente *responses* HTTP com erros, use o `HTTPException`.
|
||||||
|
|
||||||
{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
|
{* ../../docs_src/handling_errors/tutorial001.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.
|
`HTTPException`, ao fundo, nada mais é do que a conjunção entre uma exceção comum do Python e informações adicionais relevantes para APIs.
|
||||||
|
|
||||||
|
|
@ -82,7 +81,7 @@ Mas caso você precise, para um cenário mais complexo, você pode adicionar hea
|
||||||
|
|
||||||
## Instale manipuladores de exceções customizados { #install-custom-exception-handlers }
|
## 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`).
|
Digamos que você tenha uma exceção customizada `UnicornException` que você (ou uma biblioteca que você use) precise lançar (`raise`).
|
||||||
|
|
||||||
|
|
@ -102,7 +101,7 @@ Dessa forma você receberá um erro "limpo", com o HTTP status code `418` e um J
|
||||||
|
|
||||||
/// note | Detalhes Técnicos
|
/// 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`.
|
**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.
|
**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.
|
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.
|
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.py hl[2,14:19] *}
|
||||||
|
|
||||||
Se você for ao `/items/foo`, em vez de receber o JSON padrão com o erro:
|
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:
|
você receberá a versão em texto:
|
||||||
|
|
||||||
```
|
```
|
||||||
1 validation error
|
Erros de validação:
|
||||||
path -> item_id
|
Campo: ('path', 'item_id'), Erro: A entrada deve ser um inteiro válido; não foi possível interpretar a string como um inteiro
|
||||||
value is not a valid integer (type=type_error.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 }
|
### 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:
|
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.py hl[3:4,9:11,25] *}
|
||||||
|
|
||||||
/// note | Detalhes Técnicos
|
/// note | Detalhes Técnicos
|
||||||
|
|
||||||
|
|
@ -187,11 +167,19 @@ 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.
|
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.py hl[14] *}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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).
|
* `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.
|
* `Field(index=True)` informa ao SQLModel que ele deve criar um **índice SQL** para essa coluna, o que permitirá buscas mais rápidas no banco de dados ao ler dados filtrados por essa coluna.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Testando { #testing }
|
# 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.
|
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`.
|
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`).
|
Crie funções com um nome que comece com `test_` (essa é a convenção padrão do `pytest`).
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ Você também pode usar `from starlette.testclient import TestClient`.
|
||||||
|
|
||||||
/// tip | Dica
|
/// 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.
|
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}:
|
Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicações maiores](bigger-applications.md){.internal-link target=_blank}:
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicaç
|
||||||
│ └── main.py
|
│ └── 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/main.py *}
|
||||||
|
|
@ -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.
|
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:
|
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
|
│ └── 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.
|
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`.
|
Ambas as *operações de rotas* requerem um cabeçalho `X-Token`.
|
||||||
|
|
||||||
//// tab | Python 3.10+
|
{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
|
||||||
|
|
||||||
```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!}
|
|
||||||
```
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
### Arquivo de teste estendido { #extended-testing-file }
|
### Arquivo de teste estendido { #extended-testing-file }
|
||||||
|
|
||||||
Você pode então atualizar `test_main.py` com os testes estendidos:
|
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.
|
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>
|
</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 }
|
## Adicionar `.gitignore` { #add-gitignore }
|
||||||
|
|
||||||
Se você estiver usando **Git** (você deveria), adicione um arquivo `.gitignore` para excluir tudo em seu `.venv` do Git.
|
Se você estiver usando **Git** (você deveria), adicione um arquivo `.gitignore` para excluir tudo em seu `.venv` do Git.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue