From 06cdff4488d2a4f7809037b61aa227aa7bf1eec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 19 Mar 2026 19:20:13 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Update=20translations=20for=20pt?= =?UTF-8?q?=20(add-missing)=20(#15157)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- docs/pt/docs/advanced/json-base64-bytes.md | 63 ++++++++++ docs/pt/docs/advanced/stream-data.md | 117 ++++++++++++++++++ docs/pt/docs/advanced/strict-content-type.md | 88 ++++++++++++++ docs/pt/docs/editor-support.md | 23 ++++ docs/pt/docs/tutorial/server-sent-events.md | 120 +++++++++++++++++++ docs/pt/docs/tutorial/stream-json-lines.md | 111 +++++++++++++++++ 6 files changed, 522 insertions(+) create mode 100644 docs/pt/docs/advanced/json-base64-bytes.md create mode 100644 docs/pt/docs/advanced/stream-data.md create mode 100644 docs/pt/docs/advanced/strict-content-type.md create mode 100644 docs/pt/docs/editor-support.md create mode 100644 docs/pt/docs/tutorial/server-sent-events.md create mode 100644 docs/pt/docs/tutorial/stream-json-lines.md diff --git a/docs/pt/docs/advanced/json-base64-bytes.md b/docs/pt/docs/advanced/json-base64-bytes.md new file mode 100644 index 0000000000..cc956da4f0 --- /dev/null +++ b/docs/pt/docs/advanced/json-base64-bytes.md @@ -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: + +
+ +
+ +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] *} diff --git a/docs/pt/docs/advanced/stream-data.md b/docs/pt/docs/advanced/stream-data.md new file mode 100644 index 0000000000..8e0bf08b68 --- /dev/null +++ b/docs/pt/docs/advanced/stream-data.md @@ -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] *} diff --git a/docs/pt/docs/advanced/strict-content-type.md b/docs/pt/docs/advanced/strict-content-type.md new file mode 100644 index 0000000000..9530501d4e --- /dev/null +++ b/docs/pt/docs/advanced/strict-content-type.md @@ -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. + +/// diff --git a/docs/pt/docs/editor-support.md b/docs/pt/docs/editor-support.md new file mode 100644 index 0000000000..7eedd3908e --- /dev/null +++ b/docs/pt/docs/editor-support.md @@ -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 *operações de rota* 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 Ctrl + Shift + E (no macOS: Cmd + Shift + E). +- **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 (Ctrl + Shift + P ou no macOS: Cmd + Shift + P), selecionando "Welcome: Open walkthrough..." e, em seguida, escolhendo o walkthrough "Get started with FastAPI". diff --git a/docs/pt/docs/tutorial/server-sent-events.md b/docs/pt/docs/tutorial/server-sent-events.md new file mode 100644 index 0000000000..33389873ce --- /dev/null +++ b/docs/pt/docs/tutorial/server-sent-events.md @@ -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 "sentinela" 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. 🤓 diff --git a/docs/pt/docs/tutorial/stream-json-lines.md b/docs/pt/docs/tutorial/stream-json-lines.md new file mode 100644 index 0000000000..f6d5c26f09 --- /dev/null +++ b/docs/pt/docs/tutorial/stream-json-lines.md @@ -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). 🤓