Sync fastapi docs from 50113da1 on 2026-09-11

This commit is contained in:
The Librarian
2026-09-11 04:00:08 +00:00
parent 632909b5f6
commit 818066b271
739 changed files with 4974 additions and 17395 deletions
@@ -243,5 +243,5 @@ Por ejemplo:
Para ver exactamente qué puedes incluir en los responses, puedes revisar estas secciones en la especificación OpenAPI:
* [Objeto de Responses de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), incluye el `Response Object`.
* [Objeto de Response de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), puedes incluir cualquier cosa de esto directamente en cada response dentro de tu parámetro `responses`. Incluyendo `description`, `headers`, `content` (dentro de este es que declaras diferentes media types y JSON Schemas), y `links`.
* [Objeto de Responses de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object), incluye el `Response Object`.
* [Objeto de Response de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#response-object), puedes incluir cualquier cosa de esto directamente en cada response dentro de tu parámetro `responses`. Incluyendo `description`, `headers`, `content` (dentro de este es que declaras diferentes media types y JSON Schemas), y `links`.
+1 -1
View File
@@ -45,7 +45,7 @@ Puedes ejecutar tus tests como de costumbre vía:
<div class="termy">
```console
$ pytest
$ uv run pytest
---> 100%
```
+5 -5
View File
@@ -33,7 +33,7 @@ Si tu **server** está detrás de un **proxy** confiable y solo el proxy le habl
<div class="termy">
```console
$ fastapi run --forwarded-allow-ips="*"
$ uv run fastapi run --forwarded-allow-ips="*"
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -170,7 +170,7 @@ Para lograr esto, puedes usar la opción de línea de comandos `--root-path` com
<div class="termy">
```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -200,7 +200,7 @@ Luego, si inicias Uvicorn con:
<div class="termy">
```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -253,7 +253,7 @@ En un caso así (sin un prefijo de path eliminado), el proxy escucharía algo co
Puedes ejecutar fácilmente el experimento localmente con un prefijo de path eliminado usando [Traefik](https://docs.traefik.io/).
[Descarga Traefik](https://github.com/containous/traefik/releases), es un archivo binario único, puedes extraer el archivo comprimido y ejecutarlo directamente desde la terminal.
[Descarga Traefik](https://github.com/traefik/traefik/releases), es un archivo binario único, puedes extraer el archivo comprimido y ejecutarlo directamente desde la terminal.
Luego crea un archivo `traefik.toml` con:
@@ -321,7 +321,7 @@ Y ahora inicia tu app, utilizando la opción `--root-path`:
<div class="termy">
```console
$ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
$ uv run fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
+2 -2
View File
@@ -6,7 +6,7 @@ Pero FastAPI también soporta el uso de [`dataclasses`](https://docs.python.org/
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
Esto sigue siendo soportado gracias a **Pydantic**, ya que tiene [soporte interno para `dataclasses`](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel).
Esto sigue siendo soportado gracias a **Pydantic**, ya que tiene [soporte interno para `dataclasses`](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/#usage-of-stdlib-dataclasses-with-basemodel).
Así que, incluso con el código anterior que no usa Pydantic explícitamente, FastAPI está usando Pydantic para convertir esos dataclasses estándar en su propia versión de dataclasses de Pydantic.
@@ -88,7 +88,7 @@ Revisa los consejos de anotación en el código arriba para ver más detalles es
También puedes combinar `dataclasses` con otros modelos de Pydantic, heredar de ellos, incluirlos en tus propios modelos, etc.
Para saber más, revisa la [documentación de Pydantic sobre dataclasses](https://docs.pydantic.dev/latest/concepts/dataclasses/).
Para saber más, revisa la [documentación de Pydantic sobre dataclasses](https://pydantic.dev/docs/validation/latest/concepts/dataclasses/).
## Versión { #version }
+1 -1
View File
@@ -154,7 +154,7 @@ Por debajo, en la especificación técnica ASGI, esto es parte del [Protocolo de
/// note | Nota
Puedes leer más sobre los manejadores `lifespan` de Starlette en [la documentación de `Lifespan` de Starlette](https://www.starlette.dev/lifespan/).
Puedes leer más sobre los manejadores `lifespan` de Starlette en [la documentación de Lifespan de Starlette](https://starlette.dev/lifespan/).
Incluyendo cómo manejar el estado de lifespan que puede ser usado en otras áreas de tu código.
+1 -1
View File
@@ -12,7 +12,7 @@ Una opción versátil es el [OpenAPI Generator](https://openapi-generator.tech/)
Para **clientes de TypeScript**, [Hey API](https://heyapi.dev/) es una solución diseñada específicamente, que ofrece una experiencia optimizada para el ecosistema de TypeScript.
Puedes descubrir más generadores de SDK en [OpenAPI.Tools](https://openapi.tools/#sdk).
Puedes descubrir más generadores de SDK en [OpenAPI.Tools](https://openapi.tools/categories/sdk-generators).
/// tip | Consejo
+2 -2
View File
@@ -91,7 +91,7 @@ Hay muchos otros middlewares ASGI.
Por ejemplo:
* [`ProxyHeadersMiddleware` de Uvicorn](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
* [`ProxyHeadersMiddleware` de Uvicorn](https://github.com/Kludex/uvicorn/blob/main/uvicorn/middleware/proxy_headers.py)
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
Para ver otros middlewares disponibles, revisa [la documentación de Middleware de Starlette](https://www.starlette.dev/middleware/) y la [Lista ASGI Awesome](https://github.com/florimondmanca/awesome-asgi).
Para ver otros middlewares disponibles, revisa [la documentación de Middleware de Starlette](https://starlette.dev/middleware/) y la [Lista ASGI Awesome](https://github.com/florimondmanca/awesome-asgi).
+4 -4
View File
@@ -35,7 +35,7 @@ Esta parte es bastante normal, probablemente ya estés familiarizado con la mayo
/// tip | Consejo
El parámetro de query `callback_url` utiliza un tipo [Url](https://docs.pydantic.dev/latest/api/networks/) de Pydantic.
El parámetro de query `callback_url` utiliza un tipo [Url](https://pydantic.dev/docs/validation/latest/api/pydantic/networks/) de Pydantic.
///
@@ -106,11 +106,11 @@ Debería verse como una *path operation* normal de FastAPI:
Hay 2 diferencias principales respecto a una *path operation* normal:
* No necesita tener ningún código real, porque tu aplicación nunca llamará a este código. Solo se usa para documentar la *API externa*. Así que, la función podría simplemente tener `pass`.
* El *path* puede contener una [expresión OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (ver más abajo) donde puede usar variables con parámetros y partes del request original enviado a *tu API*.
* El *path* puede contener una [expresión OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression) (ver más abajo) donde puede usar variables con parámetros y partes del request original enviado a *tu API*.
### La expresión del path del callback { #the-callback-path-expression }
El *path* del callback puede tener una [expresión OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) que puede contener partes del request original enviado a *tu API*.
El *path* del callback puede tener una [expresión OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#key-expression) que puede contener partes del request original enviado a *tu API*.
En este caso, es el `str`:
@@ -165,7 +165,7 @@ Observa cómo la URL del callback utilizada contiene la URL recibida como parám
### Agrega el router de callback { #add-the-callback-router }
En este punto tienes las *path operation(s)* del callback necesarias (las que el *desarrollador externo* debería implementar en la *API externa*) en el router de callback que creaste arriba.
En este punto tienes las *callback path operation(s)* necesarias (las que el *desarrollador externo* debería implementar en la *API externa*) en el router de callback que creaste arriba.
Ahora usa el parámetro `callbacks` en el *decorador de path operation de tu API* para pasar el atributo `.routes` de ese router de callback:
+1 -1
View File
@@ -48,4 +48,4 @@ Y como el `Response` se puede usar frecuentemente para establecer headers y cook
///
Para ver todos los parámetros y opciones disponibles, revisa la [documentación en Starlette](https://www.starlette.dev/responses/#set-cookie).
Para ver todos los parámetros y opciones disponibles, revisa la [documentación en Starlette](https://starlette.dev/responses/#set-cookie).
+1 -2
View File
@@ -1,6 +1,5 @@
# Headers de Response { #response-headers }
## Usa un parámetro `Response` { #use-a-response-parameter }
Puedes declarar un parámetro de tipo `Response` en tu *path operation function* (como puedes hacer para cookies).
@@ -39,4 +38,4 @@ Y como el `Response` se puede usar frecuentemente para establecer headers y cook
Ten en cuenta que los headers propietarios personalizados se pueden agregar [usando el prefijo `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
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)), usando el parámetro `expose_headers` documentado en [la documentación CORS de Starlette](https://www.starlette.dev/middleware/#corsmiddleware).
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)), usando el parámetro `expose_headers` documentado en [la documentación CORS de Starlette](https://starlette.dev/middleware/#corsmiddleware).
+35 -11
View File
@@ -6,30 +6,34 @@ La mayoría de estas configuraciones son variables (pueden cambiar), como las UR
Por esta razón, es común proporcionarlas en variables de entorno que son leídas por la aplicación.
Una **variable de entorno** (también conocida como una **env var**) es un valor que vive fuera del código Python, en el sistema operativo, y puede ser leído por tu aplicación y otros programas.
Puedes crear una variable de entorno para un comando cuando lo ejecutas. Verás los comandos específicos de cada plataforma más abajo.
/// tip | Consejo
Para entender las variables de entorno, puedes leer [Variables de Entorno](../environment-variables.md).
Lee la [guía de Variables de Entorno](https://tiangolo.com/guides/environment-variables/) para una explicación detallada de cómo funcionan las variables de entorno.
///
## Tipos y validación { #types-and-validation }
Estas variables de entorno solo pueden manejar strings de texto, ya que son externas a Python y tienen que ser compatibles con otros programas y el resto del sistema (e incluso con diferentes sistemas operativos, como Linux, Windows, macOS).
Estas variables de entorno solo pueden manejar strings de texto, ya que son externas a Python y tienen que ser compatibles con otros programas y el resto del sistema (e incluso con diferentes sistemas operativos, como Linux, Windows, y macOS).
Eso significa que cualquier valor leído en Python desde una variable de entorno será un `str`, y cualquier conversión a un tipo diferente o cualquier validación tiene que hacerse en código.
## Pydantic `Settings` { #pydantic-settings }
Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con [Pydantic: Gestión de Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con [Pydantic: Gestión de Settings](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/).
### Instalar `pydantic-settings` { #install-pydantic-settings }
Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md), actívalo y luego instala el paquete `pydantic-settings`:
Añade el paquete `pydantic-settings` a tu proyecto:
<div class="termy">
```console
$ pip install pydantic-settings
$ uv add pydantic-settings
---> 100%
```
@@ -40,7 +44,7 @@ También viene incluido cuando instalas los extras `all` con:
<div class="termy">
```console
$ pip install "fastapi[all]"
$ uv add "fastapi[all]"
---> 100%
```
@@ -76,19 +80,39 @@ Luego puedes usar el nuevo objeto `settings` en tu aplicación:
Luego, ejecutarías el servidor pasando las configuraciones como variables de entorno, por ejemplo, podrías establecer un `ADMIN_EMAIL` y `APP_NAME` con:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.py
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uv run fastapi run main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ $Env:ADMIN_EMAIL = "deadpool@example.com"
$ $Env:APP_NAME = "ChimichangApp"
$ uv run fastapi run main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
////
/// tip | Consejo
Para establecer múltiples env vars para un solo comando, simplemente sepáralas con un espacio y ponlas todas antes del comando.
En Bash, para establecer múltiples env vars para un solo comando, sepáralas con un espacio y ponlas todas antes del comando.
///
@@ -172,11 +196,11 @@ Pero un archivo dotenv realmente no tiene que tener ese nombre exacto.
///
Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en [Pydantic Settings: soporte para Dotenv (.env)](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en [Pydantic Settings: soporte para Dotenv (.env)](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/#dotenv-env-support).
/// tip | Consejo
Para que esto funcione, necesitas `pip install python-dotenv`.
Para que esto funcione, añade `python-dotenv` a tu proyecto con `uv add python-dotenv`.
///
@@ -197,7 +221,7 @@ Y luego actualizar tu `config.py` con:
/// tip | Consejo
El atributo `model_config` se usa solo para configuración de Pydantic. Puedes leer más en [Pydantic: Conceptos: Configuración](https://docs.pydantic.dev/latest/concepts/config/).
El atributo `model_config` se usa solo para configuración de Pydantic. Puedes leer más en [Pydantic: Conceptos: Configuración](https://pydantic.dev/docs/validation/latest/concepts/config/).
///
+2 -2
View File
@@ -1,6 +1,6 @@
# Sub Aplicaciones - Mounts { #sub-applications-mounts }
Si necesitas tener dos aplicaciones de **FastAPI** independientes, cada una con su propio OpenAPI independiente y su propia interfaz de docs, puedes tener una aplicación principal y "montar" una (o más) sub-aplicación(es).
Si necesitas tener dos aplicaciones de **FastAPI** independientes, cada una con su propio OpenAPI independiente y su propia interfaz de documentación, puedes tener una aplicación principal y "montar" una (o más) sub-aplicación(es).
## Montar una aplicación **FastAPI** { #mounting-a-fastapi-application }
@@ -35,7 +35,7 @@ Ahora, ejecuta el comando `fastapi`:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
+3 -3
View File
@@ -8,12 +8,12 @@ Hay utilidades para configurarlo fácilmente que puedes usar directamente en tu
## Instala dependencias { #install-dependencies }
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo e instalar `jinja2`:
Añade `jinja2` a tu proyecto:
<div class="termy">
```console
$ pip install jinja2
$ uv add jinja2
---> 100%
```
@@ -123,4 +123,4 @@ Y porque estás usando `StaticFiles`, ese archivo CSS sería servido automática
## Más detalles { #more-details }
Para más detalles, incluyendo cómo testear plantillas, revisa [la documentación de Starlette sobre plantillas](https://www.starlette.dev/templates/).
Para más detalles, incluyendo cómo escribir pruebas para plantillas, revisa [la documentación de Starlette sobre plantillas](https://starlette.dev/templates/).
+2 -2
View File
@@ -1,11 +1,11 @@
# Eventos de testing: lifespan y startup - shutdown { #testing-events-lifespan-and-startup-shutdown }
# Eventos al escribir pruebas: lifespan y startup - shutdown { #testing-events-lifespan-and-startup-shutdown }
Cuando necesitas que `lifespan` se ejecute en tus tests, puedes usar el `TestClient` con un statement `with`:
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
Puedes leer más detalles sobre ["Ejecutar lifespan en tests en el sitio oficial de documentación de Starlette."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
Puedes leer más detalles sobre ["Ejecutar lifespan en tests en el sitio oficial de documentación de Starlette."](https://starlette.dev/lifespan/#running-lifespan-in-tests)
Para los eventos obsoletos `startup` y `shutdown`, puedes usar el `TestClient` así:
+1 -1
View File
@@ -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 [probar WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions).
Para más detalles, revisa la documentación de Starlette sobre [probar WebSockets](https://starlette.dev/testclient/#testing-websocket-sessions).
///
@@ -15,7 +15,7 @@ Pero hay situaciones donde podrías necesitar acceder al objeto `Request` direct
## 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 de Starlette [`Request`](https://www.starlette.dev/requests/) directamente cuando lo necesites.
Como **FastAPI** es en realidad **Starlette** por debajo, con una capa de varias herramientas encima, puedes usar el objeto de Starlette [`Request`](https://starlette.dev/requests/) directamente cuando lo necesites.
También significa que si obtienes datos del objeto `Request` directamente (por ejemplo, leyendo el cuerpo) no serán validados, convertidos o documentados (con OpenAPI, para la interfaz automática de usuario de la API) por FastAPI.
@@ -45,7 +45,7 @@ De la misma manera, puedes declarar cualquier otro parámetro como normalmente,
## Documentación de `Request` { #request-documentation }
Puedes leer más detalles sobre el [objeto `Request` en el sitio de documentación oficial de Starlette](https://www.starlette.dev/requests/).
Puedes leer más detalles sobre el [objeto `Request` en el sitio de documentación oficial de Starlette](https://starlette.dev/requests/).
/// note | Detalles Técnicos
+9 -9
View File
@@ -2,14 +2,14 @@
Puedes usar [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) con **FastAPI**.
## Instalar `websockets` { #install-websockets }
## Instala `websockets` { #install-websockets }
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo e instalar `websockets` (un paquete de Python que facilita usar el protocolo "WebSocket"):
Añade `websockets` (un paquete de Python que facilita usar el protocolo "WebSocket") a tu proyecto:
<div class="termy">
```console
$ pip install websockets
$ uv add websockets
---> 100%
```
@@ -40,7 +40,7 @@ Pero es la forma más sencilla de enfocarse en el lado del servidor de WebSocket
{* ../../docs_src/websockets_/tutorial001_py310.py hl[2,6:38,41:43] *}
## Crear un `websocket` { #create-a-websocket }
## Crea 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 { #await-for-messages-and-send-messages }
## Espera mensajes y envía mensajes { #await-for-messages-and-send-messages }
En tu ruta de WebSocket puedes `await` para recibir mensajes y enviar mensajes.
@@ -69,7 +69,7 @@ Pon tu código en un archivo `main.py` y luego ejecuta tu aplicación:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -126,7 +126,7 @@ Ejecuta tu aplicación:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -182,5 +182,5 @@ Si necesitas algo fácil de integrar con FastAPI pero que sea más robusto, sopo
Para aprender más sobre las opciones, revisa la documentación de Starlette para:
* [La clase `WebSocket`](https://www.starlette.dev/websockets/).
* [Manejo de WebSocket basado en clases](https://www.starlette.dev/endpoints/#websocketendpoint).
* [La clase `WebSocket`](https://starlette.dev/websockets/).
* [Manejo de WebSocket basado en clases](https://starlette.dev/endpoints/#websocketendpoint).
+1 -1
View File
@@ -9,7 +9,7 @@ Para eso, puedes usar el `WSGIMiddleware` y usarlo para envolver tu aplicación
/// note | Nota
Esto requiere instalar `a2wsgi`, por ejemplo con `pip install a2wsgi`.
Esto requiere agregar `a2wsgi` a tu proyecto, por ejemplo con `uv add a2wsgi`.
///
+7 -7
View File
@@ -125,7 +125,7 @@ Adoptar y usar un estándar abierto para especificaciones de API, en lugar de us
Y a integrar herramientas de interfaz de usuario basadas en estándares:
* [Swagger UI](https://github.com/swagger-api/swagger-ui)
* [ReDoc](https://github.com/Rebilly/ReDoc)
* [ReDoc](https://github.com/Redocly/redoc)
Estas dos fueron elegidas por ser bastante populares y estables, pero haciendo una búsqueda rápida, podrías encontrar docenas de interfaces de usuario alternativas para OpenAPI (que puedes usar con **FastAPI**).
@@ -237,11 +237,11 @@ Generar el esquema OpenAPI automáticamente, desde el mismo código que define l
///
### [NestJS](https://nestjs.com/) (y [Angular](https://angular.io/)) { #nestjs-and-angular }
### [NestJS](https://nestjs.com/) (y [Angular](https://angular.dev/)) { #nestjs-and-angular }
Esto ni siquiera es Python, NestJS es un framework de JavaScript (TypeScript) NodeJS inspirado por Angular.
Logra algo algo similar a lo que se puede hacer con Flask-apispec.
Logra algo similar a lo que se puede hacer con Flask-apispec.
Tiene un sistema de inyección de dependencias integrado, inspirado por Angular 2. Requiere pre-registrar los "inyectables" (como todos los otros sistemas de inyección de dependencias que conozco), por lo que añade a la verbosidad y repetición de código.
@@ -337,7 +337,7 @@ Dado que se basa en el estándar previo para frameworks web Python sincrónicos
/// note | Nota
Hug fue creado por Timothy Crosley, el mismo creador de [`isort`](https://github.com/timothycrosley/isort), una gran herramienta para ordenar automáticamente imports en archivos Python.
Hug fue creado por Timothy Crosley, el mismo creador de [`isort`](https://github.com/PyCQA/isort), una gran herramienta para ordenar automáticamente imports en archivos Python.
///
@@ -401,7 +401,7 @@ Considero a **FastAPI** un "sucesor espiritual" de APIStar, mientras mejora y au
## Usado por **FastAPI** { #used-by-fastapi }
### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
### [Pydantic](https://pydantic.dev/docs/) { #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,7 +417,7 @@ Manejar toda la validación de datos, serialización de datos y documentación a
///
### [Starlette](https://www.starlette.dev/) { #starlette }
### [Starlette](https://starlette.dev/) { #starlette }
Starlette es un framework/toolkit <dfn title="El nuevo estándar para construir aplicaciones web asíncronas en Python">ASGI</dfn> liviano, ideal para construir servicios asyncio de alto rendimiento.
@@ -462,7 +462,7 @@ Por lo tanto, cualquier cosa que puedas hacer con Starlette, puedes hacerlo dire
///
### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
### [Uvicorn](https://uvicorn.dev) { #uvicorn }
Uvicorn es un servidor ASGI extremadamente rápido, construido sobre uvloop y httptools.
+15 -19
View File
@@ -106,36 +106,32 @@ Esto es lo que querrías hacer en **la mayoría de los casos**, por ejemplo:
### Requisitos del Paquete { #package-requirements }
Normalmente tendrías los **requisitos del paquete** para tu aplicación en algún archivo.
Cuando gestionas tu proyecto con `uv`, sus dependencias directas se declaran en `pyproject.toml` y las versiones exactas resueltas se almacenan en `uv.lock`.
Dependería principalmente de la herramienta que uses para **instalar** esos requisitos.
La forma más común de hacerlo es tener un archivo `requirements.txt` con los nombres de los paquetes y sus versiones, uno por línea.
Por supuesto, usarías las mismas ideas que leíste en [Acerca de las versiones de FastAPI](versions.md) para establecer los rangos de versiones.
Por ejemplo, tu `requirements.txt` podría verse así:
```
fastapi[standard]>=0.113.0,<0.114.0
pydantic>=2.7.0,<3.0.0
```
Y normalmente instalarías esas dependencias de los paquetes con `pip`, por ejemplo:
Puedes añadir los paquetes que tu aplicación necesita con:
<div class="termy">
```console
$ pip install -r requirements.txt
$ uv add "fastapi[standard]" pydantic
---> 100%
Successfully installed fastapi pydantic
```
</div>
/// note | Nota
Existen otros formatos y herramientas para definir e instalar dependencias de paquetes.
El Dockerfile de abajo usa `pip` dentro del contenedor. Puedes exportar las dependencias bloqueadas de tu proyecto uv al formato `requirements.txt` que espera:
<div class="termy">
```console
$ uv export --format requirements-txt --no-dev --no-emit-project --output-file requirements.txt
```
</div>
El `requirements.txt` generado es una exportación para la construcción del contenedor. Continúa gestionando las dependencias con `uv add` y regenéralo cuando cambie `uv.lock`.
///
@@ -373,7 +369,7 @@ Verás la documentación interactiva automática de la API (proporcionada por [S
Y también puedes ir a [http://192.168.99.100/redoc](http://192.168.99.100/redoc) o [http://127.0.0.1/redoc](http://127.0.0.1/redoc) (o equivalente, usando tu host de Docker).
Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Rebilly/ReDoc)):
Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Redocly/redoc)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
+1 -1
View File
@@ -5,7 +5,7 @@ Puedes desplegar tu app de FastAPI en [FastAPI Cloud](https://fastapicloud.com)
<div class="termy">
```console
$ fastapi deploy
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
+5 -5
View File
@@ -52,7 +52,7 @@ Lo principal que necesitas para ejecutar una aplicación **FastAPI** (o cualquie
Hay varias alternativas, incluyendo:
* [Uvicorn](https://www.uvicorn.dev/): un servidor ASGI de alto rendimiento.
* [Uvicorn](https://uvicorn.dev): un servidor ASGI de alto rendimiento.
* [Hypercorn](https://hypercorn.readthedocs.io/): un servidor ASGI compatible con HTTP/2 y Trio entre otras funcionalidades.
* [Daphne](https://github.com/django/daphne): el servidor ASGI construido para Django Channels.
* [Granian](https://github.com/emmett-framework/granian): Un servidor HTTP Rust para aplicaciones en Python.
@@ -73,14 +73,14 @@ Cuando instalas FastAPI, viene con un servidor de producción, Uvicorn, y puedes
Pero también puedes instalar un servidor ASGI manualmente.
Asegúrate de crear un [entorno virtual](../virtual-environments.md), actívalo, y luego puedes instalar la aplicación del servidor.
Añade la aplicación de servidor a tu proyecto.
Por ejemplo, para instalar Uvicorn:
<div class="termy">
```console
$ pip install "uvicorn[standard]"
$ uv add "uvicorn[standard]"
---> 100%
```
@@ -95,7 +95,7 @@ Al añadir `standard`, Uvicorn instalará y usará algunas dependencias adiciona
Eso incluye `uvloop`, el reemplazo directo de alto rendimiento para `asyncio`, que proporciona un gran impulso de rendimiento en concurrencia.
Cuando instalas FastAPI con algo como `pip install "fastapi[standard]"` ya obtienes `uvicorn[standard]` también.
Cuando añades FastAPI con algo como `uv add "fastapi[standard]"` ya obtienes `uvicorn[standard]` también.
///
@@ -106,7 +106,7 @@ Si instalaste un servidor ASGI manualmente, normalmente necesitarías pasar una
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 80
$ uv run uvicorn main:app --host 0.0.0.0 --port 80
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
+1 -1
View File
@@ -86,7 +86,7 @@ Si prefieres usar el comando `uvicorn` directamente:
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
$ uv run uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
<font color="#A6E22E">INFO</font>: Uvicorn running on <b>http://0.0.0.0:8080</b> (Press CTRL+C to quit)
<font color="#A6E22E">INFO</font>: Started parent process [<font color="#A1EFE4"><b>27365</b></font>]
<font color="#A6E22E">INFO</font>: Started server process [<font color="#A1EFE4">27368</font>]
+5 -293
View File
@@ -1,299 +1,11 @@
# Variables de Entorno { #environment-variables }
Una **variable de entorno** (también conocida como **env var**) es un valor que vive fuera de tu código de Python, en el sistema operativo, y puede ser leído por tu aplicación y otros programas.
/// tip | Consejo
Las aplicaciones FastAPI comúnmente usan variables de entorno para configuraciones como URLs de bases de datos, credenciales de email y claves secretas.
Si ya sabes qué son las "variables de entorno" y cómo usarlas, siéntete libre de saltarte esto.
Aprenderás cómo usarlas para la configuración de aplicaciones en [Ajustes y Variables de Entorno](advanced/settings.md).
///
## Aprende Más { #learn-more }
Una variable de entorno (también conocida como "**env var**") es una variable que vive **fuera** del código de Python, en el **sistema operativo**, y podría ser leída por tu código de Python (o por otros programas también).
Las variables de entorno pueden ser útiles para manejar **configuraciones** de aplicaciones, como parte de la **instalación** de Python, etc.
## Crear y Usar Variables de Entorno { #create-and-use-env-vars }
Puedes **crear** y usar variables de entorno en la **shell (terminal)**, sin necesidad de Python:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
// Podrías crear una env var MY_NAME con
$ export MY_NAME="Wade Wilson"
// Luego podrías usarla con otros programas, como
$ echo "Hello $MY_NAME"
Hello Wade Wilson
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
// Crea una env var MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
// Úsala con otros programas, como
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
```
</div>
////
## Leer Variables de Entorno en Python { #read-env-vars-in-python }
También podrías crear variables de entorno **fuera** de Python, en la terminal (o con cualquier otro método), y luego **leerlas en Python**.
Por ejemplo, podrías tener un archivo `main.py` con:
```Python hl_lines="3"
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
/// tip | Consejo
El segundo argumento de [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) es el valor por defecto a retornar.
Si no se proporciona, es `None` por defecto; aquí proporcionamos `"World"` como el valor por defecto para usar.
///
Luego podrías llamar a ese programa Python:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
// Aquí todavía no configuramos la env var
$ python main.py
// Como no configuramos la env var, obtenemos el valor por defecto
Hello World from Python
// Pero si creamos una variable de entorno primero
$ export MY_NAME="Wade Wilson"
// Y luego llamamos al programa nuevamente
$ python main.py
// Ahora puede leer la variable de entorno
Hello Wade Wilson from Python
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
// Aquí todavía no configuramos la env var
$ python main.py
// Como no configuramos la env var, obtenemos el valor por defecto
Hello World from Python
// Pero si creamos una variable de entorno primero
$ $Env:MY_NAME = "Wade Wilson"
// Y luego llamamos al programa nuevamente
$ python main.py
// Ahora puede leer la variable de entorno
Hello Wade Wilson from Python
```
</div>
////
Dado que las variables de entorno pueden configurarse fuera del código, pero pueden ser leídas por el código, y no tienen que ser almacenadas (committed en `git`) con el resto de los archivos, es común usarlas para configuraciones o **ajustes**.
También puedes crear una variable de entorno solo para una **invocación específica de un programa**, que está disponible solo para ese programa, y solo durante su duración.
Para hacer eso, créala justo antes del programa en sí, en la misma línea:
<div class="termy">
```console
// Crea una env var MY_NAME en línea para esta llamada del programa
$ MY_NAME="Wade Wilson" python main.py
// Ahora puede leer la variable de entorno
Hello Wade Wilson from Python
// La env var ya no existe después
$ python main.py
Hello World from Python
```
</div>
/// tip | Consejo
Puedes leer más al respecto en [The Twelve-Factor App: Config](https://12factor.net/config).
///
## Tipos y Validación { #types-and-validation }
Estas variables de entorno solo pueden manejar **strings de texto**, ya que son externas a Python y deben ser compatibles con otros programas y el resto del sistema (e incluso con diferentes sistemas operativos, como Linux, Windows, macOS).
Esto significa que **cualquier valor** leído en Python desde una variable de entorno **será un `str`**, y cualquier conversión a un tipo diferente o cualquier validación tiene que hacerse en el código.
Aprenderás más sobre cómo usar variables de entorno para manejar **configuraciones de aplicación** en la [Guía del Usuario Avanzado - Ajustes y Variables de Entorno](./advanced/settings.md).
## Variable de Entorno `PATH` { #path-environment-variable }
Hay una variable de entorno **especial** llamada **`PATH`** que es utilizada por los sistemas operativos (Linux, macOS, Windows) para encontrar programas a ejecutar.
El valor de la variable `PATH` es un string largo que consiste en directorios separados por dos puntos `:` en Linux y macOS, y por punto y coma `;` en Windows.
Por ejemplo, la variable de entorno `PATH` podría verse así:
//// tab | Linux, macOS
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
Esto significa que el sistema debería buscar programas en los directorios:
* `/usr/local/bin`
* `/usr/bin`
* `/bin`
* `/usr/sbin`
* `/sbin`
////
//// tab | Windows
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
```
Esto significa que el sistema debería buscar programas en los directorios:
* `C:\Program Files\Python312\Scripts`
* `C:\Program Files\Python312`
* `C:\Windows\System32`
////
Cuando escribes un **comando** en la terminal, el sistema operativo **busca** el programa en **cada uno de esos directorios** listados en la variable de entorno `PATH`.
Por ejemplo, cuando escribes `python` en la terminal, el sistema operativo busca un programa llamado `python` en el **primer directorio** de esa lista.
Si lo encuentra, entonces lo **utilizará**. De lo contrario, continúa buscando en los **otros directorios**.
### Instalando Python y Actualizando el `PATH` { #installing-python-and-updating-the-path }
Cuando instalas Python, se te podría preguntar si deseas actualizar la variable de entorno `PATH`.
//// tab | Linux, macOS
Digamos que instalas Python y termina en un directorio `/opt/custompython/bin`.
Si dices que sí para actualizar la variable de entorno `PATH`, entonces el instalador añadirá `/opt/custompython/bin` a la variable de entorno `PATH`.
Podría verse así:
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
```
De esta manera, cuando escribes `python` en la terminal, el sistema encontrará el programa Python en `/opt/custompython/bin` (el último directorio) y usará ese.
////
//// tab | Windows
Digamos que instalas Python y termina en un directorio `C:\opt\custompython\bin`.
Si dices que sí para actualizar la variable de entorno `PATH`, entonces el instalador añadirá `C:\opt\custompython\bin` a la variable de entorno `PATH`.
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
```
De esta manera, cuando escribes `python` en la terminal, el sistema encontrará el programa Python en `C:\opt\custompython\bin` (el último directorio) y usará ese.
////
Entonces, si escribes:
<div class="termy">
```console
$ python
```
</div>
//// tab | Linux, macOS
El sistema **encontrará** el programa `python` en `/opt/custompython/bin` y lo ejecutará.
Esto sería más o menos equivalente a escribir:
<div class="termy">
```console
$ /opt/custompython/bin/python
```
</div>
////
//// tab | Windows
El sistema **encontrará** el programa `python` en `C:\opt\custompython\bin\python` y lo ejecutará.
Esto sería más o menos equivalente a escribir:
<div class="termy">
```console
$ C:\opt\custompython\bin\python
```
</div>
////
Esta información será útil al aprender sobre [Entornos Virtuales](virtual-environments.md).
## Conclusión { #conclusion }
Con esto deberías tener una comprensión básica de qué son las **variables de entorno** y cómo usarlas en Python.
También puedes leer más sobre ellas en la [Wikipedia para Variable de Entorno](https://en.wikipedia.org/wiki/Environment_variable).
En muchos casos no es muy obvio cómo las variables de entorno serían útiles y aplicables de inmediato. Pero siguen apareciendo en muchos escenarios diferentes cuando estás desarrollando, así que es bueno conocerlas.
Por ejemplo, necesitarás esta información en la siguiente sección, sobre [Entornos Virtuales](virtual-environments.md).
Lee la [guía de Variables de Entorno](https://tiangolo.com/guides/environment-variables/) para una explicación detallada y multiplataforma, incluyendo cómo crear y leer variables de entorno y cómo funciona la variable de entorno `PATH`.
+8 -4
View File
@@ -2,7 +2,7 @@
**FastAPI <abbr title="command line interface - interfaz de línea de comandos">CLI</abbr>** es un programa de línea de comandos que puedes usar para servir tu aplicación FastAPI, gestionar tu proyecto FastAPI, y más.
Cuando instalas FastAPI (por ejemplo, con `pip install "fastapi[standard]"`), viene con un programa de línea de comandos que puedes ejecutar en la terminal.
Cuando añades FastAPI a tu proyecto (por ejemplo, con `uv add "fastapi[standard]"`), viene con un programa de línea de comandos que puedes ejecutar en la terminal.
Para ejecutar tu aplicación FastAPI en modo de desarrollo, puedes usar el comando `fastapi dev`:
@@ -52,7 +52,7 @@ Para producción usarías `fastapi run` en lugar de `fastapi dev`. 🚀
///
Internamente, **FastAPI CLI** usa [Uvicorn](https://www.uvicorn.dev), un servidor ASGI de alto rendimiento y listo para producción. 😎
Internamente, **FastAPI CLI** usa [Uvicorn](https://uvicorn.dev), un servidor ASGI de alto rendimiento y listo para producción. 😎
El CLI `fastapi` intentará detectar automáticamente la app de FastAPI que debe ejecutar, asumiendo que es un objeto llamado `app` en un archivo `main.py` (o un par de variantes más).
@@ -100,13 +100,13 @@ from backend.main import app
También puedes pasar el path del archivo al comando `fastapi dev`, y adivinará el objeto app de FastAPI a usar:
```console
$ fastapi dev main.py
$ uv run fastapi dev main.py
```
O también puedes pasar la opción `--entrypoint` al comando `fastapi dev`:
```console
$ fastapi dev --entrypoint main:app
$ uv run fastapi dev --entrypoint main:app
```
Pero tendrías que recordar pasar el path\entrypoint correcto cada vez que llames al comando `fastapi`.
@@ -119,6 +119,10 @@ 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`).
Antes de importar tu app, `fastapi dev` establece la variable de entorno `FASTAPI_ENV` en `development`. Si `FASTAPI_ENV` ya está establecida, se conserva su valor existente. Esto permite que el código de startup de la app elija un comportamiento adecuado para desarrollo mientras te permite proporcionar un entorno específico de la app como `staging`.
Los valores convencionales de `FASTAPI_ENV` son `development` y `production`. Actualmente `fastapi run` deja `FASTAPI_ENV` sin cambios, así que establécela explícitamente si tu app necesita detectar el modo de producción.
## `fastapi run` { #fastapi-run }
Ejecutar `fastapi run` inicia FastAPI en modo de producción.
+4 -4
View File
@@ -19,7 +19,7 @@ Interfaces web de documentación y exploración de APIs interactivas. Como el fr
![Interacción Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Documentación alternativa de API con [**ReDoc**](https://github.com/Rebilly/ReDoc).
* Documentación alternativa de API con [**ReDoc**](https://github.com/Redocly/redoc).
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
@@ -153,13 +153,13 @@ Cualquier integración está diseñada para ser tan simple de usar (con dependen
### Probado { #tested }
* 100% de <dfn title="La cantidad de código que se prueba automáticamente">cobertura de tests</dfn>.
* <dfn title="La cantidad de código que se prueba automáticamente">cobertura de tests del 100%</dfn>.
* 100% <dfn title="Anotaciones de tipos en Python, con esto tu editor y herramientas externas pueden ofrecerte mejor soporte">anotada con tipos</dfn> code base.
* Usado en aplicaciones en producción.
## Funcionalidades de Starlette { #starlette-features }
**FastAPI** es totalmente compatible con (y está basado en) [**Starlette**](https://www.starlette.dev/). Así que, cualquier código adicional de Starlette que tengas, también funcionará.
**FastAPI** es totalmente compatible con (y está basado en) [**Starlette**](https://starlette.dev/). Así que, cualquier código adicional de Starlette que tengas, también funcionará.
`FastAPI` es en realidad una subclase de `Starlette`. Así que, si ya conoces o usas Starlette, la mayoría de las funcionalidades funcionarán de la misma manera.
@@ -177,7 +177,7 @@ Con **FastAPI** obtienes todas las funcionalidades de **Starlette** (ya que Fast
## Funcionalidades de Pydantic { #pydantic-features }
**FastAPI** es totalmente compatible con (y está basado en) [**Pydantic**](https://docs.pydantic.dev/). Por lo tanto, cualquier código adicional de Pydantic que tengas, también funcionará.
**FastAPI** es totalmente compatible con (y está basado en) [**Pydantic**](https://pydantic.dev/docs/). 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 - Mapeador Objeto-Relacional">ORM</abbr>s y <abbr title="Object-Document Mapper - Mapeador Objeto-Documento">ODM</abbr>s para bases de datos.
+7 -15
View File
@@ -45,20 +45,6 @@ Puedes seguir [a mí (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com),
* [@tiangolo.com en **Bluesky**](https://bsky.app/profile/tiangolo.com)
* [@tiangolo en **LinkedIn**](https://www.linkedin.com/in/tiangolo/).
## Ayuda a otros con preguntas en GitHub { #help-others-with-questions-in-github }
Puedes intentar ayudar a otros con sus preguntas en [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered).
En muchos casos, puede que ya conozcas la respuesta a esas preguntas. 🤓
Si estás ayudando mucho a la gente con sus preguntas, te convertirás en un [FastAPI Expert](fastapi-people.md#fastapi-experts) oficial. 🎉
Solo recuerda, el punto más importante es: intenta ser amable. 🤗
### Cómo ayudar { #how-to-help }
Sigue la [guía sobre cómo ayudar](https://tiangolo.com/open-source/help/#help-others-with-questions-in-github) aquí.
## Haz preguntas { #ask-questions }
Puedes [crear una nueva pregunta](https://github.com/fastapi/fastapi/discussions/new?category=questions) en el repositorio de GitHub, por ejemplo para:
@@ -68,7 +54,7 @@ Puedes [crear una nueva pregunta](https://github.com/fastapi/fastapi/discussions
## Únete al chat { #join-the-chat }
Únete al 👥 [servidor de chat de Discord](https://discord.gg/VQjSZaeJmf) 👥 y charla con otros en la comunidad de FastAPI.
Únete al 👥 [servidor de chat de Discord](https://discord.com/invite/VQjSZaeJmf) 👥 y charla con otros en la comunidad de FastAPI.
/// tip | Consejo
@@ -85,3 +71,9 @@ Ten en cuenta que dado que los chats permiten una "conversación más libre", es
En GitHub, la plantilla te guiará para escribir la pregunta correcta para que puedas obtener más fácilmente una buena respuesta, o incluso resolver el problema tú mismo antes de preguntar.
Las conversaciones en los sistemas de chat tampoco son tan fáciles de buscar como en GitHub; se pierden.
## Prueba FastAPI Cloud { #try-fastapi-cloud }
La financiación principal de FastAPI y amigos proviene de [**FastAPI Cloud**](https://fastapicloud.com), una plataforma para desplegar aplicaciones FastAPI de una forma simple y rápida, con un solo comando, `fastapi deploy`.
FastAPI Cloud está construido por el mismo equipo detrás de FastAPI. Puedes probarlo y considerarlo para tus proyectos.
+2 -2
View File
@@ -54,11 +54,11 @@ Todo de una manera que proporcionara la mejor experiencia de desarrollo para tod
## Requisitos { #requirements }
Después de probar varias alternativas, decidí que iba a usar [**Pydantic**](https://docs.pydantic.dev/) por sus ventajas.
Después de probar varias alternativas, decidí que iba a usar [**Pydantic**](https://pydantic.dev/docs/) por sus ventajas.
Luego contribuí a este, para hacerlo totalmente compatible con JSON Schema, para soportar diferentes maneras de definir declaraciones de restricciones, y para mejorar el soporte de los editores (chequeo de tipos, autocompletado) basado en las pruebas en varios editores.
Durante el desarrollo, también contribuí a [**Starlette**](https://www.starlette.dev/), el otro requisito clave.
Durante el desarrollo, también contribuí a [**Starlette**](https://starlette.dev/), el otro requisito clave.
## Desarrollo { #development }
@@ -66,7 +66,7 @@ El `dict` `scope` y la función `receive` son ambos parte de la especificación
Y esas dos cosas, `scope` y `receive`, son lo que se necesita para crear una nueva instance de `Request`.
Para aprender más sobre el `Request`, revisa [la documentación de Starlette sobre Requests](https://www.starlette.dev/requests/).
Para aprender más sobre el `Request`, revisa [la documentación de Starlette sobre Requests](https://starlette.dev/requests/).
///
+1 -1
View File
@@ -45,7 +45,7 @@ El parámetro `summary` está disponible en OpenAPI 3.1.0 y versiones superiores
Usando la información anterior, puedes usar la misma función de utilidad para generar el esquema de OpenAPI y sobrescribir cada parte que necesites.
Por ejemplo, vamos a añadir [la extensión OpenAPI de ReDoc para incluir un logo personalizado](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo).
Por ejemplo, vamos a añadir [la extensión OpenAPI de ReDoc para incluir un logo personalizado](https://github.com/Redocly/redoc/blob/main/docs/redoc-vendor-extensions.md#x-logo).
### **FastAPI** normal { #normal-fastapi }
+1 -1
View File
@@ -21,7 +21,7 @@ Aquí algunos de los paquetes de **GraphQL** que tienen soporte **ASGI**. Podrí
* [Strawberry](https://strawberry.rocks/) 🍓
* Con [documentación para FastAPI](https://strawberry.rocks/docs/integrations/fastapi)
* [Ariadne](https://ariadnegraphql.org/)
* Con [documentación para FastAPI](https://ariadnegraphql.org/docs/fastapi-integration)
* Con [documentación para FastAPI](https://ariadnegraphql.org/server/Integrations/fastapi-integration)
* [Tartiflette](https://tartiflette.io/)
* Con [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) para proporcionar integración con ASGI
* [Graphene](https://graphene-python.org/)
@@ -24,7 +24,7 @@ Si tienes una app de FastAPI antigua con Pydantic v1, aquí te muestro cómo mig
## Guía oficial { #official-guide }
Pydantic tiene una [Guía de migración](https://docs.pydantic.dev/latest/migration/) oficial de v1 a v2.
Pydantic tiene una [Guía de migración](https://pydantic.dev/docs/validation/latest/get-started/migration/) oficial de v1 a v2.
También incluye qué cambió, cómo las validaciones ahora son más correctas y estrictas, posibles consideraciones, etc.
+20 -24
View File
@@ -89,7 +89,7 @@ Las funcionalidades clave son:
<!-- only-mkdocs -->
<div class="fastapi-opinions" data-fastapi-opinions>
<div class="fastapi-opinions__tabs" role="tablist" aria-label="Companies using FastAPI">
<div class="fastapi-opinions__tabs" role="tablist" aria-label="Empresas que usan FastAPI">
<button class="fastapi-opinions__tab" role="tab" type="button" id="fo-tab-microsoft" aria-controls="fo-panel-microsoft" aria-selected="true" tabindex="0">
<span class="fastapi-opinions__mark"><img src="/img/logos/microsoft.svg" alt="Microsoft" loading="lazy"></span>
</button>
@@ -110,7 +110,7 @@ Las funcionalidades clave son:
</div>
<div class="fastapi-opinions__panel" id="fo-panel-uber" role="tabpanel" aria-labelledby="fo-tab-uber" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"Adoptamos el paquete <strong>FastAPI</strong> para crear un servidor <strong>REST</strong> que pueda ser consultado para obtener <strong>predicciones</strong>." <em>[para Ludwig]</em></blockquote>
<div class="fastapi-opinions__attr">— Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/">(ref)</a></div>
<div class="fastapi-opinions__attr">— Piero Molino, Yaroslav Dudin, Sai Sumanth Miryala, <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/">(ref)</a></div>
</div>
<div class="fastapi-opinions__panel" id="fo-panel-netflix" role="tabpanel" aria-labelledby="fo-tab-netflix" tabindex="0" hidden>
<blockquote class="fastapi-opinions__quote">"<strong>Netflix</strong> se complace en anunciar el lanzamiento open source de nuestro framework de orquestación de <strong>gestión de crisis</strong>: <strong>Dispatch</strong>!" <em>[construido con FastAPI]</em></blockquote>
@@ -133,7 +133,7 @@ Las funcionalidades clave son:
"_Adoptamos el paquete **FastAPI** para crear un servidor **REST** que pueda ser consultado para obtener **predicciones**. [para Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://www.uber.com/us/en/blog/ludwig-v0-2/"><small>(ref)</small></a></div>
---
@@ -151,12 +151,6 @@ Las funcionalidades clave son:
</div>
## FastAPI Conf { #fastapi-conf }
[**FastAPI Conf '26**](https://fastapiconf.com) se llevará a cabo el **28 de octubre de 2026** en **Ámsterdam, NL**. Todo sobre FastAPI, directo de la fuente. 🎤
<a class="fastapi-feature-banner" href="https://fastapiconf.com"><img src="https://fastapi.tiangolo.com/img/fastapi-conf.jpeg" alt="FastAPI Conf '26 - October 28, 2026 - Amsterdam, NL"></a>
## Mini documental de FastAPI { #fastapi-mini-documentary }
Hay un [mini documental de FastAPI](https://www.youtube.com/watch?v=mpR8ngthqiE) lanzado a finales de 2025, puedes verlo online:
@@ -175,17 +169,17 @@ Si estás construyendo una aplicación de <abbr title="Command Line Interface -
FastAPI se apoya en hombros de gigantes:
* [Starlette](https://www.starlette.dev/) para las partes web.
* [Pydantic](https://docs.pydantic.dev/) para las partes de datos.
* [Starlette](https://starlette.dev/) para las partes web.
* [Pydantic](https://pydantic.dev/docs/) para las partes de datos.
## Instalación { #installation }
Crea y activa un [entorno virtual](https://fastapi.tiangolo.com/es/virtual-environments/) y luego instala FastAPI:
Primero, [instala `uv`](https://docs.astral.sh/uv/getting-started/installation/), y luego añade FastAPI a tu proyecto:
<div class="termy">
```console
$ pip install "fastapi[standard]"
$ uv add "fastapi[standard]"
---> 100%
```
@@ -194,6 +188,8 @@ $ pip install "fastapi[standard]"
**Nota**: Asegúrate de poner `"fastapi[standard]"` entre comillas para asegurar que funcione en todas las terminales.
Si prefieres usar `pip`, instala `fastapi[standard]` dentro de un entorno virtual. Mira la [guía de instalación](tutorial/#install-fastapi) para los pasos alternativos.
## Ejemplo { #example }
### Créalo { #create-it }
@@ -250,7 +246,7 @@ Corre el servidor con:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
╭────────── FastAPI CLI - Development mode ───────────╮
│ │
@@ -277,7 +273,7 @@ INFO: Application startup complete.
<details markdown="1">
<summary>Acerca del comando <code>fastapi dev</code>...</summary>
El comando `fastapi dev` lee tu archivo `main.py` automáticamente, detecta la app **FastAPI** en él y arranca un servidor usando [Uvicorn](https://www.uvicorn.dev).
El comando `fastapi dev` lee tu archivo `main.py` automáticamente, detecta la app **FastAPI** en él y arranca un servidor usando [Uvicorn](https://uvicorn.dev).
Por defecto, `fastapi dev` comenzará con auto-recarga habilitada para el desarrollo local.
@@ -314,7 +310,7 @@ Verás la documentación interactiva automática de la API (proporcionada por [S
Y ahora, ve a [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Rebilly/ReDoc)):
Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Redocly/redoc)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
@@ -497,7 +493,7 @@ Opcionalmente puedes desplegar tu app de FastAPI en [FastAPI Cloud](https://fast
<div class="termy">
```console
$ fastapi deploy
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
@@ -540,7 +536,7 @@ FastAPI depende de Pydantic y Starlette.
### Dependencias `standard` { #standard-dependencies }
Cuando instalas FastAPI con `pip install "fastapi[standard]"` viene con el grupo `standard` de dependencias opcionales:
Cuando instalas FastAPI con `uv add "fastapi[standard]"` viene con el grupo `standard` de dependencias opcionales:
Usadas por Pydantic:
@@ -554,17 +550,17 @@ Usadas por Starlette:
Usadas por FastAPI:
* [`uvicorn`](https://www.uvicorn.dev) - para el servidor que carga y sirve tu aplicación. Esto incluye `uvicorn[standard]`, que incluye algunas dependencias (por ejemplo, `uvloop`) necesarias para servir con alto rendimiento.
* [`uvicorn`](https://uvicorn.dev) - para el servidor que carga y sirve tu aplicación. Esto incluye `uvicorn[standard]`, que incluye algunas dependencias (por ejemplo, `uvloop`) necesarias para servir con alto rendimiento.
* `fastapi-cli[standard]` - para proporcionar el comando `fastapi`.
* Esto incluye `fastapi-cloud-cli`, que te permite desplegar tu aplicación de FastAPI en [FastAPI Cloud](https://fastapicloud.com).
### Sin Dependencias `standard` { #without-standard-dependencies }
Si no deseas incluir las dependencias opcionales `standard`, puedes instalar con `pip install fastapi` en lugar de `pip install "fastapi[standard]"`.
Si no deseas incluir las dependencias opcionales `standard`, puedes instalar con `uv add fastapi` en lugar de `uv add "fastapi[standard]"`.
### Sin `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
Si quieres instalar FastAPI con las dependencias standard pero sin `fastapi-cloud-cli`, puedes instalar con `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
Si quieres instalar FastAPI con las dependencias standard pero sin `fastapi-cloud-cli`, puedes instalar con `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
### Dependencias Opcionales Adicionales { #additional-optional-dependencies }
@@ -572,13 +568,13 @@ Existen algunas dependencias adicionales que podrías querer instalar.
Dependencias opcionales adicionales de Pydantic:
* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) - para la gestión de configuraciones.
* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) - para tipos extra para ser usados con Pydantic.
* [`pydantic-settings`](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/) - para la gestión de configuraciones.
* [`pydantic-extra-types`](https://github.com/pydantic/pydantic-extra-types) - para tipos extra para ser usados con Pydantic.
Dependencias opcionales adicionales de FastAPI:
* [`orjson`](https://github.com/ijl/orjson) - Requerido si deseas usar `ORJSONResponse`.
* [`ujson`](https://github.com/esnme/ultrajson) - Requerido si deseas usar `UJSONResponse`.
* [`ujson`](https://github.com/ultrajson/ultrajson) - Requerido si deseas usar `UJSONResponse`.
## Licencia { #license }
+2 -2
View File
@@ -4,13 +4,13 @@ Las plantillas, aunque normalmente vienen con una configuración específica, es
Puedes usar esta plantilla para comenzar, ya que incluye gran parte de la configuración inicial, seguridad, base de datos y algunos endpoints de API ya hechos para ti.
Repositorio de GitHub: [Plantilla Full Stack FastAPI](https://github.com/tiangolo/full-stack-fastapi-template)
Repositorio de GitHub: [Plantilla Full Stack FastAPI](https://github.com/fastapi/full-stack-fastapi-template)
## Plantilla Full Stack FastAPI - Stack de tecnología y funcionalidades { #full-stack-fastapi-template-technology-stack-and-features }
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/es) para la API del backend en Python.
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) para las interacciones con bases de datos SQL en Python (ORM).
- 🔍 [Pydantic](https://docs.pydantic.dev), utilizado por FastAPI, para la validación de datos y gestión de configuraciones.
- 🔍 [Pydantic](https://pydantic.dev/docs/), 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, y otras partes de una stack moderna de frontend.
+2 -2
View File
@@ -269,7 +269,7 @@ No significa "`one_person` es la **clase** llamada `Person`".
## Modelos Pydantic { #pydantic-models }
[Pydantic](https://docs.pydantic.dev/) es un paquete de Python para realizar la validación de datos.
[Pydantic](https://pydantic.dev/docs/) es un paquete de Python para realizar la validación de datos.
Declaras la "forma" de los datos como clases con atributos.
@@ -285,7 +285,7 @@ Un ejemplo de la documentación oficial de Pydantic:
/// note | Nota
Para saber más sobre [Pydantic, revisa su documentación](https://docs.pydantic.dev/).
Para saber más sobre [Pydantic, revisa su documentación](https://pydantic.dev/docs/).
///
+7 -5
View File
@@ -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 { #create-a-task-function }
## Crea una función de tarea { #create-a-task-function }
Crea una función para que se ejecute como la tarea en segundo plano.
@@ -33,9 +33,9 @@ Y como la operación de escritura no usa `async` y `await`, definimos la funció
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## Agregar la tarea en segundo plano { #add-the-background-task }
## Agrega 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()`:
Dentro de tu *path operation function*, pasa tu función de tarea al objeto de *tareas en segundo plano* con el método `.add_task()`:
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
@@ -51,8 +51,10 @@ Usar `BackgroundTasks` también funciona con el sistema de inyección de depende
**FastAPI** sabe qué hacer en cada caso y cómo reutilizar el mismo objeto, de modo que todas las tareas en segundo plano se combinan y ejecutan en segundo plano después:
{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
En este ejemplo, los mensajes se escribirán en el archivo `log.txt` *después* de que se envíe el response.
Si hay un query en el request, se escribirá en el log en una tarea en segundo plano.
@@ -61,7 +63,7 @@ Y luego otra tarea en segundo plano generada en la *path operation function* esc
## Detalles Técnicos { #technical-details }
La clase `BackgroundTasks` proviene directamente de [`starlette.background`](https://www.starlette.dev/background/).
La clase `BackgroundTasks` proviene directamente de [`starlette.background`](https://starlette.dev/background/).
Se importa/incluye directamente en FastAPI para que puedas importarla desde `fastapi` y evitar importar accidentalmente la alternativa `BackgroundTask` (sin la `s` al final) de `starlette.background`.
@@ -69,7 +71,7 @@ Al usar solo `BackgroundTasks` (y no `BackgroundTask`), es posible usarla como u
Todavía es posible usar `BackgroundTask` solo en FastAPI, pero debes crear el objeto en tu código y devolver una `Response` de Starlette incluyéndolo.
Puedes ver más detalles en [la documentación oficial de Starlette sobre Background Tasks](https://www.starlette.dev/background/).
Puedes ver más detalles en [la documentación oficial de Starlette sobre Background Tasks](https://starlette.dev/background/).
## Advertencia { #caveat }
+15 -15
View File
@@ -81,7 +81,7 @@ Pero todavía es parte de la misma aplicación/web API de **FastAPI** (es parte
Puedes crear las *path operations* para ese módulo usando `APIRouter`.
### Importar `APIRouter` { #import-apirouter }
### Importa `APIRouter` { #import-apirouter }
Lo importas y creas una "instance" de la misma manera que lo harías con la clase `FastAPI`:
@@ -200,7 +200,7 @@ Los parámetros `prefix`, `tags`, `responses`, y `dependencies` son (como en muc
///
### Importar las dependencias { #import-the-dependencies }
### Importa las dependencias { #import-the-dependencies }
Este código vive en el módulo `app.routers.items`, el archivo `app/routers/items.py`.
@@ -273,7 +273,7 @@ Eso se referiría a algún paquete arriba de `app/`, con su propio archivo `__in
Pero ahora sabes cómo funciona, para que puedas usar imports relativos en tus propias apps sin importar cuán complejas sean. 🤓
### Agregar algunos `tags`, `responses`, y `dependencies` personalizados { #add-some-custom-tags-responses-and-dependencies }
### Agrega algunos `tags`, `responses`, y `dependencies` personalizados { #add-some-custom-tags-responses-and-dependencies }
No estamos agregando el prefijo `/items` ni los `tags=["items"]` a cada *path operation* porque los hemos añadido al `APIRouter`.
@@ -299,7 +299,7 @@ Este será el archivo principal en tu aplicación que conecta todo.
Y como la mayor parte de tu lógica ahora vivirá en su propio módulo específico, el archivo principal será bastante simple.
### Importar `FastAPI` { #import-fastapi }
### Importa `FastAPI` { #import-fastapi }
Importas y creas una clase `FastAPI` como normalmente.
@@ -307,7 +307,7 @@ Y podemos incluso declarar [dependencias globales](dependencies/global-dependenc
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
### Importar el `APIRouter` { #import-the-apirouter }
### Importa el `APIRouter` { #import-the-apirouter }
Ahora importamos los otros submódulos que tienen `APIRouter`s:
@@ -315,7 +315,7 @@ Ahora importamos los otros submódulos que tienen `APIRouter`s:
Como los archivos `app/routers/users.py` y `app/routers/items.py` son submódulos que son parte del mismo paquete de Python `app`, podemos usar un solo punto `.` para importarlos usando "imports relativos".
### Cómo funciona la importación { #how-the-importing-works }
### Cómo funciona el import { #how-the-importing-works }
La sección:
@@ -357,7 +357,7 @@ Para aprender más sobre Paquetes y Módulos de Python, lee [la documentación o
///
### Evitar colisiones de nombres { #avoid-name-collisions }
### Evita colisiones de nombres { #avoid-name-collisions }
Estamos importando el submódulo `items` directamente, en lugar de importar solo su variable `router`.
@@ -376,7 +376,7 @@ Así que, para poder usar ambos en el mismo archivo, importamos los submódulos
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
### Incluir los `APIRouter`s para `users` y `items` { #include-the-apirouters-for-users-and-items }
### Incluye los `APIRouter`s para `users` y `items` { #include-the-apirouters-for-users-and-items }
Ahora, incluyamos los `router`s de los submódulos `users` y `items`:
@@ -412,7 +412,7 @@ Así que no afectará el rendimiento. ⚡
///
### Incluir un `APIRouter` con un `prefix`, `tags`, `responses`, y `dependencies` personalizados { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies }
### Incluye un `APIRouter` con un `prefix`, `tags`, `responses`, y `dependencies` personalizados { #include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies }
Ahora, imaginemos que tu organización te dio el archivo `app/internal/admin.py`.
@@ -441,7 +441,7 @@ Pero eso solo afectará a ese `APIRouter` en nuestra app, no en ningún otro có
Así, por ejemplo, otros proyectos podrían usar el mismo `APIRouter` con un método de autenticación diferente.
### Incluir una *path operation* { #include-a-path-operation }
### Incluye una *path operation* { #include-a-path-operation }
También podemos agregar *path operations* directamente a la app de `FastAPI`.
@@ -465,7 +465,7 @@ FastAPI mantiene los routers y path operations originales activos, y combina los
///
## Configurar el `entrypoint` en `pyproject.toml` { #configure-the-entrypoint-in-pyproject-toml }
## Configura el `entrypoint` en `pyproject.toml` { #configure-the-entrypoint-in-pyproject-toml }
Como tu objeto `app` de FastAPI vive en `app/main.py`, puedes configurar el `entrypoint` en tu archivo `pyproject.toml` así:
@@ -487,7 +487,7 @@ De esa manera el comando `fastapi` sabrá dónde encontrar tu app.
También podrías pasar la ruta al comando, como:
```console
$ fastapi dev app/main.py
$ uv run fastapi dev app/main.py
```
Pero tendrías que recordar pasar la ruta correcta cada vez que llames al comando `fastapi`.
@@ -503,7 +503,7 @@ Ahora, ejecuta tu app:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -516,7 +516,7 @@ Verás la documentación automática de la API, incluyendo los paths de todos lo
<img src="/img/tutorial/bigger-applications/image01.png">
## Incluir el mismo router múltiples veces con diferentes `prefix` { #include-the-same-router-multiple-times-with-different-prefix }
## Incluye el mismo router múltiples veces con diferentes `prefix` { #include-the-same-router-multiple-times-with-different-prefix }
También puedes usar `.include_router()` múltiples veces con el *mismo* router usando diferentes prefijos.
@@ -524,7 +524,7 @@ Esto podría ser útil, por ejemplo, para exponer la misma API bajo diferentes p
Este es un uso avanzado que quizás no necesites realmente, pero está allí en caso de que lo necesites.
## Incluir un `APIRouter` en otro { #include-an-apirouter-in-another }
## Incluye un `APIRouter` en otro { #include-an-apirouter-in-another }
De la misma manera que puedes incluir un `APIRouter` en una aplicación `FastAPI`, puedes incluir un `APIRouter` en otro `APIRouter` usando:
+1 -1
View File
@@ -96,7 +96,7 @@ Nuevamente, haciendo solo esa declaración, con **FastAPI** obtienes:
Además de tipos singulares normales como `str`, `int`, `float`, etc., puedes usar tipos singulares más complejos que heredan de `str`.
Para ver todas las opciones que tienes, Revisa [Resumen de tipos de Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Verás algunos ejemplos en el siguiente capítulo.
Para ver todas las opciones que tienes, Revisa [Resumen de tipos de Pydantic](https://pydantic.dev/docs/validation/latest/concepts/types/). Verás algunos ejemplos en el siguiente capítulo.
Por ejemplo, como en el modelo `Image` tenemos un campo `url`, podemos declararlo como una instance de `HttpUrl` de Pydantic en lugar de un `str`:
+1 -1
View File
@@ -7,7 +7,7 @@ Un **request** body es un dato enviado por el cliente a tu API. Un **response**
Tu API casi siempre tiene que enviar un **response** body. Pero los clientes no necesariamente necesitan enviar **request bodies** todo el tiempo, a veces solo solicitan un path, quizás con algunos parámetros de query, pero no envían un body.
Para declarar un **request** body, usas modelos de [Pydantic](https://docs.pydantic.dev/) con todo su poder y beneficios.
Para declarar un **request** body, usas modelos de [Pydantic](https://pydantic.dev/docs/) con todo su poder y beneficios.
/// note | Nota
+2 -2
View File
@@ -16,7 +16,7 @@ El objetivo principal de `__name__ == "__main__"` es tener algo de código que s
<div class="termy">
```console
$ python myapp.py
$ uv run python myapp.py
```
</div>
@@ -36,7 +36,7 @@ Si lo ejecutas con:
<div class="termy">
```console
$ python myapp.py
$ uv run python myapp.py
```
</div>
+2 -2
View File
@@ -37,7 +37,7 @@ Aquí hay algunos de los tipos de datos adicionales que puedes usar:
* `datetime.timedelta`:
* Un `datetime.timedelta` de Python.
* En requests y responses se representará como un `float` de segundos totales.
* Pydantic también permite representarlo como una "codificación de diferencia horaria ISO 8601", [consulta la documentación para más información](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
* Pydantic también permite representarlo como una "codificación de diferencia horaria ISO 8601", [consulta la documentación para más información](https://pydantic.dev/docs/validation/latest/concepts/serialization/#custom-serializers).
* `frozenset`:
* En requests y responses, tratado igual que un `set`:
* En requests, se leerá una list, eliminando duplicados y convirtiéndola en un `set`.
@@ -50,7 +50,7 @@ Aquí hay algunos de los tipos de datos adicionales que puedes usar:
* `Decimal`:
* `Decimal` estándar de Python.
* En requests y responses, manejado igual que un `float`.
* Puedes revisar todos los tipos de datos válidos de Pydantic aquí: [Tipos de datos de Pydantic](https://docs.pydantic.dev/latest/usage/types/types/).
* Puedes revisar todos los tipos de datos válidos de Pydantic aquí: [Tipos de datos de Pydantic](https://pydantic.dev/docs/validation/latest/concepts/types/).
## Ejemplo { #example }
+1 -1
View File
@@ -166,7 +166,7 @@ Para hacerlo, usa la anotación de tipos estándar de Python [`typing.Union`](ht
/// note | Nota
Al definir una [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions), incluye el tipo más específico primero, seguido por el tipo menos específico. En el ejemplo a continuación, el más específico `PlaneItem` viene antes de `CarItem` en `Union[PlaneItem, CarItem]`.
Al definir una [`Union`](https://pydantic.dev/docs/validation/latest/concepts/unions/), incluye el tipo más específico primero, seguido por el tipo menos específico. En el ejemplo a continuación, el más específico `PlaneItem` viene antes de `CarItem` en `Union[PlaneItem, CarItem]`.
///
+12 -6
View File
@@ -6,12 +6,18 @@ El archivo FastAPI más simple podría verse así:
Copia eso en un archivo `main.py`.
/// tip | Consejo
FastAPI tiene una [extensión oficial para VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (y Cursor), que proporciona muchas funcionalidades, incluyendo un explorador de path operations, búsqueda de path operations, navegación CodeLens en tests (saltar a la definición desde los tests), y despliegue y logs de FastAPI Cloud, todo desde tu editor.
///
Ejecuta el servidor en vivo:
<div class="termy">
```console
$ <font color="#4E9A06">fastapi</font> dev
$ <font color="#4E9A06">uv run fastapi</font> dev
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
@@ -78,7 +84,7 @@ Verás la documentación interactiva automática de la API (proporcionada por [S
Y ahora, ve a [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Rebilly/ReDoc)):
Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Redocly/redoc)):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
@@ -185,13 +191,13 @@ from backend.main import app
También puedes pasar el path del archivo al comando `fastapi dev`, y adivinará el objeto app de FastAPI que debe usar:
```console
$ fastapi dev main.py
$ uv run fastapi dev main.py
```
O, también puedes pasar la opción `--entrypoint` al comando `fastapi dev`:
```console
$ fastapi dev --entrypoint main:app
$ uv run fastapi dev --entrypoint main:app
```
Pero tendrías que recordar pasar el path\entrypoint correcto cada vez que llames al comando `fastapi`.
@@ -205,7 +211,7 @@ Opcionalmente puedes desplegar tu app de FastAPI en [FastAPI Cloud](https://fast
<div class="termy">
```console
$ fastapi deploy
$ uv run fastapi deploy
Deploying to FastAPI Cloud...
@@ -232,7 +238,7 @@ La CLI detectará automáticamente tu aplicación de FastAPI y la desplegará en
`FastAPI` es una clase que hereda directamente de `Starlette`.
Puedes usar toda la funcionalidad de [Starlette](https://www.starlette.dev/) con `FastAPI` también.
Puedes usar toda la funcionalidad de [Starlette](https://starlette.dev/) con `FastAPI` también.
///
+9 -3
View File
@@ -52,7 +52,7 @@ Para eso, usa `fallback="index.html"`:
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *}
**FastAPI** usa este fallback solo para requests `GET` y `HEAD` que parecen navegación del navegador. Los archivos faltantes como JavaScript, CSS e imágenes siguen devolviendo `404`.
**FastAPI** usa este fallback solo para requests `GET` y `HEAD` que aceptan HTML explícitamente con `Accept: text/html` o `Accept: application/xhtml+xml`, como normalmente hacen los requests de navegación del navegador. Los archivos faltantes como JavaScript, CSS e imágenes siguen devolviendo `404`.
Los requests con otros métodos, como `POST` o `PUT`, a paths que solo coinciden con el fallback del frontend también devuelven `404`. Las *path operations* normales de **FastAPI** siguen teniendo mayor prioridad que las rutas frontend.
@@ -106,9 +106,13 @@ Entonces los paths frontend faltantes devuelven el `404` normal.
## Revisa el directorio { #check-directory }
Por defecto, `app.frontend()` revisa que el directorio exista cuando se crea la app.
Por defecto, `app.frontend()` usa `check_dir="auto"`.
Esto ayuda a detectar errores de configuración temprano. Por ejemplo, si falta el directorio de salida del build del frontend, **FastAPI** lanzará un error al iniciar.
Cuando la variable de entorno `FASTAPI_ENV` se configura como `development`, **FastAPI** solo muestra una advertencia si falta el directorio de salida del build del frontend. El [comando `fastapi dev`](https://github.com/fastapi/fastapi-cli#fastapi-dev) configura esta variable de entorno por ti si todavía no está configurada. Esto te permite iniciar el backend antes de construir o iniciar el frontend durante el desarrollo.
En cualquier otro entorno, **FastAPI** lanza un error cuando se crea la app. Esto ayuda a detectar errores de configuración temprano antes de desplegar una app sin sus archivos frontend.
También puedes configurar `check_dir=True` para revisar siempre el directorio cuando se crea la app.
Si tus archivos frontend se crean más tarde, por ejemplo mediante un paso de build separado después de crear el objeto app, configura `check_dir=False`:
@@ -132,6 +136,8 @@ Las responses frontend se ejecutan dentro de la aplicación **FastAPI** normal,
Las dependencias de la app, de un `APIRouter` y de `include_router()` también se aplican a las responses frontend. Esto puede ser útil para proteger un frontend con autenticación por cookie o similar.
Las dependencias también pueden modificar headers de response y agregar tareas en background, como con las *path operations* normales.
## Solo salida estática del build { #static-build-output-only }
`app.frontend()` sirve archivos ya generados por tu build del frontend.
+2 -2
View File
@@ -81,7 +81,7 @@ Pero en caso de que los necesites para un escenario avanzado, puedes agregar hea
## Instalar manejadores de excepciones personalizados { #install-custom-exception-handlers }
Puedes agregar manejadores de excepciones personalizados con [las mismas utilidades de excepciones de Starlette](https://www.starlette.dev/exceptions/).
Puedes agregar manejadores de excepciones personalizados con [las mismas utilidades de excepciones de Starlette](https://starlette.dev/exceptions/).
Supongamos que tienes una excepción personalizada `UnicornException` que tú (o un paquete que usas) podrías lanzar.
@@ -91,7 +91,7 @@ Podrías agregar un manejador de excepciones personalizado con `@app.exception_h
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
Aquí, si solicitas `/unicorns/yolo`, la *path operation* lanzará un `UnicornException`.
Aquí, si solicitas `/unicorns/yolo`, la *path operation* hará `raise` de un `UnicornException`.
Pero será manejado por el `unicorn_exception_handler`.
+55 -15
View File
@@ -10,12 +10,12 @@ También está diseñado para funcionar como una referencia futura para que pued
Todos los bloques de código pueden ser copiados y usados directamente (de hecho, son archivos Python probados).
Para ejecutar cualquiera de los ejemplos, copia el código a un archivo `main.py`, y comienza `fastapi dev`:
Para ejecutar cualquiera de los ejemplos, copia el código a un archivo `main.py`, y comienza `fastapi dev` con `uv run`:
<div class="termy">
```console
$ <font color="#4E9A06">fastapi</font> dev
$ <font color="#4E9A06">uv run fastapi</font> dev
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
@@ -60,35 +60,75 @@ Usarlo en tu editor es lo que realmente te muestra los beneficios de FastAPI, al
## Instalar FastAPI { #install-fastapi }
El primer paso es instalar FastAPI.
El primer paso es configurar tu proyecto y añadir FastAPI.
Asegúrate de crear un [entorno virtual](../virtual-environments.md), actívalo, y luego **instala FastAPI**:
Instala [`uv`](https://docs.astral.sh/uv/getting-started/installation/), luego crea un proyecto y añade FastAPI:
<div class="termy">
```console
$ pip install "fastapi[standard]"
$ uv init awesome-project --bare
$ cd awesome-project
$ uv add "fastapi[standard]"
---> 100%
```
</div>
`uv add` crea el entorno virtual del proyecto en `.venv`, añade FastAPI a `pyproject.toml`, y crea `uv.lock` para que se puedan instalar las mismas versiones de paquetes más adelante.
/// details | Qué hacen estos comandos
* `uv init`: crea un nuevo proyecto Python.
* `awesome-project`: crea el proyecto en un nuevo directorio con este nombre.
* `--bare`: crea solo el archivo mínimo `pyproject.toml`, sin generar un `main.py`, `README.md`, u otros archivos de ejemplo. Tú crearás los archivos de la aplicación en los siguientes pasos de este tutorial.
Luego `cd awesome-project` entra al nuevo directorio del proyecto antes de añadir FastAPI.
`uv` usará una versión compatible de Python ya instalada en tu sistema, o descargará una si es necesario.
Cuando ejecutas `uv add`, selecciona versiones compatibles de FastAPI y todos los paquetes de los que depende FastAPI. Registra las versiones exactas en `uv.lock`, haciendo posible instalar las mismas versiones de paquetes más adelante en otra computadora o al hacer deploy de la aplicación.
Crear o actualizar este archivo se llama hacer [**locking** de las dependencias del proyecto](https://docs.astral.sh/uv/concepts/projects/sync/). `uv` hace esto automáticamente cuando añades un paquete.
///
/// details | Opciones de instalación de FastAPI
Cuando instalas con `uv add "fastapi[standard]"` viene con algunas dependencias opcionales estándar por defecto, incluyendo `fastapi-cloud-cli`, que te permite hacer deploy a [FastAPI Cloud](https://fastapicloud.com).
Si no quieres tener esas dependencias opcionales, en su lugar puedes instalar `uv add fastapi`.
Si quieres instalar las dependencias estándar pero sin `fastapi-cloud-cli`, puedes instalar con `uv add "fastapi[standard-no-fastapi-cloud-cli]"`.
///
/// details | Usar `pip` en su lugar
Si prefieres gestionar un entorno virtual y paquetes manualmente, crea y activa un entorno virtual y luego instala FastAPI con `pip install "fastapi[standard]"`.
Lee la [guía de Entornos Virtuales](https://tiangolo.com/guides/virtual-environments/) para ver los pasos detallados.
///
## Habilidades de agentes de IA { #ai-agent-skills }
FastAPI incluye una habilidad oficial para agentes de programación con IA. Viene incluida con el paquete, por lo que su guía se mantiene alineada con la versión de FastAPI instalada en tu proyecto y se actualiza cuando actualizas FastAPI.
Después de instalar FastAPI en tu proyecto, puedes instalar la habilidad con <a href="https://library-skills.io">Library Skills</a>:
```bash
uvx library-skills
```
/// note | Nota
Cuando instalas con `pip install "fastapi[standard]"` viene con algunas dependencias opcionales estándar por defecto, incluyendo `fastapi-cloud-cli`, que te permite hacer deploy a [FastAPI Cloud](https://fastapicloud.com).
Si no quieres tener esas dependencias opcionales, en su lugar puedes instalar `pip install fastapi`.
Si quieres instalar las dependencias estándar pero sin `fastapi-cloud-cli`, puedes instalar con `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
`uvx` es un alias de `uv tool run`. Ejecuta Library Skills en un entorno temporal y aislado mientras Library Skills escanea los paquetes instalados en tu proyecto.
///
/// tip | Consejo
FastAPI tiene una [extensión oficial para VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (y Cursor), que ofrece muchas funcionalidades, incluyendo un explorador de path operation, búsqueda de path operation, navegación de CodeLens en tests (saltar a la definición desde tests), y deploy y logs de FastAPI Cloud, todo desde tu editor.
///
La habilidad es compatible con Codex, Claude Code, Cursor, GitHub Copilot, Gemini CLI, Pi, OpenCode, y la mayoría de otros agentes de programación. Para Claude Code, selecciona `.claude/skills` cuando se te pregunte dónde instalar la habilidad.
## Guía Avanzada del Usuario { #advanced-user-guide }
+3 -3
View File
@@ -37,7 +37,7 @@ La función middleware recibe:
Ten en cuenta que los custom proprietary headers se pueden añadir [usando el prefijo `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
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)) usando el parámetro `expose_headers` documentado en [la documentación de CORS de Starlette](https://www.starlette.dev/middleware/#corsmiddleware).
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)) usando el parámetro `expose_headers` documentado en [la documentación de CORS de Starlette](https://starlette.dev/middleware/#corsmiddleware).
///
@@ -67,9 +67,9 @@ Aquí usamos [`time.perf_counter()`](https://docs.python.org/3/library/time.html
## 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.
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 request, el middleware *más externo* se ejecuta primero.
En el camino de la response, se ejecuta al final.
+2 -2
View File
@@ -92,7 +92,7 @@ Nota que el parámetro de path está declarado como un entero.
## Beneficios basados en estándares, documentación alternativa { #standards-based-benefits-alternative-documentation }
Y porque el esquema generado es del estándar [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md), hay muchas herramientas compatibles.
Y porque el esquema generado es del estándar [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md), hay muchas herramientas compatibles.
Debido a esto, el propio **FastAPI** proporciona una documentación de API alternativa (usando ReDoc), a la cual puedes acceder en [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc):
@@ -102,7 +102,7 @@ De la misma manera, hay muchas herramientas compatibles. Incluyendo herramientas
## Pydantic { #pydantic }
Toda la validación de datos se realiza internamente con [Pydantic](https://docs.pydantic.dev/), así que obtienes todos los beneficios de esta. Y sabes que estás en buenas manos.
Toda la validación de datos se realiza internamente con [Pydantic](https://pydantic.dev/docs/), así que obtienes todos los beneficios de esta. Y sabes que estás en buenas manos.
Puedes usar las mismas declaraciones de tipo con `str`, `float`, `bool` y muchos otros tipos de datos complejos.
@@ -370,11 +370,11 @@ Podría haber casos donde necesites hacer alguna **validación personalizada** q
En esos casos, puedes usar una **función validadora personalizada** que se aplique después de la validación normal (por ejemplo, después de validar que el valor es un `str`).
Puedes lograr eso usando [`AfterValidator` de Pydantic](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) dentro de `Annotated`.
Puedes lograr eso usando [`AfterValidator` de Pydantic](https://pydantic.dev/docs/validation/latest/concepts/validators/#field-after-validator) dentro de `Annotated`.
/// tip | Consejo
Pydantic también tiene [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) y otros. 🤓
Pydantic también tiene [`BeforeValidator`](https://pydantic.dev/docs/validation/latest/concepts/validators/#field-before-validator) y otros. 🤓
///
+2 -2
View File
@@ -6,10 +6,10 @@ Puedes definir archivos que serán subidos por el cliente utilizando `File`.
Para recibir archivos subidos, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo y luego instalarlo, por ejemplo:
Agrégalo a tu proyecto:
```console
$ pip install python-multipart
$ uv add python-multipart
```
Esto es porque los archivos subidos se envían como "form data".
+2 -2
View File
@@ -6,10 +6,10 @@ Puedes usar **modelos de Pydantic** para declarar **campos de formulario** en Fa
Para usar formularios, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo, y luego instalarlo, por ejemplo:
Agrégalo a tu proyecto:
```console
$ pip install python-multipart
$ uv add python-multipart
```
///
@@ -6,10 +6,10 @@ Puedes definir archivos y campos de formulario al mismo tiempo usando `File` y `
Para recibir archivos subidos y/o form data, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
Asegúrate de crear un [entorno virtual](../virtual-environments.md), actívalo y luego instálalo, por ejemplo:
Añádelo a tu proyecto:
```console
$ pip install python-multipart
$ uv add python-multipart
```
///
+2 -2
View File
@@ -6,10 +6,10 @@ Cuando necesitas recibir campos de formulario en lugar de JSON, puedes usar `For
Para usar formularios, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo, y luego instalarlo, por ejemplo:
Añádelo a tu proyecto:
```console
$ pip install python-multipart
$ uv add python-multipart
```
///
+4 -4
View File
@@ -76,16 +76,16 @@ Aquí estamos declarando un modelo `UserIn`, contendrá una contraseña en texto
Para usar `EmailStr`, primero instala [`email-validator`](https://github.com/JoshData/python-email-validator).
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo, y luego instalarlo, por ejemplo:
Añádelo a tu proyecto:
```console
$ pip install email-validator
$ uv add email-validator
```
o con:
```console
$ pip install "pydantic[email]"
$ uv add "pydantic[email]"
```
///
@@ -258,7 +258,7 @@ También puedes usar:
* `response_model_exclude_defaults=True`
* `response_model_exclude_none=True`
como se describe en [la documentación de Pydantic](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict) para `exclude_defaults` y `exclude_none`.
como se describe en [la documentación de Pydantic](https://pydantic.dev/docs/validation/latest/concepts/serialization/#excluding-and-including-fields-based-on-their-value) para `exclude_defaults` y `exclude_none`.
///
@@ -12,7 +12,7 @@ Puedes declarar `examples` para un modelo de Pydantic que se añadirá al JSON S
Esa información extra se añadirá tal cual al **JSON Schema** resultante para ese modelo, y se usará en la documentación de la API.
Puedes usar el atributo `model_config` que toma un `dict` como se describe en [Documentación de Pydantic: Configuración](https://docs.pydantic.dev/latest/api/config/).
Puedes usar el atributo `model_config` que toma un `dict` como se describe en [Documentación de Pydantic: Configuración](https://pydantic.dev/docs/validation/latest/api/pydantic/config/).
Puedes establecer `"json_schema_extra"` con un `dict` que contenga cualquier dato adicional que te gustaría que aparezca en el JSON Schema generado, incluyendo `examples`.
@@ -26,14 +26,14 @@ Copia el ejemplo en un archivo `main.py`:
/// note | Nota
El paquete [`python-multipart`](https://github.com/Kludex/python-multipart) se instala automáticamente con **FastAPI** cuando ejecutas el comando `pip install "fastapi[standard]"`.
El paquete [`python-multipart`](https://github.com/Kludex/python-multipart) se instala automáticamente con **FastAPI** cuando ejecutas el comando `uv add "fastapi[standard]"`.
Sin embargo, si usas el comando `pip install fastapi`, el paquete `python-multipart` no se incluye por defecto.
Sin embargo, si usas el comando `uv add fastapi`, el paquete `python-multipart` no se incluye por defecto.
Para instalarlo manualmente, asegúrate de crear un [entorno virtual](../../virtual-environments.md), activarlo, y luego instalarlo con:
Para instalarlo manualmente, agrégalo a tu proyecto con:
```console
$ pip install python-multipart
$ uv add python-multipart
```
Esto se debe a que **OAuth2** utiliza "form data" para enviar el `username` y `password`.
@@ -45,7 +45,7 @@ Ejecuta el ejemplo con:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
+4 -5
View File
@@ -1,6 +1,5 @@
# OAuth2 con Password (y hashing), Bearer con tokens JWT { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
Ahora que tenemos todo el flujo de seguridad, hagamos que la aplicación sea realmente segura, usando tokens <abbr title="JSON Web Tokens">JWT</abbr> y hashing de contraseñas seguras.
Este código es algo que puedes usar realmente en tu aplicación, guardar los hashes de las contraseñas en tu base de datos, etc.
@@ -31,12 +30,12 @@ Si quieres jugar con tokens JWT y ver cómo funcionan, revisa [https://jwt.io](h
Necesitamos instalar `PyJWT` para generar y verificar los tokens JWT en Python.
Asegúrate de crear un [entorno virtual](../../virtual-environments.md), activarlo y luego instalar `pyjwt`:
Añade `pyjwt` a tu proyecto:
<div class="termy">
```console
$ pip install pyjwt
$ uv add pyjwt
---> 100%
```
@@ -73,12 +72,12 @@ Soporta muchos algoritmos de hashing seguros y utilidades para trabajar con ello
El algoritmo recomendado es "Argon2".
Asegúrate de crear un [entorno virtual](../../virtual-environments.md), activarlo y luego instalar pwdlib con Argon2:
Añade `pwdlib` con Argon2 a tu proyecto:
<div class="termy">
```console
$ pip install "pwdlib[argon2]"
$ uv add "pwdlib[argon2]"
---> 100%
```
+4 -4
View File
@@ -34,12 +34,12 @@ Este es un tutorial muy simple y corto, si deseas aprender sobre bases de datos
## Instalar `SQLModel` { #install-sqlmodel }
Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md), actívalo, y luego instala `sqlmodel`:
Añade `sqlmodel` a tu proyecto:
<div class="termy">
```console
$ pip install sqlmodel
$ uv add sqlmodel
---> 100%
```
@@ -152,7 +152,7 @@ Puedes ejecutar la aplicación:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -337,7 +337,7 @@ Puedes ejecutar la aplicación de nuevo:
<div class="termy">
```console
$ fastapi dev
$ uv run fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
+1 -1
View File
@@ -45,4 +45,4 @@ Todos estos parámetros pueden ser diferentes a "`static`", ajústalos según la
## Más info { #more-info }
Para más detalles y opciones revisa [la documentación de Starlette sobre Archivos Estáticos](https://www.starlette.dev/staticfiles/).
Para más detalles y opciones revisa [la documentación de Starlette sobre Archivos Estáticos](https://starlette.dev/staticfiles/).
+9 -7
View File
@@ -1,6 +1,6 @@
# Pruebas { #testing }
Gracias a [Starlette](https://www.starlette.dev/testclient/), escribir pruebas para aplicaciones de **FastAPI** es fácil y agradable.
Gracias a [Starlette](https://starlette.dev/testclient/), escribir pruebas para aplicaciones de **FastAPI** es fácil y agradable.
Está basado en [HTTPX](https://www.python-httpx.org), que a su vez está diseñado basado en Requests, por lo que es muy familiar e intuitivo.
@@ -12,10 +12,10 @@ Con él, puedes usar [pytest](https://docs.pytest.org/) directamente con **FastA
Para usar `TestClient`, primero instala [`httpx`](https://www.python-httpx.org).
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo y luego instalarlo, por ejemplo:
Añádelo a tu proyecto:
```console
$ pip install httpx
$ uv add httpx
```
///
@@ -94,11 +94,12 @@ Debido a que este archivo está en el mismo paquete, puedes usar imports relativ
{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
...y tener el código para las pruebas tal como antes.
## Pruebas: ejemplo extendido { #testing-extended-example }
Ahora extiende este ejemplo y añade más detalles para ver cómo escribir pruebas para diferentes partes.
Ahora extendamos este ejemplo y añade más detalles para ver cómo escribir pruebas para diferentes partes.
### Archivo de aplicación **FastAPI** extendido { #extended-fastapi-app-file }
@@ -128,6 +129,7 @@ Podrías entonces actualizar `test_main.py` con las pruebas extendidas:
{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
Cada vez que necesites que el cliente pase información en el request y no sepas cómo, puedes buscar (Googlear) cómo hacerlo en `httpx`, o incluso cómo hacerlo con `requests`, dado que el diseño de HTTPX está basado en el diseño de Requests.
Luego simplemente haces lo mismo en tus pruebas.
@@ -154,12 +156,12 @@ Si tienes un modelo de Pydantic en tu prueba y quieres enviar sus datos a la apl
Después de eso, solo necesitas instalar `pytest`.
Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo y luego instalarlo, por ejemplo:
Añádelo a tu proyecto:
<div class="termy">
```console
$ pip install pytest
$ uv add pytest
---> 100%
```
@@ -173,7 +175,7 @@ Ejecuta las pruebas con:
<div class="termy">
```console
$ pytest
$ uv run pytest
================ test session starts ================
platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
+10 -839
View File
@@ -1,864 +1,35 @@
# Entornos Virtuales { #virtual-environments }
Cuando trabajas en proyectos de Python probablemente deberías usar un **entorno virtual** (o un mecanismo similar) para aislar los paquetes que instalas para cada proyecto.
Cuando trabajas con proyectos de Python, deberías usar un **entorno virtual** para aislar los paquetes instalados para cada proyecto.
/// note | Nota
Si ya sabes sobre entornos virtuales, cómo crearlos y usarlos, podrías querer saltar esta sección. 🤓
///
/// tip | Consejo
Un **entorno virtual** es diferente de una **variable de entorno**.
Una **variable de entorno** es una variable en el sistema que puede ser usada por programas.
Un **entorno virtual** es un directorio con algunos archivos en él.
///
/// note | Nota
Esta página te enseñará cómo usar **entornos virtuales** y cómo funcionan.
Si estás listo para adoptar una **herramienta que gestiona todo** por ti (incluyendo la instalación de Python), prueba [uv](https://github.com/astral-sh/uv).
///
Para proyectos de FastAPI, recomiendo usar [uv](https://docs.astral.sh/uv/) para gestionar el proyecto, sus dependencias y su entorno virtual.
## Crea un Proyecto { #create-a-project }
Primero, crea un directorio para tu proyecto.
Lo que normalmente hago es crear un directorio llamado `code` dentro de mi directorio de usuario.
Y dentro de eso creo un directorio por proyecto.
Instala `uv` usando la [guía oficial de instalación](https://docs.astral.sh/uv/getting-started/installation/), y luego crea un proyecto:
<div class="termy">
```console
// Ve al directorio principal
$ cd
// Crea un directorio para todos tus proyectos de código
$ mkdir code
// Entra en ese directorio de código
$ cd code
// Crea un directorio para este proyecto
$ mkdir awesome-project
// Entra en ese directorio del proyecto
$ uv init awesome-project --bare
$ cd awesome-project
$ uv add "fastapi[standard]"
```
</div>
## Crea un Entorno Virtual { #create-a-virtual-environment }
`uv` crea un entorno virtual para el proyecto automáticamente. No necesitas crear ni activar uno tú mismo.
Cuando empiezas a trabajar en un proyecto de Python **por primera vez**, crea un entorno virtual **<dfn title="hay otras opciones, esto es solo una guía sencilla">dentro de tu proyecto</dfn>**.
/// tip | Consejo
Solo necesitas hacer esto **una vez por proyecto**, no cada vez que trabajas.
///
//// tab | `venv`
Para crear un entorno virtual, puedes usar el módulo `venv` que viene con Python.
Ejecuta comandos dentro del entorno del proyecto con `uv run`, por ejemplo:
<div class="termy">
```console
$ python -m venv .venv
$ uv run fastapi dev
```
</div>
/// details | Qué significa ese comando
## Aprende Más { #learn-more }
* `python`: usa el programa llamado `python`
* `-m`: llama a un módulo como un script, indicaremos cuál módulo a continuación
* `venv`: usa el módulo llamado `venv` que normalmente viene instalado con Python
* `.venv`: crea el entorno virtual en el nuevo directorio `.venv`
///
////
//// tab | `uv`
Si tienes instalado [`uv`](https://github.com/astral-sh/uv), puedes usarlo para crear un entorno virtual.
<div class="termy">
```console
$ uv venv
```
</div>
/// tip | Consejo
Por defecto, `uv` creará un entorno virtual en un directorio llamado `.venv`.
Pero podrías personalizarlo pasando un argumento adicional con el nombre del directorio.
///
////
Ese comando crea un nuevo entorno virtual en un directorio llamado `.venv`.
/// details | `.venv` u otro nombre
Podrías crear el entorno virtual en un directorio diferente, pero hay una convención de llamarlo `.venv`.
///
## Activa el Entorno Virtual { #activate-the-virtual-environment }
Activa el nuevo entorno virtual para que cualquier comando de Python que ejecutes o paquete que instales lo utilicen.
/// tip | Consejo
Haz esto **cada vez** que inicies una **nueva sesión de terminal** para trabajar en el proyecto.
///
//// tab | Linux, macOS
<div class="termy">
```console
$ source .venv/bin/activate
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ .venv\Scripts\Activate.ps1
```
</div>
////
//// tab | Windows Bash
O si usas Bash para Windows (por ejemplo, [Git Bash](https://gitforwindows.org/)):
<div class="termy">
```console
$ source .venv/Scripts/activate
```
</div>
////
/// tip | Consejo
Cada vez que instales un **nuevo paquete** en ese entorno, **activa** el entorno de nuevo.
Esto asegura que si usas un **programa de terminal (<abbr title="command line interface - interfaz de línea de comandos">CLI</abbr>)** instalado por ese paquete, uses el de tu entorno virtual y no cualquier otro que podría estar instalado globalmente, probablemente con una versión diferente a la que necesitas.
///
## Revisa que el Entorno Virtual esté Activo { #check-the-virtual-environment-is-active }
Revisa que el entorno virtual esté activo (el comando anterior funcionó).
/// tip | Consejo
Esto es **opcional**, pero es una buena forma de **revisar** que todo está funcionando como se esperaba y estás usando el entorno virtual que pretendes.
///
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
$ which python
/home/user/code/awesome-project/.venv/bin/python
```
</div>
Si muestra el binario de `python` en `.venv/bin/python`, dentro de tu proyecto (en este caso `awesome-project`), entonces funcionó. 🎉
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
</div>
Si muestra el binario de `python` en `.venv\Scripts\python`, dentro de tu proyecto (en este caso `awesome-project`), entonces funcionó. 🎉
////
## Actualiza `pip` { #upgrade-pip }
/// tip | Consejo
Si usas [`uv`](https://github.com/astral-sh/uv) usarías eso para instalar cosas en lugar de `pip`, por lo que no necesitas actualizar `pip`. 😎
///
Si estás usando `pip` para instalar paquetes (viene por defecto con Python), deberías **actualizarlo** a la última versión.
Muchos errores exóticos al instalar un paquete se resuelven simplemente actualizando `pip` primero.
/// tip | Consejo
Normalmente harías esto **una vez**, justo después de crear el entorno virtual.
///
Asegúrate de que el entorno virtual esté activo (con el comando anterior) y luego ejecuta:
<div class="termy">
```console
$ python -m pip install --upgrade pip
---> 100%
```
</div>
/// tip | Consejo
A veces, podrías obtener un error **`No module named pip`** al intentar actualizar pip.
Si esto pasa, instala y actualiza pip usando el siguiente comando:
<div class="termy">
```console
$ python -m ensurepip --upgrade
---> 100%
```
</div>
Este comando instalará pip si aún no está instalado y también se asegura de que la versión instalada de pip sea al menos tan reciente como la disponible en `ensurepip`.
///
## Añade `.gitignore` { #add-gitignore }
Si estás usando **Git** (deberías), añade un archivo `.gitignore` para excluir todo en tu `.venv` de Git.
/// tip | Consejo
Si usaste [`uv`](https://github.com/astral-sh/uv) para crear el entorno virtual, ya lo hizo por ti, puedes saltarte este paso. 😎
///
/// tip | Consejo
Haz esto **una vez**, justo después de crear el entorno virtual.
///
<div class="termy">
```console
$ echo "*" > .venv/.gitignore
```
</div>
/// details | Qué significa ese comando
* `echo "*"`: "imprimirá" el texto `*` en la terminal (la siguiente parte cambia eso un poco)
* `>`: cualquier cosa impresa en la terminal por el comando a la izquierda de `>` no debería imprimirse, sino escribirse en el archivo que va a la derecha de `>`
* `.gitignore`: el nombre del archivo donde debería escribirse el texto
Y `*` para Git significa "todo". Así que, ignorará todo en el directorio `.venv`.
Ese comando creará un archivo `.gitignore` con el contenido:
```gitignore
*
```
///
## Instala Paquetes { #install-packages }
Después de activar el entorno, puedes instalar paquetes en él.
/// tip | Consejo
Haz esto **una vez** al instalar o actualizar los paquetes que necesita tu proyecto.
Si necesitas actualizar una versión o agregar un nuevo paquete, **harías esto de nuevo**.
///
### Instala Paquetes Directamente { #install-packages-directly }
Si tienes prisa y no quieres usar un archivo para declarar los requisitos de paquetes de tu proyecto, puedes instalarlos directamente.
/// tip | Consejo
Es una (muy) buena idea poner los paquetes y las versiones que necesita tu programa en un archivo (por ejemplo, `requirements.txt` o `pyproject.toml`).
///
//// tab | `pip`
<div class="termy">
```console
$ pip install "fastapi[standard]"
---> 100%
```
</div>
////
//// tab | `uv`
Si tienes [`uv`](https://github.com/astral-sh/uv):
<div class="termy">
```console
$ uv pip install "fastapi[standard]"
---> 100%
```
</div>
////
### Instala desde `requirements.txt` { #install-from-requirements-txt }
Si tienes un `requirements.txt`, ahora puedes usarlo para instalar sus paquetes.
//// tab | `pip`
<div class="termy">
```console
$ pip install -r requirements.txt
---> 100%
```
</div>
////
//// tab | `uv`
Si tienes [`uv`](https://github.com/astral-sh/uv):
<div class="termy">
```console
$ uv pip install -r requirements.txt
---> 100%
```
</div>
////
/// details | `requirements.txt`
Un `requirements.txt` con algunos paquetes podría verse así:
```requirements.txt
fastapi[standard]==0.113.0
pydantic==2.8.0
```
///
## Ejecuta Tu Programa { #run-your-program }
Después de activar el entorno virtual, puedes ejecutar tu programa, y usará el Python dentro de tu entorno virtual con los paquetes que instalaste allí.
<div class="termy">
```console
$ python main.py
Hello World
```
</div>
## Configura Tu Editor { #configure-your-editor }
Probablemente usarías un editor, asegúrate de configurarlo para que use el mismo entorno virtual que creaste (probablemente lo autodetectará) para que puedas obtener autocompletado y errores en línea.
Por ejemplo:
* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
/// tip | Consejo
Normalmente solo tendrías que hacer esto **una vez**, cuando crees el entorno virtual.
///
## Desactiva el Entorno Virtual { #deactivate-the-virtual-environment }
Una vez que hayas terminado de trabajar en tu proyecto, puedes **desactivar** el entorno virtual.
<div class="termy">
```console
$ deactivate
```
</div>
De esta manera, cuando ejecutes `python` no intentará ejecutarse desde ese entorno virtual con los paquetes instalados allí.
## Listo para Trabajar { #ready-to-work }
Ahora estás listo para empezar a trabajar en tu proyecto.
/// tip | Consejo
¿Quieres entender todo lo anterior?
Continúa leyendo. 👇🤓
///
## Por qué Entornos Virtuales { #why-virtual-environments }
Para trabajar con FastAPI necesitas instalar [Python](https://www.python.org/).
Después de eso, necesitarías **instalar** FastAPI y cualquier otro **paquete** que desees usar.
Para instalar paquetes normalmente usarías el comando `pip` que viene con Python (o alternativas similares).
Sin embargo, si solo usas `pip` directamente, los paquetes se instalarían en tu **entorno global de Python** (la instalación global de Python).
### El Problema { #the-problem }
Entonces, ¿cuál es el problema de instalar paquetes en el entorno global de Python?
En algún momento, probablemente terminarás escribiendo muchos programas diferentes que dependen de **diferentes paquetes**. Y algunos de estos proyectos en los que trabajas dependerán de **diferentes versiones** del mismo paquete. 😱
Por ejemplo, podrías crear un proyecto llamado `philosophers-stone`, este programa depende de otro paquete llamado **`harry`, usando la versión `1`**. Así que, necesitas instalar `harry`.
```mermaid
flowchart LR
stone(philosophers-stone) -->|requires| harry-1[harry v1]
```
Luego, en algún momento después, creas otro proyecto llamado `prisoner-of-azkaban`, y este proyecto también depende de `harry`, pero este proyecto necesita **`harry` versión `3`**.
```mermaid
flowchart LR
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
```
Pero ahora el problema es, si instalas los paquetes globalmente (en el entorno global) en lugar de en un **entorno virtual local**, tendrás que elegir qué versión de `harry` instalar.
Si deseas ejecutar `philosophers-stone` necesitarás primero instalar `harry` versión `1`, por ejemplo con:
<div class="termy">
```console
$ pip install "harry==1"
```
</div>
Y entonces terminarías con `harry` versión `1` instalada en tu entorno global de Python.
```mermaid
flowchart LR
subgraph global[global env]
harry-1[harry v1]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -->|requires| harry-1
end
```
Pero luego si deseas ejecutar `prisoner-of-azkaban`, necesitarás desinstalar `harry` versión `1` e instalar `harry` versión `3` (o simplemente instalar la versión `3` automáticamente desinstalaría la versión `1`).
<div class="termy">
```console
$ pip install "harry==3"
```
</div>
Y entonces terminarías con `harry` versión `3` instalada en tu entorno global de Python.
Y si intentas ejecutar `philosophers-stone` de nuevo, hay una posibilidad de que **no funcione** porque necesita `harry` versión `1`.
```mermaid
flowchart LR
subgraph global[global env]
harry-1[<strike>harry v1</strike>]
style harry-1 fill:#ccc,stroke-dasharray: 5 5
harry-3[harry v3]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -.-x|⛔️| harry-1
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --> |requires| harry-3
end
```
/// tip | Consejo
Es muy común en los paquetes de Python intentar lo mejor para **evitar romper cambios** en **nuevas versiones**, pero es mejor estar seguro e instalar nuevas versiones intencionalmente y cuando puedas ejecutar las pruebas para verificar que todo está funcionando correctamente.
///
Ahora, imagina eso con **muchos** otros **paquetes** de los que dependen todos tus **proyectos**. Eso es muy difícil de manejar. Y probablemente terminarías ejecutando algunos proyectos con algunas **versiones incompatibles** de los paquetes, y sin saber por qué algo no está funcionando.
Además, dependiendo de tu sistema operativo (por ejemplo, Linux, Windows, macOS), podría haber venido con Python ya instalado. Y en ese caso probablemente tenía algunos paquetes preinstalados con algunas versiones específicas **necesitadas por tu sistema**. Si instalas paquetes en el entorno global de Python, podrías terminar **rompiendo** algunos de los programas que vinieron con tu sistema operativo.
## Dónde se Instalan los Paquetes { #where-are-packages-installed }
Cuando instalas Python, crea algunos directorios con algunos archivos en tu computadora.
Algunos de estos directorios son los encargados de tener todos los paquetes que instalas.
Cuando ejecutas:
<div class="termy">
```console
// No ejecutes esto ahora, solo es un ejemplo 🤓
$ pip install "fastapi[standard]"
---> 100%
```
</div>
Eso descargará un archivo comprimido con el código de FastAPI, normalmente desde [PyPI](https://pypi.org/project/fastapi/).
También **descargará** archivos para otros paquetes de los que depende FastAPI.
Luego, **extraerá** todos esos archivos y los pondrá en un directorio en tu computadora.
Por defecto, pondrá esos archivos descargados y extraídos en el directorio que viene con tu instalación de Python, eso es el **entorno global**.
## Qué son los Entornos Virtuales { #what-are-virtual-environments }
La solución a los problemas de tener todos los paquetes en el entorno global es usar un **entorno virtual para cada proyecto** en el que trabajas.
Un entorno virtual es un **directorio**, muy similar al global, donde puedes instalar los paquetes para un proyecto.
De esta manera, cada proyecto tendrá su propio entorno virtual (directorio `.venv`) con sus propios paquetes.
```mermaid
flowchart TB
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) --->|requires| harry-1
subgraph venv1[.venv]
harry-1[harry v1]
end
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --->|requires| harry-3
subgraph venv2[.venv]
harry-3[harry v3]
end
end
stone-project ~~~ azkaban-project
```
## Qué Significa Activar un Entorno Virtual { #what-does-activating-a-virtual-environment-mean }
Cuando activas un entorno virtual, por ejemplo con:
//// tab | Linux, macOS
<div class="termy">
```console
$ source .venv/bin/activate
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ .venv\Scripts\Activate.ps1
```
</div>
////
//// tab | Windows Bash
O si usas Bash para Windows (por ejemplo, [Git Bash](https://gitforwindows.org/)):
<div class="termy">
```console
$ source .venv/Scripts/activate
```
</div>
////
Ese comando creará o modificará algunas [variables de entorno](environment-variables.md) que estarán disponibles para los siguientes comandos.
Una de esas variables es la variable `PATH`.
/// tip | Consejo
Puedes aprender más sobre la variable de entorno `PATH` en la sección [Variables de Entorno](environment-variables.md#path-environment-variable).
///
Activar un entorno virtual agrega su path `.venv/bin` (en Linux y macOS) o `.venv\Scripts` (en Windows) a la variable de entorno `PATH`.
Digamos que antes de activar el entorno, la variable `PATH` se veía así:
//// tab | Linux, macOS
```plaintext
/usr/bin:/bin:/usr/sbin:/sbin
```
Eso significa que el sistema buscaría programas en:
* `/usr/bin`
* `/bin`
* `/usr/sbin`
* `/sbin`
////
//// tab | Windows
```plaintext
C:\Windows\System32
```
Eso significa que el sistema buscaría programas en:
* `C:\Windows\System32`
////
Después de activar el entorno virtual, la variable `PATH` se vería algo así:
//// tab | Linux, macOS
```plaintext
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
Eso significa que el sistema ahora comenzará a buscar primero los programas en:
```plaintext
/home/user/code/awesome-project/.venv/bin
```
antes de buscar en los otros directorios.
Así que, cuando escribas `python` en la terminal, el sistema encontrará el programa Python en
```plaintext
/home/user/code/awesome-project/.venv/bin/python
```
y utilizará ese.
////
//// tab | Windows
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
```
Eso significa que el sistema ahora comenzará a buscar primero los programas en:
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts
```
antes de buscar en los otros directorios.
Así que, cuando escribas `python` en la terminal, el sistema encontrará el programa Python en
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
y utilizará ese.
////
Un detalle importante es que pondrá el path del entorno virtual al **comienzo** de la variable `PATH`. El sistema lo encontrará **antes** que cualquier otro Python disponible. De esta manera, cuando ejecutes `python`, utilizará el Python **del entorno virtual** en lugar de cualquier otro `python` (por ejemplo, un `python` de un entorno global).
Activar un entorno virtual también cambia un par de otras cosas, pero esta es una de las cosas más importantes que hace.
## Revisando un Entorno Virtual { #checking-a-virtual-environment }
Cuando revisas si un entorno virtual está activo, por ejemplo con:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
$ which python
/home/user/code/awesome-project/.venv/bin/python
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
</div>
////
Eso significa que el programa `python` que se utilizará es el que está **en el entorno virtual**.
Usas `which` en Linux y macOS y `Get-Command` en Windows PowerShell.
La forma en que funciona ese comando es que irá y revisará la variable de entorno `PATH`, pasando por **cada path en orden**, buscando el programa llamado `python`. Una vez que lo encuentre, te **mostrará el path** a ese programa.
La parte más importante es que cuando llamas a `python`, ese es el exacto "`python`" que será ejecutado.
Así que, puedes confirmar si estás en el entorno virtual correcto.
/// tip | Consejo
Es fácil activar un entorno virtual, obtener un Python, y luego **ir a otro proyecto**.
Y el segundo proyecto **no funcionaría** porque estás usando el **Python incorrecto**, de un entorno virtual para otro proyecto.
Es útil poder revisar qué `python` se está usando. 🤓
///
## Por qué Desactivar un Entorno Virtual { #why-deactivate-a-virtual-environment }
Por ejemplo, podrías estar trabajando en un proyecto `philosophers-stone`, **activar ese entorno virtual**, instalar paquetes y trabajar con ese entorno.
Y luego quieres trabajar en **otro proyecto** `prisoner-of-azkaban`.
Vas a ese proyecto:
<div class="termy">
```console
$ cd ~/code/prisoner-of-azkaban
```
</div>
Si no desactivas el entorno virtual para `philosophers-stone`, cuando ejecutes `python` en la terminal, intentará usar el Python de `philosophers-stone`.
<div class="termy">
```console
$ cd ~/code/prisoner-of-azkaban
$ python main.py
// Error importando sirius, no está instalado 😱
Traceback (most recent call last):
File "main.py", line 1, in <module>
import sirius
```
</div>
Pero si desactivas el entorno virtual y activas el nuevo para `prisoner-of-azkaban` entonces cuando ejecutes `python` utilizará el Python del entorno virtual en `prisoner-of-azkaban`.
<div class="termy">
```console
$ cd ~/code/prisoner-of-azkaban
// No necesitas estar en el directorio antiguo para desactivar, puedes hacerlo donde sea que estés, incluso después de ir al otro proyecto 😎
$ deactivate
// Activa el entorno virtual en prisoner-of-azkaban/.venv 🚀
$ source .venv/bin/activate
// Ahora cuando ejecutes python, encontrará el paquete sirius instalado en este entorno virtual ✨
$ python main.py
I solemnly swear 🐺
```
</div>
## Alternativas { #alternatives }
Esta es una guía simple para comenzar y enseñarte cómo funciona todo **por debajo**.
Hay muchas **alternativas** para gestionar entornos virtuales, dependencias de paquetes (requisitos), proyectos.
Una vez que estés listo y quieras usar una herramienta para **gestionar todo el proyecto**, dependencias de paquetes, entornos virtuales, etc. Te sugeriría probar [uv](https://github.com/astral-sh/uv).
`uv` puede hacer muchas cosas, puede:
* **Instalar Python** por ti, incluyendo diferentes versiones
* Gestionar el **entorno virtual** para tus proyectos
* Instalar **paquetes**
* Gestionar **dependencias y versiones** de paquetes para tu proyecto
* Asegurarse de que tengas un conjunto **exacto** de paquetes y versiones para instalar, incluidas sus dependencias, para que puedas estar seguro de que puedes ejecutar tu proyecto en producción exactamente igual que en tu computadora mientras desarrollas, esto se llama **locking**
* Y muchas otras cosas
## Conclusión { #conclusion }
Si leíste y comprendiste todo esto, ahora **sabes mucho más** sobre entornos virtuales que muchos desarrolladores por ahí. 🤓
Conocer estos detalles probablemente te será útil en el futuro cuando estés depurando algo que parece complejo, pero sabrás **cómo funciona todo por debajo**. 😎
Lee la [guía de Entornos Virtuales](https://tiangolo.com/guides/virtual-environments/) para aprender cómo funcionan los entornos virtuales por debajo, incluyendo la activación y el flujo de trabajo alternativo con `python -m venv` y `pip`.