Sync fastapi docs from 7cb06f36 on 2026-07-11
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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/).
|
||||
|
||||
|
||||
@@ -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,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] *}
|
||||
|
||||
@@ -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.
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user