mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-23 22:29:34 -05:00
🌐 Sync Spanish docs (outdated pages found with script) (#14553)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
@@ -414,11 +414,11 @@ Generará un esquema de OpenAPI como:
|
||||
},
|
||||
{
|
||||
"url": "https://stag.example.com",
|
||||
"description": "Entorno de pruebas"
|
||||
"description": "Staging environment"
|
||||
},
|
||||
{
|
||||
"url": "https://prod.example.com",
|
||||
"description": "Entorno de producción"
|
||||
"description": "Production environment"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
|
||||
@@ -220,7 +220,7 @@ Toma un generador `async` o un generador/iterador normal y transmite el cuerpo d
|
||||
|
||||
#### Usando `StreamingResponse` con objetos similares a archivos { #using-streamingresponse-with-file-like-objects }
|
||||
|
||||
Si tienes un objeto similar a un archivo (por ejemplo, el objeto devuelto por `open()`), puedes crear una función generadora para iterar sobre ese objeto similar a un archivo.
|
||||
Si tienes un <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">objeto similar a un archivo</a> (por ejemplo, el objeto devuelto por `open()`), puedes crear una función generadora para iterar sobre ese objeto similar a un archivo.
|
||||
|
||||
De esa manera, no tienes que leerlo todo primero en memoria, y puedes pasar esa función generadora al `StreamingResponse`, y devolverlo.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Eventos de Lifespan
|
||||
# Eventos de Lifespan { #lifespan-events }
|
||||
|
||||
Puedes definir lógica (código) que debería ser ejecutada antes de que la aplicación **inicie**. Esto significa que este código será ejecutado **una vez**, **antes** de que la aplicación **comience a recibir requests**.
|
||||
|
||||
@@ -8,7 +8,7 @@ Debido a que este código se ejecuta antes de que la aplicación **comience** a
|
||||
|
||||
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
|
||||
## Caso de Uso { #use-case }
|
||||
|
||||
Empecemos con un ejemplo de **caso de uso** y luego veamos cómo resolverlo con esto.
|
||||
|
||||
@@ -22,7 +22,7 @@ Podrías cargarlo en el nivel superior del módulo/archivo, pero eso también si
|
||||
|
||||
Eso es lo que resolveremos, vamos a cargar el modelo antes de que los requests sean manejados, pero solo justo antes de que la aplicación comience a recibir requests, no mientras el código se está cargando.
|
||||
|
||||
## Lifespan
|
||||
## Lifespan { #lifespan }
|
||||
|
||||
Puedes definir esta lógica de *startup* y *shutdown* usando el parámetro `lifespan` de la app de `FastAPI`, y un "context manager" (te mostraré lo que es en un momento).
|
||||
|
||||
@@ -44,7 +44,7 @@ Quizás necesites iniciar una nueva versión, o simplemente te cansaste de ejecu
|
||||
|
||||
///
|
||||
|
||||
### Función de Lifespan
|
||||
### Función de Lifespan { #lifespan-function }
|
||||
|
||||
Lo primero que hay que notar es que estamos definiendo una función asíncrona con `yield`. Esto es muy similar a las Dependencias con `yield`.
|
||||
|
||||
@@ -54,7 +54,7 @@ La primera parte de la función, antes del `yield`, será ejecutada **antes** de
|
||||
|
||||
Y la parte después del `yield` será ejecutada **después** de que la aplicación haya terminado.
|
||||
|
||||
### Async Context Manager
|
||||
### Async Context Manager { #async-context-manager }
|
||||
|
||||
Si revisas, la función está decorada con un `@asynccontextmanager`.
|
||||
|
||||
@@ -62,7 +62,7 @@ Eso convierte a la función en algo llamado un "**async context manager**".
|
||||
|
||||
{* ../../docs_src/events/tutorial003.py hl[1,13] *}
|
||||
|
||||
Un **context manager** en Python es algo que puedes usar en una declaración `with`, por ejemplo, `open()` puede ser usado como un context manager:
|
||||
Un **context manager** en Python es algo que puedes usar en un statement `with`, por ejemplo, `open()` puede ser usado como un context manager:
|
||||
|
||||
```Python
|
||||
with open("file.txt") as file:
|
||||
@@ -84,7 +84,7 @@ El parámetro `lifespan` de la app de `FastAPI` toma un **async context manager*
|
||||
|
||||
{* ../../docs_src/events/tutorial003.py hl[22] *}
|
||||
|
||||
## Eventos Alternativos (obsoleto)
|
||||
## Eventos Alternativos (obsoleto) { #alternative-events-deprecated }
|
||||
|
||||
/// warning | Advertencia
|
||||
|
||||
@@ -100,7 +100,7 @@ Puedes definir manejadores de eventos (funciones) que necesitan ser ejecutadas a
|
||||
|
||||
Estas funciones pueden ser declaradas con `async def` o `def` normal.
|
||||
|
||||
### Evento `startup`
|
||||
### Evento `startup` { #startup-event }
|
||||
|
||||
Para añadir una función que debería ejecutarse antes de que la aplicación inicie, declárala con el evento `"startup"`:
|
||||
|
||||
@@ -112,7 +112,7 @@ Puedes añadir más de un manejador de eventos.
|
||||
|
||||
Y tu aplicación no comenzará a recibir requests hasta que todos los manejadores de eventos `startup` hayan completado.
|
||||
|
||||
### Evento `shutdown`
|
||||
### Evento `shutdown` { #shutdown-event }
|
||||
|
||||
Para añadir una función que debería ejecutarse cuando la aplicación se esté cerrando, declárala con el evento `"shutdown"`:
|
||||
|
||||
@@ -138,7 +138,7 @@ Por eso, declaramos la función manejadora del evento con `def` estándar en vez
|
||||
|
||||
///
|
||||
|
||||
### `startup` y `shutdown` juntos
|
||||
### `startup` y `shutdown` juntos { #startup-and-shutdown-together }
|
||||
|
||||
Hay una gran posibilidad de que la lógica para tu *startup* y *shutdown* esté conectada, podrías querer iniciar algo y luego finalizarlo, adquirir un recurso y luego liberarlo, etc.
|
||||
|
||||
@@ -146,7 +146,7 @@ Hacer eso en funciones separadas que no comparten lógica o variables juntas es
|
||||
|
||||
Debido a eso, ahora se recomienda en su lugar usar el `lifespan` como se explicó arriba.
|
||||
|
||||
## Detalles Técnicos
|
||||
## Detalles Técnicos { #technical-details }
|
||||
|
||||
Solo un detalle técnico para los nerds curiosos. 🤓
|
||||
|
||||
@@ -160,6 +160,6 @@ Incluyendo cómo manejar el estado de lifespan que puede ser usado en otras áre
|
||||
|
||||
///
|
||||
|
||||
## Sub Aplicaciones
|
||||
## Sub Aplicaciones { #sub-applications }
|
||||
|
||||
🚨 Ten en cuenta que estos eventos de lifespan (startup y shutdown) solo serán ejecutados para la aplicación principal, no para [Sub Aplicaciones - Mounts](sub-applications.md){.internal-link target=_blank}.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Middleware Avanzado
|
||||
# Middleware Avanzado { #advanced-middleware }
|
||||
|
||||
En el tutorial principal leíste cómo agregar [Middleware Personalizado](../tutorial/middleware.md){.internal-link target=_blank} a tu aplicación.
|
||||
|
||||
@@ -6,9 +6,9 @@ Y luego también leíste cómo manejar [CORS con el `CORSMiddleware`](../tutoria
|
||||
|
||||
En esta sección veremos cómo usar otros middlewares.
|
||||
|
||||
## Agregando middlewares ASGI
|
||||
## Agregando middlewares ASGI { #adding-asgi-middlewares }
|
||||
|
||||
Como **FastAPI** está basado en Starlette e implementa la especificación <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr>, puedes usar cualquier middleware ASGI.
|
||||
Como **FastAPI** está basado en Starlette e implementa la especificación <abbr title="Asynchronous Server Gateway Interface – Interfaz de puerta de enlace de servidor asíncrona">ASGI</abbr>, puedes usar cualquier middleware ASGI.
|
||||
|
||||
Un middleware no tiene que estar hecho para FastAPI o Starlette para funcionar, siempre que siga la especificación ASGI.
|
||||
|
||||
@@ -39,7 +39,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
|
||||
|
||||
`app.add_middleware()` recibe una clase de middleware como primer argumento y cualquier argumento adicional que se le quiera pasar al middleware.
|
||||
|
||||
## Middlewares integrados
|
||||
## Middlewares integrados { #integrated-middlewares }
|
||||
|
||||
**FastAPI** incluye varios middlewares para casos de uso común, veremos a continuación cómo usarlos.
|
||||
|
||||
@@ -51,7 +51,7 @@ Para los próximos ejemplos, también podrías usar `from starlette.middleware.s
|
||||
|
||||
///
|
||||
|
||||
## `HTTPSRedirectMiddleware`
|
||||
## `HTTPSRedirectMiddleware` { #httpsredirectmiddleware }
|
||||
|
||||
Impone que todas las requests entrantes deben ser `https` o `wss`.
|
||||
|
||||
@@ -59,7 +59,7 @@ Cualquier request entrante a `http` o `ws` será redirigida al esquema seguro.
|
||||
|
||||
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
|
||||
|
||||
## `TrustedHostMiddleware`
|
||||
## `TrustedHostMiddleware` { #trustedhostmiddleware }
|
||||
|
||||
Impone que todas las requests entrantes tengan correctamente configurado el header `Host`, para proteger contra ataques de HTTP Host Header.
|
||||
|
||||
@@ -68,10 +68,11 @@ Impone que todas las requests entrantes tengan correctamente configurado el head
|
||||
Se soportan los siguientes argumentos:
|
||||
|
||||
* `allowed_hosts` - Una list de nombres de dominio que deberían ser permitidos como nombres de host. Se soportan dominios comodín como `*.example.com` para hacer coincidir subdominios. Para permitir cualquier nombre de host, usa `allowed_hosts=["*"]` u omite el middleware.
|
||||
* `www_redirect` - Si se establece en True, las requests a versiones sin www de los hosts permitidos serán redirigidas a sus equivalentes con www. Por defecto es `True`.
|
||||
|
||||
Si una request entrante no se valida correctamente, se enviará un response `400`.
|
||||
|
||||
## `GZipMiddleware`
|
||||
## `GZipMiddleware` { #gzipmiddleware }
|
||||
|
||||
Maneja responses GZip para cualquier request que incluya `"gzip"` en el header `Accept-Encoding`.
|
||||
|
||||
@@ -84,7 +85,7 @@ Se soportan los siguientes argumentos:
|
||||
* `minimum_size` - No comprimir con GZip responses que sean más pequeñas que este tamaño mínimo en bytes. Por defecto es `500`.
|
||||
* `compresslevel` - Usado durante la compresión GZip. Es un entero que varía de 1 a 9. Por defecto es `9`. Un valor más bajo resulta en una compresión más rápida pero archivos más grandes, mientras que un valor más alto resulta en una compresión más lenta pero archivos más pequeños.
|
||||
|
||||
## Otros middlewares
|
||||
## Otros middlewares { #other-middlewares }
|
||||
|
||||
Hay muchos otros middlewares ASGI.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Cookies de Response
|
||||
# Cookies de Response { #response-cookies }
|
||||
|
||||
## Usar un parámetro `Response`
|
||||
## Usar un parámetro `Response` { #use-a-response-parameter }
|
||||
|
||||
Puedes declarar un parámetro de tipo `Response` en tu *path operation function*.
|
||||
|
||||
@@ -16,7 +16,7 @@ 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
|
||||
## Devolver una `Response` directamente { #return-a-response-directly }
|
||||
|
||||
También puedes crear cookies al devolver una `Response` directamente en tu código.
|
||||
|
||||
@@ -36,7 +36,7 @@ Y también que no estés enviando ningún dato que debería haber sido filtrado
|
||||
|
||||
///
|
||||
|
||||
### Más información
|
||||
### Más información { #more-info }
|
||||
|
||||
/// note | Detalles Técnicos
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Response Headers
|
||||
# Headers de Response { #response-headers }
|
||||
|
||||
## Usa un parámetro `Response`
|
||||
## Usa un parámetro `Response` { #use-a-response-parameter }
|
||||
|
||||
Puedes declarar un parámetro de tipo `Response` en tu *función de path operation* (como puedes hacer para cookies).
|
||||
Puedes declarar un parámetro de tipo `Response` en tu *path operation function* (como puedes hacer para cookies).
|
||||
|
||||
Y luego puedes establecer headers en ese objeto de response *temporal*.
|
||||
|
||||
@@ -16,7 +16,7 @@ Y si declaraste un `response_model`, aún se usará para filtrar y convertir el
|
||||
|
||||
También puedes declarar el parámetro `Response` en dependencias y establecer headers (y cookies) en ellas.
|
||||
|
||||
## Retorna una `Response` directamente
|
||||
## Retorna una `Response` directamente { #return-a-response-directly }
|
||||
|
||||
También puedes agregar headers cuando devuelves un `Response` directamente.
|
||||
|
||||
@@ -34,8 +34,8 @@ Y como el `Response` se puede usar frecuentemente para establecer headers y cook
|
||||
|
||||
///
|
||||
|
||||
## Headers Personalizados
|
||||
## Headers Personalizados { #custom-headers }
|
||||
|
||||
Ten en cuenta que los headers propietarios personalizados se pueden agregar <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando el prefijo 'X-'</a>.
|
||||
Ten en cuenta que los headers propietarios personalizados se pueden agregar <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando el prefijo `X-`</a>.
|
||||
|
||||
Pero si tienes headers personalizados que quieres que un cliente en un navegador pueda ver, necesitas agregarlos a tus configuraciones de CORS (leer más en [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando el parámetro `expose_headers` documentado en <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">la documentación CORS de Starlette</a>.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Scopes de OAuth2
|
||||
# Scopes de OAuth2 { #oauth2-scopes }
|
||||
|
||||
Puedes usar scopes de OAuth2 directamente con **FastAPI**, están integrados para funcionar de manera fluida.
|
||||
|
||||
@@ -26,7 +26,7 @@ Pero si sabes que lo necesitas, o tienes curiosidad, sigue leyendo.
|
||||
|
||||
///
|
||||
|
||||
## Scopes de OAuth2 y OpenAPI
|
||||
## Scopes de OAuth2 y OpenAPI { #oauth2-scopes-and-openapi }
|
||||
|
||||
La especificación de OAuth2 define "scopes" como una lista de strings separados por espacios.
|
||||
|
||||
@@ -58,15 +58,15 @@ Para OAuth2 son solo strings.
|
||||
|
||||
///
|
||||
|
||||
## Vista global
|
||||
## Vista global { #global-view }
|
||||
|
||||
Primero, echemos un vistazo rápido a las partes que cambian desde los ejemplos en el **Tutorial - User Guide** principal para [OAuth2 con Password (y hashing), Bearer con tokens JWT](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Ahora usando scopes de OAuth2:
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:125,129:135,140,156] *}
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
|
||||
|
||||
Ahora revisemos esos cambios paso a paso.
|
||||
|
||||
## Esquema de seguridad OAuth2
|
||||
## Esquema de seguridad OAuth2 { #oauth2-security-scheme }
|
||||
|
||||
El primer cambio es que ahora estamos declarando el esquema de seguridad OAuth2 con dos scopes disponibles, `me` y `items`.
|
||||
|
||||
@@ -82,7 +82,7 @@ Este es el mismo mecanismo utilizado cuando das permisos al iniciar sesión con
|
||||
|
||||
<img src="/img/tutorial/security/image11.png">
|
||||
|
||||
## Token JWT con scopes
|
||||
## Token JWT con scopes { #jwt-token-with-scopes }
|
||||
|
||||
Ahora, modifica la *path operation* del token para devolver los scopes solicitados.
|
||||
|
||||
@@ -98,9 +98,9 @@ Pero en tu aplicación, por seguridad, deberías asegurarte de añadir solo los
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[156] *}
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[157] *}
|
||||
|
||||
## Declarar scopes en *path operations* y dependencias
|
||||
## Declarar scopes en *path operations* y dependencias { #declare-scopes-in-path-operations-and-dependencies }
|
||||
|
||||
Ahora declaramos que la *path operation* para `/users/me/items/` requiere el scope `items`.
|
||||
|
||||
@@ -124,7 +124,7 @@ Lo estamos haciendo aquí para demostrar cómo **FastAPI** maneja scopes declara
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,140,171] *}
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,141,172] *}
|
||||
|
||||
/// info | Información Técnica
|
||||
|
||||
@@ -136,7 +136,7 @@ Pero cuando importas `Query`, `Path`, `Depends`, `Security` y otros de `fastapi`
|
||||
|
||||
///
|
||||
|
||||
## Usar `SecurityScopes`
|
||||
## Usar `SecurityScopes` { #use-securityscopes }
|
||||
|
||||
Ahora actualiza la dependencia `get_current_user`.
|
||||
|
||||
@@ -152,7 +152,7 @@ Esta clase `SecurityScopes` es similar a `Request` (`Request` se usó para obten
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[9,106] *}
|
||||
|
||||
## Usar los `scopes`
|
||||
## Usar los `scopes` { #use-the-scopes }
|
||||
|
||||
El parámetro `security_scopes` será del tipo `SecurityScopes`.
|
||||
|
||||
@@ -166,7 +166,7 @@ En esta excepción, incluimos los scopes requeridos (si los hay) como un string
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[106,108:116] *}
|
||||
|
||||
## Verificar el `username` y la forma de los datos
|
||||
## Verificar el `username` y la forma de los datos { #verify-the-username-and-data-shape }
|
||||
|
||||
Verificamos que obtenemos un `username`, y extraemos los scopes.
|
||||
|
||||
@@ -180,17 +180,17 @@ En lugar de, por ejemplo, un `dict`, o algo más, ya que podría romper la aplic
|
||||
|
||||
También verificamos que tenemos un usuario con ese username, y si no, lanzamos esa misma excepción que creamos antes.
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:128] *}
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[47,117:129] *}
|
||||
|
||||
## Verificar los `scopes`
|
||||
## Verificar los `scopes` { #verify-the-scopes }
|
||||
|
||||
Ahora verificamos que todos los scopes requeridos, por esta dependencia y todos los dependientes (incluyendo *path operations*), estén incluidos en los scopes proporcionados en el token recibido, de lo contrario, lanzamos una `HTTPException`.
|
||||
|
||||
Para esto, usamos `security_scopes.scopes`, que contiene una `list` con todos estos scopes como `str`.
|
||||
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[129:135] *}
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[130:136] *}
|
||||
|
||||
## Árbol de dependencias y scopes
|
||||
## Árbol de dependencias y scopes { #dependency-tree-and-scopes }
|
||||
|
||||
Revisemos de nuevo este árbol de dependencias y los scopes.
|
||||
|
||||
@@ -223,7 +223,7 @@ Todo depende de los `scopes` declarados en cada *path operation* y cada dependen
|
||||
|
||||
///
|
||||
|
||||
## Más detalles sobre `SecurityScopes`
|
||||
## Más detalles sobre `SecurityScopes` { #more-details-about-securityscopes }
|
||||
|
||||
Puedes usar `SecurityScopes` en cualquier punto, y en múltiples lugares, no tiene que ser en la dependencia "raíz".
|
||||
|
||||
@@ -233,7 +233,7 @@ Debido a que `SecurityScopes` tendrá todos los scopes declarados por dependient
|
||||
|
||||
Serán verificados independientemente para cada *path operation*.
|
||||
|
||||
## Revisa
|
||||
## Revisa { #check-it }
|
||||
|
||||
Si abres la documentación de la API, puedes autenticarte y especificar qué scopes deseas autorizar.
|
||||
|
||||
@@ -245,7 +245,7 @@ Y si seleccionas el scope `me` pero no el scope `items`, podrás acceder a `/use
|
||||
|
||||
Eso es lo que pasaría a una aplicación de terceros que intentara acceder a una de estas *path operations* con un token proporcionado por un usuario, dependiendo de cuántos permisos el usuario otorgó a la aplicación.
|
||||
|
||||
## Acerca de las integraciones de terceros
|
||||
## Acerca de las integraciones de terceros { #about-third-party-integrations }
|
||||
|
||||
En este ejemplo estamos usando el flujo de OAuth2 "password".
|
||||
|
||||
@@ -269,6 +269,6 @@ Pero al final, están implementando el mismo estándar OAuth2.
|
||||
|
||||
**FastAPI** incluye utilidades para todos estos flujos de autenticación OAuth2 en `fastapi.security.oauth2`.
|
||||
|
||||
## `Security` en `dependencies` del decorador
|
||||
## `Security` en `dependencies` del decorador { #security-in-decorator-dependencies }
|
||||
|
||||
De la misma manera que puedes definir una `list` de `Depends` en el parámetro `dependencies` del decorador (como se explica en [Dependencias en decoradores de path operation](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), también podrías usar `Security` con `scopes` allí.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Plantillas
|
||||
# Plantillas { #templates }
|
||||
|
||||
Puedes usar cualquier motor de plantillas que desees con **FastAPI**.
|
||||
|
||||
@@ -6,7 +6,7 @@ Una elección común es Jinja2, el mismo que usa Flask y otras herramientas.
|
||||
|
||||
Hay utilidades para configurarlo fácilmente que puedes usar directamente en tu aplicación de **FastAPI** (proporcionadas por Starlette).
|
||||
|
||||
## Instalar dependencias
|
||||
## Instala dependencias { #install-dependencies }
|
||||
|
||||
Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo e instalar `jinja2`:
|
||||
|
||||
@@ -20,7 +20,7 @@ $ pip install jinja2
|
||||
|
||||
</div>
|
||||
|
||||
## Usando `Jinja2Templates`
|
||||
## Usando `Jinja2Templates` { #using-jinja2templates }
|
||||
|
||||
* Importa `Jinja2Templates`.
|
||||
* Crea un objeto `templates` que puedas reutilizar más tarde.
|
||||
@@ -51,7 +51,7 @@ También podrías usar `from starlette.templating import Jinja2Templates`.
|
||||
|
||||
///
|
||||
|
||||
## Escribiendo plantillas
|
||||
## Escribiendo plantillas { #writing-templates }
|
||||
|
||||
Luego puedes escribir una plantilla en `templates/item.html` con, por ejemplo:
|
||||
|
||||
@@ -59,7 +59,7 @@ Luego puedes escribir una plantilla en `templates/item.html` con, por ejemplo:
|
||||
{!../../docs_src/templates/templates/item.html!}
|
||||
```
|
||||
|
||||
### Valores de Contexto de la Plantilla
|
||||
### Valores de Contexto de la Plantilla { #template-context-values }
|
||||
|
||||
En el HTML que contiene:
|
||||
|
||||
@@ -83,7 +83,7 @@ Por ejemplo, con un ID de `42`, esto se renderizaría como:
|
||||
Item ID: 42
|
||||
```
|
||||
|
||||
### Argumentos de la Plantilla `url_for`
|
||||
### Argumentos de la Plantilla `url_for` { #template-url-for-arguments }
|
||||
|
||||
También puedes usar `url_for()` dentro de la plantilla, toma como argumentos los mismos que usaría tu *path operation function*.
|
||||
|
||||
@@ -105,7 +105,7 @@ Por ejemplo, con un ID de `42`, esto se renderizaría como:
|
||||
<a href="/items/42">
|
||||
```
|
||||
|
||||
## Plantillas y archivos estáticos
|
||||
## Plantillas y archivos estáticos { #templates-and-static-files }
|
||||
|
||||
También puedes usar `url_for()` dentro de la plantilla, y usarlo, por ejemplo, con los `StaticFiles` que montaste con el `name="static"`.
|
||||
|
||||
@@ -121,6 +121,6 @@ En este ejemplo, enlazaría a un archivo CSS en `static/styles.css` con:
|
||||
|
||||
Y porque estás usando `StaticFiles`, ese archivo CSS sería servido automáticamente por tu aplicación de **FastAPI** en la URL `/static/styles.css`.
|
||||
|
||||
## Más detalles
|
||||
## Más detalles { #more-details }
|
||||
|
||||
Para más detalles, incluyendo cómo testear plantillas, revisa <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">la documentación de Starlette sobre plantillas</a>.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Probando WebSockets
|
||||
# Probando WebSockets { #testing-websockets }
|
||||
|
||||
Puedes usar el mismo `TestClient` para probar WebSockets.
|
||||
|
||||
@@ -8,6 +8,6 @@ Para esto, usas el `TestClient` en un statement `with`, conectándote al WebSock
|
||||
|
||||
/// note | Nota
|
||||
|
||||
Para más detalles, revisa la documentación de Starlette sobre <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">probando sesiones WebSocket</a>.
|
||||
Para más detalles, revisa la documentación de Starlette sobre <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">probar WebSockets</a>.
|
||||
|
||||
///
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Usar el Request Directamente
|
||||
# Usar el Request Directamente { #using-the-request-directly }
|
||||
|
||||
Hasta ahora, has estado declarando las partes del request que necesitas con sus tipos.
|
||||
|
||||
@@ -13,7 +13,7 @@ Y al hacerlo, **FastAPI** está validando esos datos, convirtiéndolos y generan
|
||||
|
||||
Pero hay situaciones donde podrías necesitar acceder al objeto `Request` directamente.
|
||||
|
||||
## Detalles sobre el objeto `Request`
|
||||
## Detalles sobre el objeto `Request` { #details-about-the-request-object }
|
||||
|
||||
Como **FastAPI** es en realidad **Starlette** por debajo, con una capa de varias herramientas encima, puedes usar el objeto <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a> de Starlette directamente cuando lo necesites.
|
||||
|
||||
@@ -23,7 +23,7 @@ Aunque cualquier otro parámetro declarado normalmente (por ejemplo, el cuerpo c
|
||||
|
||||
Pero hay casos específicos donde es útil obtener el objeto `Request`.
|
||||
|
||||
## Usa el objeto `Request` directamente
|
||||
## Usa el objeto `Request` directamente { #use-the-request-object-directly }
|
||||
|
||||
Imaginemos que quieres obtener la dirección IP/host del cliente dentro de tu *path operation function*.
|
||||
|
||||
@@ -43,7 +43,7 @@ De la misma manera, puedes declarar cualquier otro parámetro como normalmente,
|
||||
|
||||
///
|
||||
|
||||
## Documentación de `Request`
|
||||
## Documentación de `Request` { #request-documentation }
|
||||
|
||||
Puedes leer más detalles sobre el <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">objeto `Request` en el sitio de documentación oficial de Starlette</a>.
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# WebSockets
|
||||
# WebSockets { #websockets }
|
||||
|
||||
Puedes usar <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a> con **FastAPI**.
|
||||
|
||||
## Instalar `WebSockets`
|
||||
## Instalar `websockets` { #install-websockets }
|
||||
|
||||
Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo e instalar `websockets`:
|
||||
Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo e instalar `websockets` (un paquete de Python que facilita usar el protocolo "WebSocket"):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -16,9 +16,9 @@ $ pip install websockets
|
||||
|
||||
</div>
|
||||
|
||||
## Cliente WebSockets
|
||||
## Cliente WebSockets { #websockets-client }
|
||||
|
||||
### En producción
|
||||
### En producción { #in-production }
|
||||
|
||||
En tu sistema de producción, probablemente tengas un frontend creado con un framework moderno como React, Vue.js o Angular.
|
||||
|
||||
@@ -40,7 +40,7 @@ Pero es la forma más sencilla de enfocarse en el lado del servidor de WebSocket
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
|
||||
|
||||
## Crear un `websocket`
|
||||
## Crear un `websocket` { #create-a-websocket }
|
||||
|
||||
En tu aplicación de **FastAPI**, crea un `websocket`:
|
||||
|
||||
@@ -54,7 +54,7 @@ También podrías usar `from starlette.websockets import WebSocket`.
|
||||
|
||||
///
|
||||
|
||||
## Esperar mensajes y enviar mensajes
|
||||
## Esperar mensajes y enviar mensajes { #await-for-messages-and-send-messages }
|
||||
|
||||
En tu ruta de WebSocket puedes `await` para recibir mensajes y enviar mensajes.
|
||||
|
||||
@@ -62,7 +62,7 @@ En tu ruta de WebSocket puedes `await` para recibir mensajes y enviar mensajes.
|
||||
|
||||
Puedes recibir y enviar datos binarios, de texto y JSON.
|
||||
|
||||
## Pruébalo
|
||||
## Pruébalo { #try-it }
|
||||
|
||||
Si tu archivo se llama `main.py`, ejecuta tu aplicación con:
|
||||
|
||||
@@ -96,7 +96,7 @@ Puedes enviar (y recibir) muchos mensajes:
|
||||
|
||||
Y todos usarán la misma conexión WebSocket.
|
||||
|
||||
## Usando `Depends` y otros
|
||||
## Usando `Depends` y otros { #using-depends-and-others }
|
||||
|
||||
En endpoints de WebSocket puedes importar desde `fastapi` y usar:
|
||||
|
||||
@@ -119,7 +119,7 @@ Puedes usar un código de cierre de los <a href="https://tools.ietf.org/html/rfc
|
||||
|
||||
///
|
||||
|
||||
### Prueba los WebSockets con dependencias
|
||||
### Prueba los WebSockets con dependencias { #try-the-websockets-with-dependencies }
|
||||
|
||||
Si tu archivo se llama `main.py`, ejecuta tu aplicación con:
|
||||
|
||||
@@ -150,7 +150,7 @@ Con eso puedes conectar el WebSocket y luego enviar y recibir mensajes:
|
||||
|
||||
<img src="/img/tutorial/websockets/image05.png">
|
||||
|
||||
## Manejar desconexiones y múltiples clientes
|
||||
## Manejar desconexiones y múltiples clientes { #handling-disconnections-and-multiple-clients }
|
||||
|
||||
Cuando una conexión de WebSocket se cierra, el `await websocket.receive_text()` lanzará una excepción `WebSocketDisconnect`, que puedes capturar y manejar como en este ejemplo.
|
||||
|
||||
@@ -178,7 +178,7 @@ Si necesitas algo fácil de integrar con FastAPI pero que sea más robusto, sopo
|
||||
|
||||
///
|
||||
|
||||
## Más información
|
||||
## Más información { #more-info }
|
||||
|
||||
Para aprender más sobre las opciones, revisa la documentación de Starlette para:
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Alternativas, Inspiración y Comparaciones
|
||||
# Alternativas, Inspiración y Comparaciones { #alternatives-inspiration-and-comparisons }
|
||||
|
||||
Lo que inspiró a **FastAPI**, cómo se compara con las alternativas y lo que aprendió de ellas.
|
||||
|
||||
## Introducción
|
||||
## Introducción { #intro }
|
||||
|
||||
**FastAPI** no existiría si no fuera por el trabajo previo de otros.
|
||||
|
||||
@@ -12,17 +12,17 @@ He estado evitando la creación de un nuevo framework durante varios años. Prim
|
||||
|
||||
Pero en algún punto, no hubo otra opción que crear algo que proporcionara todas estas funcionalidades, tomando las mejores ideas de herramientas previas y combinándolas de la mejor manera posible, usando funcionalidades del lenguaje que ni siquiera estaban disponibles antes (anotaciones de tipos de Python 3.6+).
|
||||
|
||||
## Herramientas previas
|
||||
## Herramientas previas { #previous-tools }
|
||||
|
||||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a>
|
||||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
|
||||
|
||||
Es el framework más popular de Python y es ampliamente confiable. Se utiliza para construir sistemas como Instagram.
|
||||
|
||||
Está relativamente acoplado con bases de datos relacionales (como MySQL o PostgreSQL), por lo que tener una base de datos NoSQL (como Couchbase, MongoDB, Cassandra, etc) como motor de almacenamiento principal no es muy fácil.
|
||||
|
||||
Fue creado para generar el HTML en el backend, no para crear APIs utilizadas por un frontend moderno (como React, Vue.js y Angular) o por otros sistemas (como dispositivos del <abbr title="Internet of Things">IoT</abbr>) comunicándose con él.
|
||||
Fue creado para generar el HTML en el backend, no para crear APIs utilizadas por un frontend moderno (como React, Vue.js y Angular) o por otros sistemas (como dispositivos del <abbr title="Internet of Things – Internet de las cosas">IoT</abbr>) comunicándose con él.
|
||||
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a>
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
|
||||
|
||||
El framework Django REST fue creado para ser un kit de herramientas flexible para construir APIs Web utilizando Django, mejorando sus capacidades API.
|
||||
|
||||
@@ -42,7 +42,7 @@ Tener una interfaz de usuario web de documentación automática de APIs.
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a>
|
||||
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
|
||||
|
||||
Flask es un "microframework", no incluye integraciones de bases de datos ni muchas de las cosas que vienen por defecto en Django.
|
||||
|
||||
@@ -64,7 +64,7 @@ Tener un sistema de routing simple y fácil de usar.
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a>
|
||||
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
|
||||
|
||||
**FastAPI** no es en realidad una alternativa a **Requests**. Su ámbito es muy diferente.
|
||||
|
||||
@@ -106,7 +106,7 @@ Mira las similitudes entre `requests.get(...)` y `@app.get(...)`.
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a>
|
||||
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> { #swagger-openapi }
|
||||
|
||||
La principal funcionalidad que quería de Django REST Framework era la documentación automática de la API.
|
||||
|
||||
@@ -131,11 +131,11 @@ Estas dos fueron elegidas por ser bastante populares y estables, pero haciendo u
|
||||
|
||||
///
|
||||
|
||||
### Frameworks REST para Flask
|
||||
### Frameworks REST para Flask { #flask-rest-frameworks }
|
||||
|
||||
Existen varios frameworks REST para Flask, pero después de invertir tiempo y trabajo investigándolos, encontré que muchos son descontinuados o abandonados, con varios problemas existentes que los hacían inadecuados.
|
||||
|
||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a>
|
||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
|
||||
|
||||
Una de las principales funcionalidades necesitadas por los sistemas API es la "<abbr title="también llamada marshalling, conversión">serialización</abbr>" de datos, que consiste en tomar datos del código (Python) y convertirlos en algo que pueda ser enviado a través de la red. Por ejemplo, convertir un objeto que contiene datos de una base de datos en un objeto JSON. Convertir objetos `datetime` en strings, etc.
|
||||
|
||||
@@ -153,7 +153,7 @@ Usar código para definir "esquemas" que proporcionen tipos de datos y validaci
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a>
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
|
||||
|
||||
Otra gran funcionalidad requerida por las APIs es el <abbr title="lectura y conversión a datos de Python">parse</abbr> de datos de las requests entrantes.
|
||||
|
||||
@@ -175,7 +175,7 @@ Tener validación automática de datos entrantes en una request.
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a>
|
||||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
|
||||
|
||||
Marshmallow y Webargs proporcionan validación, parse y serialización como plug-ins.
|
||||
|
||||
@@ -205,7 +205,7 @@ Soportar el estándar abierto para APIs, OpenAPI.
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a>
|
||||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> { #flask-apispec }
|
||||
|
||||
Es un plug-in de Flask, que conecta juntos Webargs, Marshmallow y APISpec.
|
||||
|
||||
@@ -237,7 +237,7 @@ Generar el esquema OpenAPI automáticamente, desde el mismo código que define l
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (y <a href="https://angular.io/" class="external-link" target="_blank">Angular</a>)
|
||||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (y <a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) { #nestjs-and-angular }
|
||||
|
||||
Esto ni siquiera es Python, NestJS es un framework de JavaScript (TypeScript) NodeJS inspirado por Angular.
|
||||
|
||||
@@ -259,7 +259,7 @@ Tener un poderoso sistema de inyección de dependencias. Encontrar una forma de
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a>
|
||||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> { #sanic }
|
||||
|
||||
Fue uno de los primeros frameworks de Python extremadamente rápidos basados en `asyncio`. Fue hecho para ser muy similar a Flask.
|
||||
|
||||
@@ -279,7 +279,7 @@ Por eso **FastAPI** se basa en Starlette, ya que es el framework más rápido di
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a>
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
|
||||
|
||||
Falcon es otro framework de Python de alto rendimiento, está diseñado para ser minimalista y funcionar como la base de otros frameworks como Hug.
|
||||
|
||||
@@ -297,7 +297,7 @@ Aunque en FastAPI es opcional, y se utiliza principalmente para configurar heade
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a>
|
||||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
|
||||
|
||||
Descubrí Molten en las primeras etapas de construcción de **FastAPI**. Y tiene ideas bastante similares:
|
||||
|
||||
@@ -321,7 +321,7 @@ Esto en realidad inspiró la actualización de partes de Pydantic, para soportar
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>
|
||||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a> { #hug }
|
||||
|
||||
Hug fue uno de los primeros frameworks en implementar la declaración de tipos de parámetros API usando las anotaciones de tipos de Python. Esta fue una gran idea que inspiró a otras herramientas a hacer lo mismo.
|
||||
|
||||
@@ -351,7 +351,7 @@ Hug inspiró a **FastAPI** a declarar un parámetro `response` en funciones para
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5)
|
||||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) { #apistar-0-5 }
|
||||
|
||||
Justo antes de decidir construir **FastAPI** encontré **APIStar** server. Tenía casi todo lo que estaba buscando y tenía un gran diseño.
|
||||
|
||||
@@ -399,9 +399,9 @@ Considero a **FastAPI** un "sucesor espiritual" de APIStar, mientras mejora y au
|
||||
|
||||
///
|
||||
|
||||
## Usado por **FastAPI**
|
||||
## Usado por **FastAPI** { #used-by-fastapi }
|
||||
|
||||
### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>
|
||||
### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> { #pydantic }
|
||||
|
||||
Pydantic es un paquete para definir validación de datos, serialización y documentación (usando JSON Schema) basándose en las anotaciones de tipos de Python.
|
||||
|
||||
@@ -417,9 +417,9 @@ Manejar toda la validación de datos, serialización de datos y documentación a
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
|
||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
||||
|
||||
Starlette es un framework/toolkit <abbr title="El nuevo estándar para construir aplicaciones web asíncronas en Python">ASGI</abbr> liviano, ideal para construir servicios asyncio de alto rendimiento.
|
||||
Starlette es un framework/toolkit <abbr title="The new standard for building asynchronous Python web applications – El nuevo estándar para construir aplicaciones web asíncronas en Python">ASGI</abbr> liviano, ideal para construir servicios asyncio de alto rendimiento.
|
||||
|
||||
Es muy simple e intuitivo. Está diseñado para ser fácilmente extensible y tener componentes modulares.
|
||||
|
||||
@@ -462,7 +462,7 @@ Por lo tanto, cualquier cosa que puedas hacer con Starlette, puedes hacerlo dire
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>
|
||||
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
|
||||
|
||||
Uvicorn es un servidor ASGI extremadamente rápido, construido sobre uvloop y httptools.
|
||||
|
||||
@@ -480,6 +480,6 @@ Revisa más detalles en la sección [Despliegue](deployment/index.md){.internal-
|
||||
|
||||
///
|
||||
|
||||
## Benchmarks y velocidad
|
||||
## Benchmarks y velocidad { #benchmarks-and-speed }
|
||||
|
||||
Para entender, comparar, y ver la diferencia entre Uvicorn, Starlette y FastAPI, revisa la sección sobre [Benchmarks](benchmarks.md){.internal-link target=_blank}.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Concurrencia y async / await
|
||||
# Concurrencia y async / await { #concurrency-and-async-await }
|
||||
|
||||
Detalles sobre la sintaxis `async def` para *path operation functions* y algunos antecedentes sobre el código asíncrono, la concurrencia y el paralelismo.
|
||||
|
||||
## ¿Con prisa?
|
||||
## ¿Con prisa? { #in-a-hurry }
|
||||
|
||||
<abbr title="too long; didn't read"><strong>TL;DR:</strong></abbr>
|
||||
|
||||
@@ -40,7 +40,7 @@ def results():
|
||||
|
||||
---
|
||||
|
||||
Si tu aplicación (de alguna manera) no tiene que comunicarse con nada más y esperar a que responda, usa `async def`.
|
||||
Si tu aplicación (de alguna manera) no tiene que comunicarse con nada más y esperar a que responda, usa `async def`, incluso si no necesitas usar `await` dentro.
|
||||
|
||||
---
|
||||
|
||||
@@ -54,7 +54,7 @@ De todos modos, en cualquiera de los casos anteriores, FastAPI seguirá funciona
|
||||
|
||||
Pero al seguir los pasos anteriores, podrá hacer algunas optimizaciones de rendimiento.
|
||||
|
||||
## Detalles Técnicos
|
||||
## Detalles Técnicos { #technical-details }
|
||||
|
||||
Las versiones modernas de Python tienen soporte para **"código asíncrono"** utilizando algo llamado **"coroutines"**, con la sintaxis **`async` y `await`**.
|
||||
|
||||
@@ -64,7 +64,7 @@ Veamos esa frase por partes en las secciones a continuación:
|
||||
* **`async` y `await`**
|
||||
* **Coroutines**
|
||||
|
||||
## Código Asíncrono
|
||||
## Código Asíncrono { #asynchronous-code }
|
||||
|
||||
El código asíncrono simplemente significa que el lenguaje 💬 tiene una forma de decirle a la computadora / programa 🤖 que en algún momento del código, tendrá que esperar que *otra cosa* termine en otro lugar. Digamos que esa *otra cosa* se llama "archivo-lento" 📝.
|
||||
|
||||
@@ -74,7 +74,7 @@ Luego la computadora / programa 🤖 volverá cada vez que tenga una oportunidad
|
||||
|
||||
Después, 🤖 toma la primera tarea que termine (digamos, nuestro "archivo-lento" 📝) y continúa con lo que tenía que hacer con ella.
|
||||
|
||||
Ese "esperar otra cosa" normalmente se refiere a las operaciones de <abbr title="Input and Output">I/O</abbr> que son relativamente "lentas" (comparadas con la velocidad del procesador y la memoria RAM), como esperar:
|
||||
Ese "esperar otra cosa" normalmente se refiere a las operaciones de <abbr title="Input and Output – Entrada y salida">I/O</abbr> que son relativamente "lentas" (comparadas con la velocidad del procesador y la memoria RAM), como esperar:
|
||||
|
||||
* que los datos del cliente se envíen a través de la red
|
||||
* que los datos enviados por tu programa sean recibidos por el cliente a través de la red
|
||||
@@ -85,7 +85,7 @@ Ese "esperar otra cosa" normalmente se refiere a las operaciones de <abbr title=
|
||||
* que una query de base de datos devuelva los resultados
|
||||
* etc.
|
||||
|
||||
Como el tiempo de ejecución se consume principalmente esperando operaciones de <abbr title="Input and Output">I/O</abbr>, las llaman operaciones "I/O bound".
|
||||
Como el tiempo de ejecución se consume principalmente esperando operaciones de <abbr title="Input and Output – Entrada y salida">I/O</abbr>, las llaman operaciones "I/O bound".
|
||||
|
||||
Se llama "asíncrono" porque la computadora / programa no tiene que estar "sincronizado" con la tarea lenta, esperando el momento exacto en que la tarea termine, sin hacer nada, para poder tomar el resultado de la tarea y continuar el trabajo.
|
||||
|
||||
@@ -93,7 +93,7 @@ En lugar de eso, al ser un sistema "asíncrono", una vez terminado, la tarea pue
|
||||
|
||||
Para el "sincrónico" (contrario al "asíncrono") comúnmente también usan el término "secuencial", porque la computadora / programa sigue todos los pasos en secuencia antes de cambiar a una tarea diferente, incluso si esos pasos implican esperar.
|
||||
|
||||
### Concurrencia y Hamburguesas
|
||||
### Concurrencia y Hamburguesas { #concurrency-and-burgers }
|
||||
|
||||
Esta idea de código **asíncrono** descrita anteriormente a veces también se llama **"concurrencia"**. Es diferente del **"paralelismo"**.
|
||||
|
||||
@@ -103,7 +103,7 @@ Pero los detalles entre *concurrencia* y *paralelismo* son bastante diferentes.
|
||||
|
||||
Para ver la diferencia, imagina la siguiente historia sobre hamburguesas:
|
||||
|
||||
### Hamburguesas Concurrentes
|
||||
### Hamburguesas Concurrentes { #concurrent-burgers }
|
||||
|
||||
Vas con tu crush a conseguir comida rápida, te pones en fila mientras el cajero toma los pedidos de las personas frente a ti. 😍
|
||||
|
||||
@@ -163,7 +163,7 @@ Así que esperas a que tu crush termine la historia (termine el trabajo ⏯ / ta
|
||||
|
||||
Luego vas al mostrador 🔀, a la tarea inicial que ahora está terminada ⏯, recoges las hamburguesas, das las gracias y las llevas a la mesa. Eso termina ese paso / tarea de interacción con el mostrador ⏹. Eso a su vez, crea una nueva tarea, de "comer hamburguesas" 🔀 ⏯, pero la anterior de "obtener hamburguesas" ha terminado ⏹.
|
||||
|
||||
### Hamburguesas Paralelas
|
||||
### Hamburguesas Paralelas { #parallel-burgers }
|
||||
|
||||
Ahora imaginemos que estas no son "Hamburguesas Concurrentes", sino "Hamburguesas Paralelas".
|
||||
|
||||
@@ -233,7 +233,7 @@ Y tienes que esperar 🕙 en la fila por mucho tiempo o pierdes tu turno.
|
||||
|
||||
Probablemente no querrías llevar a tu crush 😍 contigo a hacer trámites en el banco 🏦.
|
||||
|
||||
### Conclusión de las Hamburguesas
|
||||
### Conclusión de las Hamburguesas { #burger-conclusion }
|
||||
|
||||
En este escenario de "hamburguesas de comida rápida con tu crush", como hay mucha espera 🕙, tiene mucho más sentido tener un sistema concurrente ⏸🔀⏯.
|
||||
|
||||
@@ -253,7 +253,7 @@ Y ese es el mismo nivel de rendimiento que obtienes con **FastAPI**.
|
||||
|
||||
Y como puedes tener paralelismo y asincronía al mismo tiempo, obtienes un mayor rendimiento que la mayoría de los frameworks de NodeJS probados y a la par con Go, que es un lenguaje compilado más cercano a C <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(todo gracias a Starlette)</a>.
|
||||
|
||||
### ¿Es la concurrencia mejor que el paralelismo?
|
||||
### ¿Es la concurrencia mejor que el paralelismo? { #is-concurrency-better-than-parallelism }
|
||||
|
||||
¡No! Esa no es la moraleja de la historia.
|
||||
|
||||
@@ -277,7 +277,7 @@ Pero en este caso, si pudieras traer a los 8 ex-cajeros/cocineros/ahora-limpiado
|
||||
|
||||
En este escenario, cada uno de los limpiadores (incluyéndote) sería un procesador, haciendo su parte del trabajo.
|
||||
|
||||
Y como la mayor parte del tiempo de ejecución se dedica al trabajo real (en lugar de esperar), y el trabajo en una computadora lo realiza una <abbr title="Central Processing Unit">CPU</abbr>, llaman a estos problemas "CPU bound".
|
||||
Y como la mayor parte del tiempo de ejecución se dedica al trabajo real (en lugar de esperar), y el trabajo en una computadora lo realiza una <abbr title="Central Processing Unit – Unidad Central de Procesamiento">CPU</abbr>, llaman a estos problemas "CPU bound".
|
||||
|
||||
---
|
||||
|
||||
@@ -290,7 +290,7 @@ Por ejemplo:
|
||||
* **Machine Learning**: normalmente requiere muchas multiplicaciones de "matrices" y "vectores". Piensa en una enorme hoja de cálculo con números y multiplicando todos juntos al mismo tiempo.
|
||||
* **Deep Learning**: este es un subcampo de Machine Learning, por lo tanto, se aplica lo mismo. Es solo que no hay una sola hoja de cálculo de números para multiplicar, sino un enorme conjunto de ellas, y en muchos casos, usas un procesador especial para construir y / o usar esos modelos.
|
||||
|
||||
### Concurrencia + Paralelismo: Web + Machine Learning
|
||||
### Concurrencia + Paralelismo: Web + Machine Learning { #concurrency-parallelism-web-machine-learning }
|
||||
|
||||
Con **FastAPI** puedes aprovechar la concurrencia que es muy común para el desarrollo web (la misma atracción principal de NodeJS).
|
||||
|
||||
@@ -300,7 +300,7 @@ Eso, más el simple hecho de que Python es el lenguaje principal para **Data Sci
|
||||
|
||||
Para ver cómo lograr este paralelismo en producción, consulta la sección sobre [Deployment](deployment/index.md){.internal-link target=_blank}.
|
||||
|
||||
## `async` y `await`
|
||||
## `async` y `await` { #async-and-await }
|
||||
|
||||
Las versiones modernas de Python tienen una forma muy intuitiva de definir código asíncrono. Esto hace que se vea igual que el código "secuencial" normal y hace el "wait" por ti en los momentos adecuados.
|
||||
|
||||
@@ -349,7 +349,7 @@ async def read_burgers():
|
||||
return burgers
|
||||
```
|
||||
|
||||
### Más detalles técnicos
|
||||
### Más detalles técnicos { #more-technical-details }
|
||||
|
||||
Podrías haber notado que `await` solo se puede usar dentro de funciones definidas con `async def`.
|
||||
|
||||
@@ -361,9 +361,9 @@ Si estás trabajando con **FastAPI** no tienes que preocuparte por eso, porque e
|
||||
|
||||
Pero si deseas usar `async` / `await` sin FastAPI, también puedes hacerlo.
|
||||
|
||||
### Escribe tu propio código async
|
||||
### Escribe tu propio código async { #write-your-own-async-code }
|
||||
|
||||
Starlette (y **FastAPI**) están basados en <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, lo que lo hace compatible tanto con la librería estándar de Python <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> como con <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
|
||||
Starlette (y **FastAPI**) están basados en <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, lo que lo hace compatible tanto con el <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> del paquete estándar de Python como con <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
|
||||
|
||||
En particular, puedes usar directamente <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> para tus casos de uso avanzados de concurrencia que requieran patrones más avanzados en tu propio código.
|
||||
|
||||
@@ -371,7 +371,7 @@ E incluso si no estuvieras usando FastAPI, también podrías escribir tus propia
|
||||
|
||||
Creé otro paquete sobre AnyIO, como una capa delgada, para mejorar un poco las anotaciones de tipos y obtener mejor **autocompletado**, **errores en línea**, etc. También tiene una introducción amigable y tutorial para ayudarte a **entender** y escribir **tu propio código async**: <a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>. Sería particularmente útil si necesitas **combinar código async con regular** (bloqueante/sincrónico).
|
||||
|
||||
### Otras formas de código asíncrono
|
||||
### Otras formas de código asíncrono { #other-forms-of-asynchronous-code }
|
||||
|
||||
Este estilo de usar `async` y `await` es relativamente nuevo en el lenguaje.
|
||||
|
||||
@@ -385,13 +385,13 @@ En versiones previas de Python, podrías haber usado hilos o <a href="https://ww
|
||||
|
||||
En versiones previas de NodeJS / JavaScript en el Navegador, habrías usado "callbacks". Lo que lleva al "callback hell".
|
||||
|
||||
## Coroutines
|
||||
## Coroutines { #coroutines }
|
||||
|
||||
**Coroutines** es simplemente el término muy elegante para la cosa que devuelve una función `async def`. Python sabe que es algo parecido a una función, que puede comenzar y que terminará en algún momento, pero que podría pausar ⏸ internamente también, siempre que haya un `await` dentro de él.
|
||||
|
||||
Pero toda esta funcionalidad de usar código asíncrono con `async` y `await` a menudo se resume como utilizar "coroutines". Es comparable a la funcionalidad clave principal de Go, las "Goroutines".
|
||||
|
||||
## Conclusión
|
||||
## Conclusión { #conclusion }
|
||||
|
||||
Veamos la misma frase de arriba:
|
||||
|
||||
@@ -401,7 +401,7 @@ Eso debería tener más sentido ahora. ✨
|
||||
|
||||
Todo eso es lo que impulsa FastAPI (a través de Starlette) y lo que hace que tenga un rendimiento tan impresionante.
|
||||
|
||||
## Detalles Muy Técnicos
|
||||
## Detalles Muy Técnicos { #very-technical-details }
|
||||
|
||||
/// warning | Advertencia
|
||||
|
||||
@@ -413,23 +413,23 @@ Si tienes bastante conocimiento técnico (coroutines, hilos, bloqueo, etc.) y ti
|
||||
|
||||
///
|
||||
|
||||
### Funciones de *path operation*
|
||||
### Funciones de *path operation* { #path-operation-functions }
|
||||
|
||||
Cuando declaras una *path operation function* con `def` normal en lugar de `async def`, se ejecuta en un threadpool externo que luego es esperado, en lugar de ser llamado directamente (ya que bloquearía el servidor).
|
||||
|
||||
Si vienes de otro framework async que no funciona de la manera descrita anteriormente y estás acostumbrado a definir funciones de *path operation* solo de cómputo trivial con `def` normal para una pequeña ganancia de rendimiento (alrededor de 100 nanosegundos), ten en cuenta que en **FastAPI** el efecto sería bastante opuesto. En estos casos, es mejor usar `async def` a menos que tus *path operation functions* usen código que realice <abbr title="Input/Output: lectura o escritura en disco, comunicaciones de red.">I/O</abbr> de bloqueo.
|
||||
Si vienes de otro framework async que no funciona de la manera descrita anteriormente y estás acostumbrado a definir funciones de *path operation* solo de cómputo trivial con `def` normal para una pequeña ganancia de rendimiento (alrededor de 100 nanosegundos), ten en cuenta que en **FastAPI** el efecto sería bastante opuesto. En estos casos, es mejor usar `async def` a menos que tus *path operation functions* usen código que realice <abbr title="Input/Output – Entrada/Salida: lectura o escritura en disco, comunicaciones de red.">I/O</abbr> de bloqueo.
|
||||
|
||||
Aun así, en ambas situaciones, es probable que **FastAPI** [siga siendo más rápida](index.md#performance){.internal-link target=_blank} que (o al menos comparable a) tu framework anterior.
|
||||
|
||||
### Dependencias
|
||||
### Dependencias { #dependencies }
|
||||
|
||||
Lo mismo aplica para las [dependencias](tutorial/dependencies/index.md){.internal-link target=_blank}. Si una dependencia es una función estándar `def` en lugar de `async def`, se ejecuta en el threadpool externo.
|
||||
|
||||
### Sub-dependencias
|
||||
### Sub-dependencias { #sub-dependencies }
|
||||
|
||||
Puedes tener múltiples dependencias y [sub-dependencias](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} requiriéndose mutuamente (como parámetros de las definiciones de funciones), algunas de ellas podrían ser creadas con `async def` y algunas con `def` normal. Aun funcionará, y las que fueron creadas con `def` normal serían llamadas en un hilo externo (del threadpool) en lugar de ser "awaited".
|
||||
|
||||
### Otras funciones de utilidad
|
||||
### Otras funciones de utilidad { #other-utility-functions }
|
||||
|
||||
Cualquier otra función de utilidad que llames directamente puede ser creada con `def` normal o `async def` y FastAPI no afectará la forma en que la llames.
|
||||
|
||||
|
||||
@@ -1,51 +1,39 @@
|
||||
# Ejecutar un Servidor Manualmente
|
||||
# Ejecutar un Servidor Manualmente { #run-a-server-manually }
|
||||
|
||||
## Usa el Comando `fastapi run`
|
||||
## Usa el Comando `fastapi run` { #use-the-fastapi-run-command }
|
||||
|
||||
En resumen, usa `fastapi run` para servir tu aplicación FastAPI:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:single">main.py</u>
|
||||
<font color="#3465A4">INFO </font> Usando path <font color="#3465A4">main.py</font>
|
||||
<font color="#3465A4">INFO </font> Path absoluto resuelto <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font>
|
||||
<font color="#3465A4">INFO </font> Buscando una estructura de archivos de paquete desde directorios con archivos <font color="#3465A4">__init__.py</font>
|
||||
<font color="#3465A4">INFO </font> Importando desde <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
|
||||
|
||||
╭─ <font color="#8AE234"><b>Archivo de módulo de Python</b></font> ─╮
|
||||
│ │
|
||||
│ 🐍 main.py │
|
||||
│ │
|
||||
╰──────────────────────╯
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
|
||||
|
||||
<font color="#3465A4">INFO </font> Importando módulo <font color="#4E9A06">main</font>
|
||||
<font color="#3465A4">INFO </font> Encontrada aplicación FastAPI importable
|
||||
Searching for package file structure from directories
|
||||
with <font color="#3465A4">__init__.py</font> files
|
||||
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
|
||||
╭─ <font color="#8AE234"><b>Aplicación FastAPI importable</b></font> ─╮
|
||||
│ │
|
||||
│ <span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822"> </span> │
|
||||
│ │
|
||||
╰──────────────────────────╯
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
|
||||
|
||||
<font color="#3465A4">INFO </font> Usando la cadena de import <font color="#8AE234"><b>main:app</b></font>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
|
||||
the following code:
|
||||
|
||||
<font color="#4E9A06">╭─────────── CLI de FastAPI - Modo Producción ───────────╮</font>
|
||||
<font color="#4E9A06">│ │</font>
|
||||
<font color="#4E9A06">│ Sirviendo en: http://0.0.0.0:8000 │</font>
|
||||
<font color="#4E9A06">│ │</font>
|
||||
<font color="#4E9A06">│ Docs de API: http://0.0.0.0:8000/docs │</font>
|
||||
<font color="#4E9A06">│ │</font>
|
||||
<font color="#4E9A06">│ Corriendo en modo producción, para desarrollo usa: │</font>
|
||||
<font color="#4E9A06">│ │</font>
|
||||
<font color="#4E9A06">│ </font><font color="#8AE234"><b>fastapi dev</b></font><font color="#4E9A06"> │</font>
|
||||
<font color="#4E9A06">│ │</font>
|
||||
<font color="#4E9A06">╰─────────────────────────────────────────────────────╯</font>
|
||||
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
|
||||
|
||||
<font color="#4E9A06">INFO</font>: Iniciado el proceso del servidor [<font color="#06989A">2306215</font>]
|
||||
<font color="#4E9A06">INFO</font>: Esperando el inicio de la aplicación.
|
||||
<font color="#4E9A06">INFO</font>: Inicio de la aplicación completado.
|
||||
<font color="#4E9A06">INFO</font>: Uvicorn corriendo en <b>http://0.0.0.0:8000</b> (Presiona CTRL+C para salir)
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
|
||||
|
||||
Logs:
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>2306215</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C
|
||||
to quit<b>)</b>
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -54,11 +42,11 @@ Eso funcionaría para la mayoría de los casos. 😎
|
||||
|
||||
Podrías usar ese comando, por ejemplo, para iniciar tu app **FastAPI** en un contenedor, en un servidor, etc.
|
||||
|
||||
## Servidores ASGI
|
||||
## Servidores ASGI { #asgi-servers }
|
||||
|
||||
Vamos a profundizar un poquito en los detalles.
|
||||
|
||||
FastAPI usa un estándar para construir frameworks de web y servidores de Python llamado <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr>. FastAPI es un framework web ASGI.
|
||||
FastAPI usa un estándar para construir frameworks de web y servidores de Python llamado <abbr title="Asynchronous Server Gateway Interface – Interfaz de puerta de enlace de servidor asíncrona">ASGI</abbr>. FastAPI es un framework web ASGI.
|
||||
|
||||
Lo principal que necesitas para ejecutar una aplicación **FastAPI** (o cualquier otra aplicación ASGI) en una máquina de servidor remota es un programa de servidor ASGI como **Uvicorn**, que es el que viene por defecto en el comando `fastapi`.
|
||||
|
||||
@@ -70,7 +58,7 @@ Hay varias alternativas, incluyendo:
|
||||
* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>: Un servidor HTTP Rust para aplicaciones en Python.
|
||||
* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>: NGINX Unit es un runtime para aplicaciones web ligero y versátil.
|
||||
|
||||
## Máquina Servidor y Programa Servidor
|
||||
## Máquina Servidor y Programa Servidor { #server-machine-and-server-program }
|
||||
|
||||
Hay un pequeño detalle sobre los nombres que hay que tener en cuenta. 💡
|
||||
|
||||
@@ -80,7 +68,7 @@ Solo ten en cuenta que cuando leas "servidor" en general, podría referirse a un
|
||||
|
||||
Al referirse a la máquina remota, es común llamarla **servidor**, pero también **máquina**, **VM** (máquina virtual), **nodo**. Todos esos se refieren a algún tipo de máquina remota, generalmente con Linux, donde ejecutas programas.
|
||||
|
||||
## Instala el Programa del Servidor
|
||||
## Instala el Programa del Servidor { #install-the-server-program }
|
||||
|
||||
Cuando instalas FastAPI, viene con un servidor de producción, Uvicorn, y puedes iniciarlo con el comando `fastapi run`.
|
||||
|
||||
@@ -112,7 +100,7 @@ Cuando instalas FastAPI con algo como `pip install "fastapi[standard]"` ya obtie
|
||||
|
||||
///
|
||||
|
||||
## Ejecuta el Programa del Servidor
|
||||
## Ejecuta el Programa del Servidor { #run-the-server-program }
|
||||
|
||||
Si instalaste un servidor ASGI manualmente, normalmente necesitarías pasar una cadena de import en un formato especial para que importe tu aplicación FastAPI:
|
||||
|
||||
@@ -121,7 +109,7 @@ Si instalaste un servidor ASGI manualmente, normalmente necesitarías pasar una
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn corriendo en http://0.0.0.0:80 (Presiona CTRL+C para salir)
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -153,7 +141,7 @@ Ayuda mucho durante el **desarrollo**, pero **no** deberías usarla en **producc
|
||||
|
||||
///
|
||||
|
||||
## Conceptos de Despliegue
|
||||
## Conceptos de Despliegue { #deployment-concepts }
|
||||
|
||||
Estos ejemplos ejecutan el programa del servidor (por ejemplo, Uvicorn), iniciando **un solo proceso**, escuchando en todas las IPs (`0.0.0.0`) en un puerto predefinido (por ejemplo, `80`).
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# FastAPI CLI
|
||||
# FastAPI CLI { #fastapi-cli }
|
||||
|
||||
**FastAPI CLI** es un programa de línea de comandos que puedes usar para servir tu aplicación FastAPI, gestionar tu proyecto FastAPI, y más.
|
||||
|
||||
@@ -54,13 +54,13 @@ Para producción usarías `fastapi run` en su lugar. 🚀
|
||||
|
||||
Internamente, **FastAPI CLI** usa <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>, un servidor ASGI de alto rendimiento y listo para producción. 😎
|
||||
|
||||
## `fastapi dev`
|
||||
## `fastapi dev` { #fastapi-dev }
|
||||
|
||||
Ejecutar `fastapi dev` inicia el modo de desarrollo.
|
||||
|
||||
Por defecto, **auto-reload** está habilitado, recargando automáticamente el servidor cuando realizas cambios en tu código. Esto consume muchos recursos y podría ser menos estable que cuando está deshabilitado. Deberías usarlo solo para desarrollo. También escucha en la dirección IP `127.0.0.1`, que es la IP para que tu máquina se comunique solo consigo misma (`localhost`).
|
||||
|
||||
## `fastapi run`
|
||||
## `fastapi run` { #fastapi-run }
|
||||
|
||||
Ejecutar `fastapi run` inicia FastAPI en modo de producción por defecto.
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# Funcionalidades
|
||||
# Funcionalidades { #features }
|
||||
|
||||
## Funcionalidades de FastAPI
|
||||
## Funcionalidades de FastAPI { #fastapi-features }
|
||||
|
||||
**FastAPI** te ofrece lo siguiente:
|
||||
|
||||
### Basado en estándares abiertos
|
||||
### Basado en estándares abiertos { #based-on-open-standards }
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> para la creación de APIs, incluyendo declaraciones de <abbr title="también conocido como: endpoints, rutas">path</abbr> <abbr title="también conocido como métodos HTTP, como POST, GET, PUT, DELETE">operations</abbr>, parámetros, request bodies, seguridad, etc.
|
||||
* Documentación automática de modelos de datos con <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (ya que OpenAPI en sí mismo está basado en JSON Schema).
|
||||
* Diseñado alrededor de estos estándares, tras un estudio meticuloso. En lugar de ser una capa adicional.
|
||||
* Esto también permite el uso de **generación de código cliente automática** en muchos idiomas.
|
||||
|
||||
### Documentación automática
|
||||
### Documentación automática { #automatic-docs }
|
||||
|
||||
Interfaces web de documentación y exploración de APIs interactivas. Como el framework está basado en OpenAPI, hay múltiples opciones, 2 incluidas por defecto.
|
||||
|
||||
@@ -23,7 +23,7 @@ Interfaces web de documentación y exploración de APIs interactivas. Como el fr
|
||||
|
||||

|
||||
|
||||
### Solo Python moderno
|
||||
### Solo Python moderno { #just-modern-python }
|
||||
|
||||
Todo está basado en declaraciones estándar de **tipos en Python** (gracias a Pydantic). Sin nueva sintaxis que aprender. Solo Python moderno estándar.
|
||||
|
||||
@@ -71,7 +71,7 @@ Pasa las claves y valores del dict `second_user_data` directamente como argument
|
||||
|
||||
///
|
||||
|
||||
### Soporte del editor
|
||||
### Soporte del editor { #editor-support }
|
||||
|
||||
Todo el framework fue diseñado para ser fácil e intuitivo de usar, todas las decisiones fueron probadas en múltiples editores incluso antes de comenzar el desarrollo, para asegurar la mejor experiencia de desarrollo.
|
||||
|
||||
@@ -95,13 +95,13 @@ Obtendrás autocompletado en código que podrías considerar imposible antes. Po
|
||||
|
||||
No más escribir nombres de claves incorrectos, yendo de un lado a otro entre la documentación, o desplazándote hacia arriba y abajo para encontrar si finalmente usaste `username` o `user_name`.
|
||||
|
||||
### Breve
|
||||
### Breve { #short }
|
||||
|
||||
Tiene **valores predeterminados** sensatos para todo, con configuraciones opcionales en todas partes. Todos los parámetros se pueden ajustar finamente para hacer lo que necesitas y para definir el API que necesitas.
|
||||
Tiene **valores por defecto** sensatos para todo, con configuraciones opcionales en todas partes. Todos los parámetros se pueden ajustar finamente para hacer lo que necesitas y para definir el API que necesitas.
|
||||
|
||||
Pero por defecto, todo **"simplemente funciona"**.
|
||||
|
||||
### Validación
|
||||
### Validación { #validation }
|
||||
|
||||
* Validación para la mayoría (¿o todas?) de los **tipos de datos** de Python, incluyendo:
|
||||
* Objetos JSON (`dict`).
|
||||
@@ -117,7 +117,7 @@ Pero por defecto, todo **"simplemente funciona"**.
|
||||
|
||||
Toda la validación es manejada por **Pydantic**, una herramienta bien establecida y robusta.
|
||||
|
||||
### Seguridad y autenticación
|
||||
### Seguridad y autenticación { #security-and-authentication }
|
||||
|
||||
Seguridad y autenticación integradas. Sin ningún compromiso con bases de datos o modelos de datos.
|
||||
|
||||
@@ -134,30 +134,30 @@ Además de todas las características de seguridad de Starlette (incluyendo **co
|
||||
|
||||
Todo construido como herramientas y componentes reutilizables que son fáciles de integrar con tus sistemas, almacenes de datos, bases de datos relacionales y NoSQL, etc.
|
||||
|
||||
### Inyección de dependencias
|
||||
### Inyección de dependencias { #dependency-injection }
|
||||
|
||||
FastAPI incluye un sistema de <abbr title='también conocido como "componentes", "recursos", "servicios", "proveedores"'><strong>Inyección de Dependencias</strong></abbr> extremadamente fácil de usar, pero extremadamente potente.
|
||||
|
||||
* Incluso las dependencias pueden tener dependencias, creando una jerarquía o **"gráfico de dependencias"**.
|
||||
* Incluso las dependencias pueden tener dependencias, creando una jerarquía o **"grafo de dependencias"**.
|
||||
* Todo **manejado automáticamente** por el framework.
|
||||
* Todas las dependencias pueden requerir datos de los requests y **aumentar las restricciones de la path operation** y la documentación automática.
|
||||
* **Validación automática** incluso para los parámetros de *path operation* definidos en las dependencias.
|
||||
* Soporte para sistemas de autenticación de usuario complejos, **conexiones a bases de datos**, etc.
|
||||
* **Sin compromisos** con bases de datos, frontends, etc. Pero fácil integración con todos ellos.
|
||||
|
||||
### "Plug-ins" ilimitados
|
||||
### "Plug-ins" ilimitados { #unlimited-plug-ins }
|
||||
|
||||
O de otra manera, no hay necesidad de ellos, importa y usa el código que necesitas.
|
||||
|
||||
Cualquier integración está diseñada para ser tan simple de usar (con dependencias) que puedes crear un "plug-in" para tu aplicación en 2 líneas de código usando la misma estructura y sintaxis utilizada para tus *path operations*.
|
||||
|
||||
### Probado
|
||||
### Probado { #tested }
|
||||
|
||||
* 100% de <abbr title="La cantidad de código que se prueba automáticamente">cobertura de tests</abbr>.
|
||||
* Código completamente <abbr title="Anotaciones de tipos en Python, con esto tu editor y herramientas externas pueden ofrecerte mejor soporte">anotado con tipos</abbr>.
|
||||
* 100% <abbr title="Anotaciones de tipos en Python, con esto tu editor y herramientas externas pueden ofrecerte mejor soporte">anotada con tipos</abbr> code base.
|
||||
* Usado en aplicaciones en producción.
|
||||
|
||||
## Funcionalidades de Starlette
|
||||
## Funcionalidades de Starlette { #starlette-features }
|
||||
|
||||
**FastAPI** es totalmente compatible con (y está basado en) <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Así que, cualquier código adicional de Starlette que tengas, también funcionará.
|
||||
|
||||
@@ -173,13 +173,13 @@ Con **FastAPI** obtienes todas las funcionalidades de **Starlette** (ya que Fast
|
||||
* **CORS**, GZip, archivos estáticos, responses en streaming.
|
||||
* Soporte para **Session y Cookie**.
|
||||
* Cobertura de tests del 100%.
|
||||
* Código completamente anotado con tipos.
|
||||
* code base completamente anotada con tipos.
|
||||
|
||||
## Funcionalidades de Pydantic
|
||||
## Funcionalidades de Pydantic { #pydantic-features }
|
||||
|
||||
**FastAPI** es totalmente compatible con (y está basado en) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Por lo tanto, cualquier código adicional de Pydantic que tengas, también funcionará.
|
||||
|
||||
Incluyendo paquetes externos también basados en Pydantic, como <abbr title="Object-Relational Mapper">ORM</abbr>s, <abbr title="Object-Document Mapper">ODM</abbr>s para bases de datos.
|
||||
Incluyendo paquetes externos también basados en Pydantic, como <abbr title="Object-Relational Mapper – Mapeador Objeto-Relacional">ORM</abbr>s, <abbr title="Object-Document Mapper – Mapeador Objeto-Documento">ODM</abbr>s para bases de datos.
|
||||
|
||||
Esto también significa que, en muchos casos, puedes pasar el mismo objeto que obtienes de un request **directamente a la base de datos**, ya que todo se valida automáticamente.
|
||||
|
||||
@@ -190,7 +190,7 @@ Con **FastAPI** obtienes todas las funcionalidades de **Pydantic** (ya que FastA
|
||||
* **Sin complicaciones**:
|
||||
* Sin micro-lenguaje de definición de esquemas nuevo que aprender.
|
||||
* Si conoces los tipos en Python sabes cómo usar Pydantic.
|
||||
* Se lleva bien con tu **<abbr title="Entorno de Desarrollo Integrado, similar a un editor de código">IDE</abbr>/<abbr title="Un programa que verifica errores de código">linter</abbr>/cerebro**:
|
||||
* Se lleva bien con tu **<abbr title="Integrated Development Environment – Entorno de Desarrollo Integrado: similar a un editor de código">IDE</abbr>/<abbr title="Un programa que verifica errores de código">linter</abbr>/cerebro**:
|
||||
* Porque las estructuras de datos de pydantic son solo instances de clases que defines; autocompletado, linting, mypy y tu intuición deberían funcionar correctamente con tus datos validados.
|
||||
* Valida **estructuras complejas**:
|
||||
* Uso de modelos jerárquicos de Pydantic, `List` y `Dict` de `typing` de Python, etc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Ayuda a FastAPI - Consigue Ayuda
|
||||
# Ayuda a FastAPI - Consigue Ayuda { #help-fastapi-get-help }
|
||||
|
||||
¿Te gusta **FastAPI**?
|
||||
|
||||
@@ -10,7 +10,7 @@ Hay formas muy sencillas de ayudar (varias implican solo uno o dos clics).
|
||||
|
||||
Y también hay varias formas de conseguir ayuda.
|
||||
|
||||
## Suscríbete al boletín
|
||||
## Suscríbete al boletín { #subscribe-to-the-newsletter }
|
||||
|
||||
Puedes suscribirte al (esporádico) boletín [**FastAPI and friends**](newsletter.md){.internal-link target=_blank} para mantenerte al día sobre:
|
||||
|
||||
@@ -20,17 +20,17 @@ Puedes suscribirte al (esporádico) boletín [**FastAPI and friends**](newslette
|
||||
* Cambios importantes 🚨
|
||||
* Consejos y trucos ✅
|
||||
|
||||
## Sigue a FastAPI en X (Twitter)
|
||||
## Sigue a FastAPI en X (Twitter) { #follow-fastapi-on-x-twitter }
|
||||
|
||||
<a href="https://x.com/fastapi" class="external-link" target="_blank">Sigue a @fastapi en **X (Twitter)**</a> para obtener las últimas noticias sobre **FastAPI**. 🐦
|
||||
|
||||
## Dale una estrella a **FastAPI** en GitHub
|
||||
## Dale una estrella a **FastAPI** en GitHub { #star-fastapi-in-github }
|
||||
|
||||
Puedes "darle una estrella" a FastAPI en GitHub (haciendo clic en el botón de estrella en la parte superior derecha): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️
|
||||
|
||||
Al agregar una estrella, otros usuarios podrán encontrarlo más fácilmente y ver que ya ha sido útil para otros.
|
||||
|
||||
## Observa el repositorio de GitHub para lanzamientos
|
||||
## Observa el repositorio de GitHub para lanzamientos { #watch-the-github-repository-for-releases }
|
||||
|
||||
Puedes "observar" FastAPI en GitHub (haciendo clic en el botón "watch" en la parte superior derecha): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
|
||||
|
||||
@@ -38,7 +38,7 @@ Allí puedes seleccionar "Releases only".
|
||||
|
||||
Al hacerlo, recibirás notificaciones (en tu email) cada vez que haya un nuevo lanzamiento (una nueva versión) de **FastAPI** con correcciones de bugs y nuevas funcionalidades.
|
||||
|
||||
## Conéctate con el autor
|
||||
## Conéctate con el autor { #connect-with-the-author }
|
||||
|
||||
Puedes conectar <a href="https://tiangolo.com" class="external-link" target="_blank">conmigo (Sebastián Ramírez / `tiangolo`)</a>, el autor.
|
||||
|
||||
@@ -57,19 +57,19 @@ Puedes:
|
||||
* Leer otras ideas, artículos, y leer sobre las herramientas que he creado.
|
||||
* Seguirme para leer lo que publico nuevo.
|
||||
|
||||
## Twittea sobre **FastAPI**
|
||||
## Twittea sobre **FastAPI** { #tweet-about-fastapi }
|
||||
|
||||
<a href="https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">Twittea sobre **FastAPI**</a> y dime a mí y a otros por qué te gusta. 🎉
|
||||
|
||||
Me encanta escuchar cómo se está utilizando **FastAPI**, qué te ha gustado, en qué proyecto/empresa lo estás usando, etc.
|
||||
|
||||
## Vota por FastAPI
|
||||
## Vota por FastAPI { #vote-for-fastapi }
|
||||
|
||||
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Vota por **FastAPI** en Slant</a>.
|
||||
* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">Vota por **FastAPI** en AlternativeTo</a>.
|
||||
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">Di que usas **FastAPI** en StackShare</a>.
|
||||
|
||||
## Ayuda a otros con preguntas en GitHub
|
||||
## Ayuda a otros con preguntas en GitHub { #help-others-with-questions-in-github }
|
||||
|
||||
Puedes intentar ayudar a otros con sus preguntas en:
|
||||
|
||||
@@ -88,7 +88,7 @@ La idea es que la comunidad de **FastAPI** sea amable y acogedora. Al mismo tiem
|
||||
|
||||
Aquí te explico cómo ayudar a otros con preguntas (en discusiones o issues):
|
||||
|
||||
### Entiende la pregunta
|
||||
### Entiende la pregunta { #understand-the-question }
|
||||
|
||||
* Revisa si puedes entender cuál es el **propósito** y el caso de uso de la persona que pregunta.
|
||||
|
||||
@@ -98,7 +98,7 @@ Aquí te explico cómo ayudar a otros con preguntas (en discusiones o issues):
|
||||
|
||||
* Si no puedes entender la pregunta, pide más **detalles**.
|
||||
|
||||
### Reproduce el problema
|
||||
### Reproduce el problema { #reproduce-the-problem }
|
||||
|
||||
En la mayoría de los casos y preguntas hay algo relacionado con el **código original** de la persona.
|
||||
|
||||
@@ -108,13 +108,13 @@ En muchos casos solo copiarán un fragmento del código, pero eso no es suficien
|
||||
|
||||
* Si te sientes muy generoso, puedes intentar **crear un ejemplo** así tú mismo, solo basado en la descripción del problema. Solo ten en cuenta que esto podría llevar mucho tiempo y podría ser mejor pedirles que aclaren el problema primero.
|
||||
|
||||
### Sugerir soluciones
|
||||
### Sugerir soluciones { #suggest-solutions }
|
||||
|
||||
* Después de poder entender la pregunta, puedes darles un posible **respuesta**.
|
||||
|
||||
* En muchos casos, es mejor entender su **problema subyacente o caso de uso**, porque podría haber una mejor manera de resolverlo que lo que están intentando hacer.
|
||||
|
||||
### Pide cerrar
|
||||
### Pide cerrar { #ask-to-close }
|
||||
|
||||
Si responden, hay una alta probabilidad de que hayas resuelto su problema, felicidades, ¡**eres un héroe**! 🦸
|
||||
|
||||
@@ -123,7 +123,7 @@ Si responden, hay una alta probabilidad de que hayas resuelto su problema, felic
|
||||
* En GitHub Discussions: marquen el comentario como la **respuesta**.
|
||||
* En GitHub Issues: **cierren** el issue.
|
||||
|
||||
## Observa el repositorio de GitHub
|
||||
## Observa el repositorio de GitHub { #watch-the-github-repository }
|
||||
|
||||
Puedes "observar" FastAPI en GitHub (haciendo clic en el botón "watch" en la parte superior derecha): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
|
||||
|
||||
@@ -131,7 +131,7 @@ Si seleccionas "Watching" en lugar de "Releases only", recibirás notificaciones
|
||||
|
||||
Luego puedes intentar ayudarlos a resolver esas preguntas.
|
||||
|
||||
## Haz preguntas
|
||||
## Haz preguntas { #ask-questions }
|
||||
|
||||
Puedes <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">crear una nueva pregunta</a> en el repositorio de GitHub, por ejemplo, para:
|
||||
|
||||
@@ -140,7 +140,7 @@ Puedes <a href="https://github.com/fastapi/fastapi/discussions/new?category=ques
|
||||
|
||||
**Nota**: si lo haces, entonces te voy a pedir que también ayudes a otros. 😉
|
||||
|
||||
## Revisa Pull Requests
|
||||
## Revisa Pull Requests { #review-pull-requests }
|
||||
|
||||
Puedes ayudarme a revisar pull requests de otros.
|
||||
|
||||
@@ -150,13 +150,13 @@ De nuevo, por favor, haz tu mejor esfuerzo por ser amable. 🤗
|
||||
|
||||
Aquí está lo que debes tener en cuenta y cómo revisar un pull request:
|
||||
|
||||
### Entiende el problema
|
||||
### Entiende el problema { #understand-the-problem }
|
||||
|
||||
* Primero, asegúrate de **entender el problema** que el pull request está intentando resolver. Podría tener una discusión más larga en una GitHub Discussion o issue.
|
||||
|
||||
* También hay una buena posibilidad de que el pull request no sea realmente necesario porque el problema se puede resolver de una manera **diferente**. Entonces puedes sugerir o preguntar sobre eso.
|
||||
|
||||
### No te preocupes por el estilo
|
||||
### No te preocupes por el estilo { #dont-worry-about-style }
|
||||
|
||||
* No te preocupes demasiado por cosas como los estilos de los mensajes de commit, yo haré squash y merge personalizando el commit manualmente.
|
||||
|
||||
@@ -164,7 +164,7 @@ Aquí está lo que debes tener en cuenta y cómo revisar un pull request:
|
||||
|
||||
Y si hay alguna otra necesidad de estilo o consistencia, pediré directamente eso, o agregaré commits encima con los cambios necesarios.
|
||||
|
||||
### Revisa el código
|
||||
### Revisa el código { #check-the-code }
|
||||
|
||||
* Revisa y lee el código, ve si tiene sentido, **ejecútalo localmente** y ve si realmente resuelve el problema.
|
||||
|
||||
@@ -182,7 +182,7 @@ Así que, es realmente importante que realmente leas y ejecutes el código, y me
|
||||
|
||||
* Si el PR se puede simplificar de alguna manera, puedes pedir eso, pero no hay necesidad de ser demasiado exigente, podría haber muchos puntos de vista subjetivos (y yo tendré el mío también 🙈), así que es mejor si puedes centrarte en las cosas fundamentales.
|
||||
|
||||
### Tests
|
||||
### Tests { #tests }
|
||||
|
||||
* Ayúdame a verificar que el PR tenga **tests**.
|
||||
|
||||
@@ -194,7 +194,7 @@ Así que, es realmente importante que realmente leas y ejecutes el código, y me
|
||||
|
||||
* Luego también comenta lo que intentaste, de esa manera sabré que lo revisaste. 🤓
|
||||
|
||||
## Crea un Pull Request
|
||||
## Crea un Pull Request { #create-a-pull-request }
|
||||
|
||||
Puedes [contribuir](contributing.md){.internal-link target=_blank} al código fuente con Pull Requests, por ejemplo:
|
||||
|
||||
@@ -210,7 +210,7 @@ Puedes [contribuir](contributing.md){.internal-link target=_blank} al código fu
|
||||
* Asegúrate de agregar tests.
|
||||
* Asegúrate de agregar documentación si es relevante.
|
||||
|
||||
## Ayuda a Mantener FastAPI
|
||||
## Ayuda a Mantener FastAPI { #help-maintain-fastapi }
|
||||
|
||||
¡Ayúdame a mantener **FastAPI**! 🤓
|
||||
|
||||
@@ -225,7 +225,7 @@ Esas dos tareas son las que **consumen más tiempo**. Ese es el trabajo principa
|
||||
|
||||
Si puedes ayudarme con eso, **me estás ayudando a mantener FastAPI** y asegurando que siga **avanzando más rápido y mejor**. 🚀
|
||||
|
||||
## Únete al chat
|
||||
## Únete al chat { #join-the-chat }
|
||||
|
||||
Únete al servidor de chat 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord</a> 👥 y charla con otros en la comunidad de FastAPI.
|
||||
|
||||
@@ -237,7 +237,7 @@ Usa el chat solo para otras conversaciones generales.
|
||||
|
||||
///
|
||||
|
||||
### No uses el chat para preguntas
|
||||
### No uses el chat para preguntas { #dont-use-the-chat-for-questions }
|
||||
|
||||
Ten en cuenta que dado que los chats permiten una "conversación más libre", es fácil hacer preguntas que son demasiado generales y más difíciles de responder, por lo que es posible que no recibas respuestas.
|
||||
|
||||
@@ -247,22 +247,9 @@ Las conversaciones en los sistemas de chat tampoco son tan fácilmente buscables
|
||||
|
||||
Por otro lado, hay miles de usuarios en los sistemas de chat, por lo que hay muchas posibilidades de que encuentres a alguien con quien hablar allí, casi todo el tiempo. 😄
|
||||
|
||||
## Patrocina al autor
|
||||
## Patrocina al autor { #sponsor-the-author }
|
||||
|
||||
También puedes apoyar financieramente al autor (a mí) a través de <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>.
|
||||
|
||||
Allí podrías comprarme un café ☕️ para decir gracias. 😄
|
||||
|
||||
Y también puedes convertirte en un sponsor de Plata o de Oro para FastAPI. 🏅🎉
|
||||
|
||||
## Patrocina las herramientas que impulsan FastAPI
|
||||
|
||||
Como habrás visto en la documentación, FastAPI se apoya en los hombros de gigantes, Starlette y Pydantic.
|
||||
|
||||
También puedes patrocinar:
|
||||
|
||||
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
|
||||
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
|
||||
Si tu **producto/empresa** depende de o está relacionado con **FastAPI** y quieres llegar a sus usuarios, puedes patrocinar al autor (a mí) a través de <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>. Según el nivel, podrías obtener algunos beneficios extra, como una insignia en la documentación. 🎁
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Historia, Diseño y Futuro
|
||||
# Historia, Diseño y Futuro { #history-design-and-future }
|
||||
|
||||
Hace algún tiempo, <a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">un usuario de **FastAPI** preguntó</a>:
|
||||
|
||||
@@ -6,7 +6,7 @@ Hace algún tiempo, <a href="https://github.com/fastapi/fastapi/issues/3#issueco
|
||||
|
||||
Aquí hay un poquito de esa historia.
|
||||
|
||||
## Alternativas
|
||||
## Alternativas { #alternatives }
|
||||
|
||||
He estado creando APIs con requisitos complejos durante varios años (Machine Learning, sistemas distribuidos, trabajos asíncronos, bases de datos NoSQL, etc.), liderando varios equipos de desarrolladores.
|
||||
|
||||
@@ -22,13 +22,13 @@ Como se dice en la sección [Alternativas](alternatives.md){.internal-link targe
|
||||
|
||||
Ha habido muchas herramientas creadas antes que han ayudado a inspirar su creación.
|
||||
|
||||
He estado evitando la creación de un nuevo framework durante varios años. Primero traté de resolver todas las funcionalidades cubiertas por **FastAPI** usando varios frameworks, complementos y herramientas diferentes.
|
||||
He estado evitando la creación de un nuevo framework durante varios años. Primero traté de resolver todas las funcionalidades cubiertas por **FastAPI** usando varios frameworks, plug-ins y herramientas diferentes.
|
||||
|
||||
Pero en algún momento, no había otra opción que crear algo que proporcionara todas estas funcionalidades, tomando las mejores ideas de herramientas anteriores y combinándolas de la mejor manera posible, usando funcionalidades del lenguaje que ni siquiera estaban disponibles antes (anotaciones de tipos de Python 3.6+).
|
||||
|
||||
</blockquote>
|
||||
|
||||
## Investigación
|
||||
## Investigación { #investigation }
|
||||
|
||||
Al usar todas las alternativas anteriores, tuve la oportunidad de aprender de todas ellas, tomar ideas y combinarlas de la mejor manera que pude encontrar para mí y los equipos de desarrolladores con los que he trabajado.
|
||||
|
||||
@@ -38,7 +38,7 @@ También, el mejor enfoque era usar estándares ya existentes.
|
||||
|
||||
Entonces, antes de siquiera empezar a programar **FastAPI**, pasé varios meses estudiando las especificaciones de OpenAPI, JSON Schema, OAuth2, etc. Entendiendo su relación, superposición y diferencias.
|
||||
|
||||
## Diseño
|
||||
## Diseño { #design }
|
||||
|
||||
Luego pasé algún tiempo diseñando la "API" de desarrollador que quería tener como usuario (como desarrollador usando FastAPI).
|
||||
|
||||
@@ -52,7 +52,7 @@ De esa manera, pude encontrar las mejores maneras de reducir la duplicación de
|
||||
|
||||
Todo de una manera que proporcionara la mejor experiencia de desarrollo para todos los desarrolladores.
|
||||
|
||||
## Requisitos
|
||||
## Requisitos { #requirements }
|
||||
|
||||
Después de probar varias alternativas, decidí que iba a usar <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">**Pydantic**</a> por sus ventajas.
|
||||
|
||||
@@ -60,11 +60,11 @@ Luego contribuí a este, para hacerlo totalmente compatible con JSON Schema, par
|
||||
|
||||
Durante el desarrollo, también contribuí a <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>, el otro requisito clave.
|
||||
|
||||
## Desarrollo
|
||||
## Desarrollo { #development }
|
||||
|
||||
Para cuando comencé a crear el propio **FastAPI**, la mayoría de las piezas ya estaban en su lugar, el diseño estaba definido, los requisitos y herramientas estaban listos, y el conocimiento sobre los estándares y especificaciones estaba claro y fresco.
|
||||
|
||||
## Futuro
|
||||
## Futuro { #future }
|
||||
|
||||
A este punto, ya está claro que **FastAPI** con sus ideas está siendo útil para muchas personas.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Repositorio de GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-t
|
||||
- 🔍 [Pydantic](https://docs.pydantic.dev), utilizado por FastAPI, para la validación de datos y gestión de configuraciones.
|
||||
- 💾 [PostgreSQL](https://www.postgresql.org) como base de datos SQL.
|
||||
- 🚀 [React](https://react.dev) para el frontend.
|
||||
- 💃 Usando TypeScript, hooks, [Vite](https://vitejs.dev), y otras partes de una stack moderna de frontend.
|
||||
- 💃 Usando TypeScript, hooks, Vite, y otras partes de una stack moderna de frontend.
|
||||
- 🎨 [Tailwind CSS](https://tailwindcss.com) y [shadcn/ui](https://ui.shadcn.com) para los componentes del frontend.
|
||||
- 🤖 Un cliente de frontend generado automáticamente.
|
||||
- 🧪 [Playwright](https://playwright.dev) para escribir pruebas End-to-End.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Tareas en Segundo Plano
|
||||
# Tareas en Segundo Plano { #background-tasks }
|
||||
|
||||
Puedes definir tareas en segundo plano para que se ejecuten *después* de devolver un response.
|
||||
|
||||
@@ -11,7 +11,7 @@ Esto incluye, por ejemplo:
|
||||
* Procesamiento de datos:
|
||||
* Por ejemplo, supongamos que recibes un archivo que debe pasar por un proceso lento, puedes devolver un response de "Accepted" (HTTP 202) y procesar el archivo en segundo plano.
|
||||
|
||||
## Usando `BackgroundTasks`
|
||||
## Usando `BackgroundTasks` { #using-backgroundtasks }
|
||||
|
||||
Primero, importa `BackgroundTasks` y define un parámetro en tu *path operation function* con una declaración de tipo de `BackgroundTasks`:
|
||||
|
||||
@@ -19,7 +19,7 @@ Primero, importa `BackgroundTasks` y define un parámetro en tu *path operation
|
||||
|
||||
**FastAPI** creará el objeto de tipo `BackgroundTasks` por ti y lo pasará como ese parámetro.
|
||||
|
||||
## Crear una función de tarea
|
||||
## Crear una función de tarea { #create-a-task-function }
|
||||
|
||||
Crea una función para que se ejecute como la tarea en segundo plano.
|
||||
|
||||
@@ -33,7 +33,7 @@ Y como la operación de escritura no usa `async` y `await`, definimos la funció
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
|
||||
|
||||
## Agregar la tarea en segundo plano
|
||||
## Agregar la tarea en segundo plano { #add-the-background-task }
|
||||
|
||||
Dentro de tu *path operation function*, pasa tu función de tarea al objeto de *background tasks* con el método `.add_task()`:
|
||||
|
||||
@@ -45,7 +45,7 @@ Dentro de tu *path operation function*, pasa tu función de tarea al objeto de *
|
||||
* Cualquier secuencia de argumentos que deba pasarse a la función de tarea en orden (`email`).
|
||||
* Cualquier argumento de palabras clave que deba pasarse a la función de tarea (`message="some notification"`).
|
||||
|
||||
## Inyección de Dependencias
|
||||
## Inyección de Dependencias { #dependency-injection }
|
||||
|
||||
Usar `BackgroundTasks` también funciona con el sistema de inyección de dependencias, puedes declarar un parámetro de tipo `BackgroundTasks` en varios niveles: en una *path operation function*, en una dependencia (dependable), en una sub-dependencia, etc.
|
||||
|
||||
@@ -59,7 +59,7 @@ Si hay un query en el request, se escribirá en el log en una tarea en segundo p
|
||||
|
||||
Y luego otra tarea en segundo plano generada en la *path operation function* escribirá un mensaje usando el parámetro de path `email`.
|
||||
|
||||
## Detalles Técnicos
|
||||
## Detalles Técnicos { #technical-details }
|
||||
|
||||
La clase `BackgroundTasks` proviene directamente de <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>.
|
||||
|
||||
@@ -71,7 +71,7 @@ Todavía es posible usar `BackgroundTask` solo en FastAPI, pero debes crear el o
|
||||
|
||||
Puedes ver más detalles en <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">la documentación oficial de Starlette sobre Background Tasks</a>.
|
||||
|
||||
## Advertencia
|
||||
## Advertencia { #caveat }
|
||||
|
||||
Si necesitas realizar una computación intensa en segundo plano y no necesariamente necesitas que se ejecute por el mismo proceso (por ejemplo, no necesitas compartir memoria, variables, etc.), podrías beneficiarte del uso de otras herramientas más grandes como <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
|
||||
|
||||
@@ -79,6 +79,6 @@ Tienden a requerir configuraciones más complejas, un gestor de cola de mensajes
|
||||
|
||||
Pero si necesitas acceder a variables y objetos de la misma app de **FastAPI**, o necesitas realizar pequeñas tareas en segundo plano (como enviar una notificación por email), simplemente puedes usar `BackgroundTasks`.
|
||||
|
||||
## Resumen
|
||||
## Resumen { #recap }
|
||||
|
||||
Importa y usa `BackgroundTasks` con parámetros en *path operation functions* y dependencias para agregar tareas en segundo plano.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Middleware
|
||||
# Middleware { #middleware }
|
||||
|
||||
Puedes añadir middleware a las aplicaciones de **FastAPI**.
|
||||
|
||||
@@ -15,11 +15,11 @@ Un "middleware" es una función que trabaja con cada **request** antes de que se
|
||||
|
||||
Si tienes dependencias con `yield`, el código de salida se ejecutará *después* del middleware.
|
||||
|
||||
Si hubiera alguna tarea en segundo plano (documentada más adelante), se ejecutará *después* de todo el middleware.
|
||||
Si hubiera tareas en segundo plano (cubiertas en la sección [Tareas en segundo plano](background-tasks.md){.internal-link target=_blank}, lo verás más adelante), se ejecutarán *después* de todo el middleware.
|
||||
|
||||
///
|
||||
|
||||
## Crear un middleware
|
||||
## Crear un middleware { #create-a-middleware }
|
||||
|
||||
Para crear un middleware usas el decorador `@app.middleware("http")` encima de una función.
|
||||
|
||||
@@ -35,7 +35,7 @@ La función middleware recibe:
|
||||
|
||||
/// tip | Consejo
|
||||
|
||||
Ten en cuenta que los custom proprietary headers se pueden añadir <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando el prefijo 'X-'</a>.
|
||||
Ten en cuenta que los custom proprietary headers se pueden añadir <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando el prefijo `X-`</a>.
|
||||
|
||||
Pero si tienes custom headers que deseas que un cliente en un navegador pueda ver, necesitas añadirlos a tus configuraciones de CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) usando el parámetro `expose_headers` documentado en <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">la documentación de CORS de Starlette</a>.
|
||||
|
||||
@@ -49,7 +49,7 @@ También podrías usar `from starlette.requests import Request`.
|
||||
|
||||
///
|
||||
|
||||
### Antes y después de la `response`
|
||||
### Antes y después de la `response` { #before-and-after-the-response }
|
||||
|
||||
Puedes añadir código que se ejecute con la `request`, antes de que cualquier *path operation* la reciba.
|
||||
|
||||
@@ -65,7 +65,30 @@ Aquí usamos <a href="https://docs.python.org/3/library/time.html#time.perf_coun
|
||||
|
||||
///
|
||||
|
||||
## Otros middlewares
|
||||
## Orden de ejecución con múltiples middlewares { #multiple-middleware-execution-order }
|
||||
|
||||
Cuando añades múltiples middlewares usando ya sea el decorador `@app.middleware()` o el método `app.add_middleware()`, cada nuevo middleware envuelve la aplicación, formando un stack. El último middleware añadido es el más externo, y el primero es el más interno.
|
||||
|
||||
En el camino de la request, el middleware más externo se ejecuta primero.
|
||||
|
||||
En el camino de la response, se ejecuta al final.
|
||||
|
||||
Por ejemplo:
|
||||
|
||||
```Python
|
||||
app.add_middleware(MiddlewareA)
|
||||
app.add_middleware(MiddlewareB)
|
||||
```
|
||||
|
||||
Esto da como resultado el siguiente orden de ejecución:
|
||||
|
||||
* **Request**: MiddlewareB → MiddlewareA → ruta
|
||||
|
||||
* **Response**: ruta → MiddlewareA → MiddlewareB
|
||||
|
||||
Este comportamiento de apilamiento asegura que los middlewares se ejecuten en un orden predecible y controlable.
|
||||
|
||||
## Otros middlewares { #other-middlewares }
|
||||
|
||||
Más adelante puedes leer sobre otros middlewares en la [Guía del Usuario Avanzado: Middleware Avanzado](../advanced/middleware.md){.internal-link target=_blank}.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Parámetros de Path y Validaciones Numéricas
|
||||
# Parámetros de Path y Validaciones Numéricas { #path-parameters-and-numeric-validations }
|
||||
|
||||
De la misma manera que puedes declarar más validaciones y metadatos para los parámetros de query con `Query`, puedes declarar el mismo tipo de validaciones y metadatos para los parámetros de path con `Path`.
|
||||
|
||||
## Importar Path
|
||||
## Importar Path { #import-path }
|
||||
|
||||
Primero, importa `Path` de `fastapi`, e importa `Annotated`:
|
||||
|
||||
@@ -18,7 +18,7 @@ Asegúrate de [Actualizar la versión de FastAPI](../deployment/versions.md#upgr
|
||||
|
||||
///
|
||||
|
||||
## Declarar metadatos
|
||||
## Declarar metadatos { #declare-metadata }
|
||||
|
||||
Puedes declarar todos los mismos parámetros que para `Query`.
|
||||
|
||||
@@ -32,7 +32,7 @@ Un parámetro de path siempre es requerido ya que tiene que formar parte del pat
|
||||
|
||||
///
|
||||
|
||||
## Ordena los parámetros como necesites
|
||||
## Ordena los parámetros como necesites { #order-the-parameters-as-you-need }
|
||||
|
||||
/// tip | Consejo
|
||||
|
||||
@@ -60,7 +60,7 @@ Pero ten en cuenta que si usas `Annotated`, no tendrás este problema, no import
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
|
||||
|
||||
## Ordena los parámetros como necesites, trucos
|
||||
## Ordena los parámetros como necesites, trucos { #order-the-parameters-as-you-need-tricks }
|
||||
|
||||
/// tip | Consejo
|
||||
|
||||
@@ -85,13 +85,13 @@ Python no hará nada con ese `*`, pero sabrá que todos los parámetros siguient
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
|
||||
|
||||
### Mejor con `Annotated`
|
||||
### Mejor con `Annotated` { #better-with-annotated }
|
||||
|
||||
Ten en cuenta que si usas `Annotated`, como no estás usando valores por defecto de los parámetros de la función, no tendrás este problema y probablemente no necesitarás usar `*`.
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
|
||||
|
||||
## Validaciones numéricas: mayor o igual
|
||||
## Validaciones numéricas: mayor o igual { #number-validations-greater-than-or-equal }
|
||||
|
||||
Con `Query` y `Path` (y otros que verás más adelante) puedes declarar restricciones numéricas.
|
||||
|
||||
@@ -99,7 +99,7 @@ Aquí, con `ge=1`, `item_id` necesitará ser un número entero "`g`reater than o
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
|
||||
|
||||
## Validaciones numéricas: mayor que y menor o igual
|
||||
## Validaciones numéricas: mayor que y menor o igual { #number-validations-greater-than-and-less-than-or-equal }
|
||||
|
||||
Lo mismo aplica para:
|
||||
|
||||
@@ -108,19 +108,19 @@ Lo mismo aplica para:
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
|
||||
|
||||
## Validaciones numéricas: flotantes, mayor y menor
|
||||
## Validaciones numéricas: flotantes, mayor y menor { #number-validations-floats-greater-than-and-less-than }
|
||||
|
||||
Las validaciones numéricas también funcionan para valores `float`.
|
||||
|
||||
Aquí es donde se convierte en importante poder declarar <abbr title="greater than"><code>gt</code></abbr> y no solo <abbr title="greater than or equal"><code>ge</code></abbr>. Ya que con esto puedes requerir, por ejemplo, que un valor sea mayor que `0`, incluso si es menor que `1`.
|
||||
Aquí es donde se convierte en importante poder declarar <abbr title="greater than – mayor que"><code>gt</code></abbr> y no solo <abbr title="greater than or equal – mayor o igual que"><code>ge</code></abbr>. Ya que con esto puedes requerir, por ejemplo, que un valor sea mayor que `0`, incluso si es menor que `1`.
|
||||
|
||||
Así, `0.5` sería un valor válido. Pero `0.0` o `0` no lo serían.
|
||||
|
||||
Y lo mismo para <abbr title="less than"><code>lt</code></abbr>.
|
||||
Y lo mismo para <abbr title="less than – menor que"><code>lt</code></abbr>.
|
||||
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
|
||||
|
||||
## Resumen
|
||||
## Resumen { #recap }
|
||||
|
||||
Con `Query`, `Path` (y otros que aún no has visto) puedes declarar metadatos y validaciones de string de las mismas maneras que con [Parámetros de Query y Validaciones de String](query-params-str-validations.md){.internal-link target=_blank}.
|
||||
|
||||
@@ -139,7 +139,7 @@ Todas ellas comparten los mismos parámetros para validación adicional y metada
|
||||
|
||||
///
|
||||
|
||||
/// note | Nota técnica
|
||||
/// note | Detalles técnicos
|
||||
|
||||
Cuando importas `Query`, `Path` y otros de `fastapi`, en realidad son funciones.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Parámetros de Path
|
||||
# Parámetros de Path { #path-parameters }
|
||||
|
||||
Puedes declarar "parámetros" o "variables" de path con la misma sintaxis que se usa en los format strings de Python:
|
||||
|
||||
@@ -12,7 +12,7 @@ Así que, si ejecutas este ejemplo y vas a <a href="http://127.0.0.1:8000/items/
|
||||
{"item_id":"foo"}
|
||||
```
|
||||
|
||||
## Parámetros de path con tipos
|
||||
## Parámetros de path con tipos { #path-parameters-with-types }
|
||||
|
||||
Puedes declarar el tipo de un parámetro de path en la función, usando anotaciones de tipos estándar de Python:
|
||||
|
||||
@@ -26,7 +26,7 @@ Esto te dará soporte del editor dentro de tu función, con chequeo de errores,
|
||||
|
||||
///
|
||||
|
||||
## Conversión de datos
|
||||
## <abbr title="también conocido como: serialización, parsing, marshalling">Conversión</abbr> de datos { #data-conversion }
|
||||
|
||||
Si ejecutas este ejemplo y abres tu navegador en <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, verás un response de:
|
||||
|
||||
@@ -38,11 +38,11 @@ Si ejecutas este ejemplo y abres tu navegador en <a href="http://127.0.0.1:8000/
|
||||
|
||||
Nota que el valor que tu función recibió (y devolvió) es `3`, como un `int` de Python, no un string `"3"`.
|
||||
|
||||
Entonces, con esa declaración de tipo, **FastAPI** te ofrece <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr> automático de requests.
|
||||
Entonces, con esa declaración de tipo, **FastAPI** te ofrece <abbr title="convertir el string que viene de un request HTTP en datos de Python">"parsing"</abbr> automático de request.
|
||||
|
||||
///
|
||||
|
||||
## Validación de datos
|
||||
## Validación de datos { #data-validation }
|
||||
|
||||
Pero si vas al navegador en <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, verás un bonito error HTTP de:
|
||||
|
||||
@@ -76,7 +76,7 @@ Esto es increíblemente útil mientras desarrollas y depuras código que interac
|
||||
|
||||
///
|
||||
|
||||
## Documentación
|
||||
## Documentación { #documentation }
|
||||
|
||||
Y cuando abras tu navegador en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, verás una documentación de API automática e interactiva como:
|
||||
|
||||
@@ -90,7 +90,7 @@ Nota que el parámetro de path está declarado como un entero.
|
||||
|
||||
///
|
||||
|
||||
## Beneficios basados en estándares, documentación alternativa
|
||||
## Beneficios basados en estándares, documentación alternativa { #standards-based-benefits-alternative-documentation }
|
||||
|
||||
Y porque el esquema generado es del estándar <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a>, hay muchas herramientas compatibles.
|
||||
|
||||
@@ -100,7 +100,7 @@ Debido a esto, el propio **FastAPI** proporciona una documentación de API alter
|
||||
|
||||
De la misma manera, hay muchas herramientas compatibles. Incluyendo herramientas de generación de código para muchos lenguajes.
|
||||
|
||||
## Pydantic
|
||||
## Pydantic { #pydantic }
|
||||
|
||||
Toda la validación de datos se realiza internamente con <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, así que obtienes todos los beneficios de esta. Y sabes que estás en buenas manos.
|
||||
|
||||
@@ -108,7 +108,7 @@ Puedes usar las mismas declaraciones de tipo con `str`, `float`, `bool` y muchos
|
||||
|
||||
Varios de estos se exploran en los siguientes capítulos del tutorial.
|
||||
|
||||
## El orden importa
|
||||
## El orden importa { #order-matters }
|
||||
|
||||
Al crear *path operations*, puedes encontrarte en situaciones donde tienes un path fijo.
|
||||
|
||||
@@ -128,11 +128,11 @@ De manera similar, no puedes redefinir una path operation:
|
||||
|
||||
La primera siempre será utilizada ya que el path coincide primero.
|
||||
|
||||
## Valores predefinidos
|
||||
## Valores predefinidos { #predefined-values }
|
||||
|
||||
Si tienes una *path operation* que recibe un *path parameter*, pero quieres que los valores posibles válidos del *path parameter* estén predefinidos, puedes usar un <abbr title="Enumeration">`Enum`</abbr> estándar de Python.
|
||||
Si tienes una *path operation* que recibe un *path parameter*, pero quieres que los valores posibles válidos del *path parameter* estén predefinidos, puedes usar un <abbr title="Enumeration – Enumeración">`Enum`</abbr> estándar de Python.
|
||||
|
||||
### Crear una clase `Enum`
|
||||
### Crear una clase `Enum` { #create-an-enum-class }
|
||||
|
||||
Importa `Enum` y crea una subclase que herede de `str` y de `Enum`.
|
||||
|
||||
@@ -154,29 +154,29 @@ Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de <abb
|
||||
|
||||
///
|
||||
|
||||
### Declarar un *path parameter*
|
||||
### Declarar un *path parameter* { #declare-a-path-parameter }
|
||||
|
||||
Luego crea un *path parameter* con una anotación de tipo usando la clase enum que creaste (`ModelName`):
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[16] *}
|
||||
|
||||
### Revisa la documentación
|
||||
### Revisa la documentación { #check-the-docs }
|
||||
|
||||
Como los valores disponibles para el *path parameter* están predefinidos, la documentación interactiva puede mostrarlos de manera ordenada:
|
||||
|
||||
<img src="/img/tutorial/path-params/image03.png">
|
||||
|
||||
### Trabajando con *enumeraciones* de Python
|
||||
### Trabajando con *enumeraciones* de Python { #working-with-python-enumerations }
|
||||
|
||||
El valor del *path parameter* será un *miembro* de enumeración.
|
||||
|
||||
#### Comparar *miembros* de enumeraciones
|
||||
#### Comparar *miembros* de enumeraciones { #compare-enumeration-members }
|
||||
|
||||
Puedes compararlo con el *miembro* de enumeración en tu enum creada `ModelName`:
|
||||
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[17] *}
|
||||
|
||||
#### Obtener el valor de *enumeración*
|
||||
#### Obtener el valor de *enumeración* { #get-the-enumeration-value }
|
||||
|
||||
Puedes obtener el valor actual (un `str` en este caso) usando `model_name.value`, o en general, `your_enum_member.value`:
|
||||
|
||||
@@ -188,7 +188,7 @@ También podrías acceder al valor `"lenet"` con `ModelName.lenet.value`.
|
||||
|
||||
///
|
||||
|
||||
#### Devolver *miembros* de enumeración
|
||||
#### Devolver *miembros* de enumeración { #return-enumeration-members }
|
||||
|
||||
Puedes devolver *miembros de enum* desde tu *path operation*, incluso anidados en un cuerpo JSON (por ejemplo, un `dict`).
|
||||
|
||||
@@ -205,7 +205,7 @@ En tu cliente recibirás un response JSON como:
|
||||
}
|
||||
```
|
||||
|
||||
## Parámetros de path conteniendo paths
|
||||
## Parámetros de path conteniendo paths { #path-parameters-containing-paths }
|
||||
|
||||
Imaginemos que tienes una *path operation* con un path `/files/{file_path}`.
|
||||
|
||||
@@ -213,7 +213,7 @@ Pero necesitas que `file_path` en sí mismo contenga un *path*, como `home/johnd
|
||||
|
||||
Entonces, la URL para ese archivo sería algo como: `/files/home/johndoe/myfile.txt`.
|
||||
|
||||
### Soporte de OpenAPI
|
||||
### Soporte de OpenAPI { #openapi-support }
|
||||
|
||||
OpenAPI no soporta una manera de declarar un *path parameter* para que contenga un *path* dentro, ya que eso podría llevar a escenarios que son difíciles de probar y definir.
|
||||
|
||||
@@ -221,7 +221,7 @@ Sin embargo, todavía puedes hacerlo en **FastAPI**, usando una de las herramien
|
||||
|
||||
Y la documentación seguiría funcionando, aunque no agregue ninguna documentación indicando que el parámetro debe contener un path.
|
||||
|
||||
### Convertidor de Path
|
||||
### Convertidor de Path { #path-convertor }
|
||||
|
||||
Usando una opción directamente de Starlette puedes declarar un *path parameter* conteniendo un *path* usando una URL como:
|
||||
|
||||
@@ -243,12 +243,12 @@ En ese caso, la URL sería: `/files//home/johndoe/myfile.txt`, con una doble bar
|
||||
|
||||
///
|
||||
|
||||
## Resumen
|
||||
## Resumen { #recap }
|
||||
|
||||
Con **FastAPI**, al usar declaraciones de tipo estándar de Python, cortas e intuitivas, obtienes:
|
||||
|
||||
* Soporte del editor: chequeo de errores, autocompletado, etc.
|
||||
* "<abbr title="converting the string that comes from an HTTP request into Python data">parsing</abbr>" de datos
|
||||
* "<abbr title="convertir el string que viene de un request HTTP en datos de Python">parsing</abbr>" de datos
|
||||
* Validación de datos
|
||||
* Anotación de API y documentación automática
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Parámetros de Query
|
||||
# Parámetros de Query { #query-parameters }
|
||||
|
||||
Cuando declaras otros parámetros de función que no son parte de los parámetros de path, son automáticamente interpretados como parámetros de "query".
|
||||
|
||||
@@ -24,11 +24,11 @@ Pero cuando los declaras con tipos de Python (en el ejemplo anterior, como `int`
|
||||
Todo el mismo proceso que se aplica para los parámetros de path también se aplica para los parámetros de query:
|
||||
|
||||
* Soporte del editor (obviamente)
|
||||
* <abbr title="convirtiendo el string que viene de un request HTTP en datos de Python">"Parsing"</abbr> de datos
|
||||
* <abbr title="convirtiendo el string que viene de un request HTTP en datos de Python">"parsing"</abbr> de datos
|
||||
* Validación de datos
|
||||
* Documentación automática
|
||||
|
||||
## Valores por defecto
|
||||
## Valores por defecto { #defaults }
|
||||
|
||||
Como los parámetros de query no son una parte fija de un path, pueden ser opcionales y pueden tener valores por defecto.
|
||||
|
||||
@@ -57,19 +57,21 @@ Los valores de los parámetros en tu función serán:
|
||||
* `skip=20`: porque lo configuraste en la URL
|
||||
* `limit=10`: porque ese era el valor por defecto
|
||||
|
||||
## Parámetros opcionales
|
||||
## Parámetros opcionales { #optional-parameters }
|
||||
|
||||
De la misma manera, puedes declarar parámetros de query opcionales, estableciendo su valor por defecto en `None`:
|
||||
|
||||
{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
|
||||
|
||||
En este caso, el parámetro de función `q` será opcional y será `None` por defecto.
|
||||
|
||||
/// check | Revisa
|
||||
|
||||
Además, nota que **FastAPI** es lo suficientemente inteligente para notar que el parámetro de path `item_id` es un parámetro de path y `q` no lo es, por lo tanto, es un parámetro de query.
|
||||
|
||||
///
|
||||
|
||||
## Conversión de tipos en parámetros de query
|
||||
## Conversión de tipos en parámetros de query { #query-parameter-type-conversion }
|
||||
|
||||
También puedes declarar tipos `bool`, y serán convertidos:
|
||||
|
||||
@@ -107,7 +109,7 @@ http://127.0.0.1:8000/items/foo?short=yes
|
||||
|
||||
o cualquier otra variación (mayúsculas, primera letra en mayúscula, etc.), tu función verá el parámetro `short` con un valor `bool` de `True`. De lo contrario, será `False`.
|
||||
|
||||
## Múltiples parámetros de path y de query
|
||||
## Múltiples parámetros de path y de query { #multiple-path-and-query-parameters }
|
||||
|
||||
Puedes declarar múltiples parámetros de path y de query al mismo tiempo, **FastAPI** sabe cuál es cuál.
|
||||
|
||||
@@ -117,7 +119,7 @@ Serán detectados por nombre:
|
||||
|
||||
{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
|
||||
|
||||
## Parámetros de query requeridos
|
||||
## Parámetros de query requeridos { #required-query-parameters }
|
||||
|
||||
Cuando declaras un valor por defecto para parámetros que no son de path (por ahora, solo hemos visto parámetros de query), entonces no es requerido.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Seguridad
|
||||
# Seguridad { #security }
|
||||
|
||||
Hay muchas formas de manejar la seguridad, autenticación y autorización.
|
||||
|
||||
@@ -10,11 +10,11 @@ En muchos frameworks y sistemas, solo manejar la seguridad y autenticación requ
|
||||
|
||||
Pero primero, vamos a revisar algunos pequeños conceptos.
|
||||
|
||||
## ¿Con prisa?
|
||||
## ¿Con prisa? { #in-a-hurry }
|
||||
|
||||
Si no te importan ninguno de estos términos y solo necesitas agregar seguridad con autenticación basada en nombre de usuario y contraseña *ahora mismo*, salta a los siguientes capítulos.
|
||||
|
||||
## OAuth2
|
||||
## OAuth2 { #oauth2 }
|
||||
|
||||
OAuth2 es una especificación que define varias maneras de manejar la autenticación y autorización.
|
||||
|
||||
@@ -24,7 +24,7 @@ Incluye formas de autenticarse usando un "tercero".
|
||||
|
||||
Eso es lo que todos los sistemas con "iniciar sesión con Facebook, Google, X (Twitter), GitHub" utilizan internamente.
|
||||
|
||||
### OAuth 1
|
||||
### OAuth 1 { #oauth-1 }
|
||||
|
||||
Hubo un OAuth 1, que es muy diferente de OAuth2, y más complejo, ya que incluía especificaciones directas sobre cómo encriptar la comunicación.
|
||||
|
||||
@@ -38,7 +38,7 @@ En la sección sobre **deployment** verás cómo configurar HTTPS de forma gratu
|
||||
|
||||
///
|
||||
|
||||
## OpenID Connect
|
||||
## OpenID Connect { #openid-connect }
|
||||
|
||||
OpenID Connect es otra especificación, basada en **OAuth2**.
|
||||
|
||||
@@ -48,7 +48,7 @@ Por ejemplo, el login de Google usa OpenID Connect (que internamente usa OAuth2)
|
||||
|
||||
Pero el login de Facebook no soporta OpenID Connect. Tiene su propia versión de OAuth2.
|
||||
|
||||
### OpenID (no "OpenID Connect")
|
||||
### OpenID (no "OpenID Connect") { #openid-not-openid-connect }
|
||||
|
||||
Hubo también una especificación "OpenID". Que intentaba resolver lo mismo que **OpenID Connect**, pero no estaba basada en OAuth2.
|
||||
|
||||
@@ -56,7 +56,7 @@ Entonces, era un sistema completo adicional.
|
||||
|
||||
No es muy popular o usado hoy en día.
|
||||
|
||||
## OpenAPI
|
||||
## OpenAPI { #openapi }
|
||||
|
||||
OpenAPI (anteriormente conocido como Swagger) es la especificación abierta para construir APIs (ahora parte de la Linux Foundation).
|
||||
|
||||
@@ -96,7 +96,7 @@ El problema más complejo es construir un proveedor de autenticación/autorizaci
|
||||
|
||||
///
|
||||
|
||||
## Utilidades de **FastAPI**
|
||||
## Utilidades de **FastAPI** { #fastapi-utilities }
|
||||
|
||||
FastAPI proporciona varias herramientas para cada uno de estos esquemas de seguridad en el módulo `fastapi.security` que simplifican el uso de estos mecanismos de seguridad.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Archivos Estáticos
|
||||
# Archivos Estáticos { #static-files }
|
||||
|
||||
Puedes servir archivos estáticos automáticamente desde un directorio utilizando `StaticFiles`.
|
||||
|
||||
## Usa `StaticFiles`
|
||||
## Usa `StaticFiles` { #use-staticfiles }
|
||||
|
||||
* Importa `StaticFiles`.
|
||||
* "Monta" una instance de `StaticFiles()` en un path específico.
|
||||
@@ -17,7 +17,7 @@ También podrías usar `from starlette.staticfiles import StaticFiles`.
|
||||
|
||||
///
|
||||
|
||||
### Qué es "Montar"
|
||||
### Qué es "Montar" { #what-is-mounting }
|
||||
|
||||
"Montar" significa agregar una aplicación completa "independiente" en un path específico, que luego se encargará de manejar todos los sub-paths.
|
||||
|
||||
@@ -25,7 +25,7 @@ Esto es diferente a usar un `APIRouter`, ya que una aplicación montada es compl
|
||||
|
||||
Puedes leer más sobre esto en la [Guía de Usuario Avanzada](../advanced/index.md){.internal-link target=_blank}.
|
||||
|
||||
## Detalles
|
||||
## Detalles { #details }
|
||||
|
||||
El primer `"/static"` se refiere al sub-path en el que esta "sub-aplicación" será "montada". Por lo tanto, cualquier path que comience con `"/static"` será manejado por ella.
|
||||
|
||||
@@ -35,6 +35,6 @@ El `name="static"` le da un nombre que puede ser utilizado internamente por **Fa
|
||||
|
||||
Todos estos parámetros pueden ser diferentes a "`static`", ajústalos según las necesidades y detalles específicos de tu propia aplicación.
|
||||
|
||||
## Más info
|
||||
## Más info { #more-info }
|
||||
|
||||
Para más detalles y opciones revisa <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">la documentación de Starlette sobre Archivos Estáticos</a>.
|
||||
|
||||
Reference in New Issue
Block a user