Skip to content

Commit e81d3fe

Browse files
github-actions[bot]YuriiMotov
authored andcommitted
🌐 Update translations for es (add-missing)
1 parent b61bdb7 commit e81d3fe

6 files changed

Lines changed: 522 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# JSON con Bytes como Base64 { #json-with-bytes-as-base64 }
2+
3+
Si tu app necesita recibir y enviar datos JSON, pero necesitas incluir datos binarios en él, puedes codificarlos como base64.
4+
5+
## Base64 vs Archivos { #base64-vs-files }
6+
7+
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.
8+
9+
JSON solo puede contener strings codificados en UTF-8, así que no puede contener bytes crudos.
10+
11+
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.
12+
13+
Usa base64 solo si definitivamente necesitas incluir datos binarios en JSON y no puedes usar archivos para eso.
14+
15+
## Pydantic `bytes` { #pydantic-bytes }
16+
17+
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.
18+
19+
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}
20+
21+
Si revisas `/docs`, verás que el campo `data` espera bytes codificados en base64:
22+
23+
<div class="screenshot">
24+
<img src="/img/tutorial/json-base64-bytes/image01.png">
25+
</div>
26+
27+
Podrías enviar un request como:
28+
29+
```json
30+
{
31+
"description": "Some data",
32+
"data": "aGVsbG8="
33+
}
34+
```
35+
36+
/// tip | Consejo
37+
38+
`aGVsbG8=` es la codificación base64 de `hello`.
39+
40+
///
41+
42+
Y luego Pydantic decodificará el string base64 y te dará los bytes originales en el campo `data` del modelo.
43+
44+
Recibirás una response como:
45+
46+
```json
47+
{
48+
"description": "Some data",
49+
"content": "hello"
50+
}
51+
```
52+
53+
## Pydantic `bytes` para datos de salida { #pydantic-bytes-for-output-data }
54+
55+
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.
56+
57+
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}
58+
59+
## Pydantic `bytes` para datos de entrada y salida { #pydantic-bytes-for-input-and-output-data }
60+
61+
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.
62+
63+
{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Transmitir datos { #stream-data }
2+
3+
Si quieres transmitir datos que se puedan estructurar como JSON, deberías [Transmitir JSON Lines](../tutorial/stream-json-lines.md).
4+
5+
Pero si quieres transmitir datos binarios puros o strings, aquí tienes cómo hacerlo.
6+
7+
/// info | Información
8+
9+
Añadido en FastAPI 0.134.0.
10+
11+
///
12+
13+
## Casos de uso { #use-cases }
14+
15+
Podrías usar esto si quieres transmitir strings puros, por ejemplo directamente de la salida de un servicio de AI LLM.
16+
17+
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.
18+
19+
También podrías transmitir video o audio de esta manera; incluso podría generarse mientras lo procesas y lo envías.
20+
21+
## Un `StreamingResponse` con `yield` { #a-streamingresponse-with-yield }
22+
23+
Si declaras un `response_class=StreamingResponse` en tu *path operation function*, puedes usar `yield` para enviar cada bloque de datos a su vez.
24+
25+
{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
26+
27+
FastAPI entregará cada bloque de datos a `StreamingResponse` tal cual, no intentará convertirlo a JSON ni nada parecido.
28+
29+
### *path operation functions* no async { #non-async-path-operation-functions }
30+
31+
También puedes usar funciones `def` normales (sin `async`) y usar `yield` de la misma manera.
32+
33+
{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *}
34+
35+
### Sin anotación { #no-annotation }
36+
37+
Realmente no necesitas declarar la anotación de tipo de retorno para transmitir datos binarios.
38+
39+
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á.
40+
41+
{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
42+
43+
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. 🤓
44+
45+
### Transmitir bytes { #stream-bytes }
46+
47+
Uno de los casos de uso principales sería transmitir `bytes` en lugar de strings; por supuesto puedes hacerlo.
48+
49+
{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *}
50+
51+
## Un `PNGStreamingResponse` personalizado { #a-custom-pngstreamingresponse }
52+
53+
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.
54+
55+
Puedes crear una subclase personalizada de `StreamingResponse` que establezca el header `Content-Type` al tipo de datos que estás transmitiendo.
56+
57+
Por ejemplo, puedes crear un `PNGStreamingResponse` que establezca el header `Content-Type` a `image/png` usando el atributo `media_type`:
58+
59+
{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
60+
61+
Luego puedes usar esta nueva clase en `response_class=PNGStreamingResponse` en tu *path operation function*:
62+
63+
{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
64+
65+
### Simular un archivo { #simulate-a-file }
66+
67+
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.
68+
69+
Por ejemplo, podemos iterarlo para consumir su contenido, como podríamos con un archivo.
70+
71+
{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *}
72+
73+
/// note | Detalles técnicos
74+
75+
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`.
76+
77+
Solo para que pueda vivir en el mismo archivo para este ejemplo y puedas copiarlo y ejecutarlo tal cual. 🥚
78+
79+
///
80+
81+
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.
82+
83+
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.
84+
85+
### Archivos y async { #files-and-async }
86+
87+
En la mayoría de los casos, los objetos tipo archivo no son compatibles con `async` y `await` por defecto.
88+
89+
Por ejemplo, no tienen un `await file.read()`, ni un `async for chunk in file`.
90+
91+
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.
92+
93+
/// info | Información
94+
95+
El ejemplo anterior es en realidad una excepción, porque el objeto `io.BytesIO` ya está en memoria, así que leerlo no bloqueará nada.
96+
97+
Pero en muchos casos leer un archivo u objeto tipo archivo sí bloquearía.
98+
99+
///
100+
101+
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.
102+
103+
{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
104+
105+
/// tip | Consejo
106+
107+
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.
108+
109+
///
110+
111+
### `yield from` { #yield-from }
112+
113+
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`.
114+
115+
Esto no es particular de FastAPI, es simplemente Python, pero es un truco útil que conviene conocer. 😎
116+
117+
{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Chequeo estricto de Content-Type { #strict-content-type-checking }
2+
3+
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.
4+
5+
## Riesgo de CSRF { #csrf-risk }
6+
7+
Este comportamiento por defecto provee protección contra una clase de ataques de **Cross-Site Request Forgery (CSRF)** en un escenario muy específico.
8+
9+
Estos ataques aprovechan que los navegadores permiten que los scripts envíen requests sin hacer un preflight de CORS cuando:
10+
11+
* no tienen un header `Content-Type` (p. ej. usando `fetch()` con un body `Blob`)
12+
* y no envían credenciales de autenticación.
13+
14+
Este tipo de ataque es relevante principalmente cuando:
15+
16+
* la aplicación corre localmente (p. ej. en `localhost`) o en una red interna
17+
* y la aplicación no tiene ninguna autenticación, espera que cualquier request de la misma red sea confiable.
18+
19+
## Ejemplo de ataque { #example-attack }
20+
21+
Imagina que construyes una forma de ejecutar un agente de IA local.
22+
23+
Provee un API en
24+
25+
```
26+
http://localhost:8000/v1/agents/multivac
27+
```
28+
29+
También hay un frontend en
30+
31+
```
32+
http://localhost:8000
33+
```
34+
35+
/// tip | Consejo
36+
37+
Ten en cuenta que ambos tienen el mismo host.
38+
39+
///
40+
41+
Luego, usando el frontend, puedes hacer que el agente de IA haga cosas en tu nombre.
42+
43+
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.
44+
45+
Entonces, uno de tus usuarios podría instalarlo y ejecutarlo localmente.
46+
47+
Después podría abrir un sitio web malicioso, por ejemplo algo como
48+
49+
```
50+
https://evilhackers.example.com
51+
```
52+
53+
Y ese sitio malicioso envía requests usando `fetch()` con un body `Blob` al API local en
54+
55+
```
56+
http://localhost:8000/v1/agents/multivac
57+
```
58+
59+
Aunque el host del sitio malicioso y el de la app local sea diferente, el navegador no disparará un preflight de CORS porque:
60+
61+
* Está corriendo sin ninguna autenticación, no tiene que enviar credenciales.
62+
* El navegador cree que no está enviando JSON (por la falta del header `Content-Type`).
63+
64+
Entonces el sitio malicioso podría hacer que el agente de IA local envíe mensajes agresivos al exjefe del usuario... o peor. 😅
65+
66+
## Internet abierta { #open-internet }
67+
68+
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.
69+
70+
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.
71+
72+
En ese caso, este ataque/riesgo no aplica a ti.
73+
74+
Este riesgo y ataque es relevante principalmente cuando la app corre en la red local y esa es la única protección asumida.
75+
76+
## Permitir requests sin Content-Type { #allowing-requests-without-content-type }
77+
78+
Si necesitas soportar clientes que no envían un header `Content-Type`, puedes desactivar el chequeo estricto configurando `strict_content_type=False`:
79+
80+
{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *}
81+
82+
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.
83+
84+
/// info | Información
85+
86+
Este comportamiento y configuración se añadieron en FastAPI 0.132.0.
87+
88+
///

docs/es/docs/editor-support.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Soporte del editor { #editor-support }
2+
3+
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.
4+
5+
Para más detalles sobre la extensión, consulta el README en el [repositorio de GitHub](https://github.com/fastapi/fastapi-vscode).
6+
7+
## Configuración e instalación { #setup-and-installation }
8+
9+
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).
10+
11+
### Descubrimiento de la aplicación { #application-discovery }
12+
13+
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`).
14+
15+
## Funcionalidades { #features }
16+
17+
- **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.
18+
- **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>).
19+
- **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.
20+
- **Desplegar en FastAPI Cloud** - Deployment con un clic de tu app a [FastAPI Cloud](https://fastapicloud.com/).
21+
- **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.
22+
23+
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".

0 commit comments

Comments
 (0)