]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Update translations for es (update-all and add-missing) (#14911)
authorMotov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Fri, 13 Feb 2026 13:41:41 +0000 (14:41 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Feb 2026 13:41:41 +0000 (14:41 +0100)
* Update all

* 🎨 Auto format

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
87 files changed:
docs/es/docs/advanced/additional-responses.md
docs/es/docs/advanced/advanced-dependencies.md
docs/es/docs/advanced/advanced-python-types.md [new file with mode: 0644]
docs/es/docs/advanced/async-tests.md
docs/es/docs/advanced/behind-a-proxy.md
docs/es/docs/advanced/custom-response.md
docs/es/docs/advanced/dataclasses.md
docs/es/docs/advanced/events.md
docs/es/docs/advanced/generate-clients.md
docs/es/docs/advanced/middleware.md
docs/es/docs/advanced/openapi-webhooks.md
docs/es/docs/advanced/path-operation-advanced-configuration.md
docs/es/docs/advanced/response-change-status-code.md
docs/es/docs/advanced/response-cookies.md
docs/es/docs/advanced/response-directly.md
docs/es/docs/advanced/response-headers.md
docs/es/docs/advanced/security/http-basic-auth.md
docs/es/docs/advanced/settings.md
docs/es/docs/advanced/sub-applications.md
docs/es/docs/advanced/templates.md
docs/es/docs/advanced/testing-dependencies.md
docs/es/docs/advanced/testing-events.md
docs/es/docs/advanced/testing-websockets.md
docs/es/docs/advanced/using-request-directly.md
docs/es/docs/advanced/websockets.md
docs/es/docs/advanced/wsgi.md
docs/es/docs/alternatives.md
docs/es/docs/async.md
docs/es/docs/deployment/cloud.md
docs/es/docs/deployment/concepts.md
docs/es/docs/deployment/docker.md
docs/es/docs/deployment/fastapicloud.md
docs/es/docs/deployment/https.md
docs/es/docs/deployment/manually.md
docs/es/docs/features.md
docs/es/docs/help-fastapi.md
docs/es/docs/how-to/authentication-error-status-code.md
docs/es/docs/how-to/conditional-openapi.md
docs/es/docs/how-to/configure-swagger-ui.md
docs/es/docs/how-to/custom-docs-ui-assets.md
docs/es/docs/how-to/extending-openapi.md
docs/es/docs/how-to/graphql.md
docs/es/docs/how-to/separate-openapi-schemas.md
docs/es/docs/how-to/testing-database.md
docs/es/docs/index.md
docs/es/docs/project-generation.md
docs/es/docs/python-types.md
docs/es/docs/translation-banner.md [new file with mode: 0644]
docs/es/docs/tutorial/background-tasks.md
docs/es/docs/tutorial/bigger-applications.md
docs/es/docs/tutorial/body-multiple-params.md
docs/es/docs/tutorial/body-nested-models.md
docs/es/docs/tutorial/body.md
docs/es/docs/tutorial/cookie-param-models.md
docs/es/docs/tutorial/cors.md
docs/es/docs/tutorial/debugging.md
docs/es/docs/tutorial/dependencies/classes-as-dependencies.md
docs/es/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
docs/es/docs/tutorial/dependencies/dependencies-with-yield.md
docs/es/docs/tutorial/dependencies/global-dependencies.md
docs/es/docs/tutorial/dependencies/index.md
docs/es/docs/tutorial/dependencies/sub-dependencies.md
docs/es/docs/tutorial/encoder.md
docs/es/docs/tutorial/extra-models.md
docs/es/docs/tutorial/first-steps.md
docs/es/docs/tutorial/handling-errors.md
docs/es/docs/tutorial/metadata.md
docs/es/docs/tutorial/middleware.md
docs/es/docs/tutorial/path-operation-configuration.md
docs/es/docs/tutorial/path-params-numeric-validations.md
docs/es/docs/tutorial/path-params.md
docs/es/docs/tutorial/query-params-str-validations.md
docs/es/docs/tutorial/query-params.md
docs/es/docs/tutorial/request-files.md
docs/es/docs/tutorial/request-form-models.md
docs/es/docs/tutorial/request-forms-and-files.md
docs/es/docs/tutorial/request-forms.md
docs/es/docs/tutorial/response-model.md
docs/es/docs/tutorial/response-status-code.md
docs/es/docs/tutorial/schema-extra-example.md
docs/es/docs/tutorial/security/first-steps.md
docs/es/docs/tutorial/security/get-current-user.md
docs/es/docs/tutorial/security/oauth2-jwt.md
docs/es/docs/tutorial/sql-databases.md
docs/es/docs/tutorial/static-files.md
docs/es/docs/tutorial/testing.md
docs/es/docs/virtual-environments.md

index d0baa97a4500cfbfad2b6d3a8eacec0d80c6d478..030f8dcc5af95bc420e2a2041ec4268372374982 100644 (file)
@@ -26,7 +26,7 @@ Cada uno de esos `dict`s de response puede tener una clave `model`, conteniendo
 
 Por ejemplo, para declarar otro response con un código de estado `404` y un modelo Pydantic `Message`, puedes escribir:
 
-{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
 
 /// note | Nota
 
@@ -203,7 +203,7 @@ Por ejemplo, puedes declarar un response con un código de estado `404` que usa
 
 Y un response con un código de estado `200` que usa tu `response_model`, pero incluye un `example` personalizado:
 
-{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
 
 Todo se combinará e incluirá en tu OpenAPI, y se mostrará en la documentación de la API:
 
index 622a2caa26908aee6a7793e35c11a6229e445f05..81d8d19bbe0cc59c2d4224e127815dc2e0274383 100644 (file)
@@ -18,7 +18,7 @@ No la clase en sí (que ya es un callable), sino una instance de esa clase.
 
 Para hacer eso, declaramos un método `__call__`:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
 
 En este caso, este `__call__` es lo que **FastAPI** usará para comprobar parámetros adicionales y sub-dependencias, y es lo que llamará para pasar un valor al parámetro en tu *path operation function* más adelante.
 
@@ -26,7 +26,7 @@ En este caso, este `__call__` es lo que **FastAPI** usará para comprobar parám
 
 Y ahora, podemos usar `__init__` para declarar los parámetros de la instance que podemos usar para "parametrizar" la dependencia:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
 
 En este caso, **FastAPI** nunca tocará ni se preocupará por `__init__`, lo usaremos directamente en nuestro código.
 
@@ -34,7 +34,7 @@ En este caso, **FastAPI** nunca tocará ni se preocupará por `__init__`, lo usa
 
 Podríamos crear una instance de esta clase con:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
 
 Y de esa manera podemos "parametrizar" nuestra dependencia, que ahora tiene `"bar"` dentro de ella, como el atributo `checker.fixed_content`.
 
@@ -50,7 +50,7 @@ checker(q="somequery")
 
 ...y pasará lo que eso retorne como el valor de la dependencia en nuestra *path operation function* como el parámetro `fixed_content_included`:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
 
 /// tip | Consejo
 
diff --git a/docs/es/docs/advanced/advanced-python-types.md b/docs/es/docs/advanced/advanced-python-types.md
new file mode 100644 (file)
index 0000000..a18c5d6
--- /dev/null
@@ -0,0 +1,61 @@
+# Tipos avanzados de Python { #advanced-python-types }
+
+Aquí tienes algunas ideas adicionales que podrían ser útiles al trabajar con tipos de Python.
+
+## Usar `Union` u `Optional` { #using-union-or-optional }
+
+Si por alguna razón tu código no puede usar `|`, por ejemplo si no está en una anotación de tipos sino en algo como `response_model=`, en lugar de usar la barra vertical (`|`) puedes usar `Union` de `typing`.
+
+Por ejemplo, podrías declarar que algo podría ser un `str` o `None`:
+
+```python
+from typing import Union
+
+
+def say_hi(name: Union[str, None]):
+        print(f"Hi {name}!")
+```
+
+`typing` también tiene un atajo para declarar que algo podría ser `None`, con `Optional`.
+
+Aquí va un Consejo desde mi punto de vista muy subjetivo:
+
+* 🚨 Evita usar `Optional[SomeType]`
+* En su lugar ✨ **usa `Union[SomeType, None]`** ✨.
+
+Ambas son equivalentes y por debajo son lo mismo, pero recomendaría `Union` en lugar de `Optional` porque la palabra "**optional**" parecería implicar que el valor es opcional, y en realidad significa "puede ser `None`", incluso si no es opcional y sigue siendo requerido.
+
+Creo que `Union[SomeType, None]` es más explícito respecto a lo que significa.
+
+Se trata solo de palabras y nombres. Pero esas palabras pueden afectar cómo tú y tu equipo piensan sobre el código.
+
+Como ejemplo, tomemos esta función:
+
+```python
+from typing import Optional
+
+
+def say_hi(name: Optional[str]):
+    print(f"Hey {name}!")
+```
+
+El parámetro `name` está definido como `Optional[str]`, pero **no es opcional**, no puedes llamar a la función sin el parámetro:
+
+```Python
+say_hi()  # ¡Oh, no, esto lanza un error! 😱
+```
+
+El parámetro `name` **sigue siendo requerido** (no es *opcional*) porque no tiene un valor por defecto. Aun así, `name` acepta `None` como valor:
+
+```Python
+say_hi(name=None)  # Esto funciona, None es válido 🎉
+```
+
+La buena noticia es que, en la mayoría de los casos, podrás simplemente usar `|` para definir uniones de tipos:
+
+```python
+def say_hi(name: str | None):
+    print(f"Hey {name}!")
+```
+
+Así que, normalmente no tienes que preocuparte por nombres como `Optional` y `Union`. 😎
index 4627e9bd18d4c576098554bf00f5878c50c6526b..3485536cef6b67739cfbbae7e8c944f0e2ad7600 100644 (file)
@@ -32,11 +32,11 @@ Para un ejemplo simple, consideremos una estructura de archivos similar a la des
 
 El archivo `main.py` tendría:
 
-{* ../../docs_src/async_tests/app_a_py39/main.py *}
+{* ../../docs_src/async_tests/app_a_py310/main.py *}
 
 El archivo `test_main.py` tendría los tests para `main.py`, podría verse así ahora:
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
 
 ## Ejecútalo { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 El marcador `@pytest.mark.anyio` le dice a pytest que esta función de test debe ser llamada asíncronamente:
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
 
 /// tip | Consejo
 
@@ -66,7 +66,7 @@ Nota que la función de test ahora es `async def` en lugar de solo `def` como an
 
 Luego podemos crear un `AsyncClient` con la app y enviar requests asíncronos a ella, usando `await`.
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
 
 Esto es equivalente a:
 
index f81c16ee812211a5ff8eb0981a5df5fc03909249..40729ee03d7e07cb335f356696234eeda6212dc0 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 Por ejemplo, digamos que defines una *path operation* `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
 
 Si el cliente intenta ir a `/items`, por defecto, sería redirigido a `/items/`.
 
@@ -115,7 +115,7 @@ En este caso, el path original `/app` realmente sería servido en `/api/v1/app`.
 
 Aunque todo tu código esté escrito asumiendo que solo existe `/app`.
 
-{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
 
 Y el proxy estaría **"eliminando"** el **prefijo del path** sobre la marcha antes de transmitir el request al servidor de aplicaciones (probablemente Uvicorn a través de FastAPI CLI), manteniendo a tu aplicación convencida de que está siendo servida en `/app`, así que no tienes que actualizar todo tu código para incluir el prefijo `/api/v1`.
 
@@ -193,7 +193,7 @@ Puedes obtener el `root_path` actual utilizado por tu aplicación para cada requ
 
 Aquí lo estamos incluyendo en el mensaje solo con fines de demostración.
 
-{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
 
 Luego, si inicias Uvicorn con:
 
@@ -220,7 +220,7 @@ El response sería algo como:
 
 Alternativamente, si no tienes una forma de proporcionar una opción de línea de comandos como `--root-path` o su equivalente, puedes configurar el parámetro `root_path` al crear tu app de FastAPI:
 
-{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
 
 Pasar el `root_path` a `FastAPI` sería el equivalente a pasar la opción de línea de comandos `--root-path` a Uvicorn o Hypercorn.
 
@@ -400,7 +400,7 @@ Si pasas una lista personalizada de `servers` y hay un `root_path` (porque tu AP
 
 Por ejemplo:
 
-{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
 
 Generará un esquema de OpenAPI como:
 
@@ -455,7 +455,7 @@ Si no especificas el parámetro `servers` y `root_path` es igual a `/`, la propi
 
 Si no quieres que **FastAPI** incluya un server automático usando el `root_path`, puedes usar el parámetro `root_path_in_servers=False`:
 
-{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
 
 y entonces no lo incluirá en el esquema de OpenAPI.
 
index 0884c41a7473d41c12cdc3724b27d476fcf355ae..a58f290d6ea7788734f6b39d50af1c8ec4033e79 100644 (file)
@@ -30,7 +30,7 @@ Esto se debe a que, por defecto, FastAPI inspeccionará cada elemento dentro y s
 
 Pero si estás seguro de que el contenido que estás devolviendo es **serializable con JSON**, puedes pasarlo directamente a la clase de response y evitar la sobrecarga extra que FastAPI tendría al pasar tu contenido de retorno a través de `jsonable_encoder` antes de pasarlo a la clase de response.
 
-{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
 
 /// info | Información
 
@@ -55,7 +55,7 @@ Para devolver un response con HTML directamente desde **FastAPI**, usa `HTMLResp
 * Importa `HTMLResponse`.
 * Pasa `HTMLResponse` como parámetro `response_class` de tu *path operation decorator*.
 
-{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
 
 /// info | Información
 
@@ -73,7 +73,7 @@ Como se ve en [Devolver una Response directamente](response-directly.md){.intern
 
 El mismo ejemplo de arriba, devolviendo una `HTMLResponse`, podría verse así:
 
-{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
 
 /// warning | Advertencia
 
@@ -97,7 +97,7 @@ El `response_class` solo se usará para documentar el OpenAPI *path operation*,
 
 Por ejemplo, podría ser algo así:
 
-{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
 
 En este ejemplo, la función `generate_html_response()` ya genera y devuelve una `Response` en lugar de devolver el HTML en un `str`.
 
@@ -136,7 +136,7 @@ Acepta los siguientes parámetros:
 
 FastAPI (de hecho Starlette) incluirá automáticamente un header Content-Length. También incluirá un header Content-Type, basado en el `media_type` y añadiendo un conjunto de caracteres para tipos de texto.
 
-{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ Toma algún texto o bytes y devuelve un response HTML, como leíste arriba.
 
 Toma algún texto o bytes y devuelve un response de texto plano.
 
-{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ Esto requiere instalar `ujson`, por ejemplo, con `pip install ujson`.
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
 
 /// tip | Consejo
 
@@ -194,15 +194,15 @@ Devuelve una redirección HTTP. Usa un código de estado 307 (Redirección Tempo
 
 Puedes devolver un `RedirectResponse` directamente:
 
-{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
 
 ---
 
 O puedes usarlo en el parámetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
 
-Si haces eso, entonces puedes devolver la URL directamente desde tu *path operation function*.
+Si haces eso, entonces puedes devolver la URL directamente desde tu *path operation* function.
 
 En este caso, el `status_code` utilizado será el por defecto para `RedirectResponse`, que es `307`.
 
@@ -210,13 +210,13 @@ En este caso, el `status_code` utilizado será el por defecto para `RedirectResp
 
 También puedes usar el parámetro `status_code` combinado con el parámetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Toma un generador `async` o un generador/iterador normal y transmite el cuerpo del response.
 
-{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
 
 #### Usando `StreamingResponse` con objetos similares a archivos { #using-streamingresponse-with-file-like-objects }
 
@@ -226,7 +226,7 @@ De esa manera, no tienes que leerlo todo primero en memoria, y puedes pasar esa
 
 Esto incluye muchos paquetes para interactuar con almacenamiento en la nube, procesamiento de video y otros.
 
-{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
 
 1. Esta es la función generadora. Es una "función generadora" porque contiene declaraciones `yield` dentro.
 2. Al usar un bloque `with`, nos aseguramos de que el objeto similar a un archivo se cierre después de que la función generadora termine. Así, después de que termina de enviar el response.
@@ -255,11 +255,11 @@ Toma un conjunto diferente de argumentos para crear un instance que los otros ti
 
 Los responses de archivos incluirán los headers apropiados `Content-Length`, `Last-Modified` y `ETag`.
 
-{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
 
 También puedes usar el parámetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
 
 En este caso, puedes devolver la path del archivo directamente desde tu *path operation* function.
 
@@ -273,7 +273,7 @@ Digamos que quieres que devuelva JSON con sangría y formato, por lo que quieres
 
 Podrías crear un `CustomORJSONResponse`. Lo principal que tienes que hacer es crear un método `Response.render(content)` que devuelva el contenido como `bytes`:
 
-{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
 
 Ahora en lugar de devolver:
 
@@ -299,7 +299,7 @@ El parámetro que define esto es `default_response_class`.
 
 En el ejemplo a continuación, **FastAPI** usará `ORJSONResponse` por defecto, en todas las *path operations*, en lugar de `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
 
 /// tip | Consejo
 
index 3a07482ad1596d5ac3429520db7be4238486a888..d586d3a270355ddf375dba467e6c2e63ce76605b 100644 (file)
@@ -64,7 +64,7 @@ En ese caso, simplemente puedes intercambiar los `dataclasses` estándar con `py
 
 6. Aquí estamos regresando un diccionario que contiene `items`, que es una lista de dataclasses.
 
-    FastAPI todavía es capaz de <abbr title="convertir los datos a un formato que pueda transmitirse">serializar</abbr> los datos a JSON.
+    FastAPI todavía es capaz de <dfn title="convertir los datos a un formato que pueda transmitirse">serializar</dfn> los datos a JSON.
 
 7. Aquí el `response_model` está usando una anotación de tipo de una lista de dataclasses `Author`.
 
index c2002a6f5334effaec09fae528ff15e5a237140e..4adb464d3baed77b1d14f42f3cf12c84a969527b 100644 (file)
@@ -30,7 +30,7 @@ Comencemos con un ejemplo y luego veámoslo en detalle.
 
 Creamos una función asíncrona `lifespan()` con `yield` así:
 
-{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
 
 Aquí estamos simulando la operación costosa de *startup* de cargar el modelo poniendo la función del (falso) modelo en el diccionario con modelos de machine learning antes del `yield`. Este código será ejecutado **antes** de que la aplicación **comience a tomar requests**, durante el *startup*.
 
@@ -48,7 +48,7 @@ Quizás necesites iniciar una nueva versión, o simplemente te cansaste de ejecu
 
 Lo primero que hay que notar es que estamos definiendo una función asíncrona con `yield`. Esto es muy similar a las Dependencias con `yield`.
 
-{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
 
 La primera parte de la función, antes del `yield`, será ejecutada **antes** de que la aplicación comience.
 
@@ -60,7 +60,7 @@ Si revisas, la función está decorada con un `@asynccontextmanager`.
 
 Eso convierte a la función en algo llamado un "**async context manager**".
 
-{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
 
 Un **context manager** en Python es algo que puedes usar en un statement `with`, por ejemplo, `open()` puede ser usado como un context manager:
 
@@ -82,7 +82,7 @@ En nuestro ejemplo de código arriba, no lo usamos directamente, pero se lo pasa
 
 El parámetro `lifespan` de la app de `FastAPI` toma un **async context manager**, por lo que podemos pasar nuestro nuevo `lifespan` async context manager a él.
 
-{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
 
 ## Eventos Alternativos (obsoleto) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ Estas funciones pueden ser declaradas con `async def` o `def` normal.
 
 Para añadir una función que debería ejecutarse antes de que la aplicación inicie, declárala con el evento `"startup"`:
 
-{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
 
 En este caso, la función manejadora del evento `startup` inicializará los ítems de la "base de datos" (solo un `dict`) con algunos valores.
 
@@ -116,7 +116,7 @@ Y tu aplicación no comenzará a recibir requests hasta que todos los manejadore
 
 Para añadir una función que debería ejecutarse cuando la aplicación se esté cerrando, declárala con el evento `"shutdown"`:
 
-{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
 
 Aquí, la función manejadora del evento `shutdown` escribirá una línea de texto `"Application shutdown"` a un archivo `log.txt`.
 
index daf6cefed3fa4ce49a2659df922be7b7dd4e4dc3..a079c41aa5f9660f441fea67a474f60dc1729155 100644 (file)
@@ -2,7 +2,7 @@
 
 Como **FastAPI** está basado en la especificación **OpenAPI**, sus APIs se pueden describir en un formato estándar que muchas herramientas entienden.
 
-Esto facilita generar **documentación** actualizada, paquetes de cliente (<abbr title="Software Development Kits  Kits de Desarrollo de Software">**SDKs**</abbr>) en múltiples lenguajes y **escribir pruebas** o **flujos de automatización** que se mantengan sincronizados con tu código.
+Esto facilita generar **documentación** actualizada, paquetes de cliente (<abbr title="Software Development Kits - Kits de Desarrollo de Software">**SDKs**</abbr>) en múltiples lenguajes y **escribir pruebas** o **flujos de automatización** que se mantengan sincronizados con tu código.
 
 En esta guía, aprenderás a generar un **SDK de TypeScript** para tu backend con FastAPI.
 
@@ -40,7 +40,7 @@ Algunas de estas soluciones también pueden ser open source u ofrecer niveles gr
 
 Empecemos con una aplicación simple de FastAPI:
 
-{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
+{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
 
 Nota que las *path operations* definen los modelos que usan para el payload del request y el payload del response, usando los modelos `Item` y `ResponseMessage`.
 
@@ -98,7 +98,7 @@ En muchos casos tu app de FastAPI será más grande, y probablemente usarás tag
 
 Por ejemplo, podrías tener una sección para **items** y otra sección para **users**, y podrían estar separadas por tags:
 
-{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
+{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
 
 ### Genera un Cliente TypeScript con tags { #generate-a-typescript-client-with-tags }
 
@@ -145,7 +145,7 @@ Por ejemplo, aquí está usando el primer tag (probablemente tendrás solo un ta
 
 Puedes entonces pasar esa función personalizada a **FastAPI** como el parámetro `generate_unique_id_function`:
 
-{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
+{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
 
 ### Genera un Cliente TypeScript con operation IDs personalizados { #generate-a-typescript-client-with-custom-operation-ids }
 
@@ -167,7 +167,7 @@ Pero para el cliente generado podríamos **modificar** los operation IDs de Open
 
 Podríamos descargar el JSON de OpenAPI a un archivo `openapi.json` y luego podríamos **remover ese tag prefijado** con un script como este:
 
-{* ../../docs_src/generate_clients/tutorial004_py39.py *}
+{* ../../docs_src/generate_clients/tutorial004_py310.py *}
 
 //// tab | Node.js
 
index 7eead8ae14590f2ed9ae859297622c139ec5c9e5..ed582c465540442d40038f518e334d2e5d5526c8 100644 (file)
@@ -8,7 +8,7 @@ En esta sección veremos cómo usar otros middlewares.
 
 ## Agregando middlewares ASGI { #adding-asgi-middlewares }
 
-Como **FastAPI** está basado en Starlette e implementa la especificación <abbr title="Asynchronous Server Gateway Interface  Interfaz de puerta de enlace de servidor asíncrona">ASGI</abbr>, puedes usar cualquier middleware ASGI.
+Como **FastAPI** está basado en Starlette e implementa la especificación <abbr title="Asynchronous Server Gateway Interface - Interfaz de puerta de enlace de servidor asíncrona">ASGI</abbr>, puedes usar cualquier middleware ASGI.
 
 Un middleware no tiene que estar hecho para FastAPI o Starlette para funcionar, siempre que siga la especificación ASGI.
 
@@ -57,13 +57,13 @@ Impone que todas las requests entrantes deben ser `https` o `wss`.
 
 Cualquier request entrante a `http` o `ws` será redirigida al esquema seguro.
 
-{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Impone que todas las requests entrantes tengan correctamente configurado el header `Host`, para proteger contra ataques de HTTP Host Header.
 
-{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
 
 Se soportan los siguientes argumentos:
 
@@ -78,7 +78,7 @@ Maneja responses GZip para cualquier request que incluya `"gzip"` en el header `
 
 El middleware manejará tanto responses estándar como en streaming.
 
-{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
 
 Se soportan los siguientes argumentos:
 
index c358a140086f8f2d191559deba2bb78a91742826..4f657ad53e7972e5749803a8d23c778f83a48055 100644 (file)
@@ -32,7 +32,7 @@ Los webhooks están disponibles en OpenAPI 3.1.0 y superiores, soportados por Fa
 
 Cuando creas una aplicación de **FastAPI**, hay un atributo `webhooks` que puedes usar para definir *webhooks*, de la misma manera que definirías *path operations*, por ejemplo con `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
 
 Los webhooks que defines terminarán en el esquema de **OpenAPI** y en la interfaz automática de **documentación**.
 
index ea58a300adf27d59a2a96477dfde143edb035ba4..0ba586c1c1ff419b5a9422af9b1d43e784de9709 100644 (file)
@@ -12,7 +12,7 @@ Puedes establecer el `operationId` de OpenAPI para ser usado en tu *path operati
 
 Tendrías que asegurarte de que sea único para cada operación.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
 
 ### Usar el nombre de la *path operation function* como el operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@ Si quieres usar los nombres de las funciones de tus APIs como `operationId`s, pu
 
 Deberías hacerlo después de agregar todas tus *path operations*.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
 
 /// tip | Consejo
 
@@ -40,7 +40,7 @@ Incluso si están en diferentes módulos (archivos de Python).
 
 Para excluir una *path operation* del esquema OpenAPI generado (y por lo tanto, de los sistemas de documentación automática), utiliza el parámetro `include_in_schema` y configúralo en `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
 
 ## Descripción avanzada desde el docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@ Puedes extender el esquema de OpenAPI para una *path operation* usando el parám
 
 Este `openapi_extra` puede ser útil, por ejemplo, para declarar [Extensiones de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
 
 Si abres la documentación automática de la API, tu extensión aparecerá en la parte inferior de la *path operation* específica.
 
@@ -139,9 +139,9 @@ Por ejemplo, podrías decidir leer y validar el request con tu propio código, s
 
 Podrías hacer eso con `openapi_extra`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
 
-En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el request body ni siquiera se <abbr title="converted from some plain format, like bytes, into Python objects - convertido de algún formato plano, como bytes, a objetos de Python">parse</abbr> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
+En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el request body ni siquiera es <dfn title="convertido desde algún formato plano, como bytes, a objetos de Python">parseado</dfn> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
 
 Sin embargo, podemos declarar el esquema esperado para el request body.
 
@@ -153,7 +153,7 @@ Y podrías hacer esto incluso si el tipo de datos en el request no es JSON.
 
 Por ejemplo, en esta aplicación no usamos la funcionalidad integrada de FastAPI para extraer el JSON Schema de los modelos Pydantic ni la validación automática para JSON. De hecho, estamos declarando el tipo de contenido del request como YAML, no JSON:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
 
 Sin embargo, aunque no estamos usando la funcionalidad integrada por defecto, aún estamos usando un modelo Pydantic para generar manualmente el JSON Schema para los datos que queremos recibir en YAML.
 
@@ -161,7 +161,7 @@ Luego usamos el request directamente, y extraemos el cuerpo como `bytes`. Esto s
 
 Y luego en nuestro código, parseamos ese contenido YAML directamente, y nuevamente estamos usando el mismo modelo Pydantic para validar el contenido YAML:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
 
 /// tip | Consejo
 
index 940f1dd3ff6f67c1537b6a4624f4a7642e625610..622001291f1562d91c566302a0676591ffa4cfaa 100644 (file)
@@ -20,9 +20,9 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function*
 
 Y luego puedes establecer el `status_code` en ese objeto de response *temporal*.
 
-{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
 
-Y luego puedes devolver cualquier objeto que necesites, como lo harías normalmente (un `dict`, un modelo de base de datos, etc.).
+Y luego puedes devolver cualquier objeto que necesites, como lo harías normalmente (un `dict`, un modelo de base de datos, etc).
 
 Y si declaraste un `response_model`, todavía se utilizará para filtrar y convertir el objeto que devolviste.
 
index 550a5d97a774760c526b1a1915f7f95fe3e0f65d..e451d8939075a6aeaf4fd6e57eb1d64d361dfabf 100644 (file)
@@ -6,7 +6,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function*
 
 Y luego puedes establecer cookies en ese objeto de response *temporal*.
 
-{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
 
 Y entonces puedes devolver cualquier objeto que necesites, como normalmente lo harías (un `dict`, un modelo de base de datos, etc).
 
@@ -24,7 +24,7 @@ Para hacer eso, puedes crear un response como se describe en [Devolver un Respon
 
 Luego establece Cookies en ella, y luego devuélvela:
 
-{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
 
 /// tip | Consejo
 
index 2da4e84e706f6b60ba74f5e4408b6171a54e54a6..b9b1df447a12816f58cb77d90e291c6dd909797b 100644 (file)
@@ -54,7 +54,7 @@ Digamos que quieres devolver un response en <a href="https://en.wikipedia.org/wi
 
 Podrías poner tu contenido XML en un string, poner eso en un `Response`, y devolverlo:
 
-{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
 ## Notas { #notes }
 
index 9e099bca3d474114eb81e2bf3c17f7a82144f51e..1d16d86a52c61b254186ffb7bf37cc9ca5d9cb8e 100644 (file)
@@ -6,7 +6,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function*
 
 Y luego puedes establecer headers en ese objeto de response *temporal*.
 
-{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
 
 Y luego puedes devolver cualquier objeto que necesites, como harías normalmente (un `dict`, un modelo de base de datos, etc).
 
@@ -22,7 +22,7 @@ También puedes agregar headers cuando devuelves un `Response` directamente.
 
 Crea un response como se describe en [Retorna un Response Directamente](response-directly.md){.internal-link target=_blank} y pasa los headers como un parámetro adicional:
 
-{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
 
 /// note | Detalles Técnicos
 
index 440c081e063a63ebd8ab0071e09193960b364151..d7f181ef802b1db920149a966878b2ca359cdd15 100644 (file)
@@ -20,7 +20,7 @@ Luego, cuando escribes ese nombre de usuario y contraseña, el navegador los env
 * Devuelve un objeto de tipo `HTTPBasicCredentials`:
   * Contiene el `username` y `password` enviados.
 
-{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
+{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
 
 Cuando intentas abrir la URL por primera vez (o haces clic en el botón "Execute" en la documentación) el navegador te pedirá tu nombre de usuario y contraseña:
 
@@ -40,7 +40,7 @@ Para manejar eso, primero convertimos el `username` y `password` a `bytes` codif
 
 Luego podemos usar `secrets.compare_digest()` para asegurar que `credentials.username` es `"stanleyjobson"`, y que `credentials.password` es `"swordfish"`.
 
-{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
+{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
 
 Esto sería similar a:
 
@@ -104,4 +104,4 @@ De esa manera, usando `secrets.compare_digest()` en el código de tu aplicación
 
 Después de detectar que las credenciales son incorrectas, regresa un `HTTPException` con un código de estado 401 (el mismo que se devuelve cuando no se proporcionan credenciales) y agrega el header `WWW-Authenticate` para que el navegador muestre el prompt de inicio de sesión nuevamente:
 
-{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
+{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
index a2d749103eac9c9ce3e7c0af0caa3d24522e7d01..f176dc1f38da63fe43f137ebb373b317cfd82f4c 100644 (file)
@@ -54,7 +54,7 @@ De la misma forma que con los modelos de Pydantic, declaras atributos de clase c
 
 Puedes usar todas las mismas funcionalidades de validación y herramientas que usas para los modelos de Pydantic, como diferentes tipos de datos y validaciones adicionales con `Field()`.
 
-{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
 
 /// tip | Consejo
 
@@ -70,7 +70,7 @@ Luego convertirá y validará los datos. Así que, cuando uses ese objeto `setti
 
 Luego puedes usar el nuevo objeto `settings` en tu aplicación:
 
-{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
 
 ### Ejecutar el servidor { #run-the-server }
 
@@ -104,11 +104,11 @@ Podrías poner esas configuraciones en otro archivo de módulo como viste en [Ap
 
 Por ejemplo, podrías tener un archivo `config.py` con:
 
-{* ../../docs_src/settings/app01_py39/config.py *}
+{* ../../docs_src/settings/app01_py310/config.py *}
 
 Y luego usarlo en un archivo `main.py`:
 
-{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
 
 /// tip | Consejo
 
@@ -126,7 +126,7 @@ Esto podría ser especialmente útil durante las pruebas, ya que es muy fácil s
 
 Proveniente del ejemplo anterior, tu archivo `config.py` podría verse como:
 
-{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
+{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
 
 Nota que ahora no creamos un instance por defecto `settings = Settings()`.
 
@@ -134,7 +134,7 @@ Nota que ahora no creamos un instance por defecto `settings = Settings()`.
 
 Ahora creamos una dependencia que devuelve un nuevo `config.Settings()`.
 
-{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
+{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
 
 /// tip | Consejo
 
@@ -146,13 +146,13 @@ Por ahora puedes asumir que `get_settings()` es una función normal.
 
 Y luego podemos requerirlo desde la *path operation function* como una dependencia y usarlo donde lo necesitemos.
 
-{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
+{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
 
 ### Configuraciones y pruebas { #settings-and-testing }
 
 Luego sería muy fácil proporcionar un objeto de configuraciones diferente durante las pruebas al crear una sobrescritura de dependencia para `get_settings`:
 
-{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
+{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
 
 En la sobrescritura de dependencia establecemos un nuevo valor para el `admin_email` al crear el nuevo objeto `Settings`, y luego devolvemos ese nuevo objeto.
 
@@ -193,7 +193,7 @@ APP_NAME="ChimichangApp"
 
 Y luego actualizar tu `config.py` con:
 
-{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
+{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
 
 /// tip | Consejo
 
@@ -226,7 +226,7 @@ crearíamos ese objeto para cada request, y estaríamos leyendo el archivo `.env
 
 Pero como estamos usando el decorador `@lru_cache` encima, el objeto `Settings` se creará solo una vez, la primera vez que se llame. ✔️
 
-{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
+{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
 
 Entonces, para cualquier llamada subsiguiente de `get_settings()` en las dependencias de los próximos requests, en lugar de ejecutar el código interno de `get_settings()` y crear un nuevo objeto `Settings`, devolverá el mismo objeto que fue devuelto en la primera llamada, una y otra vez.
 
index f604d18bad3f36546b6656630085f8e8591228a0..32d4c7de2a5e42909d594427956440d05c07da91 100644 (file)
@@ -10,7 +10,7 @@ Si necesitas tener dos aplicaciones de **FastAPI** independientes, cada una con
 
 Primero, crea la aplicación principal de nivel superior de **FastAPI**, y sus *path operations*:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
 
 ### Sub-aplicación { #sub-application }
 
@@ -18,7 +18,7 @@ Luego, crea tu sub-aplicación, y sus *path operations*.
 
 Esta sub-aplicación es solo otra aplicación estándar de FastAPI, pero es la que se "montará":
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
 
 ### Montar la sub-aplicación { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@ En tu aplicación de nivel superior, `app`, monta la sub-aplicación, `subapi`.
 
 En este caso, se montará en el path `/subapi`:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
 
 ### Revisa la documentación automática de la API { #check-the-automatic-api-docs }
 
index e5e8fe0613b4ed484350e0bfb2682c378e988d0d..1162d4ce4b5604529ce72abb0095b967bf05ec57 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 * Declara un parámetro `Request` en la *path operation* que devolverá una plantilla.
 * Usa los `templates` que creaste para renderizar y devolver un `TemplateResponse`, pasa el nombre de la plantilla, el objeto de request, y un diccionario "context" con pares clave-valor que se usarán dentro de la plantilla Jinja2.
 
-{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
 
 /// note | Nota
 
@@ -43,7 +43,7 @@ Al declarar `response_class=HTMLResponse`, la interfaz de usuario de la document
 
 ///
 
-/// note | Nota Técnica
+/// note | Detalles técnicos
 
 También podrías usar `from starlette.templating import Jinja2Templates`.
 
index d209f2e401fd82a2149554adc7698c26aa887328..5e85fa1ef70a767bdeac3d1528588ae993650f19 100644 (file)
@@ -14,11 +14,11 @@ Un ejemplo podría ser que tienes un proveedor de autenticación externo al que
 
 Le envías un token y te devuelve un usuario autenticado.
 
-Este proveedor podría estar cobrándote por cada request, y llamarlo podría tomar más tiempo adicional que si tuvieras un usuario de prueba fijo para los tests.
+Este proveedor podría estar cobrándote por cada request, y llamarlo podría tomar más tiempo adicional que si tuvieras un usuario mock fijo para los tests.
 
 Probablemente quieras probar el proveedor externo una vez, pero no necesariamente llamarlo para cada test que se realice.
 
-En este caso, puedes sobrescribir la dependencia que llama a ese proveedor y usar una dependencia personalizada que devuelva un usuario de prueba, solo para tus tests.
+En este caso, puedes sobrescribir la dependencia que llama a ese proveedor y usar una dependencia personalizada que devuelva un usuario mock, solo para tus tests.
 
 ### Usa el atributo `app.dependency_overrides` { #use-the-app-dependency-overrides-attribute }
 
@@ -40,7 +40,7 @@ FastAPI todavía podrá sobrescribirla.
 
 ///
 
-Entonces puedes restablecer las dependencias sobreescritas configurando `app.dependency_overrides` para que sea un `dict` vacío:
+Entonces puedes restablecer las dependencias sobreescritas (eliminarlas) configurando `app.dependency_overrides` para que sea un `dict` vacío:
 
 ```Python
 app.dependency_overrides = {}
index 4f7bf0314795371af458069ab702e9c0d73b26a2..1ab94581240ba3e9bcf2b482f0ccab7d855c336c 100644 (file)
@@ -2,11 +2,11 @@
 
 Cuando necesitas que `lifespan` se ejecute en tus tests, puedes usar el `TestClient` con un statement `with`:
 
-{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../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)
 
 Para los eventos obsoletos `startup` y `shutdown`, puedes usar el `TestClient` así:
 
-{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}
index 3f60aa2caf35d7d48a84acd2ee76e8b11d9bfe95..89ef2d5a4b69188e24c212e8820833b2bc549b4a 100644 (file)
@@ -4,7 +4,7 @@ Puedes usar el mismo `TestClient` para probar WebSockets.
 
 Para esto, usas el `TestClient` en un statement `with`, conectándote al WebSocket:
 
-{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
 
 /// note | Nota
 
index 64feef81d73bf5e6e0f8f224eaf563e96706ee77..4a063d29708a29f4550e93a614a927baa2c4bb62 100644 (file)
@@ -29,7 +29,7 @@ Imaginemos que quieres obtener la dirección IP/host del cliente dentro de tu *p
 
 Para eso necesitas acceder al request directamente.
 
-{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
 
 Al declarar un parámetro de *path operation function* con el tipo siendo `Request`, **FastAPI** sabrá pasar el `Request` en ese parámetro.
 
index 39ddc12c4d10abbcbe0dfaa1d5d99e17dfaef35c..2a7fed6c593a488e5e239f3ec2b15a62d4626c2b 100644 (file)
@@ -38,13 +38,13 @@ En producción tendrías una de las opciones anteriores.
 
 Pero es la forma más sencilla de enfocarse en el lado del servidor de WebSockets y tener un ejemplo funcional:
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
 
 ## Crear un `websocket` { #create-a-websocket }
 
 En tu aplicación de **FastAPI**, crea un `websocket`:
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
 
 /// note | Detalles Técnicos
 
@@ -58,7 +58,7 @@ También podrías usar `from starlette.websockets import WebSocket`.
 
 En tu ruta de WebSocket puedes `await` para recibir mensajes y enviar mensajes.
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
 
 Puedes recibir y enviar datos binarios, de texto y JSON.
 
@@ -154,7 +154,7 @@ Con eso puedes conectar el WebSocket y luego enviar y recibir mensajes:
 
 Cuando una conexión de WebSocket se cierra, el `await websocket.receive_text()` lanzará una excepción `WebSocketDisconnect`, que puedes capturar y manejar como en este ejemplo.
 
-{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
+{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
 
 Para probarlo:
 
index ae31185eefe89803abfa588d48d4e80f417c74ea..05322a4d1e613068352b2c3a75ad5311393a7d59 100644 (file)
@@ -18,7 +18,7 @@ Luego envuelve la aplicación WSGI (p. ej., Flask) con el middleware.
 
 Y luego móntala bajo un path.
 
-{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
+{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
 
 /// note | Nota
 
index 6dd5933b03be1a6197a67fae6b27f7b2256199bb..cc9309dd2fc74a4432d5ac195d2b562817c220c9 100644 (file)
@@ -20,7 +20,7 @@ Es el framework más popular de Python y es ampliamente confiable. Se utiliza pa
 
 Está relativamente acoplado con bases de datos relacionales (como MySQL o PostgreSQL), por lo que tener una base de datos NoSQL (como Couchbase, MongoDB, Cassandra, etc) como motor de almacenamiento principal no es muy fácil.
 
-Fue creado para generar el HTML en el backend, no para crear APIs utilizadas por un frontend moderno (como React, Vue.js y Angular) o por otros sistemas (como dispositivos del <abbr title="Internet of Things  Internet de las cosas">IoT</abbr>) comunicándose con él.
+Fue creado para generar el HTML en el backend, no para crear APIs utilizadas por un frontend moderno (como React, Vue.js y Angular) o por otros sistemas (como dispositivos del <abbr title="Internet of Things - Internet de las cosas">IoT</abbr>) comunicándose con él.
 
 ### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
 
@@ -76,7 +76,7 @@ Aun así, FastAPI se inspiró bastante en Requests.
 
 Están, más o menos, en extremos opuestos, complementándose entre sí.
 
-Requests tiene un diseño muy simple e intuitivo, es muy fácil de usar, con valores predeterminados sensatos. Pero al mismo tiempo, es muy poderoso y personalizable.
+Requests tiene un diseño muy simple e intuitivo, es muy fácil de usar, con valores por defecto sensatos. Pero al mismo tiempo, es muy poderoso y personalizable.
 
 Por eso, como se dice en el sitio web oficial:
 
@@ -102,7 +102,7 @@ Mira las similitudes entre `requests.get(...)` y `@app.get(...)`.
 
 * Tener un API simple e intuitivo.
 * Usar nombres de métodos HTTP (operaciones) directamente, de una manera sencilla e intuitiva.
-* Tener valores predeterminados sensatos, pero personalizaciones poderosas.
+* Tener valores por defecto sensatos, pero personalizaciones poderosas.
 
 ///
 
@@ -137,7 +137,7 @@ Existen varios frameworks REST para Flask, pero después de invertir tiempo y tr
 
 ### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
 
-Una de las principales funcionalidades necesitadas por los sistemas API es la "<abbr title="también llamada marshalling, conversión">serialización</abbr>" de datos, que consiste en tomar datos del código (Python) y convertirlos en algo que pueda ser enviado a través de la red. Por ejemplo, convertir un objeto que contiene datos de una base de datos en un objeto JSON. Convertir objetos `datetime` en strings, etc.
+Una de las principales funcionalidades necesitadas por los sistemas API es la "<dfn title="también llamado marshalling, conversión">serialización</dfn>" de datos, que consiste en tomar datos del código (Python) y convertirlos en algo que pueda ser enviado a través de la red. Por ejemplo, convertir un objeto que contiene datos de una base de datos en un objeto JSON. Convertir objetos `datetime` en strings, etc.
 
 Otra gran funcionalidad necesaria por las APIs es la validación de datos, asegurarse de que los datos sean válidos, dados ciertos parámetros. Por ejemplo, que algún campo sea un `int`, y no algún string aleatorio. Esto es especialmente útil para los datos entrantes.
 
@@ -145,7 +145,7 @@ Sin un sistema de validación de datos, tendrías que hacer todas las comprobaci
 
 Estas funcionalidades son para lo que fue creado Marshmallow. Es un gran paquete, y lo he usado mucho antes.
 
-Pero fue creado antes de que existieran las anotaciones de tipos en Python. Así que, para definir cada <abbr title="la definición de cómo deberían formarse los datos">esquema</abbr> necesitas usar utilidades y clases específicas proporcionadas por Marshmallow.
+Pero fue creado antes de que existieran las anotaciones de tipos en Python. Así que, para definir cada <dfn title="la definición de cómo deberían formarse los datos">esquema</dfn> necesitas usar utilidades y clases específicas proporcionadas por Marshmallow.
 
 /// check | Inspiró a **FastAPI** a
 
@@ -155,7 +155,7 @@ Usar código para definir "esquemas" que proporcionen tipos de datos y validaci
 
 ### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
 
-Otra gran funcionalidad requerida por las APIs es el <abbr title="lectura y conversión a datos de Python">parse</abbr> de datos de las requests entrantes.
+Otra gran funcionalidad requerida por las APIs es el <dfn title="lectura y conversión a datos de Python">parsing</dfn> de datos de las requests entrantes.
 
 Webargs es una herramienta que fue creada para proporcionar esa funcionalidad sobre varios frameworks, incluido Flask.
 
@@ -177,7 +177,7 @@ Tener validación automática de datos entrantes en una request.
 
 ### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
 
-Marshmallow y Webargs proporcionan validación, parse y serialización como plug-ins.
+Marshmallow y Webargs proporcionan validación, parsing y serialización como plug-ins.
 
 Pero la documentación todavía falta. Entonces APISpec fue creado.
 
@@ -419,7 +419,7 @@ Manejar toda la validación de datos, serialización de datos y documentación a
 
 ### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
 
-Starlette es un framework/toolkit <abbr title="The new standard for building asynchronous Python web applications – El nuevo estándar para construir aplicaciones web asíncronas en Python">ASGI</abbr> liviano, ideal para construir servicios asyncio de alto rendimiento.
+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.
 
 Es muy simple e intuitivo. Está diseñado para ser fácilmente extensible y tener componentes modulares.
 
index a1c8f0fb9d382618dcec9899a64c3360afa53130..a06d3e979d50f54817b508eb0de1ada0b2023a30 100644 (file)
@@ -4,7 +4,7 @@ Detalles sobre la sintaxis `async def` para *path operation functions* y algunos
 
 ## ¿Con prisa? { #in-a-hurry }
 
-<abbr title="too long; didn't read"><strong>TL;DR:</strong></abbr>
+<abbr title="too long; didn't read - demasiado largo; no lo leí"><strong>TL;DR:</strong></abbr>
 
 Si estás usando paquetes de terceros que te dicen que los llames con `await`, como:
 
@@ -74,7 +74,7 @@ Luego la computadora / programa 🤖 volverá cada vez que tenga una oportunidad
 
 Después, 🤖 toma la primera tarea que termine (digamos, nuestro "archivo-lento" 📝) y continúa con lo que tenía que hacer con ella.
 
-Ese "esperar otra cosa" normalmente se refiere a las operaciones de <abbr title="Input and Output  Entrada y salida">I/O</abbr> que son relativamente "lentas" (comparadas con la velocidad del procesador y la memoria RAM), como esperar:
+Ese "esperar otra cosa" normalmente se refiere a las operaciones de <abbr title="Input and Output - Entrada y salida">I/O</abbr> que son relativamente "lentas" (comparadas con la velocidad del procesador y la memoria RAM), como esperar:
 
 * que los datos del cliente se envíen a través de la red
 * que los datos enviados por tu programa sean recibidos por el cliente a través de la red
@@ -85,7 +85,7 @@ Ese "esperar otra cosa" normalmente se refiere a las operaciones de <abbr title=
 * que una query de base de datos devuelva los resultados
 * etc.
 
-Como el tiempo de ejecución se consume principalmente esperando operaciones de <abbr title="Input and Output  Entrada y salida">I/O</abbr>, las llaman operaciones "I/O bound".
+Como el tiempo de ejecución se consume principalmente esperando operaciones de <abbr title="Input and Output - Entrada y salida">I/O</abbr>, las llaman operaciones "I/O bound".
 
 Se llama "asíncrono" porque la computadora / programa no tiene que estar "sincronizado" con la tarea lenta, esperando el momento exacto en que la tarea termine, sin hacer nada, para poder tomar el resultado de la tarea y continuar el trabajo.
 
@@ -277,7 +277,7 @@ Pero en este caso, si pudieras traer a los 8 ex-cajeros/cocineros/ahora-limpiado
 
 En este escenario, cada uno de los limpiadores (incluyéndote) sería un procesador, haciendo su parte del trabajo.
 
-Y como la mayor parte del tiempo de ejecución se dedica al trabajo real (en lugar de esperar), y el trabajo en una computadora lo realiza una <abbr title="Central Processing Unit  Unidad Central de Procesamiento">CPU</abbr>, llaman a estos problemas "CPU bound".
+Y como la mayor parte del tiempo de ejecución se dedica al trabajo real (en lugar de esperar), y el trabajo en una computadora lo realiza una <abbr title="Central Processing Unit - Unidad Central de Procesamiento">CPU</abbr>, llaman a estos problemas "CPU bound".
 
 ---
 
@@ -417,7 +417,7 @@ Si tienes bastante conocimiento técnico (coroutines, hilos, bloqueo, etc.) y ti
 
 Cuando declaras una *path operation function* con `def` normal en lugar de `async def`, se ejecuta en un threadpool externo que luego es esperado, en lugar de ser llamado directamente (ya que bloquearía el servidor).
 
-Si vienes de otro framework async que no funciona de la manera descrita anteriormente y estás acostumbrado a definir funciones de *path operation* solo de cómputo trivial con `def` normal para una pequeña ganancia de rendimiento (alrededor de 100 nanosegundos), ten en cuenta que en **FastAPI** el efecto sería bastante opuesto. En estos casos, es mejor usar `async def` a menos que tus *path operation functions* usen código que realice <abbr title="Input/Output  Entrada/Salida: lectura o escritura en disco, comunicaciones de red.">I/O</abbr> de bloqueo.
+Si vienes de otro framework async que no funciona de la manera descrita anteriormente y estás acostumbrado a definir funciones de *path operation* solo de cómputo trivial con `def` normal para una pequeña ganancia de rendimiento (alrededor de 100 nanosegundos), ten en cuenta que en **FastAPI** el efecto sería bastante opuesto. En estos casos, es mejor usar `async def` a menos que tus *path operation functions* usen código que realice <abbr title="Input/Output - Entrada/Salida: lectura o escritura en disco, comunicaciones de red.">I/O</abbr> de bloqueo.
 
 Aun así, en ambas situaciones, es probable que **FastAPI** [siga siendo más rápida](index.md#performance){.internal-link target=_blank} que (o al menos comparable a) tu framework anterior.
 
index f3c951d9892e674cf2899930a537a72185ceda36..a3531b97a743553872496e2b654974099b2568f9 100644 (file)
@@ -10,7 +10,7 @@ En la mayoría de los casos, los principales proveedores de nube tienen guías p
 
 Simplifica el proceso de **construir**, **desplegar** y **acceder** a una API con un esfuerzo mínimo.
 
-Trae la misma experiencia de desarrollador de construir aplicaciones con FastAPI a desplegarlas en la nube. 🎉
+Trae la misma **experiencia de desarrollador** de construir aplicaciones con FastAPI a **desplegarlas** en la nube. 🎉
 
 FastAPI Cloud es el sponsor principal y proveedor de financiamiento de los proyectos open source *FastAPI and friends*. ✨
 
index c42ced70bca01ae5612bd5161a0cdb6ed548ba10..2ec7af19ba78db0d95e0b9d48f523d0240db704e 100644 (file)
@@ -318,4 +318,4 @@ Has estado leyendo aquí algunos de los conceptos principales que probablemente
 
 Comprender estas ideas y cómo aplicarlas debería darte la intuición necesaria para tomar decisiones al configurar y ajustar tus implementaciones. 🤓
 
-En las próximas secciones, te daré ejemplos más concretos de posibles estrategias que puedes seguir. 🚀
+En las próximas secciones, te daré más ejemplos concretos de posibles estrategias que puedes seguir. 🚀
index 9a0b88955913f5897cde85fc724019cde131f797..105a5902b7d07917df349c664d664cc16f0c5824 100644 (file)
@@ -14,7 +14,7 @@ Usar contenedores de Linux tiene varias ventajas, incluyendo **seguridad**, **re
 <summary>Vista previa del Dockerfile 👀</summary>
 
 ```Dockerfile
-FROM python:3.9
+FROM python:3.14
 
 WORKDIR /code
 
@@ -166,7 +166,7 @@ Ahora, en el mismo directorio del proyecto, crea un archivo `Dockerfile` con:
 
 ```{ .dockerfile .annotate }
 # (1)!
-FROM python:3.9
+FROM python:3.14
 
 # (2)!
 WORKDIR /code
@@ -390,7 +390,7 @@ Si tu FastAPI es un solo archivo, por ejemplo, `main.py` sin un directorio `./ap
 Entonces solo tendrías que cambiar las rutas correspondientes para copiar el archivo dentro del `Dockerfile`:
 
 ```{ .dockerfile .annotate hl_lines="10  13" }
-FROM python:3.9
+FROM python:3.14
 
 WORKDIR /code
 
@@ -454,7 +454,7 @@ Sin usar contenedores, hacer que las aplicaciones se ejecuten al inicio y con re
 
 ## Replicación - Número de Procesos { #replication-number-of-processes }
 
-Si tienes un <abbr title="Un grupo de máquinas que están configuradas para estar conectadas y trabajar juntas de alguna manera.">cluster</abbr> de máquinas con **Kubernetes**, Docker Swarm Mode, Nomad, u otro sistema complejo similar para gestionar contenedores distribuidos en varias máquinas, entonces probablemente querrás manejar la **replicación** a nivel de **cluster** en lugar de usar un **gestor de procesos** (como Uvicorn con workers) en cada contenedor.
+Si tienes un <dfn title="Un grupo de máquinas que están configuradas para estar conectadas y trabajar juntas de alguna manera.">clúster</dfn> de máquinas con **Kubernetes**, Docker Swarm Mode, Nomad, u otro sistema complejo similar para gestionar contenedores distribuidos en varias máquinas, entonces probablemente querrás manejar la **replicación** a nivel de **cluster** en lugar de usar un **gestor de procesos** (como Uvicorn con workers) en cada contenedor.
 
 Uno de esos sistemas de gestión de contenedores distribuidos como Kubernetes normalmente tiene alguna forma integrada de manejar la **replicación de contenedores** mientras aún soporta el **load balancing** para las requests entrantes. Todo a nivel de **cluster**.
 
@@ -499,7 +499,7 @@ Por supuesto, hay **casos especiales** donde podrías querer tener **un contened
 En esos casos, puedes usar la opción de línea de comandos `--workers` para establecer el número de workers que deseas ejecutar:
 
 ```{ .dockerfile .annotate }
-FROM python:3.9
+FROM python:3.14
 
 WORKDIR /code
 
index af3e7ce6809002b7fd496a3a76c8696c63b61088..9763af48c52cdfe161282239366c6baf3720e648 100644 (file)
@@ -1,6 +1,6 @@
 # FastAPI Cloud { #fastapi-cloud }
 
-Puedes desplegar tu app de FastAPI en <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> con un solo comando; ve y únete a la lista de espera si aún no lo has hecho. 🚀
+Puedes desplegar tu app de FastAPI en <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> con **un solo comando**; ve y únete a la lista de espera si aún no lo has hecho. 🚀
 
 ## Iniciar sesión { #login }
 
@@ -20,7 +20,7 @@ You are logged in to FastAPI Cloud 🚀
 
 ## Desplegar { #deploy }
 
-Ahora despliega tu app, con un solo comando:
+Ahora despliega tu app, con **un solo comando**:
 
 <div class="termy">
 
index e62bf8b153e3b4ec2e26ae4c3d1360c0aa0c31bc..d7a244107c17955fb60fefa14ef0f0abf7956a37 100644 (file)
@@ -65,7 +65,7 @@ Aquí tienes un ejemplo de cómo podría ser una API HTTPS, paso a paso, prestan
 
 Probablemente todo comenzaría adquiriendo un **nombre de dominio**. Luego, lo configurarías en un servidor DNS (posiblemente tu mismo proveedor de la nube).
 
-Probablemente conseguirías un servidor en la nube (una máquina virtual) o algo similar, y tendría una **dirección IP pública** <abbr title="Que no cambia">fija</abbr>.
+Probablemente conseguirías un servidor en la nube (una máquina virtual) o algo similar, y tendría una **dirección IP pública** <dfn title="No cambia con el tiempo. No dinámica.">fija</dfn>.
 
 En el/los servidor(es) DNS configurarías un registro (un "`A record`") para apuntar **tu dominio** a la **dirección IP pública de tu servidor**.
 
index 50ba79c22843c16801dc69d9a79be772bcc3e556..3c597ff69ee0c86c520772733ad1cfd3a6b2f824 100644 (file)
@@ -46,7 +46,7 @@ Podrías usar ese comando, por ejemplo, para iniciar tu app **FastAPI** en un co
 
 Vamos a profundizar un poquito en los detalles.
 
-FastAPI usa un estándar para construir frameworks de web y servidores de Python llamado <abbr title="Asynchronous Server Gateway Interface  Interfaz de puerta de enlace de servidor asíncrona">ASGI</abbr>. FastAPI es un framework web ASGI.
+FastAPI usa un estándar para construir frameworks de web y servidores de Python llamado <abbr title="Asynchronous Server Gateway Interface - Interfaz de puerta de enlace de servidor asíncrona">ASGI</abbr>. FastAPI es un framework web ASGI.
 
 Lo principal que necesitas para ejecutar una aplicación **FastAPI** (o cualquier otra aplicación ASGI) en una máquina de servidor remota es un programa de servidor ASGI como **Uvicorn**, que es el que viene por defecto en el comando `fastapi`.
 
index 9902b21fa54196784a7b112fa1f31f9e257e6d0a..947ef312dba73a38a9fad18e02f12150807b0677 100644 (file)
@@ -6,7 +6,7 @@
 
 ### Basado en estándares abiertos { #based-on-open-standards }
 
-* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> para la creación de APIs, incluyendo declaraciones de <abbr title="también conocido como: endpoints, rutas">path</abbr> <abbr title="también conocido como métodos HTTP, como POST, GET, PUT, DELETE">operations</abbr>, parámetros, request bodies, seguridad, etc.
+* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> para la creación de APIs, incluyendo declaraciones de <dfn title="también conocido como: endpoints, rutas">path</dfn> <dfn title="también conocido como métodos HTTP, como POST, GET, PUT, DELETE">operations</dfn>, parámetros, request bodies, seguridad, etc.
 * Documentación automática de modelos de datos con <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (ya que OpenAPI en sí mismo está basado en JSON Schema).
 * Diseñado alrededor de estos estándares, tras un estudio meticuloso. En lugar de ser una capa adicional.
 * Esto también permite el uso de **generación de código cliente automática** en muchos idiomas.
@@ -105,8 +105,8 @@ Pero por defecto, todo **"simplemente funciona"**.
 
 * Validación para la mayoría (¿o todas?) de los **tipos de datos** de Python, incluyendo:
     * Objetos JSON (`dict`).
-    * Array JSON (`list`) definiendo tipos de elementos.
-    * Campos de cadena de caracteres (`str`), definiendo longitudes mínimas y máximas.
+    * array JSON (`list`) definiendo tipos de elementos.
+    * Campos de string (`str`), definiendo longitudes mínimas y máximas.
     * Números (`int`, `float`) con valores mínimos y máximos, etc.
 
 * Validación para tipos más exóticos, como:
@@ -136,7 +136,7 @@ Todo construido como herramientas y componentes reutilizables que son fáciles d
 
 ### Inyección de dependencias { #dependency-injection }
 
-FastAPI incluye un sistema de <abbr title='también conocido como "componentes", "recursos", "servicios", "proveedores"'><strong>Inyección de Dependencias</strong></abbr> extremadamente fácil de usar, pero extremadamente potente.
+FastAPI incluye un sistema de <dfn title='también conocido como "componentes", "recursos", "servicios", "proveedores"'><strong>Inyección de Dependencias</strong></dfn> extremadamente fácil de usar, pero extremadamente potente.
 
 * Incluso las dependencias pueden tener dependencias, creando una jerarquía o **"grafo de dependencias"**.
 * Todo **manejado automáticamente** por el framework.
@@ -153,8 +153,8 @@ Cualquier integración está diseñada para ser tan simple de usar (con dependen
 
 ### Probado { #tested }
 
-* 100% de <abbr title="La cantidad de código que se prueba automáticamente">cobertura de tests</abbr>.
-* 100% <abbr title="Anotaciones de tipos en Python, con esto tu editor y herramientas externas pueden ofrecerte mejor soporte">anotada con tipos</abbr> code base.
+* 100% de <dfn title="La cantidad de código que se prueba automáticamente">cobertura de tests</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 }
@@ -173,7 +173,7 @@ Con **FastAPI** obtienes todas las funcionalidades de **Starlette** (ya que Fast
 * **CORS**, GZip, archivos estáticos, responses en streaming.
 * Soporte para **Session y Cookie**.
 * Cobertura de tests del 100%.
-* code base completamente anotada con tipos.
+* code base 100% anotada con tipos.
 
 ## Funcionalidades de Pydantic { #pydantic-features }
 
@@ -190,7 +190,7 @@ Con **FastAPI** obtienes todas las funcionalidades de **Pydantic** (ya que FastA
 * **Sin complicaciones**:
     * Sin micro-lenguaje de definición de esquemas nuevo que aprender.
     * Si conoces los tipos en Python sabes cómo usar Pydantic.
-* Se lleva bien con tu **<abbr title="Integrated Development Environment – Entorno de Desarrollo Integrado: similar a un editor de código">IDE</abbr>/<abbr title="Un programa que verifica errores de código">linter</abbr>/cerebro**:
+* Se lleva bien con tu **<abbr title="Integrated Development Environment – Entorno de Desarrollo Integrado: similar a un editor de código">IDE</abbr>/<dfn title="Un programa que verifica errores de código">linter</dfn>/cerebro**:
     * Porque las estructuras de datos de pydantic son solo instances de clases que defines; autocompletado, linting, mypy y tu intuición deberían funcionar correctamente con tus datos validados.
 * Valida **estructuras complejas**:
     * Uso de modelos jerárquicos de Pydantic, `List` y `Dict` de `typing` de Python, etc.
index cef9562249b10bfb0a8b0013bb1f23067cd653fb..9b727dab087625de2367ac719134dfcdb2725c17 100644 (file)
@@ -110,7 +110,7 @@ En muchos casos solo copiarán un fragmento del código, pero eso no es suficien
 
 ### Sugerir soluciones { #suggest-solutions }
 
-* Después de poder entender la pregunta, puedes darles un posible **respuesta**.
+* Después de poder entender la pregunta, puedes darles una posible **respuesta**.
 
 * En muchos casos, es mejor entender su **problema subyacente o caso de uso**, porque podría haber una mejor manera de resolverlo que lo que están intentando hacer.
 
@@ -247,9 +247,9 @@ Las conversaciones en los sistemas de chat tampoco son tan fácilmente buscables
 
 Por otro lado, hay miles de usuarios en los sistemas de chat, por lo que hay muchas posibilidades de que encuentres a alguien con quien hablar allí, casi todo el tiempo. 😄
 
-## Patrocina al autor { #sponsor-the-author }
+## Hazte sponsor del autor { #sponsor-the-author }
 
-Si tu **producto/empresa** depende de o está relacionado con **FastAPI** y quieres llegar a sus usuarios, puedes patrocinar al autor (a mí) a través de <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>. Según el nivel, podrías obtener algunos beneficios extra, como una insignia en la documentación. 🎁
+Si tu **producto/empresa** depende de o está relacionado con **FastAPI** y quieres llegar a sus usuarios, puedes hacerte sponsor del autor (de mí) a través de <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>. Según el nivel, podrías obtener algunos beneficios extra, como una insignia en la documentación. 🎁
 
 ---
 
index 9fff6c93d3b4966ede89a45c75090749543f8be4..54afcec8cbd9e9ed63db781cb86c7e0545564a76 100644 (file)
@@ -8,7 +8,7 @@ Pero si por alguna razón tus clientes dependen del comportamiento anterior, pue
 
 Por ejemplo, puedes crear una subclase de `HTTPBearer` que devuelva un error `403 Forbidden` en lugar del `401 Unauthorized` por defecto:
 
-{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
+{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
 
 /// tip | Consejo
 
index a06ad95489f2fdacad9cbcd7452503554b9703e9..671100cf8b121949036ef1f3ebf3fd521fe7f1a0 100644 (file)
@@ -29,7 +29,7 @@ Puedes usar fácilmente las mismas configuraciones de Pydantic para configurar t
 
 Por ejemplo:
 
-{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
 
 Aquí declaramos la configuración `openapi_url` con el mismo valor por defecto de `"/openapi.json"`.
 
index b2865d77d591fb06c2a7ebd23cfc2acd11d8a6cb..092c310011ca73c10197674d883af875914fb4d8 100644 (file)
@@ -18,7 +18,7 @@ Sin cambiar la configuración, el resaltado de sintaxis está activado por defec
 
 Pero puedes desactivarlo estableciendo `syntaxHighlight` en `False`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
 
 ...y entonces Swagger UI ya no mostrará el resaltado de sintaxis:
 
@@ -28,17 +28,17 @@ Pero puedes desactivarlo estableciendo `syntaxHighlight` en `False`:
 
 De la misma manera, podrías configurar el tema del resaltado de sintaxis con la clave `"syntaxHighlight.theme"` (ten en cuenta que tiene un punto en el medio):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
 
 Esa configuración cambiaría el tema de color del resaltado de sintaxis:
 
 <img src="/img/tutorial/extending-openapi/image04.png">
 
-## Cambiar los parámetros predeterminados de Swagger UI { #change-default-swagger-ui-parameters }
+## Cambiar los parámetros por defecto de Swagger UI { #change-default-swagger-ui-parameters }
 
-FastAPI incluye algunos parámetros de configuración predeterminados apropiados para la mayoría de los casos de uso.
+FastAPI incluye algunos parámetros de configuración por defecto apropiados para la mayoría de los casos de uso.
 
-Incluye estas configuraciones predeterminadas:
+Incluye estas configuraciones por defecto:
 
 {* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
 
@@ -46,7 +46,7 @@ Puedes sobrescribir cualquiera de ellos estableciendo un valor diferente en el a
 
 Por ejemplo, para desactivar `deepLinking` podrías pasar estas configuraciones a `swagger_ui_parameters`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
 
 ## Otros parámetros de Swagger UI { #other-swagger-ui-parameters }
 
index acd3f8d6d66129717c0af2f4a8f178b4ff327c63..faddab0d839b0b88c91e24678f206b4c07643321 100644 (file)
@@ -18,7 +18,7 @@ El primer paso es desactivar la documentación automática, ya que por defecto,
 
 Para desactivarlos, establece sus URLs en `None` cuando crees tu aplicación de `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
 
 ### Incluye la documentación personalizada { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@ Puedes reutilizar las funciones internas de FastAPI para crear las páginas HTML
 
 Y de manera similar para ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip | Consejo
 
@@ -50,7 +50,7 @@ Swagger UI lo manejará detrás de escena para ti, pero necesita este auxiliar d
 
 Ahora, para poder probar que todo funciona, crea una *path operation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
 
 ### Pruébalo { #test-it }
 
@@ -118,7 +118,7 @@ Después de eso, tu estructura de archivos podría verse así:
 * Importa `StaticFiles`.
 * "Monta" una instance de `StaticFiles()` en un path específico.
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
 
 ### Prueba los archivos estáticos { #test-the-static-files }
 
@@ -144,7 +144,7 @@ Igual que cuando usas un CDN personalizado, el primer paso es desactivar la docu
 
 Para desactivarlos, establece sus URLs en `None` cuando crees tu aplicación de `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
 
 ### Incluye la documentación personalizada para archivos estáticos { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Nuevamente, puedes reutilizar las funciones internas de FastAPI para crear las p
 
 Y de manera similar para ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip | Consejo
 
@@ -176,7 +176,7 @@ Swagger UI lo manejará detrás de escena para ti, pero necesita este auxiliar d
 
 Ahora, para poder probar que todo funciona, crea una *path operation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
 
 ### Prueba la UI de Archivos Estáticos { #test-static-files-ui }
 
index 2611b6e1b67fbab566db9781f4e1d92d3de4a368..d08fae073abb209bef34f234d3b504babfd7ce97 100644 (file)
@@ -43,19 +43,19 @@ Por ejemplo, vamos a añadir <a href="https://github.com/Rebilly/ReDoc/blob/mast
 
 Primero, escribe toda tu aplicación **FastAPI** como normalmente:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
 
 ### Generar el esquema de OpenAPI { #generate-the-openapi-schema }
 
 Luego, usa la misma función de utilidad para generar el esquema de OpenAPI, dentro de una función `custom_openapi()`:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
 
 ### Modificar el esquema de OpenAPI { #modify-the-openapi-schema }
 
 Ahora puedes añadir la extensión de ReDoc, agregando un `x-logo` personalizado al "objeto" `info` en el esquema de OpenAPI:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
 
 ### Cachear el esquema de OpenAPI { #cache-the-openapi-schema }
 
@@ -65,13 +65,13 @@ De esa forma, tu aplicación no tendrá que generar el esquema cada vez que un u
 
 Se generará solo una vez, y luego se usará el mismo esquema cacheado para las siguientes requests.
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
 
 ### Sobrescribir el método { #override-the-method }
 
 Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
 
 ### Revisa { #check-it }
 
index e50c1ae0acfc8e5a2563dd1c55afded8d41be70e..ee77570b3f56cec00ded8c4b1a205290592d1a1e 100644 (file)
@@ -35,7 +35,7 @@ Dependiendo de tu caso de uso, podrías preferir usar un paquete diferente, pero
 
 Aquí tienes una pequeña vista previa de cómo podrías integrar Strawberry con FastAPI:
 
-{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
+{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
 
 Puedes aprender más sobre Strawberry en la <a href="https://strawberry.rocks/" class="external-link" target="_blank">documentación de Strawberry</a>.
 
index 903313599d0472b470c84a0dcb524a0f4810f2f6..db9b46ddbed22a1dd09e4dd9e8fac2b3f617d48b 100644 (file)
@@ -85,7 +85,7 @@ Probablemente el caso principal para esto es si ya tienes algún código cliente
 
 En ese caso, puedes desactivar esta funcionalidad en **FastAPI**, con el parámetro `separate_input_output_schemas=False`.
 
-/// info
+/// info | Información
 
 El soporte para `separate_input_output_schemas` fue agregado en FastAPI `0.102.0`. 🤓
 
index 2fa260312399e3ae3322988e6380b7cf6ecf78d7..0717ea5ff78add78602b43cc2d846aaf9e219cae 100644 (file)
@@ -1,7 +1,7 @@
-# Probando una Base de Datos { #testing-a-database }
+# Escribiendo pruebas para una base de datos { #testing-a-database }
 
 Puedes estudiar sobre bases de datos, SQL y SQLModel en la <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">documentación de SQLModel</a>. 🤓
 
 Hay un mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial sobre el uso de SQLModel con FastAPI</a>. ✨
 
-Ese tutorial incluye una sección sobre <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/" class="external-link" target="_blank">cómo probar bases de datos SQL</a>. 😎
+Ese tutorial incluye una sección sobre <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/" class="external-link" target="_blank">escribir pruebas para bases de datos SQL</a>. 😎
index ffea0ed546006656aca883b49a678e8c32476947..0544eb9ba4f90f7e4b941da8a1686dbefd1ee971 100644 (file)
@@ -40,7 +40,7 @@ Las funcionalidades clave son:
 * **Rápido**: Muy alto rendimiento, a la par con **NodeJS** y **Go** (gracias a Starlette y Pydantic). [Uno de los frameworks Python más rápidos disponibles](#performance).
 * **Rápido de programar**: Aumenta la velocidad para desarrollar funcionalidades en aproximadamente un 200% a 300%. *
 * **Menos bugs**: Reduce en aproximadamente un 40% los errores inducidos por humanos (desarrolladores). *
-* **Intuitivo**: Gran soporte para editores. <abbr title="también conocido como auto-complete, autocompletado, IntelliSense">Autocompletado</abbr> en todas partes. Menos tiempo depurando.
+* **Intuitivo**: Gran soporte para editores. <dfn title="también conocido como: autocompletado, IntelliSense">Autocompletado</dfn> en todas partes. Menos tiempo depurando.
 * **Fácil**: Diseñado para ser fácil de usar y aprender. Menos tiempo leyendo documentación.
 * **Corto**: Minimiza la duplicación de código. Múltiples funcionalidades desde cada declaración de parámetro. Menos bugs.
 * **Robusto**: Obtén código listo para producción. Con documentación interactiva automática.
@@ -368,7 +368,7 @@ item: Item
 * Validación de datos:
     * Errores automáticos y claros cuando los datos son inválidos.
     * Validación incluso para objetos JSON profundamente anidados.
-* <abbr title="también conocido como: serialización, parsing, marshalling">Conversión</abbr> de datos de entrada: de la red a los datos y tipos de Python. Leyendo desde:
+* <dfn title="también conocido como: serialización, parsing, marshalling">Conversión</dfn> de datos de entrada: de la red a los datos y tipos de Python. Leyendo desde:
     * JSON.
     * Parámetros de path.
     * Parámetros de query.
@@ -376,7 +376,7 @@ item: Item
     * Headers.
     * Forms.
     * Archivos.
-* <abbr title="también conocido como: serialización, parsing, marshalling">Conversión</abbr> de datos de salida: convirtiendo de datos y tipos de Python a datos de red (como JSON):
+* <dfn title="también conocido como: serialización, parsing, marshalling">Conversión</dfn> de datos de salida: convirtiendo de datos y tipos de Python a datos de red (como JSON):
     * Convertir tipos de Python (`str`, `int`, `float`, `bool`, `list`, etc).
     * Objetos `datetime`.
     * Objetos `UUID`.
@@ -439,7 +439,7 @@ Para un ejemplo más completo incluyendo más funcionalidades, ve al <a href="ht
 
 * Declaración de **parámetros** desde otros lugares diferentes como: **headers**, **cookies**, **campos de formulario** y **archivos**.
 * Cómo establecer **restricciones de validación** como `maximum_length` o `regex`.
-* Un sistema de **<abbr title="también conocido como componentes, recursos, proveedores, servicios, inyectables">Inyección de Dependencias</abbr>** muy poderoso y fácil de usar.
+* Un sistema de **<dfn title="también conocido como: componentes, recursos, proveedores, servicios, inyectables">Inyección de Dependencias</dfn>** muy poderoso y fácil de usar.
 * Seguridad y autenticación, incluyendo soporte para **OAuth2** con **tokens JWT** y autenticación **HTTP Basic**.
 * Técnicas más avanzadas (pero igualmente fáciles) para declarar **modelos JSON profundamente anidados** (gracias a Pydantic).
 * Integración con **GraphQL** usando <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> y otros paquetes.
@@ -524,7 +524,7 @@ Usadas por Starlette:
 
 * <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Requerido si deseas usar el `TestClient`.
 * <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Requerido si deseas usar la configuración de plantilla por defecto.
-* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Requerido si deseas soportar <abbr title="convertir el string que viene de un request HTTP en datos de Python">"parsing"</abbr> de forms, con `request.form()`.
+* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Requerido si deseas soportar form <dfn title="convertir el string que viene de un request HTTP en datos de Python">"parsing"</dfn>, con `request.form()`.
 
 Usadas por FastAPI:
 
index b4aa11d0dd3b903526eea61452aadf6724bda64e..6d48d0be54f72bda3af94163b0d81cb57db1e06d 100644 (file)
@@ -6,7 +6,7 @@ Puedes usar esta plantilla para comenzar, ya que incluye gran parte de la config
 
 Repositorio de GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Plantilla Full Stack FastAPI</a>
 
-## Plantilla Full Stack FastAPI - Tecnología y Funcionalidades { #full-stack-fastapi-template-technology-stack-and-features }
+## 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).
index 60b50a08ff6d90073af61c8aabcabfc2a7ab61cc..28e2953d3591b6933ca53c7c3618df3a80025afa 100644 (file)
@@ -2,7 +2,7 @@
 
 Python tiene soporte para "anotaciones de tipos" opcionales (también llamadas "type hints").
 
-Estas **"anotaciones de tipos"** o type hints son una sintaxis especial que permite declarar el <abbr title="por ejemplo: str, int, float, bool">tipo</abbr> de una variable.
+Estas **"anotaciones de tipos"** o type hints son una sintaxis especial que permite declarar el <dfn title="por ejemplo: str, int, float, bool">tipo</dfn> de una variable.
 
 Al declarar tipos para tus variables, los editores y herramientas te pueden proporcionar un mejor soporte.
 
@@ -22,7 +22,7 @@ Si eres un experto en Python, y ya sabes todo sobre las anotaciones de tipos, sa
 
 Comencemos con un ejemplo simple:
 
-{* ../../docs_src/python_types/tutorial001_py39.py *}
+{* ../../docs_src/python_types/tutorial001_py310.py *}
 
 Llamar a este programa genera:
 
@@ -34,9 +34,9 @@ La función hace lo siguiente:
 
 * Toma un `first_name` y `last_name`.
 * Convierte la primera letra de cada uno a mayúsculas con `title()`.
-* <abbr title="Los une, como uno. Con el contenido de uno después del otro.">Concatena</abbr> ambos con un espacio en el medio.
+* <dfn title="Los une, como uno. Con el contenido de uno después del otro.">Concatena</dfn> ambos con un espacio en el medio.
 
-{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
 
 ### Edítalo { #edit-it }
 
@@ -78,7 +78,7 @@ Eso es todo.
 
 Esas son las "anotaciones de tipos":
 
-{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
 
 Eso no es lo mismo que declarar valores predeterminados como sería con:
 
@@ -106,7 +106,7 @@ Con eso, puedes desplazarte, viendo las opciones, hasta que encuentres la que "t
 
 Revisa esta función, ya tiene anotaciones de tipos:
 
-{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
 
 Porque el editor conoce los tipos de las variables, no solo obtienes autocompletado, también obtienes chequeo de errores:
 
@@ -114,7 +114,7 @@ Porque el editor conoce los tipos de las variables, no solo obtienes autocomplet
 
 Ahora sabes que debes corregirlo, convertir `age` a un string con `str(age)`:
 
-{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
 
 ## Declaración de tipos { #declaring-types }
 
@@ -133,29 +133,32 @@ Puedes usar, por ejemplo:
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
 
-### Tipos genéricos con parámetros de tipo { #generic-types-with-type-parameters }
+### Módulo `typing` { #typing-module }
 
-Hay algunas estructuras de datos que pueden contener otros valores, como `dict`, `list`, `set` y `tuple`. Y los valores internos también pueden tener su propio tipo.
+Para algunos casos adicionales, podrías necesitar importar algunas cosas del módulo `typing` de la standard library, por ejemplo cuando quieres declarar que algo tiene "cualquier tipo", puedes usar `Any` de `typing`:
 
-Estos tipos que tienen tipos internos se denominan tipos "**genéricos**". Y es posible declararlos, incluso con sus tipos internos.
+```python
+from typing import Any
 
-Para declarar esos tipos y los tipos internos, puedes usar el módulo estándar de Python `typing`. Existe específicamente para soportar estas anotaciones de tipos.
 
-#### Versiones más recientes de Python { #newer-versions-of-python }
-
-La sintaxis que utiliza `typing` es **compatible** con todas las versiones, desde Python 3.6 hasta las versiones más recientes, incluyendo Python 3.9, Python 3.10, etc.
+def some_function(data: Any):
+    print(data)
+```
 
-A medida que avanza Python, las **versiones más recientes** vienen con soporte mejorado para estas anotaciones de tipos y en muchos casos ni siquiera necesitarás importar y usar el módulo `typing` para declarar las anotaciones de tipos.
+### Tipos genéricos { #generic-types }
 
-Si puedes elegir una versión más reciente de Python para tu proyecto, podrás aprovechar esa simplicidad adicional.
+Algunos tipos pueden tomar "parámetros de tipo" entre corchetes, para definir sus tipos internos, por ejemplo una "lista de strings" se declararía `list[str]`.
 
-En toda la documentación hay ejemplos compatibles con cada versión de Python (cuando hay una diferencia).
+Estos tipos que pueden tomar parámetros de tipo se llaman **Tipos Genéricos** o **Genéricos**.
 
-Por ejemplo, "**Python 3.6+**" significa que es compatible con Python 3.6 o superior (incluyendo 3.7, 3.8, 3.9, 3.10, etc). Y "**Python 3.9+**" significa que es compatible con Python 3.9 o superior (incluyendo 3.10, etc).
+Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos dentro):
 
-Si puedes usar las **últimas versiones de Python**, utiliza los ejemplos para la última versión, esos tendrán la **mejor y más simple sintaxis**, por ejemplo, "**Python 3.10+**".
+* `list`
+* `tuple`
+* `set`
+* `dict`
 
 #### Lista { #list }
 
@@ -167,7 +170,7 @@ Como tipo, pon `list`.
 
 Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes:
 
-{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
 
 /// info | Información
 
@@ -193,7 +196,7 @@ Y aún así, el editor sabe que es un `str` y proporciona soporte para eso.
 
 Harías lo mismo para declarar `tuple`s y `set`s:
 
-{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
 
 Esto significa:
 
@@ -208,7 +211,7 @@ El primer parámetro de tipo es para las claves del `dict`.
 
 El segundo parámetro de tipo es para los valores del `dict`:
 
-{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
 
 Esto significa:
 
@@ -218,46 +221,22 @@ Esto significa:
 
 #### Union { #union }
 
-Puedes declarar que una variable puede ser cualquier de **varios tipos**, por ejemplo, un `int` o un `str`.
-
-En Python 3.6 y posterior (incluyendo Python 3.10) puedes usar el tipo `Union` de `typing` y poner dentro de los corchetes los posibles tipos a aceptar.
+Puedes declarar que una variable puede ser cualquiera de **varios tipos**, por ejemplo, un `int` o un `str`.
 
-En Python 3.10 también hay una **nueva sintaxis** donde puedes poner los posibles tipos separados por una <abbr title='también llamado "operador OR a nivel de bits", pero ese significado no es relevante aquí'>barra vertical (`|`)</abbr>.
+Para definirlo usas la <dfn title='también llamado "operador OR a nivel de bits", pero ese significado no es relevante aquí'>barra vertical (`|`)</dfn> para separar ambos tipos.
 
-//// tab | Python 3.10+
+Esto se llama una "unión", porque la variable puede ser cualquiera en la unión de esos dos conjuntos de tipos.
 
 ```Python hl_lines="1"
 {!> ../../docs_src/python_types/tutorial008b_py310.py!}
 ```
 
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b_py39.py!}
-```
-
-////
-
-En ambos casos, esto significa que `item` podría ser un `int` o un `str`.
+Esto significa que `item` podría ser un `int` o un `str`.
 
 #### Posiblemente `None` { #possibly-none }
 
 Puedes declarar que un valor podría tener un tipo, como `str`, pero que también podría ser `None`.
 
-En Python 3.6 y posteriores (incluyendo Python 3.10) puedes declararlo importando y usando `Optional` del módulo `typing`.
-
-```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009_py39.py!}
-```
-
-Usar `Optional[str]` en lugar de solo `str` te permitirá al editor ayudarte a detectar errores donde podrías estar asumiendo que un valor siempre es un `str`, cuando en realidad también podría ser `None`.
-
-`Optional[Something]` es realmente un atajo para `Union[Something, None]`, son equivalentes.
-
-Esto también significa que en Python 3.10, puedes usar `Something | None`:
-
 //// tab | Python 3.10+
 
 ```Python hl_lines="1"
@@ -266,96 +245,7 @@ Esto también significa que en Python 3.10, puedes usar `Something | None`:
 
 ////
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009_py39.py!}
-```
-
-////
-
-//// tab | Python 3.9+ alternativa
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b_py39.py!}
-```
-
-////
-
-#### Uso de `Union` u `Optional` { #using-union-or-optional }
-
-Si estás usando una versión de Python inferior a 3.10, aquí tienes un consejo desde mi punto de vista muy **subjetivo**:
-
-* 🚨 Evita usar `Optional[SomeType]`
-* En su lugar ✨ **usa `Union[SomeType, None]`** ✨.
-
-Ambos son equivalentes y debajo son lo mismo, pero recomendaría `Union` en lugar de `Optional` porque la palabra "**opcional**" parecería implicar que el valor es opcional, y en realidad significa "puede ser `None`", incluso si no es opcional y aún es requerido.
-
-Creo que `Union[SomeType, None]` es más explícito sobre lo que significa.
-
-Se trata solo de las palabras y nombres. Pero esas palabras pueden afectar cómo tú y tus compañeros de equipo piensan sobre el código.
-
-Como ejemplo, tomemos esta función:
-
-{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
-
-El parámetro `name` está definido como `Optional[str]`, pero **no es opcional**, no puedes llamar a la función sin el parámetro:
-
-```Python
-say_hi()  # ¡Oh, no, esto lanza un error! 😱
-```
-
-El parámetro `name` sigue siendo **requerido** (no *opcional*) porque no tiene un valor predeterminado. Aún así, `name` acepta `None` como valor:
-
-```Python
-say_hi(name=None)  # Esto funciona, None es válido 🎉
-```
-
-La buena noticia es que, una vez que estés en Python 3.10, no tendrás que preocuparte por eso, ya que podrás simplemente usar `|` para definir uniones de tipos:
-
-{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
-
-Y entonces no tendrás que preocuparte por nombres como `Optional` y `Union`. 😎
-
-#### Tipos genéricos { #generic-types }
-
-Estos tipos que toman parámetros de tipo en corchetes se llaman **Tipos Genéricos** o **Genéricos**, por ejemplo:
-
-//// tab | Python 3.10+
-
-Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos dentro):
-
-* `list`
-* `tuple`
-* `set`
-* `dict`
-
-Y, como con versiones anteriores de Python, desde el módulo `typing`:
-
-* `Union`
-* `Optional`
-* ...y otros.
-
-En Python 3.10, como alternativa a usar los genéricos `Union` y `Optional`, puedes usar la <abbr title='también llamado "operador OR a nivel de bits", pero ese significado no es relevante aquí'>barra vertical (`|`)</abbr> para declarar uniones de tipos, eso es mucho mejor y más simple.
-
-////
-
-//// tab | Python 3.9+
-
-Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos dentro):
-
-* `list`
-* `tuple`
-* `set`
-* `dict`
-
-Y generics desde el módulo `typing`:
-
-* `Union`
-* `Optional`
-* ...y otros.
-
-////
+Usar `str | None` en lugar de solo `str` te permitirá al editor ayudarte a detectar errores donde podrías estar asumiendo que un valor siempre es un `str`, cuando en realidad también podría ser `None`.
 
 ### Clases como tipos { #classes-as-types }
 
@@ -363,11 +253,11 @@ También puedes declarar una clase como el tipo de una variable.
 
 Digamos que tienes una clase `Person`, con un nombre:
 
-{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
 
 Luego puedes declarar una variable para que sea de tipo `Person`:
 
-{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
 
 Y luego, nuevamente, obtienes todo el soporte del editor:
 
@@ -403,19 +293,13 @@ Para saber más sobre <a href="https://docs.pydantic.dev/" class="external-link"
 
 Verás mucho más de todo esto en práctica en el [Tutorial - Guía del Usuario](tutorial/index.md){.internal-link target=_blank}.
 
-/// tip | Consejo
-
-Pydantic tiene un comportamiento especial cuando utilizas `Optional` o `Union[Something, None]` sin un valor por defecto, puedes leer más sobre ello en la documentación de Pydantic sobre <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a>.
-
-///
-
 ## Anotaciones de tipos con metadata { #type-hints-with-metadata-annotations }
 
-Python también tiene una funcionalidad que permite poner **<abbr title="Datos sobre los datos, en este caso, información sobre el tipo, por ejemplo, una descripción.">metadatos</abbr> adicional** en estas anotaciones de tipos usando `Annotated`.
+Python también tiene una funcionalidad que permite poner **<dfn title="Datos sobre los datos, en este caso, información sobre el tipo, por ejemplo, una descripción.">metadata</dfn> adicional** en estas anotaciones de tipos usando `Annotated`.
 
-Desde Python 3.9, `Annotated` es parte de la standard library, así que puedes importarlo desde `typing`.
+Puedes importar `Annotated` desde `typing`.
 
-{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
 
 Python en sí no hace nada con este `Annotated`. Y para los editores y otras herramientas, el tipo sigue siendo `str`.
 
diff --git a/docs/es/docs/translation-banner.md b/docs/es/docs/translation-banner.md
new file mode 100644 (file)
index 0000000..e38f20c
--- /dev/null
@@ -0,0 +1,11 @@
+/// details | 🌐 Traducción por IA y humanos
+
+Esta traducción fue hecha por IA guiada por humanos. 🤝
+
+Podría tener errores al interpretar el significado original, o sonar poco natural, etc. 🤖
+
+Puedes mejorar esta traducción [ayudándonos a guiar mejor al LLM de IA](https://fastapi.tiangolo.com/es/contributing/#translations).
+
+[Versión en inglés](ENGLISH_VERSION_URL)
+
+///
index cc8a2c9cbe4d9a8f15a2c2e2fa54b28befc95b94..10ad4b5ebba5a026b423f91b5e64d670669350e8 100644 (file)
@@ -15,7 +15,7 @@ Esto incluye, por ejemplo:
 
 Primero, importa `BackgroundTasks` y define un parámetro en tu *path operation function* con una declaración de tipo de `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
 
 **FastAPI** creará el objeto de tipo `BackgroundTasks` por ti y lo pasará como ese parámetro.
 
@@ -31,13 +31,13 @@ En este caso, la función de tarea escribirá en un archivo (simulando el envío
 
 Y como la operación de escritura no usa `async` y `await`, definimos la función con un `def` normal:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
 
 ## Agregar la tarea en segundo plano { #add-the-background-task }
 
 Dentro de tu *path operation function*, pasa tu función de tarea al objeto de *background tasks* con el método `.add_task()`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
 
 `.add_task()` recibe como argumentos:
 
index 7938a12158070c26a266f9ca0c0ff8e11b8639c7..96b58a7207a13ae710f931758f7f9dba875021f5 100644 (file)
@@ -85,7 +85,7 @@ Puedes crear las *path operations* para ese módulo usando `APIRouter`.
 
 Lo importas y creas una "instance" de la misma manera que lo harías con la clase `FastAPI`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
 
 ### *Path operations* con `APIRouter` { #path-operations-with-apirouter }
 
@@ -93,7 +93,7 @@ Y luego lo usas para declarar tus *path operations*.
 
 Úsalo de la misma manera que usarías la clase `FastAPI`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
 
 Puedes pensar en `APIRouter` como una clase "mini `FastAPI`".
 
@@ -117,7 +117,7 @@ Así que las ponemos en su propio módulo `dependencies` (`app/dependencies.py`)
 
 Ahora utilizaremos una dependencia simple para leer un header `X-Token` personalizado:
 
-{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
 
 /// tip | Consejo
 
@@ -149,7 +149,7 @@ Sabemos que todas las *path operations* en este módulo tienen el mismo:
 
 Entonces, en lugar de agregar todo eso a cada *path operation*, podemos agregarlo al `APIRouter`.
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
 
 Como el path de cada *path operation* tiene que empezar con `/`, como en:
 
@@ -208,7 +208,7 @@ Y necesitamos obtener la función de dependencia del módulo `app.dependencies`,
 
 Así que usamos un import relativo con `..` para las dependencias:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
 
 #### Cómo funcionan los imports relativos { #how-relative-imports-work }
 
@@ -279,7 +279,7 @@ No estamos agregando el prefijo `/items` ni los `tags=["items"]` a cada *path op
 
 Pero aún podemos agregar _más_ `tags` que se aplicarán a una *path operation* específica, y también algunas `responses` extra específicas para esa *path operation*:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
 
 /// tip | Consejo
 
@@ -305,13 +305,13 @@ Importas y creas una clase `FastAPI` como normalmente.
 
 Y podemos incluso declarar [dependencias globales](dependencies/global-dependencies.md){.internal-link target=_blank} que se combinarán con las dependencias para cada `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
 
 ### Importar el `APIRouter` { #import-the-apirouter }
 
 Ahora importamos los otros submódulos que tienen `APIRouter`s:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
 
 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".
 
@@ -374,13 +374,13 @@ el `router` de `users` sobrescribiría el de `items` y no podríamos usarlos al
 
 Así que, para poder usar ambos en el mismo archivo, importamos los submódulos directamente:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
+{* ../../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 }
 
 Ahora, incluyamos los `router`s de los submódulos `users` y `items`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
 
 /// info | Información
 
@@ -420,13 +420,13 @@ Contiene un `APIRouter` con algunas *path operations* de administración que tu
 
 Para este ejemplo será súper simple. Pero digamos que porque está compartido con otros proyectos en la organización, no podemos modificarlo y agregar un `prefix`, `dependencies`, `tags`, etc. directamente al `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
 
 Pero aún queremos configurar un `prefix` personalizado al incluir el `APIRouter` para que todas sus *path operations* comiencen con `/admin`, queremos asegurarlo con las `dependencies` que ya tenemos para este proyecto, y queremos incluir `tags` y `responses`.
 
 Podemos declarar todo eso sin tener que modificar el `APIRouter` original pasando esos parámetros a `app.include_router()`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
 
 De esa manera, el `APIRouter` original permanecerá sin modificar, por lo que aún podemos compartir ese mismo archivo `app/internal/admin.py` con otros proyectos en la organización.
 
@@ -447,7 +447,7 @@ También podemos agregar *path operations* directamente a la app de `FastAPI`.
 
 Aquí lo hacemos... solo para mostrar que podemos 🤷:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
 
 y funcionará correctamente, junto con todas las otras *path operations* añadidas con `app.include_router()`.
 
index c52486f9b86149ddd25ca4a21fb07ea3a1e8da4a..c78dd288120d7e32a976467852176d0036a23912 100644 (file)
@@ -104,12 +104,6 @@ Como, por defecto, los valores singulares se interpretan como parámetros de que
 q: str | None = None
 ```
 
-O en Python 3.9:
-
-```Python
-q: Union[str, None] = None
-```
-
 Por ejemplo:
 
 {* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
index 0dfd6576f1e3aa3f64d65d47d7904fbbae84d005..5f723e4c9f07bf3cb0f1edf3a4a3bc13e1286bc6 100644 (file)
@@ -164,7 +164,7 @@ images: list[Image]
 
 como en:
 
-{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
+{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
 
 ## Soporte de editor en todas partes { #editor-support-everywhere }
 
@@ -194,7 +194,7 @@ Eso es lo que vamos a ver aquí.
 
 En este caso, aceptarías cualquier `dict` siempre que tenga claves `int` con valores `float`:
 
-{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
+{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
 
 /// tip | Consejo
 
index dde39f78c1f2501f2dbfe121c96a68c7910906d6..3adf2e65c533d8c5be47143a63f508efdc83da42 100644 (file)
@@ -74,7 +74,7 @@ Con solo esa declaración de tipo en Python, **FastAPI** hará lo siguiente:
 * Proporcionar los datos recibidos en el parámetro `item`.
     * Como lo declaraste en la función como de tipo `Item`, también tendrás todo el soporte del editor (autocompletado, etc.) para todos los atributos y sus tipos.
 * Generar definiciones de <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> para tu modelo, que también puedes usar en cualquier otro lugar si tiene sentido para tu proyecto.
-* Esos esquemas serán parte del esquema de OpenAPI generado y usados por las <abbr title="User Interfaces  Interfaces de usuario">UIs</abbr> de documentación automática.
+* Esos esquemas serán parte del esquema de OpenAPI generado y usados por las <abbr title="User Interfaces - Interfaces de usuario">UIs</abbr> de documentación automática.
 
 ## Documentación automática { #automatic-docs }
 
@@ -155,7 +155,7 @@ Los parámetros de la función se reconocerán de la siguiente manera:
 
 FastAPI sabrá que el valor de `q` no es requerido debido al valor por defecto `= None`.
 
-El `str | None` (Python 3.10+) o `Union` en `Union[str, None]` (Python 3.9+) no es utilizado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de `= None`.
+El `str | None` no es utilizado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de `= None`.
 
 Pero agregar las anotaciones de tipos permitirá que tu editor te brinde un mejor soporte y detecte errores.
 
@@ -163,4 +163,4 @@ Pero agregar las anotaciones de tipos permitirá que tu editor te brinde un mejo
 
 ## Sin Pydantic { #without-pydantic }
 
-Si no quieres usar modelos de Pydantic, también puedes usar parámetros **Body**. Consulta la documentación para [Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
+Si no quieres usar modelos de Pydantic, también puedes usar parámetros **Body**. Consulta la documentación para [Body - Múltiples parámetros: Valores singulares en el body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
index dab7d8c0a2446ae3510bdfb21f3b1aae87964496..4e6038a46bf16717dc3e0459b2cf285bc25c48c9 100644 (file)
@@ -46,7 +46,7 @@ Pero incluso si **rellenas los datos** y haces clic en "Execute", como la UI de
 
 En algunos casos de uso especiales (probablemente no muy comunes), podrías querer **restringir** las cookies que deseas recibir.
 
-Tu API ahora tiene el poder de controlar su propio <abbr title="Esto es una broma, por si acaso. No tiene nada que ver con los consentimientos de cookies, pero es gracioso que incluso la API ahora pueda rechazar las pobres cookies. Toma una cookie. 🍪">consentimiento de cookies</abbr>. 🤪🍪
+Tu API ahora tiene el poder de controlar su propio <dfn title="Esto es una broma, por si acaso. No tiene nada que ver con los consentimientos de cookies, pero es gracioso que incluso la API ahora pueda rechazar las pobres cookies. Toma una cookie. 🍪">consentimiento de cookies</dfn>. 🤪🍪
 
 Puedes usar la configuración del modelo de Pydantic para `prohibir` cualquier campo `extra`:
 
@@ -54,9 +54,9 @@ Puedes usar la configuración del modelo de Pydantic para `prohibir` cualquier c
 
 Si un cliente intenta enviar algunas **cookies extra**, recibirán un response de **error**.
 
-Pobres banners de cookies con todo su esfuerzo para obtener tu consentimiento para que la <abbr title="Esta es otra broma. No me prestes atención. Toma un café para tu cookie. ☕">API lo rechace</abbr>. 🍪
+Pobres banners de cookies con todo su esfuerzo para obtener tu consentimiento para que la <dfn title="Esta es otra broma. No me prestes atención. Toma un café para tu cookie. ☕">API lo rechace</dfn>. 🍪
 
-Por ejemplo, si el cliente intenta enviar una cookie `santa_tracker` con un valor de `good-list-please`, el cliente recibirá un response de **error** que le informa que la cookie `santa_tracker` <abbr title="Santa desaprueba la falta de cookies. 🎅 Está bien, no más bromas de cookies.">no está permitida</abbr>:
+Por ejemplo, si el cliente intenta enviar una cookie `santa_tracker` con un valor de `good-list-please`, el cliente recibirá un response de **error** que le informa que la `santa_tracker` <dfn title="Santa desaprueba la falta de cookies. 🎅 Está bien, no más bromas de cookies.">cookie no está permitida</dfn>:
 
 ```json
 {
@@ -73,4 +73,4 @@ Por ejemplo, si el cliente intenta enviar una cookie `santa_tracker` con un valo
 
 ## Resumen { #summary }
 
-Puedes usar **modelos de Pydantic** para declarar <abbr title="Toma una última cookie antes de irte. 🍪">**cookies**</abbr> en **FastAPI**. 😎
+Puedes usar **modelos de Pydantic** para declarar <dfn title="Toma una última cookie antes de irte. 🍪">**cookies**</dfn> en **FastAPI**. 😎
index c1a23295e1d2523e6fe05093c40f41aeba684569..a118d814b03dc2e3d2b136fbd81b43017934b346 100644 (file)
@@ -46,7 +46,8 @@ También puedes especificar si tu backend permite:
 * Métodos HTTP específicos (`POST`, `PUT`) o todos ellos con el comodín `"*"`.
 * Headers HTTP específicos o todos ellos con el comodín `"*"`.
 
-{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
+
 
 Los parámetros predeterminados utilizados por la implementación de `CORSMiddleware` son restrictivos por defecto, por lo que necesitarás habilitar explícitamente orígenes, métodos o headers particulares para que los navegadores estén permitidos de usarlos en un contexto de Cross-Domain.
 
index c31daf40f48047590b9d799168e35ac20380f991..a2d47f2da7ac2689fb48b7fc9c660c830bde9231 100644 (file)
@@ -6,7 +6,7 @@ Puedes conectar el depurador en tu editor, por ejemplo con Visual Studio Code o
 
 En tu aplicación de FastAPI, importa y ejecuta `uvicorn` directamente:
 
-{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
 
 ### Acerca de `__name__ == "__main__"` { #about-name-main }
 
index a3a75efcd93675ac5e6440f17c6f9789f1d3b648..7506bda470bf99642b9210164eb24b2677934da3 100644 (file)
@@ -101,7 +101,7 @@ Ahora puedes declarar tu dependencia usando esta clase.
 
 Nota cómo escribimos `CommonQueryParams` dos veces en el código anterior:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ sin `Annotated`
+//// tab | Python 3.10+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -137,7 +137,7 @@ Es a partir de este que **FastAPI** extraerá los parámetros declarados y es lo
 
 En este caso, el primer `CommonQueryParams`, en:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.9+ sin `Annotated`
+//// tab | Python 3.10+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 De hecho, podrías escribir simplemente:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ sin `Annotated`
+//// tab | Python 3.10+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -197,7 +197,7 @@ Pero declarar el tipo es recomendable, ya que de esa manera tu editor sabrá lo
 
 Pero ves que estamos teniendo algo de repetición de código aquí, escribiendo `CommonQueryParams` dos veces:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ sin `Annotated`
+//// tab | Python 3.10+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -225,7 +225,7 @@ Para esos casos específicos, puedes hacer lo siguiente:
 
 En lugar de escribir:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ sin `Annotated`
+//// tab | Python 3.10+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ...escribes:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.9+ sin `Annotated`
+//// tab | Python 3.10+ sin `Annotated`
 
 /// tip | Consejo
 
index 60baa93a90612bbd081f318551068f760f9f5e9b..5eadbe7e1f411e96f7e13f6f19e62403232a45ef 100644 (file)
@@ -14,7 +14,7 @@ El decorador de *path operation* recibe un argumento opcional `dependencies`.
 
 Debe ser una `list` de `Depends()`:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
 
 Estas dependencias serán ejecutadas/resueltas de la misma manera que las dependencias normales. Pero su valor (si devuelven alguno) no será pasado a tu *path operation function*.
 
@@ -44,13 +44,13 @@ Puedes usar las mismas *funciones* de dependencia que usas normalmente.
 
 Pueden declarar requisitos de request (como headers) u otras sub-dependencias:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
 
 ### Lanzar excepciones { #raise-exceptions }
 
 Estas dependencias pueden `raise` excepciones, igual que las dependencias normales:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
 
 ### Valores de retorno { #return-values }
 
@@ -58,7 +58,7 @@ Y pueden devolver valores o no, los valores no serán usados.
 
 Así que, puedes reutilizar una dependencia normal (que devuelve un valor) que ya uses en otro lugar, y aunque el valor no se use, la dependencia será ejecutada:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
 
 ## Dependencias para un grupo de *path operations* { #dependencies-for-a-group-of-path-operations }
 
index aa645daa475813a510936c52a031f7ceefa6e1db..2cd68eddd23a4df3fbdff4cf27dc1b587467559c 100644 (file)
@@ -1,6 +1,6 @@
 # Dependencias con yield { #dependencies-with-yield }
 
-FastAPI admite dependencias que realizan algunos <abbr title='a veces también llamado "código de salida", "código de limpieza", "código de teardown", "código de cierre", "código de salida del context manager", etc.'>pasos adicionales después de finalizar</abbr>.
+FastAPI admite dependencias que realizan algunos <dfn title='a veces también llamado "código de salida", "código de limpieza", "código de teardown", "código de cierre", "código de salida del context manager", etc.'>pasos adicionales después de finalizar</dfn>.
 
 Para hacer esto, usa `yield` en lugar de `return`, y escribe los pasos adicionales (código) después.
 
@@ -29,15 +29,15 @@ Por ejemplo, podrías usar esto para crear una sesión de base de datos y cerrar
 
 Solo el código anterior e incluyendo la declaración `yield` se ejecuta antes de crear un response:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
 
 El valor generado es lo que se inyecta en *path operations* y otras dependencias:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
 
 El código posterior a la declaración `yield` se ejecuta después del response:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
 
 /// tip | Consejo
 
@@ -57,7 +57,7 @@ Por lo tanto, puedes buscar esa excepción específica dentro de la dependencia
 
 Del mismo modo, puedes usar `finally` para asegurarte de que los pasos de salida se ejecuten, sin importar si hubo una excepción o no.
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
 
 ## Sub-dependencias con `yield` { #sub-dependencies-with-yield }
 
@@ -67,7 +67,7 @@ Puedes tener sub-dependencias y "árboles" de sub-dependencias de cualquier tama
 
 Por ejemplo, `dependency_c` puede tener una dependencia de `dependency_b`, y `dependency_b` de `dependency_a`:
 
-{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
 
 Y todas ellas pueden usar `yield`.
 
@@ -75,7 +75,7 @@ En este caso, `dependency_c`, para ejecutar su código de salida, necesita que e
 
 Y, a su vez, `dependency_b` necesita que el valor de `dependency_a` (aquí llamado `dep_a`) esté disponible para su código de salida.
 
-{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
 
 De la misma manera, podrías tener algunas dependencias con `yield` y otras dependencias con `return`, y hacer que algunas de esas dependan de algunas de las otras.
 
@@ -109,7 +109,7 @@ Pero está ahí para ti si la necesitas. 🤓
 
 ///
 
-{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
+{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
 
 Si quieres capturar excepciones y crear un response personalizado en base a eso, crea un [Manejador de Excepciones Personalizado](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
 
@@ -117,7 +117,7 @@ Si quieres capturar excepciones y crear un response personalizado en base a eso,
 
 Si capturas una excepción usando `except` en una dependencia con `yield` y no la lanzas nuevamente (o lanzas una nueva excepción), FastAPI no podrá notar que hubo una excepción, al igual que sucedería con Python normal:
 
-{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
+{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
 
 En este caso, el cliente verá un response *HTTP 500 Internal Server Error* como debería, dado que no estamos lanzando una `HTTPException` o similar, pero el servidor **no tendrá ningún registro** ni ninguna otra indicación de cuál fue el error. 😱
 
@@ -127,7 +127,7 @@ Si capturas una excepción en una dependencia con `yield`, a menos que estés la
 
 Puedes volver a lanzar la misma excepción usando `raise`:
 
-{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
 
 Ahora el cliente obtendrá el mismo response *HTTP 500 Internal Server Error*, pero el servidor tendrá nuestro `InternalError` personalizado en los registros. 😎
 
@@ -190,7 +190,7 @@ Normalmente, el código de salida de las dependencias con `yield` se ejecuta **d
 
 Pero si sabes que no necesitarás usar la dependencia después de regresar de la *path operation function*, puedes usar `Depends(scope="function")` para decirle a FastAPI que debe cerrar la dependencia después de que la *path operation function* regrese, pero **antes** de que se envíe el **response**.
 
-{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
+{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
 
 `Depends()` recibe un parámetro `scope` que puede ser:
 
@@ -234,7 +234,6 @@ participant operation as Path Operation
 Las dependencias con `yield` han evolucionado con el tiempo para cubrir diferentes casos de uso y corregir algunos problemas.
 
 Si quieres ver qué ha cambiado en diferentes versiones de FastAPI, puedes leer más al respecto en la guía avanzada, en [Dependencias avanzadas - Dependencias con `yield`, `HTTPException`, `except` y Tareas en Background](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
-
 ## Context Managers { #context-managers }
 
 ### Qué son los "Context Managers" { #what-are-context-managers }
@@ -270,7 +269,7 @@ En Python, puedes crear Context Managers <a href="https://docs.python.org/3/refe
 También puedes usarlos dentro de las dependencias de **FastAPI** con `yield` usando
 `with` o `async with` en la función de dependencia:
 
-{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
 
 /// tip | Consejo
 
index ead949f1b6c6ca954ef15a5ecd16d489c6dd0681..567e69cf0c0e10837a3982bcc3c5ea9c63326ffe 100644 (file)
@@ -6,7 +6,7 @@ Similar a como puedes [agregar `dependencies` a los *path operation decorators*]
 
 En ese caso, se aplicarán a todas las *path operations* en la aplicación:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
 
 Y todas las ideas en la sección sobre [agregar `dependencies` a los *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} siguen aplicándose, pero en este caso, a todas las *path operations* en la app.
 
index a460bd8bf405afeb7d2aee8d94b951c5cf72f890..4eb31196f7c61c70e363df8423cbcf8ac015fb3e 100644 (file)
@@ -1,6 +1,6 @@
 # Dependencias { #dependencies }
 
-**FastAPI** tiene un sistema de **<abbr title="también conocido como componentes, recursos, proveedores, servicios, inyectables">Inyección de Dependencias</abbr>** muy poderoso pero intuitivo.
+**FastAPI** tiene un sistema de **<dfn title="también conocido como componentes, recursos, proveedores, servicios, inyectables">Inyección de Dependencias</dfn>** muy poderoso pero intuitivo.
 
 Está diseñado para ser muy simple de usar, y para hacer que cualquier desarrollador integre otros componentes con **FastAPI** de forma muy sencilla.
 
index e74d65d7e95ac19dfcf01e203e054a46678e8211..95f3fe8174b2b41d56ac3819a208bac7df1dd8bf 100644 (file)
@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
 
 Si una de tus dependencias se declara varias veces para la misma *path operation*, por ejemplo, múltiples dependencias tienen una sub-dependencia común, **FastAPI** sabrá llamar a esa sub-dependencia solo una vez por request.
 
-Y guardará el valor devuelto en un <abbr title="Una utilidad/sistema para almacenar valores calculados/generados, para reutilizarlos en lugar de calcularlos nuevamente.">"cache"</abbr> y lo pasará a todos los "dependants" que lo necesiten en ese request específico, en lugar de llamar a la dependencia varias veces para el mismo request.
+Y guardará el valor devuelto en un <dfn title="Una utilidad/sistema para almacenar valores calculados/generados, para reutilizarlos en lugar de calcularlos nuevamente.">"caché"</dfn> y lo pasará a todos los "dependants" que lo necesiten en ese request específico, en lugar de llamar a la dependencia varias veces para el mismo request.
 
-En un escenario avanzado donde sabes que necesitas que la dependencia se llame en cada paso (posiblemente varias veces) en el mismo request en lugar de usar el valor "cache", puedes establecer el parámetro `use_cache=False` al usar `Depends`:
+En un escenario avanzado donde sabes que necesitas que la dependencia se llame en cada paso (posiblemente varias veces) en el mismo request en lugar de usar el valor "en caché", puedes establecer el parámetro `use_cache=False` al usar `Depends`:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.9+ sin Anotaciones
+//// tab | Python 3.10+ sin Anotaciones
 
 /// tip | Consejo
 
index 319ae1bde83c6e5e35fb3f2442053e093dd9018f..df6099a8b9efc14d3bb3bec99ec4d66918eb73fc 100644 (file)
@@ -26,7 +26,7 @@ En este ejemplo, convertiría el modelo de Pydantic a un `dict`, y el `datetime`
 
 El resultado de llamarlo es algo que puede ser codificado con la función estándar de Python <a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a>.
 
-No devuelve un gran `str` que contenga los datos en formato JSON (como una cadena de texto). Devuelve una estructura de datos estándar de Python (por ejemplo, un `dict`) con valores y sub-valores que son todos compatibles con JSON.
+No devuelve un gran `str` que contenga los datos en formato JSON (como un string). Devuelve una estructura de datos estándar de Python (por ejemplo, un `dict`) con valores y sub-valores que son todos compatibles con JSON.
 
 /// note | Nota
 
index d72c73e24542c23eb4dfb785858ae1a778aeb3c7..4621b2db2e7d47e90d4c27ef439180e21f9ff78d 100644 (file)
@@ -190,9 +190,9 @@ Pero si ponemos eso en la asignación `response_model=PlaneItem | CarItem` obten
 
 De la misma manera, puedes declarar responses de listas de objetos.
 
-Para eso, usa el `typing.List` estándar de Python (o simplemente `list` en Python 3.9 y posteriores):
+Para eso, usa la `list` estándar de Python:
 
-{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
+{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
 
 ## Response con `dict` arbitrario { #response-with-arbitrary-dict }
 
@@ -200,9 +200,9 @@ También puedes declarar un response usando un `dict` arbitrario plano, declaran
 
 Esto es útil si no conoces los nombres de los campos/atributos válidos (que serían necesarios para un modelo Pydantic) de antemano.
 
-En este caso, puedes usar `typing.Dict` (o solo `dict` en Python 3.9 y posteriores):
+En este caso, puedes usar `dict`:
 
-{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
+{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
 
 ## Recapitulación { #recap }
 
index 789b2a0110641431d6c0c9d1e340fc232ca99bb2..b7ffd2c2abf315c7dbe5b6b2c06c62723ab05b82 100644 (file)
@@ -2,7 +2,7 @@
 
 El archivo FastAPI más simple podría verse así:
 
-{* ../../docs_src/first_steps/tutorial001_py39.py *}
+{* ../../docs_src/first_steps/tutorial001_py310.py *}
 
 Copia eso en un archivo `main.py`.
 
@@ -56,7 +56,7 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 Esa línea muestra la URL donde tu aplicación está siendo servida, en tu máquina local.
 
-### Compruébalo { #check-it }
+### Revisa { #check-it }
 
 Abre tu navegador en <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
 
@@ -183,7 +183,7 @@ Deploying to FastAPI Cloud...
 
 ### Paso 1: importa `FastAPI` { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
 
 `FastAPI` es una clase de Python que proporciona toda la funcionalidad para tu API.
 
@@ -197,7 +197,7 @@ Puedes usar toda la funcionalidad de <a href="https://www.starlette.dev/" class=
 
 ### Paso 2: crea una "instance" de `FastAPI` { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
 
 Aquí la variable `app` será una "instance" de la clase `FastAPI`.
 
@@ -266,12 +266,12 @@ Vamos a llamarlas "**operaciones**" también.
 
 #### Define un *path operation decorator* { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
 
 El `@app.get("/")` le dice a **FastAPI** que la función justo debajo se encarga de manejar requests que vayan a:
 
 * el path `/`
-* usando una <abbr title="un método HTTP GET"><code>get</code> operation</abbr>
+* usando una <dfn title="un método HTTP GET"><code>get</code> operación</dfn>
 
 /// info | Información sobre `@decorator`
 
@@ -320,7 +320,7 @@ Esta es nuestra "**path operation function**":
 * **operation**: es `get`.
 * **function**: es la función debajo del "decorador" (debajo de `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
 
 Esta es una función de Python.
 
@@ -332,7 +332,7 @@ En este caso, es una función `async`.
 
 También podrías definirla como una función normal en lugar de `async def`:
 
-{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
 
 /// note | Nota
 
@@ -342,7 +342,7 @@ Si no sabes la diferencia, Revisa la sección [Async: *"¿Tienes prisa?"*](../as
 
 ### Paso 5: retorna el contenido { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
 
 Puedes retornar un `dict`, `list`, valores singulares como `str`, `int`, etc.
 
index 71e0563203f86fa618d558b2583c74e7c6fe71f4..265269e8746dfd2ada1b6eb74c553bf9c778c915 100644 (file)
@@ -25,7 +25,7 @@ Para devolver responses HTTP con errores al cliente, usa `HTTPException`.
 
 ### Importa `HTTPException` { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
 
 ### Lanza un `HTTPException` en tu código { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@ El beneficio de lanzar una excepción en lugar de `return`ar un valor será más
 
 En este ejemplo, cuando el cliente solicita un ítem por un ID que no existe, lanza una excepción con un código de estado de `404`:
 
-{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
 
 ### El response resultante { #the-resulting-response }
 
@@ -77,7 +77,7 @@ Probablemente no necesitarás usarlos directamente en tu código.
 
 Pero en caso de que los necesites para un escenario avanzado, puedes agregar headers personalizados:
 
-{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
 
 ## Instalar manejadores de excepciones personalizados { #install-custom-exception-handlers }
 
@@ -89,7 +89,7 @@ Y quieres manejar esta excepción globalmente con FastAPI.
 
 Podrías agregar un manejador de excepciones personalizado con `@app.exception_handler()`:
 
-{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
 
 Aquí, si solicitas `/unicorns/yolo`, la *path operation* lanzará un `UnicornException`.
 
@@ -127,7 +127,7 @@ Para sobrescribirlo, importa el `RequestValidationError` y úsalo con `@app.exce
 
 El manejador de excepciones recibirá un `Request` y la excepción.
 
-{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
 
 Ahora, si vas a `/items/foo`, en lugar de obtener el error JSON por defecto con:
 
@@ -159,7 +159,7 @@ De la misma manera, puedes sobrescribir el manejador de `HTTPException`.
 
 Por ejemplo, podrías querer devolver un response de texto plano en lugar de JSON para estos errores:
 
-{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
 
 /// note | Nota Técnica
 
@@ -183,7 +183,7 @@ El `RequestValidationError` contiene el `body` que recibió con datos inválidos
 
 Podrías usarlo mientras desarrollas tu aplicación para registrar el body y depurarlo, devolverlo al usuario, etc.
 
-{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
 
 Ahora intenta enviar un ítem inválido como:
 
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 Si quieres usar la excepción junto con los mismos manejadores de excepciones predeterminados de **FastAPI**, puedes importar y reutilizar los manejadores de excepciones predeterminados de `fastapi.exception_handlers`:
 
-{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
 
 En este ejemplo solo estás `print`eando el error con un mensaje muy expresivo, pero te haces una idea. Puedes usar la excepción y luego simplemente reutilizar los manejadores de excepciones predeterminados.
index a5d9b5eadca039cb34f0908c21c04edd133d0643..2163a1cb2275d9affd90ab9f0d58b66fbedc5bb2 100644 (file)
@@ -18,7 +18,7 @@ Puedes establecer los siguientes campos que se usan en la especificación OpenAP
 
 Puedes configurarlos de la siguiente manera:
 
-{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
 
 /// tip | Consejo
 
@@ -36,7 +36,7 @@ Desde OpenAPI 3.1.0 y FastAPI 0.99.0, también puedes establecer la `license_inf
 
 Por ejemplo:
 
-{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
 
 ## Metadata para etiquetas { #metadata-for-tags }
 
@@ -58,7 +58,7 @@ Probemos eso en un ejemplo con etiquetas para `users` y `items`.
 
 Crea metadata para tus etiquetas y pásala al parámetro `openapi_tags`:
 
-{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
 
 Nota que puedes utilizar Markdown dentro de las descripciones, por ejemplo "login" se mostrará en negrita (**login**) y "fancy" se mostrará en cursiva (_fancy_).
 
@@ -72,7 +72,7 @@ No tienes que agregar metadata para todas las etiquetas que uses.
 
 Usa el parámetro `tags` con tus *path operations* (y `APIRouter`s) para asignarlas a diferentes etiquetas:
 
-{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
 
 /// info | Información
 
@@ -100,7 +100,7 @@ Pero puedes configurarlo con el parámetro `openapi_url`.
 
 Por ejemplo, para configurarlo para que se sirva en `/api/v1/openapi.json`:
 
-{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
 
 Si quieres deshabilitar el esquema OpenAPI completamente, puedes establecer `openapi_url=None`, eso también deshabilitará las interfaces de usuario de documentación que lo usan.
 
@@ -117,4 +117,4 @@ Puedes configurar las dos interfaces de usuario de documentación incluidas:
 
 Por ejemplo, para configurar Swagger UI para que se sirva en `/documentation` y deshabilitar ReDoc:
 
-{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}
index de636a48541eed1b8ca6238111856a543f1e6dbe..766e30cad650bf84c3719d7057d3d4b199d782fb 100644 (file)
@@ -31,7 +31,7 @@ La función middleware recibe:
     * Luego devuelve la `response` generada por la correspondiente *path operation*.
 * Puedes entonces modificar aún más la `response` antes de devolverla.
 
-{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
 
 /// tip | Consejo
 
@@ -57,7 +57,7 @@ Y también después de que se genere la `response`, antes de devolverla.
 
 Por ejemplo, podrías añadir un custom header `X-Process-Time` que contenga el tiempo en segundos que tomó procesar la request y generar una response:
 
-{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
 
 /// tip | Consejo
 
index f57b322fbb6a0e6360faa1094187d59d021b8fc4..90e4335b3b506f685606640dbe80e9a3a41f2c18 100644 (file)
@@ -46,7 +46,7 @@ En estos casos, podría tener sentido almacenar las tags en un `Enum`.
 
 **FastAPI** soporta eso de la misma manera que con strings normales:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
 
 ## Resumen y Descripción { #summary-and-description }
 
@@ -56,7 +56,7 @@ Puedes añadir un `summary` y `description`:
 
 ## Descripción desde docstring { #description-from-docstring }
 
-Como las descripciones tienden a ser largas y cubrir múltiples líneas, puedes declarar la descripción de la *path operation* en la <abbr title="un string de múltiples líneas como la primera expresión dentro de una función (no asignada a ninguna variable) usada para documentación">docstring</abbr> de la función y **FastAPI** la leerá desde allí.
+Como las descripciones tienden a ser largas y cubrir múltiples líneas, puedes declarar la descripción de la *path operation* en la <dfn title="un string de múltiples líneas como la primera expresión dentro de una función (no asignada a ninguna variable) usada para documentación">docstring</dfn> de la función y **FastAPI** la leerá desde allí.
 
 Puedes escribir <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> en el docstring, se interpretará y mostrará correctamente (teniendo en cuenta la indentación del docstring).
 
@@ -90,9 +90,9 @@ Entonces, si no proporcionas una, **FastAPI** generará automáticamente una de
 
 ## Deprecar una *path operation* { #deprecate-a-path-operation }
 
-Si necesitas marcar una *path operation* como <abbr title="obsoleta, se recomienda no usarla">deprecated</abbr>, pero sin eliminarla, pasa el parámetro `deprecated`:
+Si necesitas marcar una *path operation* como <dfn title="obsoleta, se recomienda no usarla">deprecated</dfn>, pero sin eliminarla, pasa el parámetro `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
 
 Se marcará claramente como deprecado en la documentación interactiva:
 
index 569dd03dd08a87e46e6678b83d07d41c926d66eb..3a38d1d63c4dd7fcf81499b9579074f177c2fcc9 100644 (file)
@@ -2,7 +2,7 @@
 
 De la misma manera que puedes declarar más validaciones y metadatos para los parámetros de query con `Query`, puedes declarar el mismo tipo de validaciones y metadatos para los parámetros de path con `Path`.
 
-## Importar Path { #import-path }
+## Importar `Path` { #import-path }
 
 Primero, importa `Path` de `fastapi`, e importa `Annotated`:
 
@@ -46,19 +46,19 @@ Y no necesitas declarar nada más para ese parámetro, así que realmente no nec
 
 Pero aún necesitas usar `Path` para el parámetro de path `item_id`. Y no quieres usar `Annotated` por alguna razón.
 
-Python se quejará si pones un valor con un "default" antes de un valor que no tenga un "default".
+Python se quejará si pones un valor con "por defecto" antes de un valor que no tenga "por defecto".
 
-Pero puedes reordenarlos y poner el valor sin un default (el parámetro de query `q`) primero.
+Pero puedes reordenarlos y poner el valor sin un valor por defecto (el parámetro de query `q`) primero.
 
-No importa para **FastAPI**. Detectará los parámetros por sus nombres, tipos y declaraciones por defecto (`Query`, `Path`, etc.), no le importa el orden.
+No importa para **FastAPI**. Detectará los parámetros por sus nombres, tipos y declaraciones por defecto (`Query`, `Path`, etc), no le importa el orden.
 
 Así que puedes declarar tu función como:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
 
 Pero ten en cuenta que si usas `Annotated`, no tendrás este problema, no importará ya que no estás usando los valores por defecto de los parámetros de la función para `Query()` o `Path()`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
 
 ## Ordena los parámetros como necesites, trucos { #order-the-parameters-as-you-need-tricks }
 
@@ -83,13 +83,13 @@ Pasa `*`, como el primer parámetro de la función.
 
 Python no hará nada con ese `*`, pero sabrá que todos los parámetros siguientes deben ser llamados como argumentos de palabras clave (parejas key-value), también conocidos como <abbr title="De: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Incluso si no tienen un valor por defecto.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
 
 ### Mejor con `Annotated` { #better-with-annotated }
 
 Ten en cuenta que si usas `Annotated`, como no estás usando valores por defecto de los parámetros de la función, no tendrás este problema y probablemente no necesitarás usar `*`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
 
 ## Validaciones numéricas: mayor o igual { #number-validations-greater-than-or-equal }
 
@@ -97,7 +97,7 @@ Con `Query` y `Path` (y otros que verás más adelante) puedes declarar restricc
 
 Aquí, con `ge=1`, `item_id` necesitará ser un número entero "`g`reater than or `e`qual" a `1`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
 
 ## Validaciones numéricas: mayor que y menor o igual { #number-validations-greater-than-and-less-than-or-equal }
 
@@ -106,19 +106,19 @@ Lo mismo aplica para:
 * `gt`: `g`reater `t`han
 * `le`: `l`ess than or `e`qual
 
-{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
 
 ## Validaciones numéricas: flotantes, mayor y menor { #number-validations-floats-greater-than-and-less-than }
 
 Las validaciones numéricas también funcionan para valores `float`.
 
-Aquí es donde se convierte en importante poder declarar <abbr title="greater than – mayor que"><code>gt</code></abbr> y no solo <abbr title="greater than or equal – mayor o igual que"><code>ge</code></abbr>. Ya que con esto puedes requerir, por ejemplo, que un valor sea mayor que `0`, incluso si es menor que `1`.
+Aquí es donde se convierte en importante poder declarar <abbr title="greater than - mayor que"><code>gt</code></abbr> y no solo <abbr title="greater than or equal - mayor o igual que"><code>ge</code></abbr>. Ya que con esto puedes requerir, por ejemplo, que un valor sea mayor que `0`, incluso si es menor que `1`.
 
 Así, `0.5` sería un valor válido. Pero `0.0` o `0` no lo serían.
 
-Y lo mismo para <abbr title="less than  menor que"><code>lt</code></abbr>.
+Y lo mismo para <abbr title="less than - menor que"><code>lt</code></abbr>.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
 
 ## Resumen { #recap }
 
index 7ba49f3b0b2ef0d1e814ea9275be1941be424a74..8dc3db351d3c02f0e7d3d31aa3fd4d2c090db40d 100644 (file)
@@ -2,7 +2,7 @@
 
 Puedes declarar "parámetros" o "variables" de path con la misma sintaxis que se usa en los format strings de Python:
 
-{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
 
 El valor del parámetro de path `item_id` se pasará a tu función como el argumento `item_id`.
 
@@ -16,7 +16,7 @@ Así que, si ejecutas este ejemplo y vas a <a href="http://127.0.0.1:8000/items/
 
 Puedes declarar el tipo de un parámetro de path en la función, usando anotaciones de tipos estándar de Python:
 
-{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
 
 En este caso, `item_id` se declara como un `int`.
 
@@ -26,7 +26,7 @@ Esto te dará soporte del editor dentro de tu función, con chequeo de errores,
 
 ///
 
-## <abbr title="también conocido como: serialización, parsing, marshalling">Conversión</abbr> de datos { #data-conversion }
+## <dfn title="también conocido como: serialización, parsing, marshalling">Conversión</dfn> de datos { #data-conversion }
 
 Si ejecutas este ejemplo y abres tu navegador en <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, verás un response de:
 
@@ -38,7 +38,7 @@ Si ejecutas este ejemplo y abres tu navegador en <a href="http://127.0.0.1:8000/
 
 Nota que el valor que tu función recibió (y devolvió) es `3`, como un `int` de Python, no un string `"3"`.
 
-Entonces, con esa declaración de tipo, **FastAPI** te ofrece <abbr title="convertir el string que viene de un request HTTP en datos de Python">"parsing"</abbr> automático de request.
+Entonces, con esa declaración de tipo, **FastAPI** te ofrece <dfn title="convertir el string que viene de un request HTTP en datos de Python">"parsing"</dfn> automático de request.
 
 ///
 
@@ -118,13 +118,13 @@ Y luego también puedes tener un path `/users/{user_id}` para obtener datos sobr
 
 Debido a que las *path operations* se evalúan en orden, necesitas asegurarte de que el path para `/users/me` se declara antes que el de `/users/{user_id}`:
 
-{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
 
 De lo contrario, el path para `/users/{user_id}` también coincidiría para `/users/me`, "pensando" que está recibiendo un parámetro `user_id` con un valor de `"me"`.
 
 De manera similar, no puedes redefinir una path operation:
 
-{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
 
 La primera siempre será utilizada ya que el path coincide primero.
 
@@ -140,11 +140,11 @@ Al heredar de `str`, la documentación de la API podrá saber que los valores de
 
 Luego crea atributos de clase con valores fijos, que serán los valores válidos disponibles:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
 
 /// tip | Consejo
 
-Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de <abbr title="Técnicamente, arquitecturas de modelos de Deep Learning">modelos</abbr> de Machine Learning.
+Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de <dfn title="Técnicamente, arquitecturas de modelos de Deep Learning">modelos</dfn> de Machine Learning.
 
 ///
 
@@ -152,7 +152,7 @@ Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de <abb
 
 Luego crea un *path parameter* con una anotación de tipo usando la clase enum que creaste (`ModelName`):
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
 
 ### Revisa la documentación { #check-the-docs }
 
@@ -168,13 +168,13 @@ El valor del *path parameter* será un *miembro* de enumeración.
 
 Puedes compararlo con el *miembro* de enumeración en tu enum creada `ModelName`:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
 
 #### Obtener el valor de *enumeración* { #get-the-enumeration-value }
 
 Puedes obtener el valor actual (un `str` en este caso) usando `model_name.value`, o en general, `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
 
 /// tip | Consejo
 
@@ -188,7 +188,7 @@ Puedes devolver *miembros de enum* desde tu *path operation*, incluso anidados e
 
 Serán convertidos a sus valores correspondientes (cadenas en este caso) antes de devolverlos al cliente:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
 
 En tu cliente recibirás un response JSON como:
 
@@ -227,7 +227,7 @@ En este caso, el nombre del parámetro es `file_path`, y la última parte, `:pat
 
 Así que, puedes usarlo con:
 
-{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
 
 /// tip | Consejo
 
@@ -242,7 +242,7 @@ En ese caso, la URL sería: `/files//home/johndoe/myfile.txt`, con una doble bar
 Con **FastAPI**, al usar declaraciones de tipo estándar de Python, cortas e intuitivas, obtienes:
 
 * Soporte del editor: chequeo de errores, autocompletado, etc.
-* "<abbr title="convertir el string que viene de un request HTTP en datos de Python">parsing</abbr>" de datos
+* " <dfn title="convertir el string que viene de un request HTTP en datos de Python">parsing</dfn> " de datos
 * Validación de datos
 * Anotación de API y documentación automática
 
index 4af4782f835dd46a08d09d7e0ebf6c71f6d3e739..b4339e1931a792d1b105c75b36efbde9a3cf6d48 100644 (file)
@@ -18,7 +18,7 @@ Tener `str | None` permitirá que tu editor te dé un mejor soporte y detecte er
 
 ## Validaciones adicionales { #additional-validation }
 
-Vamos a hacer que, aunque `q` sea opcional, siempre que se proporcione, **su longitud no exceda los 50 caracteres**.
+Vamos a hacer que, aunque `q` sea opcional, siempre que se proporcione, su longitud no exceda los 50 caracteres.
 
 ### Importar `Query` y `Annotated` { #import-query-and-annotated }
 
@@ -47,40 +47,16 @@ Ahora es el momento de usarlo con FastAPI. 🚀
 
 Teníamos esta anotación de tipo:
 
-//// tab | Python 3.10+
-
 ```Python
 q: str | None = None
 ```
 
-////
-
-//// tab | Python 3.9+
-
-```Python
-q: Union[str, None] = None
-```
-
-////
-
 Lo que haremos es envolver eso con `Annotated`, para que se convierta en:
 
-//// tab | Python 3.10+
-
 ```Python
 q: Annotated[str | None] = None
 ```
 
-////
-
-//// tab | Python 3.9+
-
-```Python
-q: Annotated[Union[str, None]] = None
-```
-
-////
-
 Ambas versiones significan lo mismo, `q` es un parámetro que puede ser un `str` o `None`, y por defecto, es `None`.
 
 Ahora vamos a lo divertido. 🎉
@@ -93,7 +69,7 @@ Ahora que tenemos este `Annotated` donde podemos poner más información (en est
 
 Nota que el valor por defecto sigue siendo `None`, por lo que el parámetro sigue siendo opcional.
 
-Pero ahora, al tener `Query(max_length=50)` dentro de `Annotated`, le estamos diciendo a FastAPI que queremos que tenga **validación adicional** para este valor, queremos que tenga un máximo de 50 caracteres. 😎
+Pero ahora, al tener `Query(max_length=50)` dentro de `Annotated`, le estamos diciendo a FastAPI que queremos que tenga validación adicional para este valor, queremos que tenga un máximo de 50 caracteres. 😎
 
 /// tip | Consejo
 
@@ -103,13 +79,13 @@ Aquí estamos usando `Query()` porque este es un **parámetro de query**. Más a
 
 FastAPI ahora:
 
-* **Validará** los datos asegurándose de que la longitud máxima sea de 50 caracteres
-* Mostrará un **error claro** para el cliente cuando los datos no sean válidos
-* **Documentará** el parámetro en el OpenAPI esquema *path operation* (así aparecerá en la **UI de documentación automática**)
+* Validará los datos asegurándose de que la longitud máxima sea de 50 caracteres
+* Mostrará un error claro para el cliente cuando los datos no sean válidos
+* Documentará el parámetro en el OpenAPI esquema *path operation* (así aparecerá en la UI de documentación automática)
 
 ## Alternativa (antigua): `Query` como valor por defecto { #alternative-old-query-as-the-default-value }
 
-Versiones anteriores de FastAPI (antes de <abbr title="before 2023-03 - antes de 2023-03">0.95.0</abbr>) requerían que usaras `Query` como el valor por defecto de tu parámetro, en lugar de ponerlo en `Annotated`, hay una alta probabilidad de que veas código usándolo alrededor, así que te lo explicaré.
+Versiones anteriores de FastAPI (antes de <dfn title="antes de 2023-03">0.95.0</dfn>) requerían que usaras `Query` como el valor por defecto de tu parámetro, en lugar de ponerlo en `Annotated`, hay una alta probabilidad de que veas código usándolo alrededor, así que te lo explicaré.
 
 /// tip | Consejo
 
@@ -174,13 +150,13 @@ q: str = Query(default="rick")
 
 ### Ventajas de `Annotated` { #advantages-of-annotated }
 
-**Usar `Annotated` es recomendado** en lugar del valor por defecto en los parámetros de función, es **mejor** por múltiples razones. 🤓
+Usar `Annotated` es recomendado en lugar del valor por defecto en los parámetros de función, es mejor por múltiples razones. 🤓
 
-El valor **por defecto** del **parámetro de función** es el valor **real por defecto**, eso es más intuitivo con Python en general. 😌
+El valor por defecto del parámetro de función es el valor real por defecto, eso es más intuitivo con Python en general. 😌
 
-Podrías **llamar** a esa misma función en **otros lugares** sin FastAPI, y **funcionaría como se espera**. Si hay un parámetro **requerido** (sin un valor por defecto), tu **editor** te avisará con un error, **Python** también se quejará si lo ejecutas sin pasar el parámetro requerido.
+Podrías llamar a esa misma función en otros lugares sin FastAPI, y funcionaría como se espera. Si hay un parámetro requerido (sin un valor por defecto), tu editor te avisará con un error, Python también se quejará si lo ejecutas sin pasar el parámetro requerido.
 
-Cuando no usas `Annotated` y en su lugar usas el estilo de valor por defecto **(antiguo)**, si llamas a esa función sin FastAPI en **otros lugares**, tienes que **recordar** pasar los argumentos a la función para que funcione correctamente, de lo contrario, los valores serán diferentes de lo que esperas (por ejemplo, `QueryInfo` o algo similar en lugar de `str`). Y tu editor no se quejará, y Python no se quejará al ejecutar esa función, solo cuando los errores dentro de las operaciones hagan que funcione incorrectamente.
+Cuando no usas `Annotated` y en su lugar usas el estilo de valor por defecto (antiguo), si llamas a esa función sin FastAPI en otros lugares, tienes que recordar pasar los argumentos a la función para que funcione correctamente, de lo contrario, los valores serán diferentes de lo que esperas (por ejemplo, `QueryInfo` o algo similar en lugar de `str`). Y tu editor no se quejará, y Python no se quejará al ejecutar esa función, solo cuando los errores dentro de las operaciones hagan que funcione incorrectamente.
 
 Dado que `Annotated` puede tener más de una anotación de metadato, ahora podrías incluso usar la misma función con otras herramientas, como <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a>. 🚀
 
@@ -192,7 +168,7 @@ También puedes agregar un parámetro `min_length`:
 
 ## Agregar expresiones regulares { #add-regular-expressions }
 
-Puedes definir una <abbr title="Una expresión regular, regex o regexp es una secuencia de caracteres que define un patrón de búsqueda para strings.">expresión regular</abbr> `pattern` que el parámetro debe coincidir:
+Puedes definir una <dfn title="Una expresión regular, regex o regexp es una secuencia de caracteres que define un patrón de búsqueda para strings.">expresión regular</dfn> `pattern` que el parámetro debe coincidir:
 
 {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
 
@@ -202,7 +178,7 @@ Este patrón específico de expresión regular comprueba que el valor recibido d
 * `fixedquery`: tiene el valor exacto `fixedquery`.
 * `$`: termina allí, no tiene más caracteres después de `fixedquery`.
 
-Si te sientes perdido con todas estas ideas de **"expresión regular"**, no te preocupes. Son un tema difícil para muchas personas. Aún puedes hacer muchas cosas sin necesitar expresiones regulares todavía.
+Si te sientes perdido con todas estas ideas de "expresión regular", no te preocupes. Son un tema difícil para muchas personas. Aún puedes hacer muchas cosas sin necesitar expresiones regulares todavía.
 
 Ahora sabes que cuando las necesites puedes usarlas en **FastAPI**.
 
@@ -212,7 +188,7 @@ Puedes, por supuesto, usar valores por defecto diferentes de `None`.
 
 Digamos que quieres declarar el parámetro de query `q` para que tenga un `min_length` de `3`, y para que tenga un valor por defecto de `"fixedquery"`:
 
-{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
 
 /// note | Nota
 
@@ -242,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
 
 Así que, cuando necesites declarar un valor como requerido mientras usas `Query`, simplemente puedes no declarar un valor por defecto:
 
-{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
 
 ### Requerido, puede ser `None` { #required-can-be-none }
 
@@ -293,7 +269,7 @@ La documentación interactiva de API se actualizará en consecuencia, para permi
 
 También puedes definir un valor por defecto `list` de valores si no se proporciona ninguno:
 
-{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
 
 Si vas a:
 
@@ -316,7 +292,7 @@ el valor por defecto de `q` será: `["foo", "bar"]` y tu response será:
 
 También puedes usar `list` directamente en lugar de `list[str]`:
 
-{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
 
 /// note | Nota
 
@@ -372,7 +348,7 @@ Entonces puedes declarar un `alias`, y ese alias será usado para encontrar el v
 
 Ahora digamos que ya no te gusta este parámetro.
 
-Tienes que dejarlo allí por un tiempo porque hay clientes usándolo, pero quieres que la documentación lo muestre claramente como <abbr title="obsolete, recommended not to use it - obsoleto, se recomienda no usarlo">deprecated</abbr>.
+Tienes que dejarlo allí por un tiempo porque hay clientes usándolo, pero quieres que la documentación lo muestre claramente como <dfn title="obsoleto, se recomienda no usarlo">obsoleto</dfn>.
 
 Luego pasa el parámetro `deprecated=True` a `Query`:
 
@@ -390,9 +366,9 @@ Para excluir un parámetro de query del esquema de OpenAPI generado (y por lo ta
 
 ## Validación personalizada { #custom-validation }
 
-Podría haber casos donde necesites hacer alguna **validación personalizada** que no puede hacerse con los parámetros mostrados arriba.
+Podría haber casos donde necesites hacer alguna validación personalizada que no puede hacerse con los parámetros mostrados arriba.
 
-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`).
+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 <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">`AfterValidator` de Pydantic</a> dentro de `Annotated`.
 
@@ -402,7 +378,7 @@ Pydantic también tiene <a href="https://docs.pydantic.dev/latest/concepts/valid
 
 ///
 
-Por ejemplo, este validador personalizado comprueba que el ID del ítem empiece con `isbn-` para un número de libro <abbr title="ISBN means International Standard Book Number - ISBN significa International Standard Book Number">ISBN</abbr> o con `imdb-` para un ID de URL de película de <abbr title="IMDB (Internet Movie Database) is a website with information about movies - IMDB (Internet Movie Database) es un sitio web con información sobre películas">IMDB</abbr>:
+Por ejemplo, este validador personalizado comprueba que el ID del ítem empiece con `isbn-` para un número de libro <abbr title="International Standard Book Number - Número Estándar Internacional de Libros">ISBN</abbr> o con `imdb-` para un ID de URL de película de <abbr title="Internet Movie Database - Base de datos de películas en Internet: un sitio web con información sobre películas">IMDB</abbr>:
 
 {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
 
@@ -414,15 +390,15 @@ Esto está disponible con Pydantic versión 2 o superior. 😎
 
 /// tip | Consejo
 
-Si necesitas hacer cualquier tipo de validación que requiera comunicarte con algún **componente externo**, como una base de datos u otra API, deberías usar **Dependencias de FastAPI**, las aprenderás más adelante.
+Si necesitas hacer cualquier tipo de validación que requiera comunicarte con algún componente externo, como una base de datos u otra API, deberías usar Dependencias de FastAPI, las aprenderás más adelante.
 
-Estos validadores personalizados son para cosas que pueden comprobarse **solo** con los **mismos datos** provistos en el request.
+Estos validadores personalizados son para cosas que pueden comprobarse solo con los mismos datos provistos en el request.
 
 ///
 
 ### Entiende ese código { #understand-that-code }
 
-El punto importante es solo usar **`AfterValidator` con una función dentro de `Annotated`**. Si quieres, sáltate esta parte. 🤸
+El punto importante es solo usar `AfterValidator` con una función dentro de `Annotated`. Si quieres, sáltate esta parte. 🤸
 
 ---
 
@@ -436,17 +412,17 @@ Pero si te da curiosidad este ejemplo de código específico y sigues entretenid
 
 #### Un ítem aleatorio { #a-random-item }
 
-Con `data.items()` obtenemos un <abbr title="Algo que podemos iterar con un for loop, como una list, set, etc.">objeto iterable</abbr> con tuplas que contienen la clave y el valor para cada elemento del diccionario.
+Con `data.items()` obtenemos un <dfn title="Algo que podemos iterar con un for loop, como una list, set, etc.">objeto iterable</dfn> con tuplas que contienen la clave y el valor para cada elemento del diccionario.
 
 Convertimos este objeto iterable en una `list` propiamente dicha con `list(data.items())`.
 
-Luego con `random.choice()` podemos obtener un **valor aleatorio** de la lista, así que obtenemos una tupla con `(id, name)`. Será algo como `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
+Luego con `random.choice()` podemos obtener un valor aleatorio de la lista, así que obtenemos una tupla con `(id, name)`. Será algo como `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
 
-Luego **asignamos esos dos valores** de la tupla a las variables `id` y `name`.
+Luego asignamos esos dos valores de la tupla a las variables `id` y `name`.
 
 Así, si el usuario no proporcionó un ID de ítem, aún recibirá una sugerencia aleatoria.
 
-...hacemos todo esto en una **sola línea simple**. 🤯 ¿No te encanta Python? 🐍
+...hacemos todo esto en una sola línea simple. 🤯 ¿No te encanta Python? 🐍
 
 {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
 
index 2b58a2b4b6704942305385232610b958ed1a8179..edbe51a0ea9ee3f86a573ee44e4d603f9713debc 100644 (file)
@@ -2,7 +2,7 @@
 
 Cuando declaras otros parámetros de función que no son parte de los parámetros de path, son automáticamente interpretados como parámetros de "query".
 
-{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
 
 La query es el conjunto de pares clave-valor que van después del `?` en una URL, separados por caracteres `&`.
 
@@ -24,7 +24,7 @@ Pero cuando los declaras con tipos de Python (en el ejemplo anterior, como `int`
 Todo el mismo proceso que se aplica para los parámetros de path también se aplica para los parámetros de query:
 
 * Soporte del editor (obviamente)
-* <abbr title="convirtiendo el string que viene de un request HTTP en datos de Python">"parsing"</abbr> de datos
+* <dfn title="convirtiendo el string que viene de un request HTTP en datos de Python">"parsing"</dfn> de datos
 * Validación de datos
 * Documentación automática
 
@@ -127,7 +127,7 @@ Si no quieres agregar un valor específico pero solo hacer que sea opcional, est
 
 Pero cuando quieres hacer un parámetro de query requerido, simplemente no declares ningún valor por defecto:
 
-{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
 
 Aquí el parámetro de query `needy` es un parámetro de query requerido de tipo `str`.
 
index cc99deb2e3f8c765039c486b3c64955c547ab355..717968d7418a0e29ca669b62fe1e6c9a58da6b2c 100644 (file)
@@ -20,13 +20,13 @@ Esto es porque los archivos subidos se envían como "form data".
 
 Importa `File` y `UploadFile` desde `fastapi`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
 
 ## Definir Parámetros `File` { #define-file-parameters }
 
 Crea parámetros de archivo de la misma manera que lo harías para `Body` o `Form`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
 
 /// info | Información
 
@@ -54,7 +54,7 @@ Pero hay varios casos en los que podrías beneficiarte de usar `UploadFile`.
 
 Define un parámetro de archivo con un tipo de `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
 
 Usar `UploadFile` tiene varias ventajas sobre `bytes`:
 
@@ -121,7 +121,7 @@ Los datos de los forms normalmente se codifican usando el "media type" `applicat
 
 Pero cuando el formulario incluye archivos, se codifica como `multipart/form-data`. Si usas `File`, **FastAPI** sabrá que tiene que obtener los archivos de la parte correcta del cuerpo.
 
-Si deseas leer más sobre estas codificaciones y campos de formularios, dirígete a la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network  Red de Desarrolladores de Mozilla">MDN</abbr> web docs para <code>POST</code></a>.
+Si deseas leer más sobre estas codificaciones y campos de formularios, dirígete a la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla">MDN</abbr> web docs para <code>POST</code></a>.
 
 ///
 
@@ -143,7 +143,7 @@ Puedes hacer un archivo opcional utilizando anotaciones de tipos estándar y est
 
 También puedes usar `File()` con `UploadFile`, por ejemplo, para establecer metadatos adicionales:
 
-{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
+{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
 
 ## Subidas de Múltiples Archivos { #multiple-file-uploads }
 
@@ -151,9 +151,9 @@ Es posible subir varios archivos al mismo tiempo.
 
 Estarían asociados al mismo "campo de formulario" enviado usando "form data".
 
-Para usar eso, declara una lista de `bytes` o `UploadFile`:
+Para usar eso, declara una `list` de `bytes` o `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
+{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
 
 Recibirás, como se declaró, una `list` de `bytes` o `UploadFile`s.
 
@@ -169,7 +169,7 @@ También podrías usar `from starlette.responses import HTMLResponse`.
 
 Y de la misma manera que antes, puedes usar `File()` para establecer parámetros adicionales, incluso para `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
+{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
 
 ## Recapitulación { #recap }
 
index 1f4668c8400748cd7fe6205ac13c7667bd70725b..9afadf0b2ee7de1d20e73e7255f4be5d8a97c8a0 100644 (file)
@@ -24,7 +24,7 @@ Esto es compatible desde la versión `0.113.0` de FastAPI. 🤓
 
 Solo necesitas declarar un **modelo de Pydantic** con los campos que quieres recibir como **campos de formulario**, y luego declarar el parámetro como `Form`:
 
-{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
+{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
 
 **FastAPI** **extraerá** los datos de **cada campo** de los **form data** en el request y te dará el modelo de Pydantic que definiste.
 
@@ -48,7 +48,7 @@ Esto es compatible desde la versión `0.114.0` de FastAPI. 🤓
 
 Puedes usar la configuración del modelo de Pydantic para `forbid` cualquier campo `extra`:
 
-{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
+{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
 
 Si un cliente intenta enviar datos extra, recibirá un response de **error**.
 
index 363553e8627114f0a65e12be06fc7ad4639e6422..738a2bc4b404b38deedd0090d5be08304034a8f9 100644 (file)
@@ -16,13 +16,13 @@ $ pip install python-multipart
 
 ## Importa `File` y `Form` { #import-file-and-form }
 
-{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
 
 ## Define parámetros `File` y `Form` { #define-file-and-form-parameters }
 
 Crea parámetros de archivo y formulario de la misma manera que lo harías para `Body` o `Query`:
 
-{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
 
 Los archivos y campos de formulario se subirán como form data y recibirás los archivos y campos de formulario.
 
index 33061e6a1b431afd6aee0744a4d858b0f088f386..cc29296eed5a5c273caba3479f5bf29b9d970069 100644 (file)
@@ -18,17 +18,17 @@ $ pip install python-multipart
 
 Importar `Form` desde `fastapi`:
 
-{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
 
 ## Definir parámetros de `Form` { #define-form-parameters }
 
 Crea parámetros de formulario de la misma manera que lo harías para `Body` o `Query`:
 
-{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
 
 Por ejemplo, en una de las formas en las que se puede usar la especificación OAuth2 (llamada "password flow") se requiere enviar un `username` y `password` como campos de formulario.
 
-La <abbr title="specification – especificación">spec</abbr> requiere que los campos se llamen exactamente `username` y `password`, y que se envíen como campos de formulario, no JSON.
+La <dfn title="especificación">especificación</dfn> requiere que los campos se llamen exactamente `username` y `password`, y que se envíen como campos de formulario, no JSON.
 
 Con `Form` puedes declarar las mismas configuraciones que con `Body` (y `Query`, `Path`, `Cookie`), incluyendo validación, ejemplos, un alias (por ejemplo, `user-name` en lugar de `username`), etc.
 
@@ -56,7 +56,7 @@ Los datos de formularios normalmente se codifican usando el "media type" `applic
 
 Pero cuando el formulario incluye archivos, se codifica como `multipart/form-data`. Leerás sobre la gestión de archivos en el próximo capítulo.
 
-Si quieres leer más sobre estas codificaciones y campos de formulario, dirígete a la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network  Red de Desarrolladores de Mozilla">MDN</abbr> web docs para <code>POST</code></a>.
+Si quieres leer más sobre estas codificaciones y campos de formulario, dirígete a la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla">MDN</abbr> web docs para <code>POST</code></a>.
 
 ///
 
index 8cfe69e782328cf04a67a5ab39498208814014f8..c9e931d47765bec328dab74076b33d12d5107007 100644 (file)
@@ -51,7 +51,7 @@ FastAPI usará este `response_model` para hacer toda la documentación de datos,
 
 /// tip | Consejo
 
-Si tienes chequeos estrictos de tipos en tu editor, mypy, etc., puedes declarar el tipo de retorno de la función como `Any`.
+Si tienes chequeo de tipos estricto en tu editor, mypy, etc., puedes declarar el tipo de retorno de la función como `Any`.
 
 De esa manera le dices al editor que intencionalmente estás devolviendo cualquier cosa. Pero FastAPI todavía hará la documentación de datos, validación, filtrado, etc. con `response_model`.
 
@@ -183,7 +183,7 @@ Podría haber casos en los que devuelvas algo que no es un campo válido de Pyda
 
 El caso más común sería [devolver un Response directamente como se explica más adelante en la documentación avanzada](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
 
 Este caso simple es manejado automáticamente por FastAPI porque la anotación del tipo de retorno es la clase (o una subclase de) `Response`.
 
@@ -193,7 +193,7 @@ Y las herramientas también estarán felices porque tanto `RedirectResponse` com
 
 También puedes usar una subclase de `Response` en la anotación del tipo:
 
-{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
 
 Esto también funcionará porque `RedirectResponse` es una subclase de `Response`, y FastAPI manejará automáticamente este caso simple.
 
@@ -201,7 +201,7 @@ Esto también funcionará porque `RedirectResponse` es una subclase de `Response
 
 Pero cuando devuelves algún otro objeto arbitrario que no es un tipo válido de Pydantic (por ejemplo, un objeto de base de datos) y lo anotas así en la función, FastAPI intentará crear un modelo de response de Pydantic a partir de esa anotación de tipo, y fallará.
 
-Lo mismo sucedería si tuvieras algo como un <abbr title='Una unión entre múltiples tipos significa "cualquiera de estos tipos".'>union</abbr> entre diferentes tipos donde uno o más de ellos no son tipos válidos de Pydantic, por ejemplo esto fallaría 💥:
+Lo mismo sucedería si tuvieras algo como una <dfn title='una unión entre múltiples tipos significa "cualquiera de estos tipos".'>unión</dfn> entre diferentes tipos donde uno o más de ellos no son tipos válidos de Pydantic, por ejemplo esto fallaría 💥:
 
 {* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
 
index dce69f9bcee6ed0abcf10b0edd3aaa20d7d7404c..35235eb883fd6615dd7194bb883ae52923e30f3f 100644 (file)
@@ -8,7 +8,7 @@ De la misma manera que puedes especificar un modelo de response, también puedes
 * `@app.delete()`
 * etc.
 
-{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
 
 /// note | Nota
 
@@ -66,7 +66,7 @@ En breve:
 
 /// tip | Consejo
 
-Para saber más sobre cada código de estado y qué código es para qué, revisa la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank">documentación de <abbr title="Mozilla Developer Network  Red de Desarrolladores de Mozilla">MDN</abbr> sobre códigos de estado HTTP</a>.
+Para saber más sobre cada código de estado y qué código es para qué, revisa la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank">documentación de <abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla">MDN</abbr> sobre códigos de estado HTTP</a>.
 
 ///
 
@@ -74,7 +74,7 @@ Para saber más sobre cada código de estado y qué código es para qué, revisa
 
 Veamos de nuevo el ejemplo anterior:
 
-{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
 
 `201` es el código de estado para "Created".
 
@@ -82,7 +82,7 @@ Pero no tienes que memorizar lo que significa cada uno de estos códigos.
 
 Puedes usar las variables de conveniencia de `fastapi.status`.
 
-{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
 
 Son solo una conveniencia, mantienen el mismo número, pero de esa manera puedes usar el autocompletado del editor para encontrarlos:
 
index 396a2a6bf53808db05c87acd89840e2d94b045ec..9af8261380d94539b5833adeda14ad589b2da9a7 100644 (file)
@@ -74,7 +74,7 @@ Por supuesto, también puedes pasar múltiples `examples`:
 
 Cuando haces esto, los ejemplos serán parte del **JSON Schema** interno para esos datos del body.
 
-Sin embargo, al <abbr title="2023-08-26">momento de escribir esto</abbr>, Swagger UI, la herramienta encargada de mostrar la interfaz de documentación, no soporta mostrar múltiples ejemplos para los datos en **JSON Schema**. Pero lee más abajo para una solución alternativa.
+Sin embargo, al <dfn title="2023-08-26">momento de escribir esto</dfn>, Swagger UI, la herramienta encargada de mostrar la interfaz de documentación, no soporta mostrar múltiples ejemplos para los datos en **JSON Schema**. Pero lee más abajo para una solución alternativa.
 
 ### `examples` específicos de OpenAPI { #openapi-specific-examples }
 
index 604adedad7f85e74a087173bceb821b56f475fa5..909f14765cb326e6fbfbeba11beafd6a8eb1e497 100644 (file)
@@ -20,7 +20,7 @@ Primero solo usemos el código y veamos cómo funciona, y luego volveremos para
 
 Copia el ejemplo en un archivo `main.py`:
 
-{* ../../docs_src/security/tutorial001_an_py39.py *}
+{* ../../docs_src/security/tutorial001_an_py310.py *}
 
 ## Ejecútalo { #run-it }
 
@@ -132,7 +132,7 @@ En ese caso, **FastAPI** también te proporciona las herramientas para construir
 
 Cuando creamos una instance de la clase `OAuth2PasswordBearer` pasamos el parámetro `tokenUrl`. Este parámetro contiene la URL que el cliente (el frontend corriendo en el navegador del usuario) usará para enviar el `username` y `password` a fin de obtener un token.
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
 
 /// tip | Consejo
 
@@ -170,7 +170,7 @@ Así que, puede usarse con `Depends`.
 
 Ahora puedes pasar ese `oauth2_scheme` en una dependencia con `Depends`.
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
 
 Esta dependencia proporcionará un `str` que se asigna al parámetro `token` de la *path operation function*.
 
index ced002f597624a0111c8c350dda8c44974fa2366..67b6c58359b2ff9a2eb26da31ccf4da57bdd2a51 100644 (file)
@@ -2,7 +2,7 @@
 
 En el capítulo anterior, el sistema de seguridad (que se basa en el sistema de inyección de dependencias) le estaba dando a la *path operation function* un `token` como un `str`:
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
 
 Pero eso aún no es tan útil. Vamos a hacer que nos dé el usuario actual.
 
index f7004ffb2df21f8fb61d2d6015c8e6734281a16a..e481fb6462cd01e7f2cba05ee15707d3c5b1973a 100644 (file)
@@ -116,7 +116,11 @@ Y otra utilidad para verificar si una contraseña recibida coincide con el hash
 
 Y otra más para autenticar y devolver un usuario.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
+
+Cuando `authenticate_user` se llama con un nombre de usuario que no existe en la base de datos, aun así ejecutamos `verify_password` contra un hash ficticio.
+
+Esto asegura que el endpoint tarda aproximadamente la misma cantidad de tiempo en responder tanto si el nombre de usuario es válido como si no, previniendo los **timing attacks** que podrían usarse para enumerar nombres de usuario existentes.
 
 /// note | Nota
 
@@ -152,7 +156,7 @@ Define un Modelo de Pydantic que se usará en el endpoint de token para el respo
 
 Crea una función de utilidad para generar un nuevo token de acceso.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
 
 ## Actualizar las dependencias { #update-the-dependencies }
 
@@ -162,7 +166,7 @@ Decodifica el token recibido, verifícalo y devuelve el usuario actual.
 
 Si el token es inválido, devuelve un error HTTP de inmediato.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
 
 ## Actualizar la *path operation* `/token` { #update-the-token-path-operation }
 
@@ -170,7 +174,7 @@ Crea un `timedelta` con el tiempo de expiración del token.
 
 Crea un verdadero token de acceso JWT y devuélvelo.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
 
 ### Detalles técnicos sobre el "sujeto" `sub` de JWT { #technical-details-about-the-jwt-subject-sub }
 
index 6273c7059af5ba4f0fa55b3a396b65e19274f6f8..b57ebdbbe5a6d6a36e0f410ee79159a2406a72f5 100644 (file)
@@ -8,7 +8,7 @@ Aquí veremos un ejemplo usando <a href="https://sqlmodel.tiangolo.com/" class="
 
 /// tip | Consejo
 
-Puedes usar cualquier otro paquete de bases de datos SQL o NoSQL que quieras (en algunos casos llamadas <abbr title="Object Relational Mapper  Mapeador Objeto-Relacional: un término elegante para un paquete donde algunas clases representan tablas SQL y las instances representan filas en esas tablas">"ORMs"</abbr>), FastAPI no te obliga a usar nada. 😎
+Puedes usar cualquier otro paquete de bases de datos SQL o NoSQL que quieras (en algunos casos llamadas <abbr title="Object Relational Mapper - Mapeador Objeto-Relacional: un término elegante para un paquete donde algunas clases representan tablas SQL y las instances representan filas en esas tablas">"ORMs"</abbr>), FastAPI no te obliga a usar nada. 😎
 
 ///
 
@@ -354,4 +354,4 @@ Si vas a la interfaz de `/docs` de la API, verás que ahora está actualizada, y
 
 Puedes usar <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">**SQLModel**</a> para interactuar con una base de datos SQL y simplificar el código con *modelos de datos* y *modelos de tablas*.
 
-Puedes aprender mucho más en la documentación de **SQLModel**, hay un mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial sobre el uso de SQLModel con **FastAPI**</a>. 🚀
+Puedes aprender mucho más en la documentación de **SQLModel**, hay un mini <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">tutorial más largo sobre el uso de SQLModel con **FastAPI**</a>. 🚀
index f1badd2af69c998ad4350e0bf14450937c260fc5..84d2e94a97aac0380aadb349ae531b7bcf62e1df 100644 (file)
@@ -7,7 +7,7 @@ Puedes servir archivos estáticos automáticamente desde un directorio utilizand
 * Importa `StaticFiles`.
 * "Monta" una instance de `StaticFiles()` en un path específico.
 
-{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
 
 /// note | Detalles Técnicos
 
index 555da55bf6a0450ef271d8d4f98eddd45044daea..c477129035fef6f902a4f32f2f5662a5ae5ea9b1 100644 (file)
@@ -30,7 +30,7 @@ Usa el objeto `TestClient` de la misma manera que con `httpx`.
 
 Escribe declaraciones `assert` simples con las expresiones estándar de Python que necesites revisar (otra vez, estándar de `pytest`).
 
-{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
 
 /// tip | Consejo
 
@@ -75,7 +75,7 @@ Digamos que tienes una estructura de archivos como se describe en [Aplicaciones
 
 En el archivo `main.py` tienes tu aplicación de **FastAPI**:
 
-{* ../../docs_src/app_testing/app_a_py39/main.py *}
+{* ../../docs_src/app_testing/app_a_py310/main.py *}
 
 ### Archivo de prueba { #testing-file }
 
@@ -91,7 +91,7 @@ Entonces podrías tener un archivo `test_main.py` con tus pruebas. Podría estar
 
 Debido a que este archivo está en el mismo paquete, puedes usar importaciones relativas para importar el objeto `app` desde el módulo `main` (`main.py`):
 
-{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
 
 ...y tener el código para las pruebas tal como antes.
 
index 8c90c28f0be3d50d4b8fd37d11660da99215d77f..f8839ac6c31b6cc2bb9b24cdc20478a162641377 100644 (file)
@@ -53,7 +53,7 @@ $ cd awesome-project
 
 ## Crea un Entorno Virtual { #create-a-virtual-environment }
 
-Cuando empiezas a trabajar en un proyecto de Python **por primera vez**, crea un entorno virtual **<abbr title="hay otras opciones, esto es solo una guía sencilla">dentro de tu proyecto</abbr>**.
+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
 
@@ -170,9 +170,9 @@ Esto asegura que si usas un programa de **terminal (<abbr title="command line in
 
 ///
 
-## Verifica que el Entorno Virtual esté Activo { #check-the-virtual-environment-is-active }
+## Revisa que el Entorno Virtual esté Activo { #check-the-virtual-environment-is-active }
 
-Verifica que el entorno virtual esté activo (el comando anterior funcionó).
+Revisa que el entorno virtual esté activo (el comando anterior funcionó).
 
 /// tip | Consejo
 
@@ -732,7 +732,7 @@ Un detalle importante es que pondrá el path del entorno virtual al **comienzo**
 
 Activar un entorno virtual también cambia un par de otras cosas, pero esta es una de las cosas más importantes que hace.
 
-## Verificando un Entorno Virtual { #checking-a-virtual-environment }
+## Revisando un Entorno Virtual { #checking-a-virtual-environment }
 
 Cuando revisas si un entorno virtual está activo, por ejemplo con: