@ -34,7 +34,7 @@ Lembre-se que você deve retornar o `JSONResponse` diretamente.
///
///
/// info | Informação
/// note | Nota
A chave `model` não é parte do OpenAPI.
A chave `model` não é parte do OpenAPI.
@ -183,7 +183,7 @@ Note que você deve retornar a imagem utilizando um `FileResponse` diretamente.
///
///
/// info | Informação
/// note | Nota
A menos que você especifique um media type diferente explicitamente em seu parâmetro `responses`, o FastAPI assumirá que o retorno possui o mesmo media type contido na classe principal de retorno (padrão `application/json`).
A menos que você especifique um media type diferente explicitamente em seu parâmetro `responses`, o FastAPI assumirá que o retorno possui o mesmo media type contido na classe principal de retorno (padrão `application/json`).
@ -98,7 +98,7 @@ Por exemplo, se você tivesse uma sessão de banco de dados em uma dependência
Esse comportamento foi revertido na versão 0.118.0, para que o código de saída após o `yield` seja executado depois que a resposta for enviada.
Esse comportamento foi revertido na versão 0.118.0, para que o código de saída após o `yield` seja executado depois que a resposta for enviada.
/// info | Informação
/// note | Nota
Como você verá abaixo, isso é muito semelhante ao comportamento antes da versão 0.106.0, mas com várias melhorias e correções de bugs para casos extremos.
Como você verá abaixo, isso é muito semelhante ao comportamento antes da versão 0.106.0, mas com várias melhorias e correções de bugs para casos extremos.
@ -108,7 +108,7 @@ Como você verá abaixo, isso é muito semelhante ao comportamento antes da vers
Há alguns casos de uso, com condições específicas, que poderiam se beneficiar do comportamento antigo de executar o código de saída das dependências com `yield` antes de enviar a resposta.
Há alguns casos de uso, com condições específicas, que poderiam se beneficiar do comportamento antigo de executar o código de saída das dependências com `yield` antes de enviar a resposta.
Por exemplo, imagine que você tem código que usa uma sessão de banco de dados em uma dependência com `yield` apenas para verificar um usuário, mas a sessão de banco de dados nunca é usada novamente na *função de operação de rota*, somente na dependência, e a resposta demora a ser enviada, como um `StreamingResponse` que envia dados lentamente, mas por algum motivo não usa o banco de dados.
Por exemplo, imagine que você tem código que usa uma sessão de banco de dados em uma dependência com `yield` apenas para verificar um usuário, mas a sessão de banco de dados nunca é usada novamente na *função de operação de rota*, somente na dependência, e a response demora a ser enviada, como um `StreamingResponse` que envia dados lentamente, mas por algum motivo não usa o banco de dados.
Nesse caso, a sessão de banco de dados seria mantida até que a resposta termine de ser enviada, mas se você não a usa, então não seria necessário mantê-la.
Nesse caso, a sessão de banco de dados seria mantida até que a resposta termine de ser enviada, mas se você não a usa, então não seria necessário mantê-la.
@ -120,7 +120,7 @@ Para adicionar uma função que deve ser executada quando a aplicação estiver
Aqui, a função de manipulador do evento `shutdown` escreverá uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
Aqui, a função de manipulador do evento `shutdown` escreverá uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
/// info | Informação
/// note | Nota
Na função `open()`, o `mode="a"` significa "acrescentar", então a linha será adicionada depois do que já estiver naquele arquivo, sem sobrescrever o conteúdo anterior.
Na função `open()`, o `mode="a"` significa "acrescentar", então a linha será adicionada depois do que já estiver naquele arquivo, sem sobrescrever o conteúdo anterior.
@ -152,7 +152,7 @@ Apenas um detalhe técnico para nerds curiosos. 🤓
Por baixo, na especificação técnica do ASGI, isso é parte do [Protocolo Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), e define eventos chamados `startup` e `shutdown`.
Por baixo, na especificação técnica do ASGI, isso é parte do [Protocolo Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), e define eventos chamados `startup` e `shutdown`.
/// info | Informação
/// note | Nota
Você pode ler mais sobre os manipuladores de `lifespan` do Starlette na [Documentação do Lifespan do Starlette](https://www.starlette.dev/lifespan/).
Você pode ler mais sobre os manipuladores de `lifespan` do Starlette na [Documentação do Lifespan do Starlette](https://www.starlette.dev/lifespan/).
Algumas dessas soluções também podem ser open source ou oferecer planos gratuitos, para que você possa testá-las sem compromisso financeiro. Outros geradores comerciais de SDK estão disponíveis e podem ser encontrados online. 🤓
Algumas dessas soluções também podem ser open source ou oferecer planos gratuitos, para que você possa testá-las sem compromisso financeiro. Outros geradores comerciais de SDK estão disponíveis e podem ser encontrados online. 🤓
@ -167,13 +167,13 @@ Perceba como a URL de callback usada contém a URL recebida como um parâmetro d
Nesse ponto você tem a(s) *operação(ões) de rota de callback* necessária(s) (a(s) que o *desenvolvedor externo* deveria implementar na *API externa*) no roteador de callback que você criou acima.
Nesse ponto você tem a(s) *operação(ões) de rota de callback* necessária(s) (a(s) que o *desenvolvedor externo* deveria implementar na *API externa*) no roteador de callback que você criou acima.
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` do roteador de callback:
Perceba que você não está passando o roteador em si (`invoices_callback_router`) para `callback=`, mas o atributo `.routes`, como em `invoices_callback_router.routes`.
Perceba que você não está passando o roteador em si (`invoices_callback_router`) para `callbacks=`, mas o atributo `.routes`, como em `invoices_callback_router.routes`. O FastAPI usará essas rotas para gerar a documentação OpenAPI do callback.
@ -22,7 +22,7 @@ Com o **FastAPI**, utilizando o OpenAPI, você pode definir os nomes destes webh
Isto pode facilitar bastante para os seus usuários **implementarem as APIs deles** para receber as requisições dos seus **webhooks**, eles podem inclusive ser capazes de gerar parte do código da API deles.
Isto pode facilitar bastante para os seus usuários **implementarem as APIs deles** para receber as requisições dos seus **webhooks**, eles podem inclusive ser capazes de gerar parte do código da API deles.
/// info | Informação
/// note | Nota
Webhooks estão disponíveis a partir do OpenAPI 3.1.0, e possui suporte do FastAPI a partir da versão `0.99.0`.
Webhooks estão disponíveis a partir do OpenAPI 3.1.0, e possui suporte do FastAPI a partir da versão `0.99.0`.
@ -36,7 +36,7 @@ Quando você cria uma aplicação com o **FastAPI**, existe um atributo chamado
Os webhooks que você define aparecerão no esquema do **OpenAPI** e na **página de documentação** gerada automaticamente.
Os webhooks que você define aparecerão no esquema do **OpenAPI** e na **página de documentação** gerada automaticamente.
/// info | Informação
/// note | Nota
O objeto `app.webhooks` é na verdade apenas um `APIRouter`, o mesmo tipo que você utilizaria ao estruturar a sua aplicação com diversos arquivos.
O objeto `app.webhooks` é na verdade apenas um `APIRouter`, o mesmo tipo que você utilizaria ao estruturar a sua aplicação com diversos arquivos.
@ -16,17 +16,11 @@ Você deveria 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 `operation_id` em cada *operação de rota* utilizando o `APIRoute.name` dela.
Se você quiser utilizar os nomes das funções da sua API como `operationId`s, você pode passar uma `generate_unique_id_function` personalizada para o `FastAPI`.
Você deveria fazer isso depois de adicionar todas as suas *operações de rota*.
A função recebe cada `APIRoute` e retorna o `operationId` a ser usado para aquela operação de rota.
# Verificação Estrita de Content-Type { #strict-content-type-checking }
# Verificação Estrita de Content-Type { #strict-content-type-checking }
Por padrão, o **FastAPI** usa verificação estrita do cabeçalho `Content-Type` para corpos de requisição JSON; isso significa que requisições JSON devem incluir um `Content-Type` válido (por exemplo, `application/json`) para que o corpo seja interpretado como JSON.
Por padrão, o **FastAPI** usa verificação estrita do cabeçalho `Content-Type` para corpos de requisição JSON; isso significa que requisições JSON **devem** incluir um `Content-Type` válido (por exemplo, `application/json`) para que o corpo seja interpretado como JSON.
## Risco de CSRF { #csrf-risk }
## Risco de CSRF { #csrf-risk }
@ -40,7 +40,7 @@ Observe que ambos têm o mesmo host.
Usando o frontend, você pode fazer o agente de IA executar ações em seu nome.
Usando o frontend, você pode fazer o agente de IA executar ações em seu nome.
Como está em execução localmente e não na Internet aberta, você decide não configurar autenticação, confiando apenas no acesso à rede local.
Como está em execução **localmente** e não na Internet aberta, você decide **não configurar autenticação**, confiando apenas no acesso à rede local.
Então um de seus usuários poderia instalá-lo e executá-lo localmente.
Então um de seus usuários poderia instalá-lo e executá-lo localmente.
@ -69,9 +69,9 @@ Se sua aplicação está na Internet aberta, você não “confiaria na rede”
Atacantes poderiam simplesmente executar um script para enviar requisições à sua API, sem necessidade de interação do navegador, então você provavelmente já está protegendo quaisquer endpoints privilegiados.
Atacantes poderiam simplesmente executar um script para enviar requisições à sua API, sem necessidade de interação do navegador, então você provavelmente já está protegendo quaisquer endpoints privilegiados.
Nesse caso, esse ataque/risco não se aplica a você.
Nesse caso, **esse ataque/risco não se aplica a você**.
Esse risco e ataque é relevante principalmente quando a aplicação roda na rede local e essa é a única proteção presumida.
Esse risco e ataque é relevante principalmente quando a aplicação roda na **rede local** e essa é a **única proteção presumida**.
## Permitindo Requisições sem Content-Type { #allowing-requests-without-content-type }
## Permitindo Requisições sem Content-Type { #allowing-requests-without-content-type }
@ -81,7 +81,7 @@ Se você precisa dar suporte a clientes que não enviam um cabeçalho `Content-T
Com essa configuração, requisições sem um cabeçalho `Content-Type` terão o corpo interpretado como JSON, o mesmo comportamento das versões mais antigas do FastAPI.
Com essa configuração, requisições sem um cabeçalho `Content-Type` terão o corpo interpretado como JSON, o mesmo comportamento das versões mais antigas do FastAPI.
/// info | Informação
/// note | Nota
Esse comportamento e configuração foram adicionados no FastAPI 0.132.0.
Esse comportamento e configuração foram adicionados no FastAPI 0.132.0.
Há outros formatos e ferramentas para definir e instalar dependências de pacotes.
Há outros formatos e ferramentas para definir e instalar dependências de pacotes.
@ -556,7 +556,7 @@ Se você estiver usando contêineres (por exemplo, Docker, Kubernetes), existem
Se você tiver **múltiplos contêineres**, provavelmente cada um executando um **único processo** (por exemplo, em um cluster do **Kubernetes**), então provavelmente você gostaria de ter um **contêiner separado** fazendo o trabalho dos **passos anteriores** em um único contêiner, executando um único processo, **antes** de executar os contêineres workers replicados.
Se você tiver **múltiplos contêineres**, provavelmente cada um executando um **único processo** (por exemplo, em um cluster do **Kubernetes**), então provavelmente você gostaria de ter um **contêiner separado** fazendo o trabalho dos **passos anteriores** em um único contêiner, executando um único processo, **antes** de executar os contêineres workers replicados.
/// info | Informação
/// note | Nota
Se você estiver usando o Kubernetes, provavelmente será um [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
Se você estiver usando o Kubernetes, provavelmente será um [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
Você pode implantar sua aplicação FastAPI no [FastAPI Cloud](https://fastapicloud.com) com um **único comando**; entre na lista de espera, caso ainda não tenha feito isso. 🚀
Você pode implantar sua aplicação FastAPI no [FastAPI Cloud](https://fastapicloud.com) com apenas **um comando**. 🚀
## 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:
<divclass="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
## Implantar { #deploy }
Agora, implante sua aplicação, com **um único comando**:
<divclass="termy">
<divclass="termy">
@ -36,6 +16,8 @@ Deploying to FastAPI Cloud...
</div>
</div>
A CLI detectará automaticamente sua aplicação FastAPI e a implantará na nuvem. Se você não estiver autenticado, seu navegador será aberto para concluir o processo de autenticação.
É isso! Agora você pode acessar sua aplicação nesse URL. ✨
É isso! Agora você pode acessar sua aplicação nesse URL. ✨
@ -17,7 +17,7 @@ Como você viu no capítulo anterior sobre [Conceitos de implantação](concepts
Aqui mostrarei como usar o **Uvicorn** com **processos de trabalho** usando o comando `fastapi` ou o comando `uvicorn` diretamente.
Aqui mostrarei como usar o **Uvicorn** com **processos de trabalho** usando o comando `fastapi` ou o comando `uvicorn` diretamente.
/// info | Informação
/// note | Nota
Se você estiver usando contêineres, por exemplo com Docker ou Kubernetes, falarei mais sobre isso no próximo capítulo: [FastAPI em contêineres - Docker](docker.md).
Se você estiver usando contêineres, por exemplo com Docker ou Kubernetes, falarei mais sobre isso no próximo capítulo: [FastAPI em contêineres - Docker](docker.md).
@ -25,9 +25,17 @@ E essa função `get_openapi()` recebe como parâmetros:
* `openapi_version`: A versão da especificação OpenAPI utilizada. Por padrão, a mais recente: `3.1.0`.
* `openapi_version`: A versão da especificação OpenAPI utilizada. Por padrão, a mais recente: `3.1.0`.
* `summary`: Um resumo curto da API.
* `summary`: Um resumo curto da API.
* `description`: A descrição da sua API, que pode incluir markdown e será exibida na documentação.
* `description`: A descrição da sua API, que pode incluir markdown e será exibida na documentação.
* `routes`: Uma lista de rotas, que são cada uma das *operações de rota* registradas. Elas são obtidas de `app.routes`.
* `routes`: As rotas da aplicação, obtidas de `app.routes`. O FastAPI as usa para coletar as *operações de rota* registradas, incluindo as dos routers incluídos.
/// info | Informação
/// tip | Detalhes Técnicos
`app.routes` é uma árvore de rotas de baixo nível. Ela pode incluir rotas candidatas que o FastAPI usa internamente para routers incluídos, não apenas objetos finais `APIRoute`.
Você ainda pode passar `app.routes` para `get_openapi()`. O FastAPI vai percorrer essa árvore de rotas para coletar as operações de rota efetivas.
///
/// note | Nota
O parâmetro `summary` está disponível no OpenAPI 3.1.0 e superior, suportado pelo FastAPI 0.99.0 e superior.
O parâmetro `summary` está disponível no OpenAPI 3.1.0 e superior, suportado pelo FastAPI 0.99.0 e superior.
@ -38,7 +38,7 @@ Mas se você usar o mesmo modelo como saída, como aqui:
### Modelo para Dados de Resposta de Saída { #model-for-output-response-data }
### Modelo para Dados de Resposta de Saída { #model-for-output-response-data }
Se você interagir com a documentação e verificar a resposta, mesmo que o código não tenha adicionado nada em um dos campos `description`, a resposta JSON contém o valor padrão (`null`):
Se você interagir com a documentação e verificar a resposta, mesmo que o código não tenha adicionado nada em um dos campos `description`, a response JSON contém o valor padrão (`null`):
@ -81,11 +81,11 @@ Com esse recurso do **Pydantic v2**, sua documentação da API fica mais **preci
Agora, há alguns casos em que você pode querer ter o **mesmo esquema para entrada e saída**.
Agora, há alguns casos em que você pode querer ter o **mesmo esquema para entrada e saída**.
Provavelmente, o principal caso de uso para isso é se você já tem algum código de cliente/SDK gerado automaticamente e não quer atualizar todo o código de cliente/SDK gerado ainda, você provavelmente vai querer fazer isso em algum momento, mas talvez não agora.
Provavelmente, o principal caso de uso para isso é se você já tem algum código de cliente/SDKs gerado automaticamente e não quer atualizar todo o código de cliente/SDKs gerado ainda, você provavelmente vai querer fazer isso em algum momento, mas talvez não agora.
Nesse caso, você pode desativar esse recurso no **FastAPI**, com o parâmetro `separate_input_output_schemas=False`.
Nesse caso, você pode desativar esse recurso no **FastAPI**, com o parâmetro `separate_input_output_schemas=False`.
/// info | Informação
/// note | Nota
O suporte para `separate_input_output_schemas` foi adicionado no FastAPI `0.102.0`. 🤓
O suporte para `separate_input_output_schemas` foi adicionado no FastAPI `0.102.0`. 🤓
@ -492,9 +492,7 @@ Para um exemplo mais completo incluindo mais recursos, veja o <a href="https://f
### Implemente sua aplicação (opcional) { #deploy-your-app-optional }
### Implemente sua aplicação (opcional) { #deploy-your-app-optional }
Você pode opcionalmente implantar sua aplicação FastAPI na [FastAPI Cloud](https://fastapicloud.com), vá e entre na lista de espera se ainda não o fez. 🚀
Você pode opcionalmente implantar sua aplicação FastAPI na [FastAPI Cloud](https://fastapicloud.com) com um único comando. 🚀
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.
<divclass="termy">
<divclass="termy">
@ -510,6 +508,8 @@ Deploying to FastAPI Cloud...
</div>
</div>
A CLI detectará automaticamente sua aplicação FastAPI e a implantará na nuvem. Se você não estiver autenticado, o navegador será aberto para concluir o processo de autenticação.
É isso! Agora você pode acessar sua aplicação nesse URL. ✨
É isso! Agora você pode acessar sua aplicação nesse URL. ✨
#### Sobre a FastAPI Cloud { #about-fastapi-cloud }
#### Sobre a FastAPI Cloud { #about-fastapi-cloud }
`users.router` contém o `APIRouter` dentro do arquivo `app/routers/users.py`.
O FastAPI mantém o `APIRouter` original e seus `APIRoute`s ativos quando o router é incluído na aplicação principal.
E `items.router` contém o `APIRouter` dentro do arquivo `app/routers/items.py`.
Isso significa que subclasses personalizadas de `APIRouter` e `APIRoute` ainda podem participar depois que o router é incluído.
///
///
@ -394,19 +394,11 @@ Com `app.include_router()` podemos adicionar cada `APIRouter` ao aplicativo prin
Ele incluirá todas as rotas daquele router como parte dele.
Ele incluirá todas as rotas daquele router como parte dele.
/// note | Detalhes Técnicos
Na verdade, ele criará internamente uma *operação de rota* para cada *operação de rota* que foi declarada no `APIRouter`.
Então, nos bastidores, ele realmente funcionará como se tudo fosse o mesmo aplicativo único.
///
/// tip | Dica
/// tip | Dica
Você não precisa se preocupar com desempenho ao incluir routers.
Você não precisa se preocupar com desempenho ao incluir routers.
Isso levará microssegundos e só acontecerá na inicialização.
Isso foi projetado para ser leve e evitar adicionar overhead a cada request.
Então não afetará o desempenho. ⚡
Então não afetará o desempenho. ⚡
@ -461,7 +453,7 @@ Os `APIRouter`s não são "montados", eles não são isolados do resto do aplica
Isso ocorre porque queremos incluir suas *operações de rota* no esquema OpenAPI e nas interfaces de usuário.
Isso ocorre porque queremos incluir suas *operações de rota* no esquema OpenAPI e nas interfaces de usuário.
Como não podemos simplesmente isolá-los e "montá-los" independentemente do resto, as *operações de rota* são "clonadas" (recriadas), não incluídas diretamente.
O FastAPI mantém os routers e as operações de rota originais ativos e combina os prefixos, dependências, tags, responses e outros metadados do router ao tratar as requisições e gerar o OpenAPI.
///
///
@ -532,4 +524,16 @@ Da mesma forma que você pode incluir um `APIRouter` em uma aplicação `FastAPI
router.include_router(other_router)
router.include_router(other_router)
```
```
Certifique-se de fazer isso antes de incluir `router` na aplicação `FastAPI`, para que as *operações de rota* de `other_router` também sejam incluídas.
Você pode fazer isso antes ou depois de incluir o `router` na aplicação `FastAPI`. O FastAPI ainda incluirá as *operações de rota* de `other_router` no roteamento e no OpenAPI.
O mesmo vale para *operações de rota* adicionadas depois aos routers. Elas também ficarão visíveis por meio da inclusão anterior.
/// warning | Detalhes Técnicos
Evite mutar diretamente `router.routes` após incluir um router. O FastAPI trata a inclusão de routers como algo ativo, então o router original e suas rotas permanecem parte do roteamento e da geração do OpenAPI.
Use APIs documentadas como os decoradores de operações de rota e `.include_router()` para adicionar rotas e routers.
Trate `router.routes` como uma árvore de rotas de nível mais baixo que pode conter definições de rotas e routers incluídos, e evite depender dela como uma lista plana de operações de rota finais.
`Body` também possui todas as validações adicionais e metadados de parâmetros como em `Query`,`Path` e outras que você verá depois.
`Body` também possui todas as validações adicionais e metadados de parâmetros como em `Query`,`Path` e outras que você verá depois.
@ -123,7 +123,7 @@ Por padrão, o **FastAPI** esperará que seu conteúdo venha no corpo diretament
Mas se você quiser que ele espere por um JSON com uma chave `item` e dentro dele os conteúdos do modelo, como ocorre ao declarar vários parâmetros de corpo, você pode usar o parâmetro especial de `Body` chamado `embed`:
Mas se você quiser que ele espere por um JSON com uma chave `item` e dentro dele os conteúdos do modelo, como ocorre ao declarar vários parâmetros de corpo, você pode usar o parâmetro especial de `Body` chamado `embed`:
Tenha em mente que, como os **navegadores lidam com cookies** de maneira especial e por baixo dos panos, eles **não** permitem facilmente que o **JavaScript** lidem com eles.
Tenha em mente que, como os **navegadores lidam com cookies** de maneira especial e por baixo dos panos, eles **não** permitem facilmente que o **JavaScript** lidem com eles.
@ -24,13 +24,13 @@ Mas lembre-se que quando você importa `Query`, `Path`, `Cookie` e outras de `fa
///
///
/// info | Informação
/// note | Nota
Para declarar cookies, você precisa usar `Cookie`, pois caso contrário, os parâmetros seriam interpretados como parâmetros de consulta.
Para declarar cookies, você precisa usar `Cookie`, pois caso contrário, os parâmetros seriam interpretados como parâmetros de consulta.
///
///
/// info | Informação
/// note | Nota
Tenha em mente que, como os **navegadores lidam com cookies** de maneiras especiais e nos bastidores, eles **não** permitem facilmente que o **JavaScript** os acesse.
Tenha em mente que, como os **navegadores lidam com cookies** de maneiras especiais e nos bastidores, eles **não** permitem facilmente que o **JavaScript** os acesse.
@ -121,7 +121,7 @@ Se você capturar uma exceção com `except` em uma dependência que utilize `yi
Neste caso, o cliente irá ver uma resposta *HTTP 500 Internal Server Error* como deveria acontecer, já que não estamos levantando nenhuma `HTTPException` ou coisa parecida, mas o servidor **não terá nenhum log** ou qualquer outra indicação de qual foi o erro. 😱
Neste caso, o cliente irá ver uma resposta *HTTP 500 Internal Server Error* como deveria acontecer, já que não estamos levantando nenhuma `HTTPException` ou coisa parecida, mas o servidor **não terá nenhum log** ou qualquer outra indicação de qual foi o erro. 😱
### Sempre levante (`raise`) em Dependências com `yield` e `except` { #always-raise-in-dependencies-with-yield-and-except }
### Sempre `raise` em Dependências com `yield` e `except` { #always-raise-in-dependencies-with-yield-and-except }
Se você capturar uma exceção em uma dependência com `yield`, a menos que você esteja levantando outra `HTTPException` ou coisa parecida, **você deve relançar a exceção original**.
Se você capturar uma exceção em uma dependência com `yield`, a menos que você esteja levantando outra `HTTPException` ou coisa parecida, **você deve relançar a exceção original**.
@ -170,7 +170,7 @@ participant tasks as Tarefas de Background
end
end
```
```
/// info | Informação
/// note | Nota
Apenas **uma resposta** será enviada para o cliente. Ela pode ser uma das respostas de erro, ou então a resposta da *operação de rota*.
Apenas **uma resposta** será enviada para o cliente. Ela pode ser uma das respostas de erro, ou então a resposta da *operação de rota*.
Assim, você escreve um código compartilhado apenas uma vez e o **FastAPI** se encarrega de chamá-lo em suas *operações de rota*.
Assim, você escreve um código compartilhado apenas uma vez e o **FastAPI** se encarrega de chamá-lo em suas *operações de rota*.
/// check | Verifique
/// tip | Dica
Perceba que você não precisa criar uma classe especial e enviar a dependência para algum outro lugar em que o **FastAPI** a "registre" ou realize qualquer operação similar.
Perceba que você não precisa criar uma classe especial e enviar a dependência para algum outro lugar em que o **FastAPI** a "registre" ou realize qualquer operação similar.
@ -136,7 +136,7 @@ Mas como o **FastAPI** se baseia em convenções do Python, incluindo `Annotated
///
///
As dependências continuarão funcionando como esperado, e a **melhor parte** é que a **informação sobre o tipo é preservada**, o que signfica que seu editor de texto ainda irá incluir **preenchimento automático**, **visualização de erros**, etc. O mesmo vale para ferramentas como `mypy`.
As dependências continuarão funcionando como esperado, e a **melhor parte** é que a **informação sobre o tipo é preservada**, o que significa que seu editor de texto ainda irá incluir **preenchimento automático**, **erros em linha**, etc. O mesmo vale para ferramentas como `mypy`.
Isso é especialmente útil para uma **base de código grande** onde **as mesmas dependências** são utilizadas repetidamente em **muitas *operações de rota***.
Isso é especialmente útil para uma **base de código grande** onde **as mesmas dependências** são utilizadas repetidamente em **muitas *operações de rota***.
@ -152,7 +152,7 @@ Não faz diferença. O **FastAPI** sabe o que fazer.
/// note | Nota
/// note | Nota
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#in-a-hurry) a sessão acerca de `async` e `await` na documentação.
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#in-a-hurry) a seção acerca de `async` e `await` na documentação.
### `fastapi dev` com path { #fastapi-dev-with-path }
### `fastapi dev` com path ou com a opção de CLI `--entrypoint`{ #fastapi-dev-with-path-or-with-entrypoint-cli-option }
Você também pode passar o path do arquivo para o comando `fastapi dev`, e ele vai deduzir o objeto de aplicação FastAPI a ser usado:
Você também pode passar o path do arquivo para o comando `fastapi dev`, e ele vai deduzir o objeto de aplicação FastAPI a ser usado:
@ -188,29 +188,19 @@ Você também pode passar o path do arquivo para o comando `fastapi dev`, e ele
$ fastapi dev main.py
$ fastapi dev main.py
```
```
Mas você teria que lembrar de passar o path correto toda vez que chamar o comando `fastapi`.
Ou você também pode passar a opção `--entrypoint` para o comando `fastapi dev`:
Além disso, outras ferramentas podem não conseguir encontrá-la, por exemplo, a [Extensão do VS Code](../editor-support.md) ou a [FastAPI Cloud](https://fastapicloud.com), então é recomendado usar o `entrypoint` no `pyproject.toml`.
### 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 [FastAPI Cloud](https://fastapicloud.com); 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:
<divclass="termy">
```console
```console
$ fastapi login
$ fastapi dev --entrypoint main:app
You are logged in to FastAPI Cloud 🚀
```
```
</div>
Mas você teria que lembrar de passar o path\entrypoint correto toda vez que chamar o comando `fastapi`.
Além disso, outras ferramentas podem não conseguir encontrá-la, por exemplo, a [Extensão do VS Code](../editor-support.md) ou a [FastAPI Cloud](https://fastapicloud.com), então é recomendado usar o `entrypoint` no `pyproject.toml`.
Em seguida, faça o deploy da sua aplicação:
### 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 [FastAPI Cloud](https://fastapicloud.com) com um único comando. 🚀
<divclass="termy">
<divclass="termy">
@ -226,6 +216,8 @@ Deploying to FastAPI Cloud...
</div>
</div>
A CLI detectará automaticamente sua aplicação FastAPI e a fará o deploy na nuvem. Se você não estiver autenticado, o seu navegador será aberto para concluir o processo de autenticação.
É isso! Agora você pode acessar sua aplicação nessa URL. ✨
É 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 }
@ -270,7 +262,7 @@ https://example.com/items/foo
/items/foo
/items/foo
```
```
/// info | Informação
/// note | Nota
Um "path" também é comumente chamado de "endpoint" ou de "rota".
Um "path" também é comumente chamado de "endpoint" ou de "rota".
@ -322,7 +314,7 @@ O `@app.get("/")` diz ao **FastAPI** que a função logo abaixo é responsável
* o path `/`
* o path `/`
* usando uma <dfntitle="um método HTTP GET"><code>get</code> operação</dfn>
* usando uma <dfntitle="um método HTTP GET"><code>get</code> operação</dfn>
/// info | Informações sobre `@decorator`
/// note | Informações sobre `@decorator`
Essa sintaxe `@alguma_coisa` em Python é chamada de "decorador".
Essa sintaxe `@alguma_coisa` em Python é chamada de "decorador".
@ -20,7 +20,7 @@ Você pode declarar o tipo de um parâmetro de path na função, usando as anota
Neste caso, `item_id` é declarado como um `int`.
Neste caso, `item_id` é declarado como um `int`.
/// check | Verifique
/// tip | Dica
Isso fornecerá suporte do editor dentro da sua função, com verificações de erros, preenchimento automático, etc.
Isso fornecerá suporte do editor dentro da sua função, com verificações de erros, preenchimento automático, etc.
///
///
@ -32,7 +32,7 @@ Se você executar este exemplo e abrir seu navegador em [http://127.0.0.1:8000/i
{"item_id":3}
{"item_id":3}
```
```
/// check | Verifique
/// tip | Dica
Perceba que o valor que sua função recebeu (e retornou) é `3`, como um `int` do Python, não uma string `"3"`.
Perceba que o valor que sua função recebeu (e retornou) é `3`, como um `int` do Python, não uma string `"3"`.
Então, com essa declaração de tipo, o **FastAPI** fornece <dfntitle="convertendo a string que vem de um request HTTP em dados Python">"parsing"</dfn> automático do request.
Então, com essa declaração de tipo, o **FastAPI** fornece <dfntitle="convertendo a string que vem de um request HTTP em dados Python">"parsing"</dfn> automático do request.
@ -62,7 +62,7 @@ porque o parâmetro de path `item_id` tinha o valor `"foo"`, que não é um `int
O mesmo erro apareceria se você fornecesse um `float` em vez de um `int`, como em: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
O mesmo erro apareceria se você fornecesse um `float` em vez de um `int`, como em: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
/// check | Verifique
/// tip | Dica
Então, com a mesma declaração de tipo do Python, o **FastAPI** fornece validação de dados.
Então, com a mesma declaração de tipo do Python, o **FastAPI** fornece validação de dados.
Observe que o erro também declara claramente exatamente o ponto onde a validação não passou.
Observe que o erro também declara claramente exatamente o ponto onde a validação não passou.
@ -76,7 +76,7 @@ E quando você abrir seu navegador em [http://127.0.0.1:8000/docs](http://127.0.
<imgsrc="/img/tutorial/path-params/image01.png">
<imgsrc="/img/tutorial/path-params/image01.png">
/// check | Verifique
/// tip | Dica
Novamente, apenas com a mesma declaração de tipo do Python, o **FastAPI** fornece documentação automática e interativa (integrando o Swagger UI).
Novamente, apenas com a mesma declaração de tipo do Python, o **FastAPI** fornece documentação automática e interativa (integrando o Swagger UI).
Observe que o parâmetro de path está declarado como um inteiro.
Observe que o parâmetro de path está declarado como um inteiro.
Isso está disponível com a versão 2 do Pydantic ou superior. 😎
Isso está disponível com a versão 2 do Pydantic ou superior. 😎
@ -414,7 +414,7 @@ Percebeu? Uma string usando `value.startswith()` pode receber uma tupla, e verif
Com `data.items()` obtemos um <dfntitle="Algo que podemos iterar com um laço for, como uma list, set, etc.">objeto iterável</dfn> com tuplas contendo a chave e o valor de cada item do dicionário.
Com `data.items()` obtemos um <dfntitle="Algo que podemos iterar com um laço for, como uma list, set, etc.">objeto iterável</dfn> com tuplas contendo a chave e o valor de cada item do dicionário.
Convertimos esse objeto iterável em uma `list` adequada com `list(data.items())`.
Convertemos esse objeto iterável em uma `list` adequada com `list(data.items())`.
Em seguida, com `random.choice()` podemos obter um valor aleatório da lista, então obtemos uma tupla com `(id, name)`. Será algo como `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Em seguida, com `random.choice()` podemos obter um valor aleatório da lista, então obtemos uma tupla com `(id, name)`. Será algo como `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
@ -65,7 +65,7 @@ Da mesma forma, você pode declarar parâmetros de consulta opcionais, definindo
Nesse caso, o parâmetro da função `q` será opcional, e `None` será o padrão.
Nesse caso, o parâmetro da função `q` será opcional, e `None` será o padrão.
/// check | Verifique
/// tip | Dica
Você também pode notar que o **FastAPI** é esperto o suficiente para perceber que o parâmetro da rota `item_id` é um parâmetro da rota, e `q` não é, portanto, `q` é o parâmetro de consulta.
Você também pode notar que o **FastAPI** é esperto o suficiente para perceber que o parâmetro da rota `item_id` é um parâmetro da rota, e `q` não é, portanto, `q` é o parâmetro de consulta.
Você pode utilizar **Modelos Pydantic** para declarar **campos de formulários** no FastAPI.
Você pode utilizar **Modelos Pydantic** para declarar **campos de formulários** no FastAPI.
/// info | Informação
/// note | Nota
Para utilizar formulários, instale primeiramente o [`python-multipart`](https://github.com/Kludex/python-multipart).
Para utilizar formulários, instale primeiramente o [`python-multipart`](https://github.com/Kludex/python-multipart).
@ -28,7 +28,7 @@ Você precisa apenas declarar um **modelo Pydantic** com os campos que deseja re
O **FastAPI** irá **extrair** as informações para **cada campo** dos **dados do formulário** na requisição e dar para você o modelo Pydantic que você definiu.
O **FastAPI** irá **extrair** as informações para **cada campo** dos **dados do formulário** na requisição e dar para você o modelo Pydantic que você definiu.
## Confira os Documentos { #check-the-docs }
## Confira a Documentação { #check-the-docs }
Você pode verificar na UI de documentação em `/docs`:
Você pode verificar na UI de documentação em `/docs`:
Quando você precisar receber campos de formulário em vez de JSON, você pode usar `Form`.
Quando você precisar receber campos de formulário em vez de JSON, você pode usar `Form`.
/// info | Informação
/// note | Nota
Para usar formulários, primeiro instale [`python-multipart`](https://github.com/Kludex/python-multipart).
Para usar formulários, primeiro instale [`python-multipart`](https://github.com/Kludex/python-multipart).
@ -32,7 +32,7 @@ A <dfn title="especificação">especificação</dfn> exige que os campos sejam e
Com `Form` você pode declarar as mesmas configurações que com `Body` (e `Query`, `Path`, `Cookie`), incluindo validação, exemplos, um alias (por exemplo, `user-name` em vez de `username`), etc.
Com `Form` você pode declarar as mesmas configurações que com `Body` (e `Query`, `Path`, `Cookie`), incluindo validação, exemplos, um alias (por exemplo, `user-name` em vez de `username`), etc.
/// info | Informação
/// note | Nota
`Form` é uma classe que herda diretamente de `Body`.
`Form` é uma classe que herda diretamente de `Body`.
@ -24,7 +24,7 @@ Por exemplo, você poderia usá-la para adicionar metadados para uma interface d
///
///
/// info | Informação
/// note | Nota
O OpenAPI 3.1.0 (usado desde o FastAPI 0.99.0) adicionou suporte a `examples`, que faz parte do padrão **JSON Schema**.
O OpenAPI 3.1.0 (usado desde o FastAPI 0.99.0) adicionou suporte a `examples`, que faz parte do padrão **JSON Schema**.
@ -155,7 +155,7 @@ O OpenAPI também adicionou os campos `example` e `examples` a outras partes da
* `File()`
* `File()`
* `Form()`
* `Form()`
/// info | Informação
/// note | Nota
Esse parâmetro antigo `examples` específico do OpenAPI agora é `openapi_examples` desde o FastAPI `0.103.0`.
Esse parâmetro antigo `examples` específico do OpenAPI agora é `openapi_examples` desde o FastAPI `0.103.0`.
@ -171,7 +171,7 @@ E agora esse novo campo `examples` tem precedência sobre o antigo campo único
Esse novo campo `examples` no JSON Schema é **apenas uma `list`** de exemplos, não um dict com metadados extras como nos outros lugares do OpenAPI (descritos acima).
Esse novo campo `examples` no JSON Schema é **apenas uma `list`** de exemplos, não um dict com metadados extras como nos outros lugares do OpenAPI (descritos acima).
/// info | Informação
/// note | Nota
Mesmo após o lançamento do OpenAPI 3.1.0 com essa nova integração mais simples com o JSON Schema, por um tempo o Swagger UI, a ferramenta que fornece a documentação automática, não suportava OpenAPI 3.1.0 (passou a suportar desde a versão 5.0.0 🎉).
Mesmo após o lançamento do OpenAPI 3.1.0 com essa nova integração mais simples com o JSON Schema, por um tempo o Swagger UI, a ferramenta que fornece a documentação automática, não suportava OpenAPI 3.1.0 (passou a suportar desde a versão 5.0.0 🎉).
@ -24,7 +24,7 @@ Copie o exemplo em um arquivo `main.py`:
## Execute-o { #run-it }
## Execute-o { #run-it }
/// info | Informação
/// note | Nota
O pacote [`python-multipart`](https://github.com/Kludex/python-multipart) é instalado automaticamente com o **FastAPI** quando você executa o comando `pip install "fastapi[standard]"`.
O pacote [`python-multipart`](https://github.com/Kludex/python-multipart) é instalado automaticamente com o **FastAPI** quando você executa o comando `pip install "fastapi[standard]"`.
@ -60,7 +60,7 @@ Você verá algo deste tipo:
<imgsrc="/img/tutorial/security/image01.png">
<imgsrc="/img/tutorial/security/image01.png">
/// check | Botão Autorizar!
/// tip | Botão Autorizar!
Você já tem um novo botão 'Authorize'.
Você já tem um novo botão 'Authorize'.
@ -118,7 +118,7 @@ O **FastAPI** fornece várias ferramentas, em diferentes níveis de abstração,
Neste exemplo, vamos usar **OAuth2**, com o fluxo **Password**, usando um token **Bearer**. Fazemos isso usando a classe `OAuth2PasswordBearer`.
Neste exemplo, vamos usar **OAuth2**, com o fluxo **Password**, usando um token **Bearer**. Fazemos isso usando a classe `OAuth2PasswordBearer`.
/// info | Informação
/// note | Nota
Um token "bearer" não é a única opção.
Um token "bearer" não é a única opção.
@ -148,7 +148,7 @@ Esse parâmetro não cria aquele endpoint/operação de rota, mas declara que a
Em breve também criaremos a operação de rota real.
Em breve também criaremos a operação de rota real.
/// info | Informação
/// note | Nota
Se você é um "Pythonista" muito rigoroso, pode não gostar do estilo do nome do parâmetro `tokenUrl` em vez de `token_url`.
Se você é um "Pythonista" muito rigoroso, pode não gostar do estilo do nome do parâmetro `tokenUrl` em vez de `token_url`.
@ -176,7 +176,7 @@ Essa dependência fornecerá uma `str` que é atribuída ao parâmetro `token` d
O **FastAPI** saberá que pode usar essa dependência para definir um "esquema de segurança" no esquema OpenAPI (e na documentação automática da API).
O **FastAPI** saberá que pode usar essa dependência para definir um "esquema de segurança" no esquema OpenAPI (e na documentação automática da API).
/// info | Detalhes Técnicos
/// note | Detalhes Técnicos
O **FastAPI** saberá que pode usar a classe `OAuth2PasswordBearer` (declarada em uma dependência) para definir o esquema de segurança no OpenAPI porque ela herda de `fastapi.security.oauth2.OAuth2`, que por sua vez herda de `fastapi.security.base.SecurityBase`.
O **FastAPI** saberá que pode usar a classe `OAuth2PasswordBearer` (declarada em uma dependência) para definir o esquema de segurança no OpenAPI porque ela herda de `fastapi.security.oauth2.OAuth2`, que por sua vez herda de `fastapi.security.base.SecurityBase`.
@ -18,7 +18,7 @@ Da mesma forma que usamos o Pydantic para declarar corpos, podemos usá-lo em qu
## Criar uma dependência `get_current_user` { #create-a-get-current-user-dependency }
## Criar uma dependência `get_current_user` { #create-a-get-current-user-dependency }
Vamos criar uma dependência chamada `get_current_user`.
Vamos criar uma dependência `get_current_user`.
Lembra que as dependências podem ter subdependências?
Lembra que as dependências podem ter subdependências?
@ -52,7 +52,7 @@ Aqui, o **FastAPI** não ficará confuso porque você está usando `Depends`.
///
///
/// check | Verifique
/// tip | Dica
A forma como esse sistema de dependências foi projetado nos permite ter diferentes dependências (diferentes "dependables") que retornam um modelo `User`.
A forma como esse sistema de dependências foi projetado nos permite ter diferentes dependências (diferentes "dependables") que retornam um modelo `User`.
Se você pretente utilizar algoritmos de assinatura digital como o RSA ou o ECDSA, você deve instalar a dependência da biblioteca de criptografia `pyjwt[crypto]`.
Se você pretende utilizar algoritmos de assinatura digital como o RSA ou o ECDSA, você deve instalar a dependência da biblioteca de criptografia `pyjwt[crypto]`.
Você pode ler mais sobre isso na [documentação de instalação do PyJWT](https://pyjwt.readthedocs.io/en/latest/installation.html).
Você pode ler mais sobre isso na [documentação de instalação do PyJWT](https://pyjwt.readthedocs.io/en/latest/installation.html).
@ -213,7 +213,7 @@ Usando as credenciais:
Username: `johndoe`
Username: `johndoe`
Password: `secret`
Password: `secret`
/// check | Verifique
/// tip | Dica
Observe que em nenhuma parte do código está a senha em texto puro "`secret`", nós temos apenas o hash.
Observe que em nenhuma parte do código está a senha em texto puro "`secret`", nós temos apenas o hash.
@ -4,7 +4,7 @@ Agora vamos construir a partir do capítulo anterior e adicionar as partes que f
## Obtenha o `username` e a `password` { #get-the-username-and-password }
## Obtenha o `username` e a `password` { #get-the-username-and-password }
É utilizado o utils de segurança da **FastAPI** para obter o `username` e a `password`.
Vamos usar os utilitários de segurança da **FastAPI** para obter o `username` e a `password`.
OAuth2 especifica que ao usar o "password flow" (fluxo de senha), que estamos usando, o cliente/usuário deve enviar os campos `username` e `password` como dados do formulário.
OAuth2 especifica que ao usar o "password flow" (fluxo de senha), que estamos usando, o cliente/usuário deve enviar os campos `username` e `password` como dados do formulário.
@ -32,7 +32,7 @@ Normalmente são usados para declarar permissões de segurança específicas, po
* `instagram_basic` é usado pelo Facebook e Instagram.
* `instagram_basic` é usado pelo Facebook e Instagram.
* `https://www.googleapis.com/auth/drive` é usado pelo Google.
* `https://www.googleapis.com/auth/drive` é usado pelo Google.
/// info | Informação
/// note | Nota
No OAuth2, um "scope" é apenas uma string que declara uma permissão específica necessária.
No OAuth2, um "scope" é apenas uma string que declara uma permissão específica necessária.
@ -72,7 +72,7 @@ Se você precisar aplicá-lo, use `OAuth2PasswordRequestFormStrict` em vez de `O
* Um `client_id` opcional (não precisamos dele em nosso exemplo).
* Um `client_id` opcional (não precisamos dele em nosso exemplo).
* Um `client_secret` opcional (não precisamos dele em nosso exemplo).
* Um `client_secret` opcional (não precisamos dele em nosso exemplo).
/// info | Informação
/// note | Nota
O `OAuth2PasswordRequestForm` não é uma classe especial para **FastAPI** como é `OAuth2PasswordBearer`.
O `OAuth2PasswordRequestForm` não é uma classe especial para **FastAPI** como é `OAuth2PasswordBearer`.
@ -144,8 +144,7 @@ UserInDB(
)
)
```
```
/// note | Nota
/// info | Informação
Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Extra Models**](../extra-models.md#about-user-in-dict).
Para uma explicação mais completa de `**user_dict`, verifique [a documentação para **Extra Models**](../extra-models.md#about-user-in-dict).
@ -173,7 +172,7 @@ Mas, por enquanto, vamos nos concentrar nos detalhes específicos de que precisa
/// tip | Dica
/// tip | Dica
Pela especificação, você deve retornar um JSON com um `access_token` e um `token_type`, o mesmo que neste exemplo.
Pela especificação, você deveria retornar um JSON com um `access_token` e um `token_type`, o mesmo que neste exemplo.
Isso é algo que você mesmo deve fazer em seu código e certifique-se de usar essas chaves JSON.
Isso é algo que você mesmo deve fazer em seu código e certifique-se de usar essas chaves JSON.
@ -197,7 +196,7 @@ Portanto, em nosso endpoint, só obteremos um usuário se o usuário existir, ti
@ -4,7 +4,7 @@ Você pode transmitir dados para o cliente usando Server-Sent Events (SSE).
Isso é semelhante a [Stream de JSON Lines](stream-json-lines.md), mas usa o formato `text/event-stream`, que é suportado nativamente pelos navegadores com a [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
Isso é semelhante a [Stream de JSON Lines](stream-json-lines.md), mas usa o formato `text/event-stream`, que é suportado nativamente pelos navegadores com a [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
Você pode ter uma sequência de dados que deseja enviar em um "**Stream**"; é possível fazer isso com **JSON Lines**.
Você pode ter uma sequência de dados que deseja enviar em um "**Stream**"; é possível fazer isso com **JSON Lines**.
/// info | Informação
/// note | Nota
Adicionado no FastAPI 0.134.0.
Adicionado no FastAPI 0.134.0.
@ -48,7 +48,7 @@ Uma response teria um tipo de conteúdo `application/jsonl` (em vez de `applicat
É muito semelhante a um array JSON (equivalente a uma list do Python), mas em vez de estar envolto em `[]` e ter `,` entre os itens, há **um objeto JSON por linha**, separados por um caractere de nova linha.
É muito semelhante a um array JSON (equivalente a uma list do Python), mas em vez de estar envolto em `[]` e ter `,` entre os itens, há **um objeto JSON por linha**, separados por um caractere de nova linha.
/// info | Informação
/// note | Nota
O ponto importante é que sua aplicação poderá produzir cada linha em sequência, enquanto o cliente consome as anteriores.
O ponto importante é que sua aplicação poderá produzir cada linha em sequência, enquanto o cliente consome as anteriores.
@ -8,7 +8,7 @@ Com ele, você pode usar o [pytest](https://docs.pytest.org/) diretamente com **
## Usando `TestClient` { #using-testclient }
## Usando `TestClient` { #using-testclient }
/// info | Informação
/// note | Nota
Para usar o `TestClient`, primeiro instale [`httpx`](https://www.python-httpx.org).
Para usar o `TestClient`, primeiro instale [`httpx`](https://www.python-httpx.org).
@ -142,7 +142,7 @@ Por exemplo:
Para mais informações sobre como passar dados para o backend (usando `httpx` ou `TestClient`), consulte a [documentação do HTTPX](https://www.python-httpx.org).
Para mais informações sobre como passar dados para o backend (usando `httpx` ou `TestClient`), consulte a [documentação do HTTPX](https://www.python-httpx.org).
/// info | Informação
/// note | Nota
Observe que o `TestClient` recebe dados que podem ser convertidos para JSON, não para modelos Pydantic.
Observe que o `TestClient` recebe dados que podem ser convertidos para JSON, não para modelos Pydantic.