Sync fastapi docs from 7cb06f36 on 2026-07-11

This commit is contained in:
The Librarian
2026-07-11 04:00:12 +00:00
parent 2c5483ee1c
commit d71a936809
1032 changed files with 12357 additions and 6438 deletions
@@ -34,7 +34,7 @@ Ten en cuenta que debes devolver el `JSONResponse` directamente.
///
/// info | Información
/// note | Nota
La clave `model` no es parte de OpenAPI.
@@ -183,7 +183,7 @@ Nota que debes devolver la imagen usando un `FileResponse` directamente.
///
/// info | Información
/// note | Nota
A menos que especifiques un media type diferente explícitamente en tu parámetro `responses`, FastAPI asumirá que el response tiene el mismo media type que la clase de response principal (por defecto `application/json`).
@@ -1,5 +1,6 @@
# Códigos de Estado Adicionales { #additional-status-codes }
Por defecto, **FastAPI** devolverá los responses usando un `JSONResponse`, colocando el contenido que devuelves desde tu *path operation* dentro de ese `JSONResponse`.
Usará el código de estado por defecto o el que configures en tu *path operation*.
@@ -10,7 +10,7 @@ Imaginemos que queremos tener una dependencia que revise si el parámetro de que
Pero queremos poder parametrizar ese contenido fijo.
## Una *instance* "callable" { #a-callable-instance }
## Una instance "callable" { #a-callable-instance }
En Python hay una forma de hacer que una instance de una clase sea un "callable".
@@ -98,7 +98,7 @@ Por ejemplo, si tenías una sesión de base de datos en una dependencia con `yie
Este comportamiento se revirtió en la 0.118.0, para hacer que el código de salida después de `yield` se ejecute después de que la response sea enviada.
/// info | Información
/// note | Nota
Como verás abajo, esto es muy similar al comportamiento anterior a la versión 0.106.0, pero con varias mejoras y arreglos de bugs para casos límite.
@@ -108,7 +108,7 @@ Como verás abajo, esto es muy similar al comportamiento anterior a la versión
Hay algunos casos de uso con condiciones específicas que podrían beneficiarse del comportamiento antiguo de ejecutar el código de salida de dependencias con `yield` antes de enviar la response.
Por ejemplo, imagina que tienes código que usa una sesión de base de datos en una dependencia con `yield` solo para verificar un usuario, pero la sesión de base de datos no se vuelve a usar en la *path operation function*, solo en la dependencia, y la response tarda mucho en enviarse, como un `StreamingResponse` que envía datos lentamente, pero que por alguna razón no usa la base de datos.
Por ejemplo, imagina que tienes código que usa una sesión de base de datos en una dependencia con `yield` solo para verificar un usuario, pero la sesión de base de datos no se vuelve a usar en la *path operation function*, solo en la dependencia, **y** la response tarda mucho en enviarse, como un `StreamingResponse` que envía datos lentamente, pero que por alguna razón no usa la base de datos.
En este caso, la sesión de base de datos se mantendría hasta que la response termine de enviarse, pero si no la usas, entonces no sería necesario mantenerla.
+4 -4
View File
@@ -24,7 +24,7 @@ Si declaras un [Response Model](../tutorial/response-model.md) FastAPI lo usará
Si no declaras un response model, FastAPI usará el `jsonable_encoder` explicado en [Codificador Compatible con JSON](../tutorial/encoder.md) y lo pondrá en un `JSONResponse`.
Si declaras un `response_class` con un media type JSON (`application/json`), como es el caso con `JSONResponse`, los datos que devuelvas se convertirán automáticamente (y serán filtrados) con cualquier `response_model` de Pydantic que hayas declarado en el *path operation decorator*. Pero los datos no se serializarán a bytes JSON con Pydantic, en su lugar se convertirán con el `jsonable_encoder` y luego se pasarán a la clase `JSONResponse`, que los serializará a bytes usando la librería JSON estándar de Python.
Si declaras un `response_class` con un media type JSON (`application/json`), como es el caso con `JSONResponse`, los datos que devuelvas se convertirán automáticamente (y serán filtrados) con cualquier `response_model` de Pydantic que hayas declarado en el *path operation decorator*. Pero los datos no se serializarán a bytes JSON con Pydantic, en su lugar se convertirán con el `jsonable_encoder` y luego se pasarán a la clase `JSONResponse`, que los serializará a bytes usando el paquete JSON estándar de Python.
### Rendimiento JSON { #json-performance }
@@ -41,7 +41,7 @@ Para devolver un response con HTML directamente desde **FastAPI**, usa `HTMLResp
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info | Información
/// note | Nota
El parámetro `response_class` también se utilizará para definir el "media type" del response.
@@ -65,7 +65,7 @@ Una `Response` devuelta directamente por tu *path operation function* no se docu
///
/// info | Información
/// note | Nota
Por supuesto, el `Content-Type` header real, el código de estado, etc., provendrán del objeto `Response` que devolviste.
@@ -181,7 +181,7 @@ Toma un generador `async` o un generador/iterador normal (una función con `yiel
Una tarea `async` solo puede cancelarse cuando llega a un `await`. Si no hay `await`, el generador (función con `yield`) no se puede cancelar correctamente y puede seguir ejecutándose incluso después de solicitar la cancelación.
Como este pequeño ejemplo no necesita ninguna sentencia `await`, añadimos un `await anyio.sleep(0)` para darle al loop de eventos la oportunidad de manejar la cancelación.
Como este pequeño ejemplo no necesita ninguna statement `await`, añadimos un `await anyio.sleep(0)` para darle al loop de eventos la oportunidad de manejar la cancelación.
Esto sería aún más importante con streams grandes o infinitos.
+2 -2
View File
@@ -18,7 +18,7 @@ Y por supuesto, soporta lo mismo:
Esto funciona de la misma manera que con los modelos de Pydantic. Y en realidad se logra de la misma manera internamente, utilizando Pydantic.
/// info | Información
/// note | Nota
Ten en cuenta que los dataclasses no pueden hacer todo lo que los modelos de Pydantic pueden hacer.
@@ -82,7 +82,7 @@ En ese caso, simplemente puedes intercambiar los `dataclasses` estándar con `py
Puedes combinar `dataclasses` con otras anotaciones de tipos en muchas combinaciones diferentes para formar estructuras de datos complejas.
Revisa las anotaciones en el código arriba para ver más detalles específicos.
Revisa los consejos de anotación en el código arriba para ver más detalles específicos.
## Aprende Más { #learn-more }
+5 -5
View File
@@ -6,13 +6,13 @@ De la misma manera, puedes definir lógica (código) que debería ser ejecutada
Debido a que este código se ejecuta antes de que la aplicación **comience** a tomar requests, y justo después de que **termine** de manejarlos, cubre todo el **lifespan** de la aplicación (la palabra "lifespan" será importante en un momento 😉).
Esto puede ser muy útil para configurar **recursos** que necesitas usar para toda la app, y que son **compartidos** entre requests, y/o que necesitas **limpiar** después. Por ejemplo, un pool de conexiones a una base de datos, o cargando un modelo de machine learning compartido.
Esto puede ser muy útil para configurar **recursos** que necesitas usar para toda la app, y que son **compartidos** entre requests, y/o que necesitas **limpiar** después. Por ejemplo, un pool de conexiones a una base de datos, o cargando un modelo de Machine Learning compartido.
## Caso de Uso { #use-case }
Empecemos con un ejemplo de **caso de uso** y luego veamos cómo resolverlo con esto.
Imaginemos que tienes algunos **modelos de machine learning** que quieres usar para manejar requests. 🤖
Imaginemos que tienes algunos **modelos de Machine Learning** que quieres usar para manejar requests. 🤖
Los mismos modelos son compartidos entre requests, por lo que no es un modelo por request, o uno por usuario o algo similar.
@@ -32,7 +32,7 @@ Creamos una función asíncrona `lifespan()` con `yield` así:
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
Aquí estamos simulando la operación costosa de *startup* de cargar el modelo poniendo la función del (falso) modelo en el diccionario con modelos de machine learning antes del `yield`. Este código será ejecutado **antes** de que la aplicación **comience a tomar requests**, durante el *startup*.
Aquí estamos simulando la operación costosa de *startup* de cargar el modelo poniendo la función del (falso) modelo en el diccionario con modelos de Machine Learning antes del `yield`. Este código será ejecutado **antes** de que la aplicación **comience a tomar requests**, durante el *startup*.
Y luego, justo después del `yield`, quitaremos el modelo de memoria. Este código será ejecutado **después** de que la aplicación **termine de manejar requests**, justo antes del *shutdown*. Esto podría, por ejemplo, liberar recursos como la memoria o una GPU.
@@ -120,7 +120,7 @@ Para añadir una función que debería ejecutarse cuando la aplicación se esté
Aquí, la función manejadora del evento `shutdown` escribirá una línea de texto `"Application shutdown"` a un archivo `log.txt`.
/// info | Información
/// note | Nota
En la función `open()`, el `mode="a"` significa "añadir", por lo tanto, la línea será añadida después de lo que sea que esté en ese archivo, sin sobrescribir el contenido anterior.
@@ -152,7 +152,7 @@ Solo un detalle técnico para los nerds curiosos. 🤓
Por debajo, en la especificación técnica ASGI, esto es parte del [Protocolo de Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), y define eventos llamados `startup` y `shutdown`.
/// info | Información
/// note | Nota
Puedes leer más sobre los manejadores `lifespan` de Starlette en [la documentación de `Lifespan` de Starlette](https://www.starlette.dev/lifespan/).
+2 -17
View File
@@ -20,21 +20,6 @@ FastAPI genera automáticamente especificaciones **OpenAPI 3.1**, así que cualq
///
## Generadores de SDKs de sponsors de FastAPI { #sdk-generators-from-fastapi-sponsors }
Esta sección destaca soluciones **respaldadas por empresas** y **venture-backed** de compañías que sponsorean FastAPI. Estos productos ofrecen **funcionalidades adicionales** e **integraciones** además de SDKs generados de alta calidad.
Al ✨ [**sponsorear FastAPI**](../help-fastapi.md#sponsor-the-author) ✨, estas compañías ayudan a asegurar que el framework y su **ecosistema** se mantengan saludables y **sustentables**.
Su sponsorship también demuestra un fuerte compromiso con la **comunidad** de FastAPI (tú), mostrando que no solo les importa ofrecer un **gran servicio**, sino también apoyar un **framework robusto y próspero**, FastAPI. 🙇
Por ejemplo, podrías querer probar:
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
Algunas de estas soluciones también pueden ser open source u ofrecer niveles gratuitos, así que puedes probarlas sin un compromiso financiero. Hay otros generadores de SDK comerciales disponibles y se pueden encontrar en línea. 🤓
## Crea un SDK de TypeScript { #create-a-typescript-sdk }
Empecemos con una aplicación simple de FastAPI:
@@ -53,7 +38,7 @@ Puedes ver esos esquemas porque fueron declarados con los modelos en la app.
Esa información está disponible en el **OpenAPI schema** de la app, y luego se muestra en la documentación de la API.
Y esa misma información de los modelos que está incluida en OpenAPI es lo que puede usarse para **generar el código del cliente**.
Esa misma información de los modelos que está incluida en OpenAPI es lo que puede usarse para **generar el código del cliente**.
### Hey API { #hey-api }
@@ -132,7 +117,7 @@ Puedes **modificar** la forma en que estos operation IDs son **generados** para
En este caso tendrás que asegurarte de que cada operation ID sea **único** de alguna otra manera.
Por ejemplo, podrías asegurarte de que cada *path operation* tenga un tag, y luego generar el operation ID basado en el **tag** y el **name** de la *path operation* (el nombre de la función).
Por ejemplo, podrías asegurarte de que cada *path operation* tenga un tag, y luego generar el operation ID basado en el **tag** y el **nombre** de la *path operation* (el nombre de la función).
### Función personalizada para generar ID único { #custom-generate-unique-id-function }
+4 -4
View File
@@ -4,7 +4,7 @@ Si tu app necesita recibir y enviar datos JSON, pero necesitas incluir datos bin
## 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.
Considera primero si puedes usar [Archivos en request](../tutorial/request-files.md) para subir datos binarios y [Response personalizada - FileResponse](./custom-response.md#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.
@@ -14,7 +14,7 @@ Usa base64 solo si definitivamente necesitas incluir datos binarios en JSON y no
## 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.
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] *}
@@ -52,12 +52,12 @@ Recibirás una response como:
## 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.
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.
Y por supuesto, puedes usar el mismo modelo configurado para usar base64 para manejar tanto la entrada (*validar*) con `val_json_bytes` como la salida (*serializar*) 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] *}
+3 -3
View File
@@ -4,7 +4,7 @@ Podrías crear una API con una *path operation* que podría desencadenar un requ
El proceso que ocurre cuando tu aplicación API llama a la *API externa* se llama un "callback". Porque el software que escribió el desarrollador externo envía un request a tu API y luego tu API hace un *callback*, enviando un request a una *API externa* (que probablemente fue creada por el mismo desarrollador).
En este caso, podrías querer documentar cómo esa API externa *debería* verse. Qué *path operation* debería tener, qué cuerpo debería esperar, qué response debería devolver, etc.
En este caso, podrías querer documentar cómo esa API externa *debería* verse. Qué *path operation* debería tener, qué body debería esperar, qué response debería devolver, etc.
## Una aplicación con callbacks { #an-app-with-callbacks }
@@ -167,13 +167,13 @@ Observa cómo la URL del callback utilizada contiene la URL recibida como parám
En este punto tienes las *path operation(s)* del callback necesarias (las que el *desarrollador externo* debería implementar en la *API externa*) en el router de callback que creaste arriba.
Ahora usa el parámetro `callbacks` en el *decorador de path operation de tu API* para pasar el atributo `.routes` (que en realidad es solo un `list` de rutas/*path operations*) de ese router de callback:
Ahora usa el parámetro `callbacks` en el *decorador de path operation de tu API* para pasar el atributo `.routes` de ese router de callback:
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
/// tip | Consejo
Observa que no estás pasando el router en sí (`invoices_callback_router`) a `callback=`, sino el atributo `.routes`, como en `invoices_callback_router.routes`.
Observa que no estás pasando el router en sí (`invoices_callback_router`) a `callbacks=`, sino su `.routes`, como en `invoices_callback_router.routes`. FastAPI usará esas rutas para generar la documentación OpenAPI del callback.
///
+2 -2
View File
@@ -22,7 +22,7 @@ Con **FastAPI**, usando OpenAPI, puedes definir los nombres de estos webhooks, l
Esto puede hacer mucho más fácil para tus usuarios **implementar sus APIs** para recibir tus requests de **webhook**, incluso podrían ser capaces de autogenerar algo de su propio código de API.
/// info | Información
/// note | Nota
Los webhooks están disponibles en OpenAPI 3.1.0 y superiores, soportados por FastAPI `0.99.0` y superiores.
@@ -36,7 +36,7 @@ Cuando creas una aplicación de **FastAPI**, hay un atributo `webhooks` que pued
Los webhooks que defines terminarán en el esquema de **OpenAPI** y en la interfaz automática de **documentación**.
/// info | Información
/// note | Nota
El objeto `app.webhooks` es en realidad solo un `APIRouter`, el mismo tipo que usarías al estructurar tu aplicación con múltiples archivos.
@@ -16,17 +16,11 @@ Tendrías que asegurarte de que sea único para cada operación.
### Usar el nombre de la *path operation function* como el operationId { #using-the-path-operation-function-name-as-the-operationid }
Si quieres usar los nombres de las funciones de tus APIs como `operationId`s, puedes iterar sobre todas ellas y sobrescribir el `operation_id` de cada *path operation* usando su `APIRoute.name`.
Si quieres usar los nombres de las funciones de tus APIs como `operationId`s, puedes pasar una `generate_unique_id_function` personalizada a `FastAPI`.
Deberías hacerlo después de agregar todas tus *path operations*.
La función recibe cada `APIRoute` y devuelve el `operationId` a usar para esa *path operation*.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip | Consejo
Si llamas manualmente a `app.openapi()`, deberías actualizar los `operationId`s antes de eso.
///
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2,5:6,9] *}
/// warning | Advertencia
@@ -2,7 +2,7 @@
Probablemente leíste antes que puedes establecer un [Código de Estado de Response](../tutorial/response-status-code.md) por defecto.
Pero en algunos casos necesitas devolver un código de estado diferente al predeterminado.
Pero en algunos casos necesitas devolver un código de estado diferente al por defecto.
## Caso de uso { #use-case }
+3 -3
View File
@@ -1,6 +1,6 @@
# Cookies de Response { #response-cookies }
## Usar un parámetro `Response` { #use-a-response-parameter }
## Usa un parámetro `Response` { #use-a-response-parameter }
Puedes declarar un parámetro de tipo `Response` en tu *path operation function*.
@@ -16,11 +16,11 @@ Y si declaraste un `response_model`, todavía se utilizará para filtrar y conve
También puedes declarar el parámetro `Response` en las dependencias, y establecer cookies (y headers) en ellas.
## Devolver una `Response` directamente { #return-a-response-directly }
## Devuelve una `Response` directamente { #return-a-response-directly }
También puedes crear cookies al devolver una `Response` directamente en tu código.
Para hacer eso, puedes crear un response como se describe en [Devolver un Response Directamente](response-directly.md).
Para hacer eso, puedes crear un response como se describe en [Devuelve un Response Directamente](response-directly.md).
Luego establece Cookies en ella, y luego devuélvela:
+3 -3
View File
@@ -16,9 +16,9 @@ Normalmente tendrás mucho mejor rendimiento usando un [Response Model](../tutor
## Devolver una `Response` { #return-a-response }
De hecho, puedes devolver cualquier `Response` o cualquier subclase de ella.
Puedes devolver una `Response` o cualquier subclase de ella.
/// info | Información
/// note | Nota
`JSONResponse` en sí misma es una subclase de `Response`.
@@ -78,6 +78,6 @@ En su lugar, toma los bytes JSON generados con Pydantic usando el response model
Cuando devuelves una `Response` directamente, sus datos no son validados, convertidos (serializados), ni documentados automáticamente.
Pero aún puedes documentarlo como se describe en [Additional Responses in OpenAPI](additional-responses.md).
Pero aún puedes documentarlo como se describe en [Respuestas adicionales en OpenAPI](additional-responses.md).
Puedes ver en secciones posteriores cómo usar/declarar estas `Response`s personalizadas mientras todavía tienes conversión automática de datos, documentación, etc.
@@ -1,5 +1,6 @@
# Headers de Response { #response-headers }
## Usa un parámetro `Response` { #use-a-response-parameter }
Puedes declarar un parámetro de tipo `Response` en tu *path operation function* (como puedes hacer para cookies).
@@ -1,5 +1,6 @@
# Scopes de OAuth2 { #oauth2-scopes }
Puedes usar scopes de OAuth2 directamente con **FastAPI**, están integrados para funcionar de manera fluida.
Esto te permitiría tener un sistema de permisos más detallado, siguiendo el estándar de OAuth2, integrado en tu aplicación OpenAPI (y la documentación de la API).
@@ -46,7 +47,7 @@ Normalmente se utilizan para declarar permisos de seguridad específicos, por ej
* `instagram_basic` es usado por Facebook / Instagram.
* `https://www.googleapis.com/auth/drive` es usado por Google.
/// info | Información
/// note | Nota
En OAuth2 un "scope" es solo un string que declara un permiso específico requerido.
@@ -126,7 +127,7 @@ Lo estamos haciendo aquí para demostrar cómo **FastAPI** maneja scopes declara
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
/// info | Información Técnica
/// note | Detalles técnicos
`Security` es en realidad una subclase de `Depends`, y tiene solo un parámetro extra que veremos más adelante.
+11 -11
View File
@@ -20,7 +20,7 @@ Eso significa que cualquier valor leído en Python desde una variable de entorno
## Pydantic `Settings` { #pydantic-settings }
Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con [Pydantic: Settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con [Pydantic: Gestión de Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
### Instalar `pydantic-settings` { #install-pydantic-settings }
@@ -120,7 +120,7 @@ También necesitarías un archivo `__init__.py` como viste en [Aplicaciones Más
En algunas ocasiones podría ser útil proporcionar las configuraciones desde una dependencia, en lugar de tener un objeto global con `settings` que se use en todas partes.
Esto podría ser especialmente útil durante las pruebas, ya que es muy fácil sobrescribir una dependencia con tus propias configuraciones personalizadas.
Esto podría ser especialmente útil al escribir pruebas, ya que es muy fácil sobrescribir una dependencia con tus propias configuraciones personalizadas.
### El archivo de configuración { #the-config-file }
@@ -148,9 +148,9 @@ Y luego podemos requerirlo desde la *path operation function* como una dependenc
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
### Configuraciones y pruebas { #settings-and-testing }
### Configuraciones y escribir pruebas { #settings-and-testing }
Luego sería muy fácil proporcionar un objeto de configuraciones diferente durante las pruebas al crear una sobrescritura de dependencia para `get_settings`:
Luego sería muy fácil proporcionar un objeto de configuraciones diferente al escribir pruebas creando una sobrescritura de dependencia para `get_settings`:
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
@@ -160,7 +160,7 @@ Luego podemos probar que se está usando.
## Leer un archivo `.env` { #reading-a-env-file }
Si tienes muchas configuraciones que posiblemente cambien mucho, tal vez en diferentes entornos, podría ser útil ponerlos en un archivo y luego leerlos desde allí como si fueran variables de entorno.
Si tienes muchas configuraciones que posiblemente cambien mucho, tal vez en diferentes entornos, podría ser útil ponerlas en un archivo y luego leerlas desde allí como si fueran variables de entorno.
Esta práctica es lo suficientemente común que tiene un nombre, estas variables de entorno generalmente se colocan en un archivo `.env`, y el archivo se llama un "dotenv".
@@ -172,7 +172,7 @@ Pero un archivo dotenv realmente no tiene que tener ese nombre exacto.
///
Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en [Pydantic Settings: Dotenv (.env) support](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en [Pydantic Settings: soporte para Dotenv (.env)](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
/// tip | Consejo
@@ -197,7 +197,7 @@ Y luego actualizar tu `config.py` con:
/// tip | Consejo
El atributo `model_config` se usa solo para configuración de Pydantic. Puedes leer más en [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/).
El atributo `model_config` se usa solo para configuración de Pydantic. Puedes leer más en [Pydantic: Conceptos: Configuración](https://docs.pydantic.dev/latest/concepts/config/).
///
@@ -289,14 +289,14 @@ participant execute as Ejecutar función
En el caso de nuestra dependencia `get_settings()`, la función ni siquiera toma argumentos, por lo que siempre devuelve el mismo valor.
De esa manera, se comporta casi como si fuera solo una variable global. Pero como usa una función de dependencia, entonces podemos sobrescribirla fácilmente para las pruebas.
De esa manera, se comporta casi como si fuera solo una variable global. Pero como usa una función de dependencia, entonces podemos sobrescribirla fácilmente al escribir pruebas.
`@lru_cache` es parte de `functools`, que es parte del paquete estándar de Python, puedes leer más sobre él en las [docs de Python para `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
`@lru_cache` es parte de `functools`, que es parte del paquete estándar de Python, puedes leer más sobre él en la [documentación de Python para `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
## Resumen { #recap }
Puedes usar Pydantic Settings para manejar las configuraciones o ajustes de tu aplicación, con todo el poder de los modelos de Pydantic.
* Al usar una dependencia, puedes simplificar las pruebas.
* Al usar una dependencia, puedes simplificar la escritura de pruebas.
* Puedes usar archivos `.env` con él.
* Usar `@lru_cache` te permite evitar leer el archivo dotenv una y otra vez para cada request, mientras te permite sobrescribirlo durante las pruebas.
* Usar `@lru_cache` te permite evitar leer el archivo dotenv una y otra vez para cada request, mientras te permite sobrescribirlo al escribir pruebas.
+7 -7
View File
@@ -2,9 +2,9 @@
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.
Pero si quieres **transmitir datos binarios puros** o strings, aquí tienes cómo hacerlo.
/// info | Información
/// note | Nota
Añadido en FastAPI 0.134.0.
@@ -12,11 +12,11 @@ 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.
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 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.
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 }
@@ -40,7 +40,7 @@ Como FastAPI no intentará convertir los datos a JSON con Pydantic ni serializar
{* ../../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. 🤓
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 }
@@ -90,7 +90,7 @@ 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
/// note | Nota
El ejemplo anterior es en realidad una excepción, porque el objeto `io.BytesIO` ya está en memoria, así que leerlo no bloqueará nada.
+4 -4
View File
@@ -40,7 +40,7 @@ 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.
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.
@@ -69,9 +69,9 @@ Si tu app está en Internet abierta, no “confiarías en la red” ni permitir
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.
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.
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 }
@@ -81,7 +81,7 @@ Si necesitas soportar clientes que no envían un header `Content-Type`, puedes d
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
/// note | Nota
Este comportamiento y configuración se añadieron en FastAPI 0.132.0.
+1 -1
View File
@@ -111,7 +111,7 @@ Funcionan de la misma manera que para otros endpoints de FastAPI/*path operation
{* ../../docs_src/websockets_/tutorial002_an_py310.py hl[68:69,82] *}
/// info | Información
/// note | Nota
Como esto es un WebSocket no tiene mucho sentido lanzar un `HTTPException`, en su lugar lanzamos un `WebSocketException`.
+2 -1
View File
@@ -1,12 +1,13 @@
# Incluyendo WSGI - Flask, Django, otros { #including-wsgi-flask-django-others }
Puedes montar aplicaciones WSGI como viste con [Sub Aplicaciones - Mounts](sub-applications.md), [Detrás de un Proxy](behind-a-proxy.md).
Para eso, puedes usar el `WSGIMiddleware` y usarlo para envolver tu aplicación WSGI, por ejemplo, Flask, Django, etc.
## Usando `WSGIMiddleware` { #using-wsgimiddleware }
/// info | Información
/// note | Nota
Esto requiere instalar `a2wsgi`, por ejemplo con `pip install a2wsgi`.