mirror of https://github.com/tiangolo/fastapi.git
🌐 Update translations for pt (add-missing) (#15157)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
2742546af6
commit
06cdff4488
|
|
@ -0,0 +1,63 @@
|
|||
# JSON com bytes em Base64 { #json-with-bytes-as-base64 }
|
||||
|
||||
Se sua aplicação precisa receber e enviar dados JSON, mas você precisa incluir dados binários nele, você pode codificá-los em base64.
|
||||
|
||||
## Base64 vs Arquivos { #base64-vs-files }
|
||||
|
||||
Primeiro, considere se você pode usar [Arquivos na request](../tutorial/request-files.md) para fazer upload de dados binários e [Response personalizada - FileResponse](./custom-response.md#fileresponse--fileresponse-) para enviar dados binários, em vez de codificá-los em JSON.
|
||||
|
||||
JSON só pode conter strings codificadas em UTF-8, portanto não pode conter bytes puros.
|
||||
|
||||
Base64 pode codificar dados binários em strings, mas, para isso, precisa usar mais caracteres do que os dados binários originais; assim, normalmente é menos eficiente do que arquivos comuns.
|
||||
|
||||
Use base64 apenas se realmente precisar incluir dados binários em JSON e não puder usar arquivos para isso.
|
||||
|
||||
## Pydantic `bytes` { #pydantic-bytes }
|
||||
|
||||
Você pode declarar um modelo Pydantic com campos `bytes` e então usar `val_json_bytes` na configuração do modelo para indicar que deve usar base64 para *validar* os dados JSON de entrada; como parte dessa validação, ele decodificará a string base64 em bytes.
|
||||
|
||||
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}
|
||||
|
||||
Se você verificar a `/docs`, verá que o campo `data` espera bytes codificados em base64:
|
||||
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/json-base64-bytes/image01.png">
|
||||
</div>
|
||||
|
||||
Você poderia enviar uma request assim:
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "Some data",
|
||||
"data": "aGVsbG8="
|
||||
}
|
||||
```
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
`aGVsbG8=` é a codificação base64 de `hello`.
|
||||
|
||||
///
|
||||
|
||||
Em seguida, o Pydantic decodificará a string base64 e fornecerá os bytes originais no campo `data` do modelo.
|
||||
|
||||
Você receberá uma response assim:
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "Some data",
|
||||
"content": "hello"
|
||||
}
|
||||
```
|
||||
|
||||
## Pydantic `bytes` para dados de saída { #pydantic-bytes-for-output-data }
|
||||
|
||||
Você também pode usar campos `bytes` com `ser_json_bytes` na configuração do modelo para dados de saída, e o Pydantic irá *serializar* os bytes como base64 ao gerar a response JSON.
|
||||
|
||||
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}
|
||||
|
||||
## Pydantic `bytes` para dados de entrada e saída { #pydantic-bytes-for-input-and-output-data }
|
||||
|
||||
E, claro, você pode usar o mesmo modelo configurado para usar base64 para lidar tanto com a entrada (*validar*) com `val_json_bytes` quanto com a saída (*serializar*) com `ser_json_bytes` ao receber e enviar dados JSON.
|
||||
|
||||
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
# Transmitir dados { #stream-data }
|
||||
|
||||
Se você quer transmitir dados que podem ser estruturados como JSON, você deveria [Transmitir JSON Lines](../tutorial/stream-json-lines.md).
|
||||
|
||||
Mas se você quer transmitir dados binários puros ou strings, veja como fazer.
|
||||
|
||||
/// info | Informação
|
||||
|
||||
Adicionado no FastAPI 0.134.0.
|
||||
|
||||
///
|
||||
|
||||
## Casos de uso { #use-cases }
|
||||
|
||||
Você pode usar isto para transmitir strings puras, por exemplo diretamente da saída de um serviço de AI LLM.
|
||||
|
||||
Você também pode usá-lo para transmitir arquivos binários grandes, enviando cada bloco de dados à medida que o lê, sem precisar carregar tudo na memória de uma vez.
|
||||
|
||||
Você também pode transmitir vídeo ou áudio desta forma; pode até ser gerado enquanto você processa e envia.
|
||||
|
||||
## Um `StreamingResponse` com `yield` { #a-streamingresponse-with-yield }
|
||||
|
||||
Se você declarar `response_class=StreamingResponse` na sua função de operação de rota, você pode usar `yield` para enviar cada bloco de dados em sequência.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
|
||||
|
||||
O FastAPI entregará cada bloco de dados para `StreamingResponse` como está, não tentará convertê-lo para JSON nem nada semelhante.
|
||||
|
||||
### Funções de operação de rota não assíncronas { #non-async-path-operation-functions }
|
||||
|
||||
Você também pode usar funções `def` normais (sem `async`) e usar `yield` da mesma forma.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *}
|
||||
|
||||
### Sem anotação { #no-annotation }
|
||||
|
||||
Você não precisa declarar a anotação de tipo de retorno para transmitir dados binários.
|
||||
|
||||
Como o FastAPI não tentará converter os dados para JSON com Pydantic nem serializá-los de nenhuma forma, neste caso a anotação de tipo serve apenas para seu editor e ferramentas; ela não será usada pelo FastAPI.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
|
||||
|
||||
Isso também significa que, com `StreamingResponse`, você tem a liberdade e a responsabilidade de produzir e codificar os bytes exatamente como precisam ser enviados, independentemente das anotações de tipo. 🤓
|
||||
|
||||
### Transmitir bytes { #stream-bytes }
|
||||
|
||||
Um dos principais casos de uso é transmitir `bytes` em vez de strings; você pode fazer isso sem problemas.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *}
|
||||
|
||||
## Um `PNGStreamingResponse` personalizado { #a-custom-pngstreamingresponse }
|
||||
|
||||
Nos exemplos acima, os bytes eram transmitidos, mas a resposta não tinha um cabeçalho `Content-Type`, então o cliente não sabia que tipo de dado estava recebendo.
|
||||
|
||||
Você pode criar uma subclasse personalizada de `StreamingResponse` que define o cabeçalho `Content-Type` para o tipo de dado que você está transmitindo.
|
||||
|
||||
Por exemplo, você pode criar um `PNGStreamingResponse` que define o cabeçalho `Content-Type` como `image/png` usando o atributo `media_type`:
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
|
||||
|
||||
Em seguida, você pode usar essa nova classe em `response_class=PNGStreamingResponse` na sua função de operação de rota:
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
|
||||
|
||||
### Simular um arquivo { #simulate-a-file }
|
||||
|
||||
Neste exemplo, estamos simulando um arquivo com `io.BytesIO`, que é um objeto semelhante a arquivo que vive somente na memória, mas nos permite usar a mesma interface.
|
||||
|
||||
Por exemplo, podemos iterar sobre ele para consumir seu conteúdo, como faríamos com um arquivo.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *}
|
||||
|
||||
/// note | Detalhes Técnicos
|
||||
|
||||
As outras duas variáveis, `image_base64` e `binary_image`, são uma imagem codificada em Base64 e depois convertida para bytes, para então passá-la para `io.BytesIO`.
|
||||
|
||||
Apenas para que possa viver no mesmo arquivo deste exemplo e você possa copiar e executar como está. 🥚
|
||||
|
||||
///
|
||||
|
||||
Ao usar um bloco `with`, garantimos que o objeto semelhante a arquivo seja fechado após a função geradora (a função com `yield`) terminar. Ou seja, após terminar de enviar a resposta.
|
||||
|
||||
Isso não seria tão importante neste exemplo específico porque é um arquivo falso em memória (com `io.BytesIO`), mas com um arquivo real, seria importante garantir que o arquivo fosse fechado ao final do trabalho.
|
||||
|
||||
### Arquivos e async { #files-and-async }
|
||||
|
||||
Na maioria dos casos, objetos semelhantes a arquivo não são compatíveis com async e await por padrão.
|
||||
|
||||
Por exemplo, eles não têm `await file.read()`, nem `async for chunk in file`.
|
||||
|
||||
E, em muitos casos, lê-los seria uma operação bloqueante (que poderia bloquear o loop de eventos), pois são lidos do disco ou da rede.
|
||||
|
||||
/// info | Informação
|
||||
|
||||
O exemplo acima é, na verdade, uma exceção, porque o objeto `io.BytesIO` já está em memória, então lê-lo não bloqueará nada.
|
||||
|
||||
Mas, em muitos casos, ler um arquivo ou um objeto semelhante a arquivo bloquearia.
|
||||
|
||||
///
|
||||
|
||||
Para evitar bloquear o loop de eventos, você pode simplesmente declarar a função de operação de rota com `def` normal em vez de `async def`. Assim, o FastAPI a executará em um worker de threadpool, evitando bloquear o loop principal.
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Se você precisar chamar código bloqueante de dentro de uma função assíncrona ou uma função assíncrona de dentro de uma função bloqueante, você poderia usar o [Asyncer](https://asyncer.tiangolo.com), uma biblioteca irmã do FastAPI.
|
||||
|
||||
///
|
||||
|
||||
### `yield from` { #yield-from }
|
||||
|
||||
Quando você está iterando sobre algo, como um objeto semelhante a arquivo, e faz `yield` para cada item, você também pode usar `yield from` para produzir cada item diretamente e pular o loop `for`.
|
||||
|
||||
Isso não é particular do FastAPI, é apenas Python, mas é um truque útil para conhecer. 😎
|
||||
|
||||
{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
# 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.
|
||||
|
||||
## Risco de CSRF { #csrf-risk }
|
||||
|
||||
Esse comportamento padrão oferece proteção contra uma classe de ataques de **Cross-Site Request Forgery (CSRF)** em um cenário muito específico.
|
||||
|
||||
Esses ataques exploram o fato de que navegadores permitem que scripts enviem requisições sem fazer qualquer verificação de preflight de CORS quando:
|
||||
|
||||
- não têm um cabeçalho `Content-Type` (por exemplo, usando `fetch()` com um corpo `Blob`)
|
||||
- e não enviam nenhuma credencial de autenticação.
|
||||
|
||||
Esse tipo de ataque é relevante principalmente quando:
|
||||
|
||||
- a aplicação está em execução localmente (por exemplo, em `localhost`) ou em uma rede interna
|
||||
- e a aplicação não tem autenticação, pressupondo que qualquer requisição da mesma rede é confiável.
|
||||
|
||||
## Exemplo de Ataque { #example-attack }
|
||||
|
||||
Imagine que você desenvolve uma forma de executar um agente de IA local.
|
||||
|
||||
Ele fornece uma API em
|
||||
|
||||
```
|
||||
http://localhost:8000/v1/agents/multivac
|
||||
```
|
||||
|
||||
Há também um frontend em
|
||||
|
||||
```
|
||||
http://localhost:8000
|
||||
```
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Observe que ambos têm o mesmo host.
|
||||
|
||||
///
|
||||
|
||||
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.
|
||||
|
||||
Então um de seus usuários poderia instalá-lo e executá-lo localmente.
|
||||
|
||||
Em seguida, poderia abrir um site malicioso, por exemplo:
|
||||
|
||||
```
|
||||
https://evilhackers.example.com
|
||||
```
|
||||
|
||||
E esse site malicioso envia requisições usando `fetch()` com um corpo `Blob` para a API local em
|
||||
|
||||
```
|
||||
http://localhost:8000/v1/agents/multivac
|
||||
```
|
||||
|
||||
Mesmo que o host do site malicioso e o da aplicação local sejam diferentes, o navegador não acionará uma requisição preflight de CORS porque:
|
||||
|
||||
- Está em execução sem autenticação, não precisa enviar credenciais.
|
||||
- O navegador acha que não está enviando JSON (devido à falta do cabeçalho `Content-Type`).
|
||||
|
||||
Então o site malicioso poderia fazer o agente de IA local enviar mensagens raivosas ao ex-chefe do usuário... ou pior. 😅
|
||||
|
||||
## Internet Aberta { #open-internet }
|
||||
|
||||
Se sua aplicação está na Internet aberta, você não “confiaria na rede” nem deixaria qualquer pessoa enviar requisições privilegiadas sem autenticação.
|
||||
|
||||
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ê.
|
||||
|
||||
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 }
|
||||
|
||||
Se você precisa dar suporte a clientes que não enviam um cabeçalho `Content-Type`, você pode desativar a verificação estrita definindo `strict_content_type=False`:
|
||||
|
||||
{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *}
|
||||
|
||||
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
|
||||
|
||||
Esse comportamento e configuração foram adicionados no FastAPI 0.132.0.
|
||||
|
||||
///
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Suporte a Editores { #editor-support }
|
||||
|
||||
A [FastAPI Extension](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) oficial melhora seu fluxo de trabalho de desenvolvimento com descoberta e navegação de *operação de rota*, além de implantação no FastAPI Cloud e transmissão ao vivo de logs.
|
||||
|
||||
Para mais detalhes sobre a extensão, consulte o README no [repositório do GitHub](https://github.com/fastapi/fastapi-vscode).
|
||||
|
||||
## Configuração e Instalação { #setup-and-installation }
|
||||
|
||||
A **FastAPI Extension** está disponível para [VS Code](https://code.visualstudio.com/) e [Cursor](https://www.cursor.com/). Pode ser instalada diretamente pelo painel de Extensões de cada editor, pesquisando por "FastAPI" e selecionando a extensão publicada por **FastAPI Labs**. A extensão também funciona em editores no navegador, como [vscode.dev](https://vscode.dev) e [github.dev](https://github.dev).
|
||||
|
||||
### Descoberta da Aplicação { #application-discovery }
|
||||
|
||||
Por padrão, a extensão descobre automaticamente aplicações FastAPI no seu workspace procurando por arquivos que instanciam `FastAPI()`. Se a detecção automática não funcionar para a estrutura do seu projeto, você pode especificar um ponto de entrada via `[tool.fastapi]` em `pyproject.toml` ou pela configuração `fastapi.entryPoint` do VS Code usando notação de módulo (por exemplo, `myapp.main:app`).
|
||||
|
||||
## Funcionalidades { #features }
|
||||
|
||||
- **Explorador de Operações de Rota** - Uma visualização em árvore na barra lateral de todas as <dfn title="rotas, endpoints">*operações de rota*</dfn> da sua aplicação. Clique para ir diretamente a qualquer definição de rota ou de router.
|
||||
- **Pesquisa de Rotas** - Pesquise por path, método ou nome com <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (no macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>).
|
||||
- **Navegação com CodeLens** - Links clicáveis acima das chamadas do cliente de testes (por exemplo, `client.get('/items')`) que levam à *operação de rota* correspondente, facilitando a navegação entre testes e implementação.
|
||||
- **Implantar no FastAPI Cloud** - Implantação com um clique da sua aplicação no [FastAPI Cloud](https://fastapicloud.com/).
|
||||
- **Transmitir logs da aplicação** - Transmissão em tempo real dos logs da aplicação implantada no FastAPI Cloud, com filtragem por nível e busca de texto.
|
||||
|
||||
Se quiser se familiarizar com as funcionalidades da extensão, você pode abrir o walkthrough da extensão acessando a Paleta de Comandos (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> ou no macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>), selecionando "Welcome: Open walkthrough..." e, em seguida, escolhendo o walkthrough "Get started with FastAPI".
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
# Eventos Enviados pelo Servidor (SSE) { #server-sent-events-sse }
|
||||
|
||||
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).
|
||||
|
||||
/// info | Informação
|
||||
|
||||
Adicionado no FastAPI 0.135.0.
|
||||
|
||||
///
|
||||
|
||||
## O que são Server-Sent Events? { #what-are-server-sent-events }
|
||||
|
||||
SSE é um padrão para transmitir dados do servidor para o cliente via HTTP.
|
||||
|
||||
Cada evento é um pequeno bloco de texto com “campos” como `data`, `event`, `id` e `retry`, separados por linhas em branco.
|
||||
|
||||
Fica assim:
|
||||
|
||||
```
|
||||
data: {"name": "Portal Gun", "price": 999.99}
|
||||
|
||||
data: {"name": "Plumbus", "price": 32.99}
|
||||
|
||||
```
|
||||
|
||||
SSE é comumente usado para streaming de chat de IA, notificações em tempo real, logs e observabilidade, e outros casos em que o servidor envia atualizações para o cliente.
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Se você quiser transmitir dados binários, por exemplo vídeo ou áudio, veja o guia avançado: [Stream de Dados](../advanced/stream-data.md).
|
||||
|
||||
///
|
||||
|
||||
## Transmitir SSE com FastAPI { #stream-sse-with-fastapi }
|
||||
|
||||
Para transmitir SSE com FastAPI, use `yield` na sua função de operação de rota e defina `response_class=EventSourceResponse`.
|
||||
|
||||
Importe `EventSourceResponse` de `fastapi.sse`:
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[4,22] *}
|
||||
|
||||
Cada item produzido é codificado como JSON e enviado no campo `data:` de um evento SSE.
|
||||
|
||||
Se você declarar o tipo de retorno como `AsyncIterable[Item]`, o FastAPI o usará para validar, documentar e serializar os dados com o Pydantic.
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[10:12,23] *}
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Como o Pydantic fará a serialização no lado em **Rust**, você terá um desempenho muito maior do que se não declarar um tipo de retorno.
|
||||
|
||||
///
|
||||
|
||||
### *Funções de operação de rota* não assíncronas { #non-async-path-operation-functions }
|
||||
|
||||
Você também pode usar funções `def` normais (sem `async`) e usar `yield` da mesma forma.
|
||||
|
||||
O FastAPI garantirá a execução correta para não bloquear o event loop.
|
||||
|
||||
Como, neste caso, a função não é assíncrona, o tipo de retorno adequado seria `Iterable[Item]`:
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[28:31] hl[29] *}
|
||||
|
||||
### Sem tipo de retorno { #no-return-type }
|
||||
|
||||
Você também pode omitir o tipo de retorno. O FastAPI usará o [`jsonable_encoder`](./encoder.md) para converter os dados e enviá-los.
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[34:37] hl[35] *}
|
||||
|
||||
## `ServerSentEvent` { #serversentevent }
|
||||
|
||||
Se você precisar definir campos de SSE como `event`, `id`, `retry` ou `comment`, você pode produzir objetos `ServerSentEvent` em vez de dados simples.
|
||||
|
||||
Importe `ServerSentEvent` de `fastapi.sse`:
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial002_py310.py hl[4,26] *}
|
||||
|
||||
O campo `data` é sempre codificado como JSON. Você pode passar qualquer valor que possa ser serializado como JSON, incluindo modelos do Pydantic.
|
||||
|
||||
## Dados brutos { #raw-data }
|
||||
|
||||
Se você precisar enviar dados sem codificação JSON, use `raw_data` em vez de `data`.
|
||||
|
||||
Isto é útil para enviar texto pré-formatado, linhas de log ou valores <dfn title="um valor usado para indicar uma condição ou estado especial">"sentinela"</dfn> especiais como `[DONE]`.
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial003_py310.py hl[17] *}
|
||||
|
||||
/// note | Nota
|
||||
|
||||
`data` e `raw_data` são mutuamente exclusivos. Você só pode definir um deles em cada `ServerSentEvent`.
|
||||
|
||||
///
|
||||
|
||||
## Retomando com `Last-Event-ID` { #resuming-with-last-event-id }
|
||||
|
||||
Quando um navegador se reconecta após uma queda na conexão, ele envia o último `id` recebido no cabeçalho `Last-Event-ID`.
|
||||
|
||||
Você pode lê-lo como um parâmetro de cabeçalho e usá-lo para retomar o stream de onde o cliente parou:
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial004_py310.py hl[25,27,31] *}
|
||||
|
||||
## SSE com POST { #sse-with-post }
|
||||
|
||||
SSE funciona com qualquer método HTTP, não apenas `GET`.
|
||||
|
||||
Isso é útil para protocolos como o [MCP](https://modelcontextprotocol.io) que fazem stream de SSE via `POST`:
|
||||
|
||||
{* ../../docs_src/server_sent_events/tutorial005_py310.py hl[14] *}
|
||||
|
||||
## Detalhes Técnicos { #technical-details }
|
||||
|
||||
O FastAPI implementa algumas boas práticas de SSE prontas para uso.
|
||||
|
||||
- Enviar um comentário de keep alive `ping` a cada 15 segundos quando não houver mensagens, para evitar que alguns proxies fechem a conexão, como sugerido na [especificação HTML: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes).
|
||||
- Definir o cabeçalho `Cache-Control: no-cache` para evitar o cache do stream.
|
||||
- Definir o cabeçalho especial `X-Accel-Buffering: no` para evitar buffering em alguns proxies como o Nginx.
|
||||
|
||||
Você não precisa fazer nada, isso funciona automaticamente. 🤓
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
# Stream de JSON Lines { #stream-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
|
||||
|
||||
Adicionado no FastAPI 0.134.0.
|
||||
|
||||
///
|
||||
|
||||
## O que é um Stream? { #what-is-a-stream }
|
||||
|
||||
"**Streaming**" de dados significa que sua aplicação começará a enviar itens ao cliente sem esperar que toda a sequência esteja pronta.
|
||||
|
||||
Assim, ela envia o primeiro item, o cliente o recebe e começa a processá-lo, enquanto você ainda pode estar produzindo o próximo item.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App
|
||||
participant Client
|
||||
|
||||
App->>App: Produce Item 1
|
||||
App->>Client: Send Item 1
|
||||
App->>App: Produce Item 2
|
||||
Client->>Client: Process Item 1
|
||||
App->>Client: Send Item 2
|
||||
App->>App: Produce Item 3
|
||||
Client->>Client: Process Item 2
|
||||
App->>Client: Send Item 3
|
||||
Client->>Client: Process Item 3
|
||||
Note over App: Keeps producing...
|
||||
Note over Client: Keeps consuming...
|
||||
```
|
||||
|
||||
Pode até ser um Stream infinito, em que você continua enviando dados.
|
||||
|
||||
## JSON Lines { #json-lines }
|
||||
|
||||
Nesses casos, é comum enviar "**JSON Lines**", um formato em que você envia um objeto JSON por linha.
|
||||
|
||||
Uma response teria um tipo de conteúdo `application/jsonl` (em vez de `application/json`) e o corpo seria algo como:
|
||||
|
||||
```json
|
||||
{"name": "Plumbus", "description": "A multi-purpose household device."}
|
||||
{"name": "Portal Gun", "description": "A portal opening device."}
|
||||
{"name": "Meeseeks Box", "description": "A box that summons a Meeseeks."}
|
||||
```
|
||||
|
||||
É 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
|
||||
|
||||
O ponto importante é que sua aplicação poderá produzir cada linha em sequência, enquanto o cliente consome as anteriores.
|
||||
|
||||
///
|
||||
|
||||
/// note | Detalhes Técnicos
|
||||
|
||||
Como cada objeto JSON será separado por uma nova linha, eles não podem conter caracteres de nova linha literais em seu conteúdo, mas podem conter novas linhas com escape (`\n`), o que faz parte do padrão JSON.
|
||||
|
||||
Mas, normalmente, você não precisará se preocupar com isso, é feito automaticamente, continue lendo. 🤓
|
||||
|
||||
///
|
||||
|
||||
## Casos de uso { #use-cases }
|
||||
|
||||
Você pode usar isso para transmitir dados de um serviço de **IA LLM**, de **logs** ou **telemetria**, ou de outros tipos de dados que possam ser estruturados em itens **JSON**.
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Se você quiser transmitir dados binários, por exemplo vídeo ou áudio, confira o guia avançado: [Stream Data](../advanced/stream-data.md).
|
||||
|
||||
///
|
||||
|
||||
## Stream de JSON Lines com FastAPI { #stream-json-lines-with-fastapi }
|
||||
|
||||
Para transmitir JSON Lines com FastAPI, em vez de usar `return` na sua *função de operação de rota*, use `yield` para produzir cada item em sequência.
|
||||
|
||||
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[24] *}
|
||||
|
||||
Se cada item JSON que você quer enviar de volta for do tipo `Item` (um modelo Pydantic) e a função for assíncrona, você pode declarar o tipo de retorno como `AsyncIterable[Item]`:
|
||||
|
||||
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[9:11,22] *}
|
||||
|
||||
Se você declarar o tipo de retorno, o FastAPI o usará para **validar** os dados, **documentá-los** no OpenAPI, **filtrá-los** e **serializá-los** usando o Pydantic.
|
||||
|
||||
/// tip | Dica
|
||||
|
||||
Como o Pydantic fará a serialização no lado em **Rust**, você terá uma **performance** muito maior do que se não declarar um tipo de retorno.
|
||||
|
||||
///
|
||||
|
||||
### Funções de operação de rota não assíncronas { #non-async-path-operation-functions }
|
||||
|
||||
Você também pode usar funções `def` normais (sem `async`) e usar `yield` da mesma forma.
|
||||
|
||||
O FastAPI garantirá que sejam executadas corretamente para não bloquear o event loop.
|
||||
|
||||
Como, neste caso, a função não é assíncrona, o tipo de retorno adequado seria `Iterable[Item]`:
|
||||
|
||||
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[27:30] hl[28] *}
|
||||
|
||||
### Sem tipo de retorno { #no-return-type }
|
||||
|
||||
Você também pode omitir o tipo de retorno. O FastAPI então usará o [`jsonable_encoder`](./encoder.md) para converter os dados em algo que possa ser serializado para JSON e depois enviá-los como JSON Lines.
|
||||
|
||||
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[33:36] hl[34] *}
|
||||
|
||||
## Eventos enviados pelo servidor (SSE) { #server-sent-events-sse }
|
||||
|
||||
O FastAPI também tem suporte de primeira classe a Server-Sent Events (SSE), que são bastante semelhantes, mas com alguns detalhes extras. Você pode aprender sobre eles no próximo capítulo: [Eventos enviados pelo servidor (SSE)](server-sent-events.md). 🤓
|
||||
Loading…
Reference in New Issue