🌐 Update translations for es (add-missing) (#15154)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Sebastián Ramírez 2026-03-19 19:12:26 +01:00 committed by GitHub
parent b61bdb79b8
commit cd5869b897
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 522 additions and 0 deletions

View File

@ -0,0 +1,63 @@
# JSON con Bytes como Base64 { #json-with-bytes-as-base64 }
Si tu app necesita recibir y enviar datos JSON, pero necesitas incluir datos binarios en él, puedes codificarlos como base64.
## Base64 vs Archivos { #base64-vs-files }
Considera primero si puedes usar [Archivos en request](../tutorial/request-files.md) para subir datos binarios y [Response personalizada - FileResponse](./custom-response.md#fileresponse--fileresponse-) para enviar datos binarios, en lugar de codificarlos en JSON.
JSON solo puede contener strings codificados en UTF-8, así que no puede contener bytes crudos.
Base64 puede codificar datos binarios en strings, pero para hacerlo necesita usar más caracteres que los datos binarios originales, así que normalmente sería menos eficiente que los archivos normales.
Usa base64 solo si definitivamente necesitas incluir datos binarios en JSON y no puedes usar archivos para eso.
## Pydantic `bytes` { #pydantic-bytes }
Puedes declarar un modelo de Pydantic con campos `bytes`, y luego usar `val_json_bytes` en la configuración del modelo para indicarle que use base64 para validar datos JSON de entrada; como parte de esa validación decodificará el string base64 en bytes.
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}
Si revisas `/docs`, verás que el campo `data` espera bytes codificados en base64:
<div class="screenshot">
<img src="/img/tutorial/json-base64-bytes/image01.png">
</div>
Podrías enviar un request como:
```json
{
"description": "Some data",
"data": "aGVsbG8="
}
```
/// tip | Consejo
`aGVsbG8=` es la codificación base64 de `hello`.
///
Y luego Pydantic decodificará el string base64 y te dará los bytes originales en el campo `data` del modelo.
Recibirás una response como:
```json
{
"description": "Some data",
"content": "hello"
}
```
## Pydantic `bytes` para datos de salida { #pydantic-bytes-for-output-data }
También puedes usar campos `bytes` con `ser_json_bytes` en la configuración del modelo para datos de salida, y Pydantic serializará los bytes como base64 al generar la response JSON.
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}
## Pydantic `bytes` para datos de entrada y salida { #pydantic-bytes-for-input-and-output-data }
Y por supuesto, puedes usar el mismo modelo configurado para usar base64 para manejar tanto la entrada (*validate*) con `val_json_bytes` como la salida (*serialize*) con `ser_json_bytes` al recibir y enviar datos JSON.
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}

View File

@ -0,0 +1,117 @@
# Transmitir datos { #stream-data }
Si quieres transmitir datos que se puedan estructurar como JSON, deberías [Transmitir JSON Lines](../tutorial/stream-json-lines.md).
Pero si quieres transmitir datos binarios puros o strings, aquí tienes cómo hacerlo.
/// info | Información
Añadido en FastAPI 0.134.0.
///
## Casos de uso { #use-cases }
Podrías usar esto si quieres transmitir strings puros, por ejemplo directamente de la salida de un servicio de AI LLM.
También podrías usarlo para transmitir archivos binarios grandes, donde transmites cada bloque de datos a medida que lo lees, sin tener que leerlo todo en memoria de una sola vez.
También podrías transmitir video o audio de esta manera; incluso podría generarse mientras lo procesas y lo envías.
## Un `StreamingResponse` con `yield` { #a-streamingresponse-with-yield }
Si declaras un `response_class=StreamingResponse` en tu *path operation function*, puedes usar `yield` para enviar cada bloque de datos a su vez.
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
FastAPI entregará cada bloque de datos a `StreamingResponse` tal cual, no intentará convertirlo a JSON ni nada parecido.
### *path operation functions* no async { #non-async-path-operation-functions }
También puedes usar funciones `def` normales (sin `async`) y usar `yield` de la misma manera.
{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *}
### Sin anotación { #no-annotation }
Realmente no necesitas declarar la anotación de tipo de retorno para transmitir datos binarios.
Como FastAPI no intentará convertir los datos a JSON con Pydantic ni serializarlos de ninguna manera, en este caso la anotación de tipos es solo para que la use tu editor y tus herramientas; FastAPI no la usará.
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
Esto también significa que con `StreamingResponse` tienes la libertad y la responsabilidad de producir y codificar los bytes de datos exactamente como necesites enviarlos, independientemente de las anotaciones de tipos. 🤓
### Transmitir bytes { #stream-bytes }
Uno de los casos de uso principales sería transmitir `bytes` en lugar de strings; por supuesto puedes hacerlo.
{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *}
## Un `PNGStreamingResponse` personalizado { #a-custom-pngstreamingresponse }
En los ejemplos anteriores, se transmitieron los bytes de datos, pero la response no tenía un header `Content-Type`, así que el cliente no sabía qué tipo de datos estaba recibiendo.
Puedes crear una subclase personalizada de `StreamingResponse` que establezca el header `Content-Type` al tipo de datos que estás transmitiendo.
Por ejemplo, puedes crear un `PNGStreamingResponse` que establezca el header `Content-Type` a `image/png` usando el atributo `media_type`:
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
Luego puedes usar esta nueva clase en `response_class=PNGStreamingResponse` en tu *path operation function*:
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
### Simular un archivo { #simulate-a-file }
En este ejemplo estamos simulando un archivo con `io.BytesIO`, que es un objeto tipo archivo que vive solo en memoria, pero nos permite usar la misma interfaz.
Por ejemplo, podemos iterarlo para consumir su contenido, como podríamos con un archivo.
{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *}
/// note | Detalles técnicos
Las otras dos variables, `image_base64` y `binary_image`, son una imagen codificada en Base64 y luego convertida a bytes, para después pasarla a `io.BytesIO`.
Solo para que pueda vivir en el mismo archivo para este ejemplo y puedas copiarlo y ejecutarlo tal cual. 🥚
///
Al usar un bloque `with`, nos aseguramos de que el objeto tipo archivo se cierre cuando termine la función generadora (la función con `yield`). Es decir, después de que termine de enviar la response.
No sería tan importante en este ejemplo específico porque es un archivo falso en memoria (con `io.BytesIO`), pero con un archivo real sí sería importante asegurarse de que el archivo se cierre al terminar de trabajar con él.
### Archivos y async { #files-and-async }
En la mayoría de los casos, los objetos tipo archivo no son compatibles con `async` y `await` por defecto.
Por ejemplo, no tienen un `await file.read()`, ni un `async for chunk in file`.
Y en muchos casos leerlos sería una operación bloqueante (que podría bloquear el event loop), porque se leen desde disco o desde la red.
/// info | Información
El ejemplo anterior es en realidad una excepción, porque el objeto `io.BytesIO` ya está en memoria, así que leerlo no bloqueará nada.
Pero en muchos casos leer un archivo u objeto tipo archivo sí bloquearía.
///
Para evitar bloquear el event loop, puedes simplemente declarar la *path operation function* con un `def` normal en lugar de `async def`; de esa forma FastAPI la ejecutará en un worker de threadpool para evitar bloquear el loop principal.
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
/// tip | Consejo
Si necesitas llamar código bloqueante desde dentro de una función async, o una función async desde dentro de una función bloqueante, podrías usar [Asyncer](https://asyncer.tiangolo.com), un paquete hermano de FastAPI.
///
### `yield from` { #yield-from }
Cuando estés iterando sobre algo, como un objeto tipo archivo, y estés haciendo `yield` para cada elemento, también podrías usar `yield from` para hacer `yield` de cada elemento directamente y saltarte el `for`.
Esto no es particular de FastAPI, es simplemente Python, pero es un truco útil que conviene conocer. 😎
{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *}

View File

@ -0,0 +1,88 @@
# Chequeo estricto de Content-Type { #strict-content-type-checking }
Por defecto, **FastAPI** usa un chequeo estricto del header `Content-Type` para request bodies JSON, esto significa que las requests JSON deben incluir un header `Content-Type` válido (p. ej. `application/json`) para que el request body se parse como JSON.
## Riesgo de CSRF { #csrf-risk }
Este comportamiento por defecto provee protección contra una clase de ataques de **Cross-Site Request Forgery (CSRF)** en un escenario muy específico.
Estos ataques aprovechan que los navegadores permiten que los scripts envíen requests sin hacer un preflight de CORS cuando:
* no tienen un header `Content-Type` (p. ej. usando `fetch()` con un body `Blob`)
* y no envían credenciales de autenticación.
Este tipo de ataque es relevante principalmente cuando:
* la aplicación corre localmente (p. ej. en `localhost`) o en una red interna
* y la aplicación no tiene ninguna autenticación, espera que cualquier request de la misma red sea confiable.
## Ejemplo de ataque { #example-attack }
Imagina que construyes una forma de ejecutar un agente de IA local.
Provee un API en
```
http://localhost:8000/v1/agents/multivac
```
También hay un frontend en
```
http://localhost:8000
```
/// tip | Consejo
Ten en cuenta que ambos tienen el mismo host.
///
Luego, usando el frontend, puedes hacer que el agente de IA haga cosas en tu nombre.
Como está corriendo localmente y no en Internet abierta, decides no tener ninguna autenticación configurada, confiando simplemente en el acceso a la red local.
Entonces, uno de tus usuarios podría instalarlo y ejecutarlo localmente.
Después podría abrir un sitio web malicioso, por ejemplo algo como
```
https://evilhackers.example.com
```
Y ese sitio malicioso envía requests usando `fetch()` con un body `Blob` al API local en
```
http://localhost:8000/v1/agents/multivac
```
Aunque el host del sitio malicioso y el de la app local sea diferente, el navegador no disparará un preflight de CORS porque:
* Está corriendo sin ninguna autenticación, no tiene que enviar credenciales.
* El navegador cree que no está enviando JSON (por la falta del header `Content-Type`).
Entonces el sitio malicioso podría hacer que el agente de IA local envíe mensajes agresivos al exjefe del usuario... o peor. 😅
## Internet abierta { #open-internet }
Si tu app está en Internet abierta, no “confiarías en la red” ni permitirías que cualquiera envíe requests privilegiadas sin autenticación.
Los atacantes podrían simplemente ejecutar un script para enviar requests a tu API, sin necesidad de interacción del navegador, así que probablemente ya estás asegurando cualquier endpoint privilegiado.
En ese caso, este ataque/riesgo no aplica a ti.
Este riesgo y ataque es relevante principalmente cuando la app corre en la red local y esa es la única protección asumida.
## Permitir requests sin Content-Type { #allowing-requests-without-content-type }
Si necesitas soportar clientes que no envían un header `Content-Type`, puedes desactivar el chequeo estricto configurando `strict_content_type=False`:
{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *}
Con esta configuración, las requests sin un header `Content-Type` tendrán su body parseado como JSON, que es el mismo comportamiento de versiones anteriores de FastAPI.
/// info | Información
Este comportamiento y configuración se añadieron en FastAPI 0.132.0.
///

View File

@ -0,0 +1,23 @@
# Soporte del editor { #editor-support }
La [Extensión de FastAPI](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) oficial mejora tu flujo de trabajo de desarrollo con FastAPI con descubrimiento de *path operation*, navegación, además de deployment a FastAPI Cloud y streaming en vivo de logs.
Para más detalles sobre la extensión, consulta el README en el [repositorio de GitHub](https://github.com/fastapi/fastapi-vscode).
## Configuración e instalación { #setup-and-installation }
La **Extensión de FastAPI** está disponible tanto para [VS Code](https://code.visualstudio.com/) como para [Cursor](https://www.cursor.com/). Se puede instalar directamente desde el panel de Extensiones en cada editor buscando "FastAPI" y seleccionando la extensión publicada por **FastAPI Labs**. La extensión también funciona en editores basados en navegador como [vscode.dev](https://vscode.dev) y [github.dev](https://github.dev).
### Descubrimiento de la aplicación { #application-discovery }
Por defecto, la extensión descubrirá automáticamente aplicaciones FastAPI en tu espacio de trabajo escaneando archivos que creen un instance de `FastAPI()`. Si la detección automática no funciona con la estructura de tu proyecto, puedes especificar un punto de entrada mediante `[tool.fastapi]` en `pyproject.toml` o la configuración de VS Code `fastapi.entryPoint` usando notación de módulo (p. ej. `myapp.main:app`).
## Funcionalidades { #features }
- **Explorador de Path Operations** - Una vista en árbol en la barra lateral de todas las <dfn title="rutas, endpoints">*path operations*</dfn> de tu aplicación. Haz clic para saltar a cualquier definición de ruta o de router.
- **Búsqueda de rutas** - Busca por path, método o nombre con <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (en macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>).
- **Navegación con CodeLens** - Enlaces clicables encima de llamadas del cliente de tests (p. ej. `client.get('/items')`) que saltan a la *path operation* correspondiente para navegar rápidamente entre tests e implementación.
- **Desplegar en FastAPI Cloud** - Deployment con un clic de tu app a [FastAPI Cloud](https://fastapicloud.com/).
- **Streaming de logs de la aplicación** - Streaming en tiempo real de logs desde tu aplicación desplegada en FastAPI Cloud, con filtrado por nivel y búsqueda de texto.
Si quieres familiarizarte con las funcionalidades de la extensión, puedes revisar el recorrido guiado de la extensión abriendo la Paleta de Comandos (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> o en macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) y seleccionando "Welcome: Open walkthrough..." y luego eligiendo el recorrido "Get started with FastAPI".

View File

@ -0,0 +1,120 @@
# Server-Sent Events (SSE) { #server-sent-events-sse }
Puedes enviar datos en streaming al cliente usando **Server-Sent Events** (SSE).
Esto es similar a [Stream JSON Lines](stream-json-lines.md), pero usa el formato `text/event-stream`, que los navegadores soportan de forma nativa con la [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
/// info | Información
Añadido en FastAPI 0.135.0.
///
## ¿Qué son los Server-Sent Events? { #what-are-server-sent-events }
SSE es un estándar para hacer streaming de datos desde el servidor al cliente sobre HTTP.
Cada evento es un pequeño bloque de texto con “campos” como `data`, `event`, `id` y `retry`, separados por líneas en blanco.
Se ve así:
```
data: {"name": "Portal Gun", "price": 999.99}
data: {"name": "Plumbus", "price": 32.99}
```
SSE se usa comúnmente para streaming de chat de IA, notificaciones en vivo, logs y observabilidad, y otros casos donde el servidor envía actualizaciones al cliente.
/// tip | Consejo
Si quieres hacer streaming de datos binarios, por ejemplo video o audio, Revisa la guía avanzada: [Stream Data](../advanced/stream-data.md).
///
## Streaming de SSE con FastAPI { #stream-sse-with-fastapi }
Para hacer streaming de SSE con FastAPI, usa `yield` en tu path operation function y establece `response_class=EventSourceResponse`.
import `EventSourceResponse` de `fastapi.sse`:
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[4,22] *}
Cada ítem producido con `yield` se codifica como JSON y se envía en el campo `data:` de un evento SSE.
Si declaras el tipo de retorno como `AsyncIterable[Item]`, FastAPI lo usará para **validar**, **documentar** y **serializar** los datos usando Pydantic.
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[10:12,23] *}
/// tip | Consejo
Como Pydantic lo serializará en el lado de **Rust**, obtendrás un **rendimiento** mucho mayor que si no declaras un tipo de retorno.
///
### No async *path operation functions* { #non-async-path-operation-functions }
También puedes usar funciones `def` normales (sin `async`), y usar `yield` de la misma manera.
FastAPI se asegurará de ejecutarlo correctamente para que no bloquee el event loop.
Como en este caso la función no es async, el tipo de retorno correcto sería `Iterable[Item]`:
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[28:31] hl[29] *}
### Sin tipo de retorno { #no-return-type }
También puedes omitir el tipo de retorno. FastAPI usará el [`jsonable_encoder`](./encoder.md) para convertir los datos y enviarlos.
{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[34:37] hl[35] *}
## `ServerSentEvent` { #serversentevent }
Si necesitas configurar campos SSE como `event`, `id`, `retry` o `comment`, puedes hacer `yield` de objetos `ServerSentEvent` en lugar de datos simples.
import `ServerSentEvent` de `fastapi.sse`:
{* ../../docs_src/server_sent_events/tutorial002_py310.py hl[4,26] *}
El campo `data` siempre se codifica como JSON. Puedes pasar cualquier valor que pueda serializarse como JSON, incluidos modelos de Pydantic.
## Datos sin procesar { #raw-data }
Si necesitas enviar datos **sin** codificarlos a JSON, usa `raw_data` en lugar de `data`.
Esto es útil para enviar texto preformateado, líneas de log, o valores especiales de <dfn title="Un valor usado para indicar una condición o estado especial">"centinela"</dfn> como `[DONE]`.
{* ../../docs_src/server_sent_events/tutorial003_py310.py hl[17] *}
/// note | Nota
`data` y `raw_data` son mutuamente excluyentes. Solo puedes establecer uno de ellos en cada `ServerSentEvent`.
///
## Reanudar con `Last-Event-ID` { #resuming-with-last-event-id }
Cuando un navegador se reconecta después de una caída de la conexión, envía el último `id` recibido en el header `Last-Event-ID`.
Puedes leerlo como un parámetro de header y usarlo para reanudar el stream desde donde el cliente se quedó:
{* ../../docs_src/server_sent_events/tutorial004_py310.py hl[25,27,31] *}
## SSE con `POST` { #sse-with-post }
SSE funciona con **cualquier método HTTP**, no solo con `GET`.
Esto es útil para protocolos como [MCP](https://modelcontextprotocol.io) que hacen streaming de SSE sobre `POST`:
{* ../../docs_src/server_sent_events/tutorial005_py310.py hl[14] *}
## Detalles técnicos { #technical-details }
FastAPI implementa algunas mejores prácticas de SSE desde el primer momento.
- Enviar un comentario de **"keep alive" `ping`** cada 15 segundos cuando no ha habido ningún mensaje, para evitar que algunos proxies cierren la conexión, como se sugiere en la [Especificación HTML: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes).
- Configurar el header `Cache-Control: no-cache` para **evitar el almacenamiento en caché** del stream.
- Configurar un header especial `X-Accel-Buffering: no` para **evitar el buffering** en algunos proxies como Nginx.
No tienes que hacer nada, funciona tal cual viene. 🤓

View File

@ -0,0 +1,111 @@
# Transmitir JSON Lines { #stream-json-lines }
Podrías tener una secuencia de datos que quieras enviar en un "**stream**", podrías hacerlo con **JSON Lines**.
/// info | Información
Añadido en FastAPI 0.134.0.
///
## ¿Qué es un Stream? { #what-is-a-stream }
Hacer "**Streaming**" de datos significa que tu app empezará a enviar ítems de datos al cliente sin esperar a que toda la secuencia de ítems esté lista.
Entonces, enviará el primer ítem, el cliente lo recibirá y empezará a procesarlo, y tú podrías seguir produciendo el siguiente ítem.
```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...
```
Incluso podría ser un stream infinito, donde sigues enviando datos.
## JSON Lines { #json-lines }
En estos casos, es común enviar "**JSON Lines**", que es un formato donde envías un objeto JSON por línea.
Una response tendría un tipo de contenido `application/jsonl` (en lugar de `application/json`) y el response body sería 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."}
```
Es muy similar a un array JSON (equivalente de una list de Python), pero en lugar de estar envuelto en `[]` y tener `,` entre los ítems, tiene **un objeto JSON por línea**, separados por un carácter de nueva línea.
/// info | Información
El punto importante es que tu app podrá producir cada línea a su turno, mientras el cliente consume las líneas anteriores.
///
/// note | Detalles técnicos
Como cada objeto JSON estará separado por una nueva línea, no pueden contener caracteres de nueva línea literales en su contenido, pero sí pueden contener nuevas líneas escapadas (`\n`), lo cual es parte del estándar JSON.
Pero normalmente no tendrás que preocuparte por eso, se hace automáticamente, sigue leyendo. 🤓
///
## Casos de uso { #use-cases }
Podrías usar esto para hacer stream de datos desde un servicio de **AI LLM**, desde **logs** o **telemetry**, o desde otros tipos de datos que puedan estructurarse en ítems **JSON**.
/// tip | Consejo
Si quieres hacer stream de datos binarios, por ejemplo video o audio, Revisa la guía avanzada: [Transmitir datos](../advanced/stream-data.md).
///
## Transmitir JSON Lines con FastAPI { #stream-json-lines-with-fastapi }
Para transmitir JSON Lines con FastAPI puedes, en lugar de usar `return` en tu *path operation function*, usar `yield` para producir cada ítem a su turno.
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[24] *}
Si cada ítem JSON que quieres enviar de vuelta es de tipo `Item` (un modelo de Pydantic) y es una función async, puedes declarar el tipo de retorno como `AsyncIterable[Item]`:
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[9:11,22] *}
Si declaras el tipo de retorno, FastAPI lo usará para **validar** los datos, **documentarlos** en OpenAPI, **filtrarlos** y **serializarlos** usando Pydantic.
/// tip | Consejo
Como Pydantic lo serializará en el lado de **Rust**, obtendrás un **rendimiento** mucho mayor que si no declaras un tipo de retorno.
///
### *path operation functions* no-async { #non-async-path-operation-functions }
También puedes usar funciones `def` regulares (sin `async`), y usar `yield` de la misma forma.
FastAPI se asegurará de que se ejecute correctamente para que no bloquee el event loop.
Como en este caso la función no es async, el tipo de retorno correcto sería `Iterable[Item]`:
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[27:30] hl[28] *}
### Sin tipo de retorno { #no-return-type }
También puedes omitir el tipo de retorno. Entonces FastAPI usará [`jsonable_encoder`](./encoder.md) para convertir los datos a algo que se pueda serializar a JSON y luego enviarlo como JSON Lines.
{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[33:36] hl[34] *}
## Server-Sent Events (SSE) { #server-sent-events-sse }
FastAPI también tiene soporte de primera clase para Server-Sent Events (SSE), que son bastante similares pero con un par de detalles extra. Puedes aprender sobre ellos en el siguiente capítulo: [Eventos enviados por el servidor (SSE)](server-sent-events.md). 🤓