]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Update translations for es (update-outdated) (#15155)
authorSebastián Ramírez <tiangolo@gmail.com>
Thu, 19 Mar 2026 18:15:55 +0000 (19:15 +0100)
committerGitHub <noreply@github.com>
Thu, 19 Mar 2026 18:15:55 +0000 (19:15 +0100)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
98 files changed:
docs/es/docs/_llm-test.md
docs/es/docs/advanced/additional-responses.md
docs/es/docs/advanced/additional-status-codes.md
docs/es/docs/advanced/advanced-dependencies.md
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/index.md
docs/es/docs/advanced/middleware.md
docs/es/docs/advanced/openapi-callbacks.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/security/index.md
docs/es/docs/advanced/security/oauth2-scopes.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-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/benchmarks.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/index.md
docs/es/docs/deployment/manually.md
docs/es/docs/deployment/server-workers.md
docs/es/docs/deployment/versions.md
docs/es/docs/environment-variables.md
docs/es/docs/fastapi-cli.md
docs/es/docs/features.md
docs/es/docs/help-fastapi.md
docs/es/docs/history-design-future.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/custom-request-and-route.md
docs/es/docs/how-to/extending-openapi.md
docs/es/docs/how-to/general.md
docs/es/docs/how-to/graphql.md
docs/es/docs/how-to/index.md
docs/es/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.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/tutorial/background-tasks.md
docs/es/docs/tutorial/bigger-applications.md
docs/es/docs/tutorial/body-nested-models.md
docs/es/docs/tutorial/body-updates.md
docs/es/docs/tutorial/body.md
docs/es/docs/tutorial/cors.md
docs/es/docs/tutorial/debugging.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/encoder.md
docs/es/docs/tutorial/extra-data-types.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/index.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/oauth2-jwt.md
docs/es/docs/tutorial/security/simple-oauth2.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 dda425acbc878812b9a7eccf82508192f20f518d..703d8009c802af6b4641e7c9420875c7be806d97 100644 (file)
@@ -11,7 +11,7 @@ Las pruebas añadidas aquí serán vistas por todas las personas que diseñan pr
 * Revisa si las cosas están bien en la traducción.
 * Si es necesario, mejora tu prompt específico del idioma, el prompt general, o el documento en inglés.
 * Luego corrige manualmente los problemas restantes en la traducción para que sea una buena traducción.
-* Vuelve a traducir, teniendo la buena traducción en su lugar. El resultado ideal sería que el LLM ya no hiciera cambios a la traducción. Eso significa que el prompt general y tu prompt específico del idioma están tan bien como pueden estar (A veces hará algunos cambios aparentemente aleatorios; la razón es que <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">los LLMs no son algoritmos deterministas</a>).
+* Vuelve a traducir, teniendo la buena traducción en su lugar. El resultado ideal sería que el LLM ya no hiciera cambios a la traducción. Eso significa que el prompt general y tu prompt específico del idioma están tan bien como pueden estar (A veces hará algunos cambios aparentemente aleatorios; la razón es que [los LLMs no son algoritmos deterministas](https://doublespeak.chat/#/handbook#deterministic-output)).
 
 Las pruebas:
 
@@ -169,15 +169,15 @@ Consulta las secciones `### Special blocks` y `### Tab blocks` en el prompt gene
 El texto del enlace debe traducirse, la dirección del enlace debe permanecer sin cambios:
 
 * [Enlace al encabezado de arriba](#code-snippets)
-* [Enlace interno](index.md#installation){.internal-link target=_blank}
-* <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">Enlace externo</a>
-* <a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">Enlace a un estilo</a>
-* <a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">Enlace a un script</a>
-* <a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">Enlace a una imagen</a>
+* [Enlace interno](index.md#installation)
+* [Enlace externo](https://sqlmodel.tiangolo.com/)
+* [Enlace a un estilo](https://fastapi.tiangolo.com/css/styles.css)
+* [Enlace a un script](https://fastapi.tiangolo.com/js/logic.js)
+* [Enlace a una imagen](https://fastapi.tiangolo.com/img/foo.jpg)
 
 El texto del enlace debe traducirse, la dirección del enlace debe apuntar a la traducción:
 
-* <a href="https://fastapi.tiangolo.com/es/" class="external-link" target="_blank">Enlace a FastAPI</a>
+* [Enlace a FastAPI](https://fastapi.tiangolo.com/es/)
 
 ////
 
index 030f8dcc5af95bc420e2a2041ec4268372374982..83053d3a9ebcde1dc7447d5b81236cd4e86cdd5f 100644 (file)
@@ -243,5 +243,5 @@ Por ejemplo:
 
 Para ver exactamente qué puedes incluir en los responses, puedes revisar estas secciones en la especificación OpenAPI:
 
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object" class="external-link" target="_blank">Objeto de Responses de OpenAPI</a>, incluye el `Response Object`.
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object" class="external-link" target="_blank">Objeto de Response de OpenAPI</a>, puedes incluir cualquier cosa de esto directamente en cada response dentro de tu parámetro `responses`. Incluyendo `description`, `headers`, `content` (dentro de este es que declaras diferentes media types y JSON Schemas), y `links`.
+* [Objeto de Responses de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), incluye el `Response Object`.
+* [Objeto de Response de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), puedes incluir cualquier cosa de esto directamente en cada response dentro de tu parámetro `responses`. Incluyendo `description`, `headers`, `content` (dentro de este es que declaras diferentes media types y JSON Schemas), y `links`.
index 9adfa65cf321bf12dd742ae92d5cd1af549fd580..5c0ab6980fca066d1d9d8144253efffacba27c9e 100644 (file)
@@ -38,4 +38,4 @@ También podrías usar `from starlette.responses import JSONResponse`.
 
 Si devuelves códigos de estado adicionales y responses directamente, no se incluirán en el esquema de OpenAPI (la documentación de la API), porque FastAPI no tiene una forma de saber de antemano qué vas a devolver.
 
-Pero puedes documentarlo en tu código, usando: [Responses Adicionales](additional-responses.md){.internal-link target=_blank}.
+Pero puedes documentarlo en tu código, usando: [Responses Adicionales](additional-responses.md).
index 81d8d19bbe0cc59c2d4224e127815dc2e0274383..cee93692d751aa33fecd2779517e97ff47354196 100644 (file)
@@ -132,7 +132,7 @@ Si tienes este caso de uso específico usando SQLModel (o SQLAlchemy), podrías
 
 De esa manera la sesión liberaría la conexión a la base de datos, para que otras requests puedan usarla.
 
-Si tienes un caso de uso diferente que necesite salir temprano desde una dependencia con `yield`, por favor crea una <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">Pregunta de Discusión en GitHub</a> con tu caso de uso específico y por qué te beneficiaría tener cierre temprano para dependencias con `yield`.
+Si tienes un caso de uso diferente que necesite salir temprano desde una dependencia con `yield`, por favor crea una [Pregunta de Discusión en GitHub](https://github.com/fastapi/fastapi/discussions/new?category=questions) con tu caso de uso específico y por qué te beneficiaría tener cierre temprano para dependencias con `yield`.
 
 Si hay casos de uso convincentes para el cierre temprano en dependencias con `yield`, consideraría agregar una nueva forma de optar por el cierre temprano.
 
@@ -144,7 +144,7 @@ Esto cambió en la versión 0.110.0 para arreglar consumo de memoria no manejado
 
 ### Tareas en segundo plano y dependencias con `yield`, detalles técnicos { #background-tasks-and-dependencies-with-yield-technical-details }
 
-Antes de FastAPI 0.106.0, elevar excepciones después de `yield` no era posible, el código de salida en dependencias con `yield` se ejecutaba después de que la response era enviada, por lo que [Manejadores de Excepciones](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} ya habrían corrido.
+Antes de FastAPI 0.106.0, elevar excepciones después de `yield` no era posible, el código de salida en dependencias con `yield` se ejecutaba después de que la response era enviada, por lo que [Manejadores de Excepciones](../tutorial/handling-errors.md#install-custom-exception-handlers) ya habrían corrido.
 
 Esto se diseñó así principalmente para permitir usar los mismos objetos devueltos con `yield` por las dependencias dentro de tareas en segundo plano, porque el código de salida se ejecutaría después de que las tareas en segundo plano terminaran.
 
index 3485536cef6b67739cfbbae7e8c944f0e2ad7600..4ccd664e63c02c5d6f5bcfb1b05cb5395e4a1fe5 100644 (file)
@@ -16,11 +16,11 @@ Incluso si tu aplicación de **FastAPI** usa funciones `def` normales en lugar d
 
 El `TestClient` hace algo de magia interna para llamar a la aplicación FastAPI asíncrona en tus funciones de test `def` normales, usando pytest estándar. Pero esa magia ya no funciona cuando lo usamos dentro de funciones asíncronas. Al ejecutar nuestros tests de manera asíncrona, ya no podemos usar el `TestClient` dentro de nuestras funciones de test.
 
-El `TestClient` está basado en <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>, y afortunadamente, podemos usarlo directamente para probar la API.
+El `TestClient` está basado en [HTTPX](https://www.python-httpx.org), y afortunadamente, podemos usarlo directamente para probar la API.
 
 ## Ejemplo { #example }
 
-Para un ejemplo simple, consideremos una estructura de archivos similar a la descrita en [Aplicaciones Más Grandes](../tutorial/bigger-applications.md){.internal-link target=_blank} y [Testing](../tutorial/testing.md){.internal-link target=_blank}:
+Para un ejemplo simple, consideremos una estructura de archivos similar a la descrita en [Aplicaciones Más Grandes](../tutorial/bigger-applications.md) y [Testing](../tutorial/testing.md):
 
 ```
 .
@@ -84,7 +84,7 @@ Nota que estamos usando async/await con el nuevo `AsyncClient`: el request es as
 
 /// warning | Advertencia
 
-Si tu aplicación depende de eventos de lifespan, el `AsyncClient` no activará estos eventos. Para asegurarte de que se activen, usa `LifespanManager` de <a href="https://github.com/florimondmanca/asgi-lifespan#usage" class="external-link" target="_blank">florimondmanca/asgi-lifespan</a>.
+Si tu aplicación depende de eventos de lifespan, el `AsyncClient` no activará estos eventos. Para asegurarte de que se activen, usa `LifespanManager` de [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage).
 
 ///
 
@@ -94,6 +94,6 @@ Al ser la función de test asíncrona, ahora también puedes llamar (y `await`)
 
 /// tip | Consejo
 
-Si encuentras un `RuntimeError: Task attached to a different loop` al integrar llamadas a funciones asíncronas en tus tests (por ejemplo, cuando usas <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MotorClient de MongoDB</a>), recuerda crear instances de objetos que necesiten un loop de eventos solo dentro de funciones async, por ejemplo, en un callback `@app.on_event("startup")`.
+Si encuentras un `RuntimeError: Task attached to a different loop` al integrar llamadas a funciones asíncronas en tus tests (por ejemplo, cuando usas [MotorClient de MongoDB](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)), recuerda crear instances de objetos que necesiten un loop de eventos solo dentro de funciones async, por ejemplo, en un callback `@app.on_event("startup")`.
 
 ///
index 40729ee03d7e07cb335f356696234eeda6212dc0..31d38c1bb6e0f8b98847a57580de8368d2e3057c 100644 (file)
@@ -16,9 +16,9 @@ Pero por seguridad, como el server no sabe que está detrás de un proxy confiab
 
 Los headers del proxy son:
 
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
+* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
+* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
+* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
 
 ///
 
@@ -60,7 +60,7 @@ https://mysuperapp.com/items/
 
 /// tip | Consejo
 
-Si quieres aprender más sobre HTTPS, revisa la guía [Acerca de HTTPS](../deployment/https.md){.internal-link target=_blank}.
+Si quieres aprender más sobre HTTPS, revisa la guía [Acerca de HTTPS](../deployment/https.md).
 
 ///
 
@@ -228,7 +228,7 @@ Pasar el `root_path` a `FastAPI` sería el equivalente a pasar la opción de lí
 
 Ten en cuenta que el servidor (Uvicorn) no usará ese `root_path` para nada, a excepción de pasárselo a la app.
 
-Pero si vas con tu navegador a <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> verás el response normal:
+Pero si vas con tu navegador a [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app) verás el response normal:
 
 ```JSON
 {
@@ -251,9 +251,9 @@ En un caso así (sin un prefijo de path eliminado), el proxy escucharía algo co
 
 ## Probando localmente con Traefik { #testing-locally-with-traefik }
 
-Puedes ejecutar fácilmente el experimento localmente con un prefijo de path eliminado usando <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
+Puedes ejecutar fácilmente el experimento localmente con un prefijo de path eliminado usando [Traefik](https://docs.traefik.io/).
 
-<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">Descarga Traefik</a>, es un archivo binario único, puedes extraer el archivo comprimido y ejecutarlo directamente desde la terminal.
+[Descarga Traefik](https://github.com/containous/traefik/releases), es un archivo binario único, puedes extraer el archivo comprimido y ejecutarlo directamente desde la terminal.
 
 Luego crea un archivo `traefik.toml` con:
 
@@ -330,7 +330,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 ### Revisa los responses { #check-the-responses }
 
-Ahora, si vas a la URL con el puerto para Uvicorn: <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, verás el response normal:
+Ahora, si vas a la URL con el puerto para Uvicorn: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), verás el response normal:
 
 ```JSON
 {
@@ -345,7 +345,7 @@ Nota que incluso aunque estés accediendo en `http://127.0.0.1:8000/app`, muestr
 
 ///
 
-Y ahora abre la URL con el puerto para Traefik, incluyendo el prefijo de path: <a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>.
+Y ahora abre la URL con el puerto para Traefik, incluyendo el prefijo de path: [http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app).
 
 Obtenemos el mismo response:
 
@@ -370,13 +370,13 @@ Pero aquí está la parte divertida. ✨
 
 La forma "oficial" de acceder a la app sería a través del proxy con el prefijo de path que definimos. Así que, como esperaríamos, si intentas usar la UI de los docs servida por Uvicorn directamente, sin el prefijo de path en la URL, no funcionará, porque espera ser accedida a través del proxy.
 
-Puedes verificarlo en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>:
+Puedes verificarlo en [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs):
 
 <img src="/img/tutorial/behind-a-proxy/image01.png">
 
 Pero si accedemos a la UI de los docs en la URL "oficial" usando el proxy con puerto `9999`, en `/api/v1/docs`, ¡funciona correctamente! 🎉
 
-Puedes verificarlo en <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>:
+Puedes verificarlo en [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs):
 
 <img src="/img/tutorial/behind-a-proxy/image02.png">
 
@@ -433,7 +433,7 @@ Observa el server auto-generado con un valor `url` de `/api/v1`, tomado del `roo
 
 ///
 
-En la UI de los docs en <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> se vería como:
+En la UI de los docs en [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) se vería como:
 
 <img src="/img/tutorial/behind-a-proxy/image03.png">
 
@@ -461,6 +461,6 @@ y entonces no lo incluirá en el esquema de OpenAPI.
 
 ## Montando una sub-aplicación { #mounting-a-sub-application }
 
-Si necesitas montar una sub-aplicación (como se describe en [Aplicaciones secundarias - Monturas](sub-applications.md){.internal-link target=_blank}) mientras usas un proxy con `root_path`, puedes hacerlo normalmente, como esperarías.
+Si necesitas montar una sub-aplicación (como se describe en [Aplicaciones secundarias - Monturas](sub-applications.md)) mientras usas un proxy con `root_path`, puedes hacerlo normalmente, como esperarías.
 
 FastAPI usará internamente el `root_path` de manera inteligente, así que simplemente funcionará. ✨
index a58f290d6ea7788734f6b39d50af1c8ec4033e79..e1db101479dfea8b8c95e2482dea9fe75b332b8b 100644 (file)
@@ -1,8 +1,8 @@
 # Response Personalizado - HTML, Stream, Archivo, otros { #custom-response-html-stream-file-others }
 
-Por defecto, **FastAPI** devolverá los responses usando `JSONResponse`.
+Por defecto, **FastAPI** devolverá responses JSON.
 
-Puedes sobrescribirlo devolviendo un `Response` directamente como se ve en [Devolver una Response directamente](response-directly.md){.internal-link target=_blank}.
+Puedes sobrescribirlo devolviendo un `Response` directamente como se ve en [Devolver una Response directamente](response-directly.md).
 
 Pero si devuelves un `Response` directamente (o cualquier subclase, como `JSONResponse`), los datos no se convertirán automáticamente (incluso si declaras un `response_model`), y la documentación no se generará automáticamente (por ejemplo, incluyendo el "media type" específico, en el HTTP header `Content-Type` como parte del OpenAPI generado).
 
@@ -10,43 +10,27 @@ Pero también puedes declarar el `Response` que quieres usar (por ejemplo, cualq
 
 Los contenidos que devuelvas desde tu *path operation function* se colocarán dentro de esa `Response`.
 
-Y si ese `Response` tiene un media type JSON (`application/json`), como es el caso con `JSONResponse` y `UJSONResponse`, los datos que devuelvas se convertirán automáticamente (y serán filtrados) con cualquier `response_model` de Pydantic que hayas declarado en el *path operation decorator*.
-
 /// note | Nota
 
 Si usas una clase de response sin media type, FastAPI esperará que tu response no tenga contenido, por lo que no documentará el formato del response en su OpenAPI generado.
 
 ///
 
-## Usa `ORJSONResponse` { #use-orjsonresponse }
-
-Por ejemplo, si estás exprimendo el rendimiento, puedes instalar y usar <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> y establecer el response como `ORJSONResponse`.
-
-Importa la clase `Response` (sub-clase) que quieras usar y declárala en el *path operation decorator*.
-
-Para responses grandes, devolver una `Response` directamente es mucho más rápido que devolver un diccionario.
-
-Esto se debe a que, por defecto, FastAPI inspeccionará cada elemento dentro y se asegurará de que sea serializable como JSON, usando el mismo [Codificador Compatible con JSON](../tutorial/encoder.md){.internal-link target=_blank} explicado en el tutorial. Esto es lo que te permite devolver **objetos arbitrarios**, por ejemplo, modelos de bases de datos.
-
-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.
+## Responses JSON { #json-responses }
 
-{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
+Por defecto FastAPI devuelve responses JSON.
 
-/// info | Información
-
-El parámetro `response_class` también se utilizará para definir el "media type" del response.
+Si declaras un [Response Model](../tutorial/response-model.md) FastAPI lo usará para serializar los datos a JSON, usando Pydantic.
 
-En este caso, el HTTP header `Content-Type` se establecerá en `application/json`.
+Si no declaras un response model, FastAPI usará el `jsonable_encoder` explicado en [Codificador Compatible con JSON](../tutorial/encoder.md) y lo pondrá en un `JSONResponse`.
 
-Y se documentará así en OpenAPI.
+Si declaras un `response_class` con un media type JSON (`application/json`), como es el caso con `JSONResponse`, los datos que devuelvas se convertirán automáticamente (y serán filtrados) con cualquier `response_model` de Pydantic que hayas declarado en el *path operation decorator*. Pero los datos no se serializarán a bytes JSON con Pydantic, en su lugar se convertirán con el `jsonable_encoder` y luego se pasarán a la clase `JSONResponse`, que los serializará a bytes usando la librería JSON estándar de Python.
 
-///
+### Rendimiento JSON { #json-performance }
 
-/// tip | Consejo
+En resumen, si quieres el máximo rendimiento, usa un [Response Model](../tutorial/response-model.md) y no declares un `response_class` en el *path operation decorator*.
 
-El `ORJSONResponse` solo está disponible en FastAPI, no en Starlette.
-
-///
+{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
 
 ## Response HTML { #html-response }
 
@@ -69,7 +53,7 @@ Y se documentará así en OpenAPI.
 
 ### Devuelve una `Response` { #return-a-response }
 
-Como se ve en [Devolver una Response directamente](response-directly.md){.internal-link target=_blank}, también puedes sobrescribir el response directamente en tu *path operation*, devolviéndolo.
+Como se ve en [Devolver una Response directamente](response-directly.md), también puedes sobrescribir el response directamente en tu *path operation*, devolviéndolo.
 
 El mismo ejemplo de arriba, devolviendo una `HTMLResponse`, podría verse así:
 
@@ -154,37 +138,11 @@ Toma algunos datos y devuelve un response codificado como `application/json`.
 
 Este es el response usado por defecto en **FastAPI**, como leíste arriba.
 
-### `ORJSONResponse` { #orjsonresponse }
-
-Un response JSON rápido alternativo usando <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, como leíste arriba.
-
-/// info | Información
-
-Esto requiere instalar `orjson`, por ejemplo, con `pip install orjson`.
-
-///
-
-### `UJSONResponse` { #ujsonresponse }
-
-Un response JSON alternativo usando <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>.
-
-/// info | Información
-
-Esto requiere instalar `ujson`, por ejemplo, con `pip install ujson`.
-
-///
-
-/// warning | Advertencia
-
-`ujson` es menos cuidadoso que la implementación integrada de Python en cómo maneja algunos casos extremos.
-
-///
-
-{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
+/// note | Nota Técnica
 
-/// tip | Consejo
+Pero si declaras un response model o un tipo de retorno, eso se usará directamente para serializar los datos a JSON, y se devolverá directamente un response con el media type correcto para JSON, sin usar la clase `JSONResponse`.
 
-Es posible que `ORJSONResponse` sea una alternativa más rápida.
+Esta es la forma ideal de obtener el mejor rendimiento.
 
 ///
 
@@ -200,6 +158,7 @@ Puedes devolver un `RedirectResponse` directamente:
 
 O puedes usarlo en el parámetro `response_class`:
 
+
 {* ../../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.
@@ -214,31 +173,25 @@ También puedes usar el parámetro `status_code` combinado con el parámetro `re
 
 ### `StreamingResponse` { #streamingresponse }
 
-Toma un generador `async` o un generador/iterador normal y transmite el cuerpo del response.
-
-{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
-
-#### Usando `StreamingResponse` con objetos similares a archivos { #using-streamingresponse-with-file-like-objects }
+Toma un generador `async` o un generador/iterador normal (una función con `yield`) y transmite el cuerpo del response.
 
-Si tienes un <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">objeto similar a un archivo</a> (por ejemplo, el objeto devuelto por `open()`), puedes crear una función generadora para iterar sobre ese objeto similar a un archivo.
+{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
 
-De esa manera, no tienes que leerlo todo primero en memoria, y puedes pasar esa función generadora al `StreamingResponse`, y devolverlo.
-
-Esto incluye muchos paquetes para interactuar con almacenamiento en la nube, procesamiento de video y otros.
+/// note | Nota Técnica
 
-{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
+Una tarea `async` solo puede cancelarse cuando llega a un `await`. Si no hay `await`, el generador (función con `yield`) no se puede cancelar correctamente y puede seguir ejecutándose incluso después de solicitar la cancelación.
 
-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.
-3. Este `yield from` le dice a la función que itere sobre esa cosa llamada `file_like`. Y luego, para cada parte iterada, yield esa parte como proveniente de esta función generadora (`iterfile`).
+Como este pequeño ejemplo no necesita ninguna sentencia `await`, añadimos un `await anyio.sleep(0)` para darle al loop de eventos la oportunidad de manejar la cancelación.
 
-    Entonces, es una función generadora que transfiere el trabajo de "generar" a algo más internamente.
+Esto sería aún más importante con streams grandes o infinitos.
 
-    Al hacerlo de esta manera, podemos ponerlo en un bloque `with`, y de esa manera, asegurarnos de que el objeto similar a un archivo se cierre después de finalizar.
+///
 
 /// tip | Consejo
 
-Nota que aquí como estamos usando `open()` estándar que no admite `async` y `await`, declaramos el path operation con `def` normal.
+En lugar de devolver un `StreamingResponse` directamente, probablemente deberías seguir el estilo en [Stream Data](./stream-data.md), es mucho más conveniente y maneja la cancelación por detrás de escena por ti.
+
+Si estás transmitiendo JSON Lines, sigue el tutorial [Stream JSON Lines](../tutorial/stream-json-lines.md).
 
 ///
 
@@ -267,7 +220,7 @@ En este caso, puedes devolver la path del archivo directamente desde tu *path op
 
 Puedes crear tu propia clase de response personalizada, heredando de `Response` y usándola.
 
-Por ejemplo, digamos que quieres usar <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, pero con algunas configuraciones personalizadas no utilizadas en la clase `ORJSONResponse` incluida.
+Por ejemplo, digamos que quieres usar [`orjson`](https://github.com/ijl/orjson) con algunas configuraciones.
 
 Digamos que quieres que devuelva JSON con sangría y formato, por lo que quieres usar la opción de orjson `orjson.OPT_INDENT_2`.
 
@@ -291,13 +244,21 @@ Ahora en lugar de devolver:
 
 Por supuesto, probablemente encontrarás formas mucho mejores de aprovechar esto que formatear JSON. 😉
 
+### `orjson` o Response Model { #orjson-or-response-model }
+
+Si lo que buscas es rendimiento, probablemente te convenga más usar un [Response Model](../tutorial/response-model.md) que un response con `orjson`.
+
+Con un response model, FastAPI usará Pydantic para serializar los datos a JSON, sin pasos intermedios, como convertirlos con `jsonable_encoder`, que ocurriría en cualquier otro caso.
+
+Y por debajo, Pydantic usa los mismos mecanismos en Rust que `orjson` para serializar a JSON, así que ya obtendrás el mejor rendimiento con un response model.
+
 ## Clase de response por defecto { #default-response-class }
 
 Al crear una instance de la clase **FastAPI** o un `APIRouter`, puedes especificar qué clase de response usar por defecto.
 
 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`.
+En el ejemplo a continuación, **FastAPI** usará `HTMLResponse` por defecto, en todas las *path operations*, en lugar de JSON.
 
 {* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
 
@@ -309,4 +270,4 @@ Todavía puedes sobrescribir `response_class` en *path operations* como antes.
 
 ## Documentación adicional { #additional-documentation }
 
-También puedes declarar el media type y muchos otros detalles en OpenAPI usando `responses`: [Responses Adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}.
+También puedes declarar el media type y muchos otros detalles en OpenAPI usando `responses`: [Responses Adicionales en OpenAPI](additional-responses.md).
index d586d3a270355ddf375dba467e6c2e63ce76605b..3ce5c754f5e9ab04c0e0c45070eb5829aeb4346e 100644 (file)
@@ -2,11 +2,11 @@
 
 FastAPI está construido sobre **Pydantic**, y te he estado mostrando cómo usar modelos de Pydantic para declarar requests y responses.
 
-Pero FastAPI también soporta el uso de <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> de la misma manera:
+Pero FastAPI también soporta el uso de [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) de la misma manera:
 
 {* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
 
-Esto sigue siendo soportado gracias a **Pydantic**, ya que tiene <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">soporte interno para `dataclasses`</a>.
+Esto sigue siendo soportado gracias a **Pydantic**, ya que tiene [soporte interno para `dataclasses`](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel).
 
 Así que, incluso con el código anterior que no usa Pydantic explícitamente, FastAPI está usando Pydantic para convertir esos dataclasses estándar en su propia versión de dataclasses de Pydantic.
 
@@ -74,7 +74,7 @@ En ese caso, simplemente puedes intercambiar los `dataclasses` estándar con `py
 
     Como siempre, en FastAPI puedes combinar `def` y `async def` según sea necesario.
 
-    Si necesitas un repaso sobre cuándo usar cuál, revisa la sección _"¿Con prisa?"_ en la documentación sobre [`async` y `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
+    Si necesitas un repaso sobre cuándo usar cuál, revisa la sección _"¿Con prisa?"_ en la documentación sobre [`async` y `await`](../async.md#in-a-hurry).
 
 9. Esta *path operation function* no está devolviendo dataclasses (aunque podría), sino una lista de diccionarios con datos internos.
 
@@ -88,7 +88,7 @@ Revisa las anotaciones en el código arriba para ver más detalles específicos.
 
 También puedes combinar `dataclasses` con otros modelos de Pydantic, heredar de ellos, incluirlos en tus propios modelos, etc.
 
-Para saber más, revisa la <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">documentación de Pydantic sobre dataclasses</a>.
+Para saber más, revisa la [documentación de Pydantic sobre dataclasses](https://docs.pydantic.dev/latest/concepts/dataclasses/).
 
 ## Versión { #version }
 
index 4adb464d3baed77b1d14f42f3cf12c84a969527b..264ee27ede5933fdd993ed0e244c41325ae5ed6b 100644 (file)
@@ -150,11 +150,11 @@ Debido a eso, ahora se recomienda en su lugar usar el `lifespan` como se explic
 
 Solo un detalle técnico para los nerds curiosos. 🤓
 
-Por debajo, en la especificación técnica ASGI, esto es parte del <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Protocolo de Lifespan</a>, y define eventos llamados `startup` y `shutdown`.
+Por debajo, en la especificación técnica ASGI, esto es parte del [Protocolo de Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), y define eventos llamados `startup` y `shutdown`.
 
 /// info | Información
 
-Puedes leer más sobre los manejadores `lifespan` de Starlette en <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">la documentación de `Lifespan` de Starlette</a>.
+Puedes leer más sobre los manejadores `lifespan` de Starlette en [la documentación de `Lifespan` de Starlette](https://www.starlette.dev/lifespan/).
 
 Incluyendo cómo manejar el estado de lifespan que puede ser usado en otras áreas de tu código.
 
@@ -162,4 +162,4 @@ Incluyendo cómo manejar el estado de lifespan que puede ser usado en otras áre
 
 ## Sub Aplicaciones { #sub-applications }
 
-🚨 Ten en cuenta que estos eventos de lifespan (startup y shutdown) solo serán ejecutados para la aplicación principal, no para [Sub Aplicaciones - Mounts](sub-applications.md){.internal-link target=_blank}.
+🚨 Ten en cuenta que estos eventos de lifespan (startup y shutdown) solo serán ejecutados para la aplicación principal, no para [Sub Aplicaciones - Mounts](sub-applications.md).
index a079c41aa5f9660f441fea67a474f60dc1729155..e43cb7f052da92bdc3f03464087a90c5c685a144 100644 (file)
@@ -8,11 +8,11 @@ En esta guía, aprenderás a generar un **SDK de TypeScript** para tu backend co
 
 ## Generadores de SDKs de código abierto { #open-source-sdk-generators }
 
-Una opción versátil es el <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>, que soporta **muchos lenguajes de programación** y puede generar SDKs a partir de tu especificación OpenAPI.
+Una opción versátil es el [OpenAPI Generator](https://openapi-generator.tech/), que soporta **muchos lenguajes de programación** y puede generar SDKs a partir de tu especificación OpenAPI.
 
-Para **clientes de TypeScript**, <a href="https://heyapi.dev/" class="external-link" target="_blank">Hey API</a> es una solución diseñada específicamente, que ofrece una experiencia optimizada para el ecosistema de TypeScript.
+Para **clientes de TypeScript**, [Hey API](https://heyapi.dev/) es una solución diseñada específicamente, que ofrece una experiencia optimizada para el ecosistema de TypeScript.
 
-Puedes descubrir más generadores de SDK en <a href="https://openapi.tools/#sdk" class="external-link" target="_blank">OpenAPI.Tools</a>.
+Puedes descubrir más generadores de SDK en [OpenAPI.Tools](https://openapi.tools/#sdk).
 
 /// tip | Consejo
 
@@ -24,15 +24,15 @@ FastAPI genera automáticamente especificaciones **OpenAPI 3.1**, así que cualq
 
 Esta sección destaca soluciones **respaldadas por empresas** y **venture-backed** de compañías que sponsorean FastAPI. Estos productos ofrecen **funcionalidades adicionales** e **integraciones** además de SDKs generados de alta calidad.
 
-Al ✨ [**sponsorear FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, estas compañías ayudan a asegurar que el framework y su **ecosistema** se mantengan saludables y **sustentables**.
+Al ✨ [**sponsorear FastAPI**](../help-fastapi.md#sponsor-the-author) ✨, estas compañías ayudan a asegurar que el framework y su **ecosistema** se mantengan saludables y **sustentables**.
 
 Su sponsorship también demuestra un fuerte compromiso con la **comunidad** de FastAPI (tú), mostrando que no solo les importa ofrecer un **gran servicio**, sino también apoyar un **framework robusto y próspero**, FastAPI. 🙇
 
 Por ejemplo, podrías querer probar:
 
-* <a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>
-* <a href="https://www.stainless.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>
-* <a href="https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi" class="external-link" target="_blank">liblab</a>
+* [Speakeasy](https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship)
+* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
+* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
 
 Algunas de estas soluciones también pueden ser open source u ofrecer niveles gratuitos, así que puedes probarlas sin un compromiso financiero. Hay otros generadores de SDK comerciales disponibles y se pueden encontrar en línea. 🤓
 
@@ -66,7 +66,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
 
 Esto generará un SDK de TypeScript en `./src/client`.
 
-Puedes aprender cómo <a href="https://heyapi.dev/openapi-ts/get-started" class="external-link" target="_blank">instalar `@hey-api/openapi-ts`</a> y leer sobre el <a href="https://heyapi.dev/openapi-ts/output" class="external-link" target="_blank">output generado</a> en su sitio web.
+Puedes aprender cómo [instalar `@hey-api/openapi-ts`](https://heyapi.dev/openapi-ts/get-started) y leer sobre el [output generado](https://heyapi.dev/openapi-ts/output) en su sitio web.
 
 ### Usar el SDK { #using-the-sdk }
 
index f3f4bb85ce67aeec3937aa16865949a30f3f7159..a18a7fd64d14ad9effe9af1604630d252d5973a1 100644 (file)
@@ -2,7 +2,7 @@
 
 ## Funcionalidades adicionales { #additional-features }
 
-El [Tutorial - Guía del usuario](../tutorial/index.md){.internal-link target=_blank} principal debería ser suficiente para darte un recorrido por todas las funcionalidades principales de **FastAPI**.
+El [Tutorial - Guía del usuario](../tutorial/index.md) principal debería ser suficiente para darte un recorrido por todas las funcionalidades principales de **FastAPI**.
 
 En las siguientes secciones verás otras opciones, configuraciones y funcionalidades adicionales.
 
@@ -16,6 +16,6 @@ Y es posible que para tu caso de uso, la solución esté en una de ellas.
 
 ## Lee primero el Tutorial { #read-the-tutorial-first }
 
-Aún podrías usar la mayoría de las funcionalidades en **FastAPI** con el conocimiento del [Tutorial - Guía del usuario](../tutorial/index.md){.internal-link target=_blank} principal.
+Aún podrías usar la mayoría de las funcionalidades en **FastAPI** con el conocimiento del [Tutorial - Guía del usuario](../tutorial/index.md) principal.
 
 Y las siguientes secciones asumen que ya lo leíste y que conoces esas ideas principales.
index ed582c465540442d40038f518e334d2e5d5526c8..bfe70267a5b6bacceb8c67e0fcfc7a3b9cd83340 100644 (file)
@@ -1,8 +1,8 @@
 # Middleware Avanzado { #advanced-middleware }
 
-En el tutorial principal leíste cómo agregar [Middleware Personalizado](../tutorial/middleware.md){.internal-link target=_blank} a tu aplicación.
+En el tutorial principal leíste cómo agregar [Middleware Personalizado](../tutorial/middleware.md) a tu aplicación.
 
-Y luego también leíste cómo manejar [CORS con el `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
+Y luego también leíste cómo manejar [CORS con el `CORSMiddleware`](../tutorial/cors.md).
 
 En esta sección veremos cómo usar otros middlewares.
 
@@ -91,7 +91,7 @@ Hay muchos otros middlewares ASGI.
 
 Por ejemplo:
 
-* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">`ProxyHeadersMiddleware` de Uvicorn</a>
-* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
+* [`ProxyHeadersMiddleware` de Uvicorn](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
+* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
 
-Para ver otros middlewares disponibles, revisa <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">la documentación de Middleware de Starlette</a> y la <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">Lista ASGI Awesome</a>.
+Para ver otros middlewares disponibles, revisa [la documentación de Middleware de Starlette](https://www.starlette.dev/middleware/) y la [Lista ASGI Awesome](https://github.com/florimondmanca/awesome-asgi).
index caaa70fa89e653dcfdab6cb98eff49abb987a07d..5e3a1572c6fc7586d5b598242044dc387374988c 100644 (file)
@@ -35,7 +35,7 @@ Esta parte es bastante normal, probablemente ya estés familiarizado con la mayo
 
 /// tip | Consejo
 
-El parámetro de query `callback_url` utiliza un tipo <a href="https://docs.pydantic.dev/latest/api/networks/" class="external-link" target="_blank">Url</a> de Pydantic.
+El parámetro de query `callback_url` utiliza un tipo [Url](https://docs.pydantic.dev/latest/api/networks/) de Pydantic.
 
 ///
 
@@ -66,7 +66,7 @@ Este ejemplo no implementa el callback en sí (eso podría ser solo una línea d
 
 El callback real es solo un request HTTP.
 
-Cuando implementes el callback tú mismo, podrías usar algo como <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> o <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">Requests</a>.
+Cuando implementes el callback tú mismo, podrías usar algo como [HTTPX](https://www.python-httpx.org) o [Requests](https://requests.readthedocs.io/).
 
 ///
 
@@ -106,11 +106,11 @@ Debería verse como una *path operation* normal de FastAPI:
 Hay 2 diferencias principales respecto a una *path operation* normal:
 
 * No necesita tener ningún código real, porque tu aplicación nunca llamará a este código. Solo se usa para documentar la *API externa*. Así que, la función podría simplemente tener `pass`.
-* El *path* puede contener una <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">expresión OpenAPI 3</a> (ver más abajo) donde puede usar variables con parámetros y partes del request original enviado a *tu API*.
+* El *path* puede contener una [expresión OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (ver más abajo) donde puede usar variables con parámetros y partes del request original enviado a *tu API*.
 
 ### La expresión del path del callback { #the-callback-path-expression }
 
-El *path* del callback puede tener una <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">expresión OpenAPI 3</a> que puede contener partes del request original enviado a *tu API*.
+El *path* del callback puede tener una [expresión OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) que puede contener partes del request original enviado a *tu API*.
 
 En este caso, es el `str`:
 
@@ -179,7 +179,7 @@ Observa que no estás pasando el router en sí (`invoices_callback_router`) a `c
 
 ### Revisa la documentación { #check-the-docs }
 
-Ahora puedes iniciar tu aplicación e ir a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ahora puedes iniciar tu aplicación e ir a [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 Verás tu documentación incluyendo una sección de "Callbacks" para tu *path operation* que muestra cómo debería verse la *API externa*:
 
index 4f657ad53e7972e5749803a8d23c778f83a48055..163293f8340133a931e4b9e60a65a0bff695b809 100644 (file)
@@ -48,7 +48,7 @@ Esto es porque se espera que **tus usuarios** definan el actual **URL path** don
 
 ### Revisa la documentación { #check-the-docs }
 
-Ahora puedes iniciar tu app e ir a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ahora puedes iniciar tu app e ir a [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 Verás que tu documentación tiene las *path operations* normales y ahora también algunos **webhooks**:
 
index 0ba586c1c1ff419b5a9422af9b1d43e784de9709..a21975bc7c73fd35bc01176426c9556cdf8de5a3 100644 (file)
@@ -60,7 +60,7 @@ Eso define los metadatos sobre el response principal de una *path operation*.
 
 También puedes declarar responses adicionales con sus modelos, códigos de estado, etc.
 
-Hay un capítulo entero en la documentación sobre ello, puedes leerlo en [Responses Adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Hay un capítulo entero en la documentación sobre ello, puedes leerlo en [Responses Adicionales en OpenAPI](additional-responses.md).
 
 ## OpenAPI Extra { #openapi-extra }
 
@@ -68,7 +68,7 @@ Cuando declaras una *path operation* en tu aplicación, **FastAPI** genera autom
 
 /// note | Detalles técnicos
 
-En la especificación de OpenAPI se llama el <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Objeto de Operación</a>.
+En la especificación de OpenAPI se llama el [Objeto de Operación](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object).
 
 ///
 
@@ -82,7 +82,7 @@ Este esquema de OpenAPI específico de *path operation* normalmente se genera au
 
 Este es un punto de extensión de bajo nivel.
 
-Si solo necesitas declarar responses adicionales, una forma más conveniente de hacerlo es con [Responses Adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Si solo necesitas declarar responses adicionales, una forma más conveniente de hacerlo es con [Responses Adicionales en OpenAPI](additional-responses.md).
 
 ///
 
@@ -141,7 +141,7 @@ Podrías hacer eso con `openapi_extra`:
 
 {* ../../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 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.
+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 hacer parse de él de alguna manera.
 
 Sin embargo, podemos declarar el esquema esperado para el request body.
 
@@ -157,9 +157,9 @@ Por ejemplo, en esta aplicación no usamos la funcionalidad integrada de FastAPI
 
 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.
 
-Luego usamos el request directamente, y extraemos el cuerpo como `bytes`. Esto significa que FastAPI ni siquiera intentará parsear la carga útil del request como JSON.
+Luego usamos el request directamente, y extraemos el cuerpo como `bytes`. Esto significa que FastAPI ni siquiera intentará hacer parse de la carga útil del request como JSON.
 
-Y luego en nuestro código, parseamos ese contenido YAML directamente, y nuevamente estamos usando el mismo modelo Pydantic para validar el contenido YAML:
+Y luego en nuestro código, hacemos parse de ese contenido YAML directamente, y nuevamente estamos usando el mismo modelo Pydantic para validar el contenido YAML:
 
 {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
 
index 622001291f1562d91c566302a0676591ffa4cfaa..859f484de6c646ef841950fac4f81bc76b3e44e1 100644 (file)
@@ -1,6 +1,6 @@
 # Response - Cambiar Código de Estado { #response-change-status-code }
 
-Probablemente leíste antes que puedes establecer un [Código de Estado de Response](../tutorial/response-status-code.md){.internal-link target=_blank} por defecto.
+Probablemente leíste antes que puedes establecer un [Código de Estado de Response](../tutorial/response-status-code.md) por defecto.
 
 Pero en algunos casos necesitas devolver un código de estado diferente al predeterminado.
 
index e451d8939075a6aeaf4fd6e57eb1d64d361dfabf..e40a19129891af7daa079e388517bd646a84b76e 100644 (file)
@@ -20,7 +20,7 @@ También puedes declarar el parámetro `Response` en las dependencias, y estable
 
 También puedes crear cookies al devolver una `Response` directamente en tu código.
 
-Para hacer eso, puedes crear un response como se describe en [Devolver un Response Directamente](response-directly.md){.internal-link target=_blank}.
+Para hacer eso, puedes crear un response como se describe en [Devolver un Response Directamente](response-directly.md).
 
 Luego establece Cookies en ella, y luego devuélvela:
 
@@ -48,4 +48,4 @@ Y como el `Response` se puede usar frecuentemente para establecer headers y cook
 
 ///
 
-Para ver todos los parámetros y opciones disponibles, revisa la <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">documentación en Starlette</a>.
+Para ver todos los parámetros y opciones disponibles, revisa la [documentación en Starlette](https://www.starlette.dev/responses/#set-cookie).
index b9b1df447a12816f58cb77d90e291c6dd909797b..b2d5d18b88896e97c0ef2d889c726be50cde3e11 100644 (file)
@@ -2,19 +2,23 @@
 
 Cuando creas una *path operation* en **FastAPI**, normalmente puedes devolver cualquier dato desde ella: un `dict`, una `list`, un modelo de Pydantic, un modelo de base de datos, etc.
 
-Por defecto, **FastAPI** convertiría automáticamente ese valor de retorno a JSON usando el `jsonable_encoder` explicado en [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
+Si declaras un [Response Model](../tutorial/response-model.md) FastAPI lo usará para serializar los datos a JSON, usando Pydantic.
 
-Luego, detrás de escena, pondría esos datos compatibles con JSON (por ejemplo, un `dict`) dentro de un `JSONResponse` que se usaría para enviar el response al cliente.
+Si no declaras un response model, FastAPI usará el `jsonable_encoder` explicado en [JSON Compatible Encoder](../tutorial/encoder.md) y lo pondrá en un `JSONResponse`.
 
-Pero puedes devolver un `JSONResponse` directamente desde tus *path operations*.
+También podrías crear un `JSONResponse` directamente y devolverlo.
 
-Esto podría ser útil, por ejemplo, para devolver headers o cookies personalizados.
+/// tip | Consejo
+
+Normalmente tendrás mucho mejor rendimiento usando un [Response Model](../tutorial/response-model.md) que devolviendo un `JSONResponse` directamente, ya que de esa forma serializa los datos usando Pydantic, en Rust.
+
+///
 
 ## Devolver una `Response` { #return-a-response }
 
 De hecho, puedes devolver cualquier `Response` o cualquier subclase de ella.
 
-/// tip | Consejo
+/// info | Información
 
 `JSONResponse` en sí misma es una subclase de `Response`.
 
@@ -26,6 +30,8 @@ No hará ninguna conversión de datos con los modelos de Pydantic, no convertir
 
 Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de datos, sobrescribir cualquier declaración o validación de datos, etc.
 
+También te da mucha responsabilidad. Tienes que asegurarte de que los datos que devuelves sean correctos, en el formato correcto, que se puedan serializar, etc.
+
 ## Usar el `jsonable_encoder` en una `Response` { #using-the-jsonable-encoder-in-a-response }
 
 Como **FastAPI** no realiza cambios en una `Response` que devuelves, tienes que asegurarte de que sus contenidos estén listos para ello.
@@ -50,16 +56,28 @@ El ejemplo anterior muestra todas las partes que necesitas, pero aún no es muy
 
 Ahora, veamos cómo podrías usar eso para devolver un response personalizado.
 
-Digamos que quieres devolver un response en <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a>.
+Digamos que quieres devolver un response en [XML](https://en.wikipedia.org/wiki/XML).
 
 Podrías poner tu contenido XML en un string, poner eso en un `Response`, y devolverlo:
 
 {* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
+## Cómo funciona un Response Model { #how-a-response-model-works }
+
+Cuando declaras un [Response Model - Return Type](../tutorial/response-model.md) en una *path operation*, **FastAPI** lo usará para serializar los datos a JSON, usando Pydantic.
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+Como eso sucederá del lado de Rust, el rendimiento será mucho mejor que si se hiciera con Python normal y la clase `JSONResponse`.
+
+Al usar un `response_model` o tipo de retorno, FastAPI no usará el `jsonable_encoder` para convertir los datos (lo cual sería más lento) ni la clase `JSONResponse`.
+
+En su lugar, toma los bytes JSON generados con Pydantic usando el response model (o tipo de retorno) y devuelve una `Response` con el media type correcto para JSON directamente (`application/json`).
+
 ## Notas { #notes }
 
 Cuando devuelves una `Response` directamente, sus datos no son validados, convertidos (serializados), ni documentados automáticamente.
 
-Pero aún puedes documentarlo como se describe en [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Pero aún puedes documentarlo como se describe en [Additional Responses in OpenAPI](additional-responses.md).
 
 Puedes ver en secciones posteriores cómo usar/declarar estas `Response`s personalizadas mientras todavía tienes conversión automática de datos, documentación, etc.
index 1d16d86a52c61b254186ffb7bf37cc9ca5d9cb8e..06107eb2d1e153765dfd1a79f84f403a792c8a82 100644 (file)
@@ -20,7 +20,7 @@ También puedes declarar el parámetro `Response` en dependencias y establecer h
 
 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:
+Crea un response como se describe en [Retorna un Response Directamente](response-directly.md) y pasa los headers como un parámetro adicional:
 
 {* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
 
@@ -36,6 +36,6 @@ Y como el `Response` se puede usar frecuentemente para establecer headers y cook
 
 ## Headers Personalizados { #custom-headers }
 
-Ten en cuenta que los headers propietarios personalizados se pueden agregar <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando el prefijo `X-`</a>.
+Ten en cuenta que los headers propietarios personalizados se pueden agregar [usando el prefijo `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
 
-Pero si tienes headers personalizados que quieres que un cliente en un navegador pueda ver, necesitas agregarlos a tus configuraciones de CORS (leer más en [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando el parámetro `expose_headers` documentado en <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">la documentación CORS de Starlette</a>.
+Pero si tienes headers personalizados que quieres que un cliente en un navegador pueda ver, necesitas agregarlos a tus configuraciones de CORS (leer más en [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), usando el parámetro `expose_headers` documentado en [la documentación CORS de Starlette](https://www.starlette.dev/middleware/#corsmiddleware).
index d7f181ef802b1db920149a966878b2ca359cdd15..c9c1562b5a31a62c24d4eeea065453158c60b45b 100644 (file)
@@ -32,7 +32,7 @@ Aquí hay un ejemplo más completo.
 
 Usa una dependencia para comprobar si el nombre de usuario y la contraseña son correctos.
 
-Para esto, usa el módulo estándar de Python <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> para verificar el nombre de usuario y la contraseña.
+Para esto, usa el módulo estándar de Python [`secrets`](https://docs.python.org/3/library/secrets.html) para verificar el nombre de usuario y la contraseña.
 
 `secrets.compare_digest()` necesita tomar `bytes` o un `str` que solo contenga caracteres ASCII (los carácteres en inglés), esto significa que no funcionaría con caracteres como `á`, como en `Sebastián`.
 
index 8b3e67fac42149b048ff243fdb509bc236d64cee..3aa4d2dcf8cce53386bc8b5cb79084b21ef892c5 100644 (file)
@@ -2,11 +2,11 @@
 
 ## Funcionalidades Adicionales { #additional-features }
 
-Hay algunas funcionalidades extra para manejar la seguridad aparte de las cubiertas en el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank}.
+Hay algunas funcionalidades extra para manejar la seguridad aparte de las cubiertas en el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md).
 
 /// tip | Consejo
 
-Las siguientes secciones **no son necesariamente "avanzadas"**.
+Las siguientes secciones no son necesariamente "avanzadas".
 
 Y es posible que para tu caso de uso, la solución esté en una de ellas.
 
@@ -14,6 +14,6 @@ Y es posible que para tu caso de uso, la solución esté en una de ellas.
 
 ## Lee primero el Tutorial { #read-the-tutorial-first }
 
-Las siguientes secciones asumen que ya leíste el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank} principal.
+Las siguientes secciones asumen que ya leíste el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md) principal.
 
 Todas están basadas en los mismos conceptos, pero permiten algunas funcionalidades adicionales.
index 4e4580fde3bf77ad97281fde5759eef651a0f46e..6ee3dd5ac977f2a04d159c2e5fb342794ed97047 100644 (file)
@@ -60,7 +60,7 @@ Para OAuth2 son solo strings.
 
 ## Vista global { #global-view }
 
-Primero, echemos un vistazo rápido a las partes que cambian desde los ejemplos en el **Tutorial - User Guide** principal para [OAuth2 con Password (y hashing), Bearer con tokens JWT](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Ahora usando scopes de OAuth2:
+Primero, echemos un vistazo rápido a las partes que cambian desde los ejemplos en el **Tutorial - User Guide** principal para [OAuth2 con Password (y hashing), Bearer con tokens JWT](../../tutorial/security/oauth2-jwt.md). Ahora usando scopes de OAuth2:
 
 {* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
 
@@ -271,4 +271,4 @@ Pero al final, están implementando el mismo estándar OAuth2.
 
 ## `Security` en `dependencies` del decorador { #security-in-decorator-dependencies }
 
-De la misma manera que puedes definir una `list` de `Depends` en el parámetro `dependencies` del decorador (como se explica en [Dependencias en decoradores de path operation](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), también podrías usar `Security` con `scopes` allí.
+De la misma manera que puedes definir una `list` de `Depends` en el parámetro `dependencies` del decorador (como se explica en [Dependencias en decoradores de path operation](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md)), también podrías usar `Security` con `scopes` allí.
index f176dc1f38da63fe43f137ebb373b317cfd82f4c..2411ddc452041631970cc12f8256ff64c147af1a 100644 (file)
@@ -8,7 +8,7 @@ Por esta razón, es común proporcionarlas en variables de entorno que son leíd
 
 /// tip | Consejo
 
-Para entender las variables de entorno, puedes leer [Variables de Entorno](../environment-variables.md){.internal-link target=_blank}.
+Para entender las variables de entorno, puedes leer [Variables de Entorno](../environment-variables.md).
 
 ///
 
@@ -20,11 +20,11 @@ Eso significa que cualquier valor leído en Python desde una variable de entorno
 
 ## Pydantic `Settings` { #pydantic-settings }
 
-Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic: Settings management</a>.
+Afortunadamente, Pydantic proporciona una gran utilidad para manejar estas configuraciones provenientes de variables de entorno con [Pydantic: Settings management](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
 
 ### Instalar `pydantic-settings` { #install-pydantic-settings }
 
-Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo y luego instala el paquete `pydantic-settings`:
+Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md), actívalo y luego instala el paquete `pydantic-settings`:
 
 <div class="termy">
 
@@ -100,7 +100,7 @@ Y el `items_per_user` mantendría su valor por defecto de `50`.
 
 ## Configuraciones en otro módulo { #settings-in-another-module }
 
-Podrías poner esas configuraciones en otro archivo de módulo como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+Podrías poner esas configuraciones en otro archivo de módulo como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md).
 
 Por ejemplo, podrías tener un archivo `config.py` con:
 
@@ -112,7 +112,7 @@ Y luego usarlo en un archivo `main.py`:
 
 /// tip | Consejo
 
-También necesitarías un archivo `__init__.py` como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+También necesitarías un archivo `__init__.py` como viste en [Aplicaciones Más Grandes - Múltiples Archivos](../tutorial/bigger-applications.md).
 
 ///
 
@@ -172,7 +172,7 @@ Pero un archivo dotenv realmente no tiene que tener ese nombre exacto.
 
 ///
 
-Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings: Dotenv (.env) support</a>.
+Pydantic tiene soporte para leer desde estos tipos de archivos usando un paquete externo. Puedes leer más en [Pydantic Settings: Dotenv (.env) support](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
 
 /// tip | Consejo
 
@@ -197,7 +197,7 @@ Y luego actualizar tu `config.py` con:
 
 /// tip | Consejo
 
-El atributo `model_config` se usa solo para configuración de Pydantic. Puedes leer más en <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a>.
+El atributo `model_config` se usa solo para configuración de Pydantic. Puedes leer más en [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/).
 
 ///
 
@@ -291,7 +291,7 @@ En el caso de nuestra dependencia `get_settings()`, la función ni siquiera toma
 
 De esa manera, se comporta casi como si fuera solo una variable global. Pero como usa una función de dependencia, entonces podemos sobrescribirla fácilmente para las pruebas.
 
-`@lru_cache` es parte de `functools`, que es parte del paquete estándar de Python, puedes leer más sobre él en las <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">docs de Python para `@lru_cache`</a>.
+`@lru_cache` es parte de `functools`, que es parte del paquete estándar de Python, puedes leer más sobre él en las [docs de Python para `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
 
 ## Resumen { #recap }
 
index 32d4c7de2a5e42909d594427956440d05c07da91..934bb1608df4b1a0e80adb61369ae78fb0387ad1 100644 (file)
@@ -30,25 +30,25 @@ En este caso, se montará en el path `/subapi`:
 
 ### Revisa la documentación automática de la API { #check-the-automatic-api-docs }
 
-Ahora, ejecuta el comando `fastapi` con tu archivo:
+Ahora, ejecuta el comando `fastapi`:
 
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
 </div>
 
-Y abre la documentación en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Y abre la documentación en [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 Verás la documentación automática de la API para la aplicación principal, incluyendo solo sus propias _path operations_:
 
 <img src="/img/tutorial/sub-applications/image01.png">
 
-Y luego, abre la documentación para la sub-aplicación, en <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>.
+Y luego, abre la documentación para la sub-aplicación, en [http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs).
 
 Verás la documentación automática de la API para la sub-aplicación, incluyendo solo sus propias _path operations_, todas bajo el prefijo correcto del sub-path `/subapi`:
 
@@ -64,4 +64,4 @@ De esa manera, la sub-aplicación sabrá usar ese prefijo de path para la interf
 
 Y la sub-aplicación también podría tener sus propias sub-aplicaciones montadas y todo funcionaría correctamente, porque FastAPI maneja todos estos `root_path`s automáticamente.
 
-Aprenderás más sobre el `root_path` y cómo usarlo explícitamente en la sección sobre [Detrás de un Proxy](behind-a-proxy.md){.internal-link target=_blank}.
+Aprenderás más sobre el `root_path` y cómo usarlo explícitamente en la sección sobre [Detrás de un Proxy](behind-a-proxy.md).
index 1162d4ce4b5604529ce72abb0095b967bf05ec57..ce28c3062cf29e886bcdbb2e27330ce6af5b1b1d 100644 (file)
@@ -8,7 +8,7 @@ Hay utilidades para configurarlo fácilmente que puedes usar directamente en tu
 
 ## Instala dependencias { #install-dependencies }
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo e instalar `jinja2`:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo e instalar `jinja2`:
 
 <div class="termy">
 
@@ -123,4 +123,4 @@ Y porque estás usando `StaticFiles`, ese archivo CSS sería servido automática
 
 ## Más detalles { #more-details }
 
-Para más detalles, incluyendo cómo testear plantillas, revisa <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">la documentación de Starlette sobre plantillas</a>.
+Para más detalles, incluyendo cómo testear plantillas, revisa [la documentación de Starlette sobre plantillas](https://www.starlette.dev/templates/).
index 89ef2d5a4b69188e24c212e8820833b2bc549b4a..47360316337b920c404de5e18b30231057f8576a 100644 (file)
@@ -8,6 +8,6 @@ Para esto, usas el `TestClient` en un statement `with`, conectándote al WebSock
 
 /// note | Nota
 
-Para más detalles, revisa la documentación de Starlette sobre <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">probar WebSockets</a>.
+Para más detalles, revisa la documentación de Starlette sobre [probar WebSockets](https://www.starlette.dev/testclient/#testing-websocket-sessions).
 
 ///
index 4a063d29708a29f4550e93a614a927baa2c4bb62..3aed8e5a36ae8fdeb949fc75c40861141eda335c 100644 (file)
@@ -15,7 +15,7 @@ Pero hay situaciones donde podrías necesitar acceder al objeto `Request` direct
 
 ## Detalles sobre el objeto `Request` { #details-about-the-request-object }
 
-Como **FastAPI** es en realidad **Starlette** por debajo, con una capa de varias herramientas encima, puedes usar el objeto <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a> de Starlette directamente cuando lo necesites.
+Como **FastAPI** es en realidad **Starlette** por debajo, con una capa de varias herramientas encima, puedes usar el objeto de Starlette [`Request`](https://www.starlette.dev/requests/) directamente cuando lo necesites.
 
 También significa que si obtienes datos del objeto `Request` directamente (por ejemplo, leyendo el cuerpo) no serán validados, convertidos o documentados (con OpenAPI, para la interfaz automática de usuario de la API) por FastAPI.
 
@@ -45,7 +45,7 @@ De la misma manera, puedes declarar cualquier otro parámetro como normalmente,
 
 ## Documentación de `Request` { #request-documentation }
 
-Puedes leer más detalles sobre el <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">objeto `Request` en el sitio de documentación oficial de Starlette</a>.
+Puedes leer más detalles sobre el [objeto `Request` en el sitio de documentación oficial de Starlette](https://www.starlette.dev/requests/).
 
 /// note | Detalles Técnicos
 
index e9391c36ca196debc5672476c4e2bbfba682d159..fe75e644b841550325d57ec0c6b2b43e5d77be6f 100644 (file)
@@ -1,10 +1,10 @@
 # WebSockets { #websockets }
 
-Puedes usar <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a> con **FastAPI**.
+Puedes usar [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) con **FastAPI**.
 
 ## Instalar `websockets` { #install-websockets }
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo e instalar `websockets` (un paquete de Python que facilita usar el protocolo "WebSocket"):
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo e instalar `websockets` (un paquete de Python que facilita usar el protocolo "WebSocket"):
 
 <div class="termy">
 
@@ -64,19 +64,19 @@ Puedes recibir y enviar datos binarios, de texto y JSON.
 
 ## Pruébalo { #try-it }
 
-Si tu archivo se llama `main.py`, ejecuta tu aplicación con:
+Pon tu código en un archivo `main.py` y luego ejecuta tu aplicación:
 
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
 </div>
 
-Abre tu navegador en <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
+Abre tu navegador en [http://127.0.0.1:8000](http://127.0.0.1:8000).
 
 Verás una página simple como:
 
@@ -115,25 +115,25 @@ Funcionan de la misma manera que para otros endpoints de FastAPI/*path operation
 
 Como esto es un WebSocket no tiene mucho sentido lanzar un `HTTPException`, en su lugar lanzamos un `WebSocketException`.
 
-Puedes usar un código de cierre de los <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">códigos válidos definidos en la especificación</a>.
+Puedes usar un código de cierre de los [códigos válidos definidos en la especificación](https://tools.ietf.org/html/rfc6455#section-7.4.1).
 
 ///
 
 ### Prueba los WebSockets con dependencias { #try-the-websockets-with-dependencies }
 
-Si tu archivo se llama `main.py`, ejecuta tu aplicación con:
+Ejecuta tu aplicación:
 
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
 </div>
 
-Abre tu navegador en <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
+Abre tu navegador en [http://127.0.0.1:8000](http://127.0.0.1:8000).
 
 Ahí puedes establecer:
 
@@ -174,7 +174,7 @@ La aplicación anterior es un ejemplo mínimo y simple para demostrar cómo mane
 
 Pero ten en cuenta que, como todo se maneja en memoria, en una sola lista, solo funcionará mientras el proceso esté en ejecución, y solo funcionará con un solo proceso.
 
-Si necesitas algo fácil de integrar con FastAPI pero que sea más robusto, soportado por Redis, PostgreSQL u otros, revisa <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a>.
+Si necesitas algo fácil de integrar con FastAPI pero que sea más robusto, soportado por Redis, PostgreSQL u otros, revisa [encode/broadcaster](https://github.com/encode/broadcaster).
 
 ///
 
@@ -182,5 +182,5 @@ Si necesitas algo fácil de integrar con FastAPI pero que sea más robusto, sopo
 
 Para aprender más sobre las opciones, revisa la documentación de Starlette para:
 
-* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">La clase `WebSocket`</a>.
-* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">Manejo de WebSocket basado en clases</a>.
+* [La clase `WebSocket`](https://www.starlette.dev/websockets/).
+* [Manejo de WebSocket basado en clases](https://www.starlette.dev/endpoints/#websocketendpoint).
index 05322a4d1e613068352b2c3a75ad5311393a7d59..0d0c42fd540a75e0b302370c64b1e8951d33503f 100644 (file)
@@ -1,6 +1,6 @@
 # Incluyendo WSGI - Flask, Django, otros { #including-wsgi-flask-django-others }
 
-Puedes montar aplicaciones WSGI como viste con [Sub Aplicaciones - Mounts](sub-applications.md){.internal-link target=_blank}, [Detrás de un Proxy](behind-a-proxy.md){.internal-link target=_blank}.
+Puedes montar aplicaciones WSGI como viste con [Sub Aplicaciones - Mounts](sub-applications.md), [Detrás de un Proxy](behind-a-proxy.md).
 
 Para eso, puedes usar el `WSGIMiddleware` y usarlo para envolver tu aplicación WSGI, por ejemplo, Flask, Django, etc.
 
@@ -36,13 +36,13 @@ Ahora, cada request bajo el path `/v1/` será manejado por la aplicación Flask.
 
 Y el resto será manejado por **FastAPI**.
 
-Si lo ejecutas y vas a <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a> verás el response de Flask:
+Si lo ejecutas y vas a [http://localhost:8000/v1/](http://localhost:8000/v1/) verás el response de Flask:
 
 ```txt
 Hello, World from Flask!
 ```
 
-Y si vas a <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a> verás el response de FastAPI:
+Y si vas a [http://localhost:8000/v2](http://localhost:8000/v2) verás el response de FastAPI:
 
 ```JSON
 {
index cc9309dd2fc74a4432d5ac195d2b562817c220c9..4250f0a02bc9c8432c8a723d0d5b57b4edb924cc 100644 (file)
@@ -14,7 +14,7 @@ Pero en algún punto, no hubo otra opción que crear algo que proporcionara toda
 
 ## Herramientas previas { #previous-tools }
 
-### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
+### [Django](https://www.djangoproject.com/) { #django }
 
 Es el framework más popular de Python y es ampliamente confiable. Se utiliza para construir sistemas como Instagram.
 
@@ -22,7 +22,7 @@ Está relativamente acoplado con bases de datos relacionales (como MySQL o Postg
 
 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 }
+### [Django REST Framework](https://www.django-rest-framework.org/) { #django-rest-framework }
 
 El framework Django REST fue creado para ser un kit de herramientas flexible para construir APIs Web utilizando Django, mejorando sus capacidades API.
 
@@ -42,7 +42,7 @@ Tener una interfaz de usuario web de documentación automática de APIs.
 
 ///
 
-### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
+### [Flask](https://flask.palletsprojects.com) { #flask }
 
 Flask es un "microframework", no incluye integraciones de bases de datos ni muchas de las cosas que vienen por defecto en Django.
 
@@ -64,7 +64,7 @@ Tener un sistema de routing simple y fácil de usar.
 
 ///
 
-### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
+### [Requests](https://requests.readthedocs.io) { #requests }
 
 **FastAPI** no es en realidad una alternativa a **Requests**. Su ámbito es muy diferente.
 
@@ -106,7 +106,7 @@ Mira las similitudes entre `requests.get(...)` y `@app.get(...)`.
 
 ///
 
-### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> { #swagger-openapi }
+### [Swagger](https://swagger.io/) / [OpenAPI](https://github.com/OAI/OpenAPI-Specification/) { #swagger-openapi }
 
 La principal funcionalidad que quería de Django REST Framework era la documentación automática de la API.
 
@@ -124,8 +124,8 @@ Adoptar y usar un estándar abierto para especificaciones de API, en lugar de us
 
 Y a integrar herramientas de interfaz de usuario basadas en estándares:
 
-* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>
-* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>
+* [Swagger UI](https://github.com/swagger-api/swagger-ui)
+* [ReDoc](https://github.com/Rebilly/ReDoc)
 
 Estas dos fueron elegidas por ser bastante populares y estables, pero haciendo una búsqueda rápida, podrías encontrar docenas de interfaces de usuario alternativas para OpenAPI (que puedes usar con **FastAPI**).
 
@@ -135,7 +135,7 @@ Estas dos fueron elegidas por ser bastante populares y estables, pero haciendo u
 
 Existen varios frameworks REST para Flask, pero después de invertir tiempo y trabajo investigándolos, encontré que muchos son descontinuados o abandonados, con varios problemas existentes que los hacían inadecuados.
 
-### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
+### [Marshmallow](https://marshmallow.readthedocs.io/en/stable/) { #marshmallow }
 
 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.
 
@@ -153,7 +153,7 @@ Usar código para definir "esquemas" que proporcionen tipos de datos y validaci
 
 ///
 
-### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
+### [Webargs](https://webargs.readthedocs.io/en/latest/) { #webargs }
 
 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.
 
@@ -175,7 +175,7 @@ Tener validación automática de datos entrantes en una request.
 
 ///
 
-### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
+### [APISpec](https://apispec.readthedocs.io/en/stable/) { #apispec }
 
 Marshmallow y Webargs proporcionan validación, parsing y serialización como plug-ins.
 
@@ -205,7 +205,7 @@ Soportar el estándar abierto para APIs, OpenAPI.
 
 ///
 
-### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> { #flask-apispec }
+### [Flask-apispec](https://flask-apispec.readthedocs.io/en/latest/) { #flask-apispec }
 
 Es un plug-in de Flask, que conecta juntos Webargs, Marshmallow y APISpec.
 
@@ -219,11 +219,11 @@ Esta combinación de Flask, Flask-apispec con Marshmallow y Webargs fue mi stack
 
 Usarlo llevó a la creación de varios generadores de full-stack para Flask. Estos son los principales stacks que yo (y varios equipos externos) hemos estado usando hasta ahora:
 
-* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a>
-* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a>
-* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a>
+* [https://github.com/tiangolo/full-stack](https://github.com/tiangolo/full-stack)
+* [https://github.com/tiangolo/full-stack-flask-couchbase](https://github.com/tiangolo/full-stack-flask-couchbase)
+* [https://github.com/tiangolo/full-stack-flask-couchdb](https://github.com/tiangolo/full-stack-flask-couchdb)
 
-Y estos mismos generadores de full-stack fueron la base de los [Generadores de Proyectos **FastAPI**](project-generation.md){.internal-link target=_blank}.
+Y estos mismos generadores de full-stack fueron la base de los [Generadores de Proyectos **FastAPI**](project-generation.md).
 
 /// info | Información
 
@@ -237,7 +237,7 @@ Generar el esquema OpenAPI automáticamente, desde el mismo código que define l
 
 ///
 
-### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (y <a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) { #nestjs-and-angular }
+### [NestJS](https://nestjs.com/) (y [Angular](https://angular.io/)) { #nestjs-and-angular }
 
 Esto ni siquiera es Python, NestJS es un framework de JavaScript (TypeScript) NodeJS inspirado por Angular.
 
@@ -259,13 +259,13 @@ Tener un poderoso sistema de inyección de dependencias. Encontrar una forma de
 
 ///
 
-### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> { #sanic }
+### [Sanic](https://sanic.readthedocs.io/en/latest/) { #sanic }
 
 Fue uno de los primeros frameworks de Python extremadamente rápidos basados en `asyncio`. Fue hecho para ser muy similar a Flask.
 
 /// note | Detalles Técnicos
 
-Usó <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> en lugar del loop `asyncio` por defecto de Python. Eso fue lo que lo hizo tan rápido.
+Usó [`uvloop`](https://github.com/MagicStack/uvloop) en lugar del loop `asyncio` por defecto de Python. Eso fue lo que lo hizo tan rápido.
 
 Claramente inspiró a Uvicorn y Starlette, que actualmente son más rápidos que Sanic en benchmarks abiertos.
 
@@ -279,7 +279,7 @@ Por eso **FastAPI** se basa en Starlette, ya que es el framework más rápido di
 
 ///
 
-### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
+### [Falcon](https://falconframework.org/) { #falcon }
 
 Falcon es otro framework de Python de alto rendimiento, está diseñado para ser minimalista y funcionar como la base de otros frameworks como Hug.
 
@@ -297,7 +297,7 @@ Aunque en FastAPI es opcional, y se utiliza principalmente para configurar heade
 
 ///
 
-### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
+### [Molten](https://moltenframework.com/) { #molten }
 
 Descubrí Molten en las primeras etapas de construcción de **FastAPI**. Y tiene ideas bastante similares:
 
@@ -321,7 +321,7 @@ Esto en realidad inspiró la actualización de partes de Pydantic, para soportar
 
 ///
 
-### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a> { #hug }
+### [Hug](https://github.com/hugapi/hug) { #hug }
 
 Hug fue uno de los primeros frameworks en implementar la declaración de tipos de parámetros API usando las anotaciones de tipos de Python. Esta fue una gran idea que inspiró a otras herramientas a hacer lo mismo.
 
@@ -337,7 +337,7 @@ Dado que se basa en el estándar previo para frameworks web Python sincrónicos
 
 /// info | Información
 
-Hug fue creado por Timothy Crosley, el mismo creador de <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a>, una gran herramienta para ordenar automáticamente imports en archivos Python.
+Hug fue creado por Timothy Crosley, el mismo creador de [`isort`](https://github.com/timothycrosley/isort), una gran herramienta para ordenar automáticamente imports en archivos Python.
 
 ///
 
@@ -351,7 +351,7 @@ Hug inspiró a **FastAPI** a declarar un parámetro `response` en funciones para
 
 ///
 
-### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) { #apistar-0-5 }
+### [APIStar](https://github.com/encode/apistar) (<= 0.5) { #apistar-0-5 }
 
 Justo antes de decidir construir **FastAPI** encontré **APIStar** server. Tenía casi todo lo que estaba buscando y tenía un gran diseño.
 
@@ -401,7 +401,7 @@ Considero a **FastAPI** un "sucesor espiritual" de APIStar, mientras mejora y au
 
 ## Usado por **FastAPI** { #used-by-fastapi }
 
-### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> { #pydantic }
+### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
 
 Pydantic es un paquete para definir validación de datos, serialización y documentación (usando JSON Schema) basándose en las anotaciones de tipos de Python.
 
@@ -417,7 +417,7 @@ Manejar toda la validación de datos, serialización de datos y documentación a
 
 ///
 
-### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
+### [Starlette](https://www.starlette.dev/) { #starlette }
 
 Starlette es un framework/toolkit <dfn title="El nuevo estándar para construir aplicaciones web asíncronas en Python">ASGI</dfn> liviano, ideal para construir servicios asyncio de alto rendimiento.
 
@@ -433,7 +433,7 @@ Tiene:
 * CORS, GZip, Archivos estáticos, Responses en streaming.
 * Soporte para sesiones y cookies.
 * Cobertura de tests del 100%.
-* Base de código 100% tipada.
+* code base 100% tipada.
 * Pocas dependencias obligatorias.
 
 Starlette es actualmente el framework de Python más rápido probado. Solo superado por Uvicorn, que no es un framework, sino un servidor.
@@ -462,7 +462,7 @@ Por lo tanto, cualquier cosa que puedas hacer con Starlette, puedes hacerlo dire
 
 ///
 
-### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
+### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
 
 Uvicorn es un servidor ASGI extremadamente rápido, construido sobre uvloop y httptools.
 
@@ -476,10 +476,10 @@ El servidor web principal para ejecutar aplicaciones **FastAPI**.
 
 También puedes usar la opción de línea de comandos `--workers` para tener un servidor multiproceso asíncrono.
 
-Revisa más detalles en la sección [Despliegue](deployment/index.md){.internal-link target=_blank}.
+Revisa más detalles en la sección [Despliegue](deployment/index.md).
 
 ///
 
 ## Benchmarks y velocidad { #benchmarks-and-speed }
 
-Para entender, comparar, y ver la diferencia entre Uvicorn, Starlette y FastAPI, revisa la sección sobre [Benchmarks](benchmarks.md){.internal-link target=_blank}.
+Para entender, comparar, y ver la diferencia entre Uvicorn, Starlette y FastAPI, revisa la sección sobre [Benchmarks](benchmarks.md).
index a06d3e979d50f54817b508eb0de1ada0b2023a30..a8ed00df128fa1e2afd69ddc26890e83be0defb1 100644 (file)
@@ -141,7 +141,7 @@ Tú y tu crush comen las hamburguesas y pasan un buen rato. ✨
 
 /// info | Información
 
-Hermosas ilustraciones de <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
+Hermosas ilustraciones de [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
 
 ///
 
@@ -207,7 +207,7 @@ No hubo mucho hablar o coquetear ya que la mayor parte del tiempo se dedicó a e
 
 /// info | Información
 
-Hermosas ilustraciones de <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
+Hermosas ilustraciones de [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
 
 ///
 
@@ -251,7 +251,7 @@ Este tipo de asincronía es lo que hizo popular a NodeJS (aunque NodeJS no es pa
 
 Y ese es el mismo nivel de rendimiento que obtienes con **FastAPI**.
 
-Y como puedes tener paralelismo y asincronía al mismo tiempo, obtienes un mayor rendimiento que la mayoría de los frameworks de NodeJS probados y a la par con Go, que es un lenguaje compilado más cercano a C <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(todo gracias a Starlette)</a>.
+Y como puedes tener paralelismo y asincronía al mismo tiempo, obtienes un mayor rendimiento que la mayoría de los frameworks de NodeJS probados y a la par con Go, que es un lenguaje compilado más cercano a C [(todo gracias a Starlette)](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1).
 
 ### ¿Es la concurrencia mejor que el paralelismo? { #is-concurrency-better-than-parallelism }
 
@@ -298,7 +298,7 @@ Pero también puedes explotar los beneficios del paralelismo y la multiprocesami
 
 Eso, más el simple hecho de que Python es el lenguaje principal para **Data Science**, Machine Learning y especialmente Deep Learning, hacen de FastAPI una muy buena opción para APIs web de Data Science / Machine Learning y aplicaciones (entre muchas otras).
 
-Para ver cómo lograr este paralelismo en producción, consulta la sección sobre [Deployment](deployment/index.md){.internal-link target=_blank}.
+Para ver cómo lograr este paralelismo en producción, consulta la sección sobre [Despliegue](deployment/index.md).
 
 ## `async` y `await` { #async-and-await }
 
@@ -363,13 +363,13 @@ Pero si deseas usar `async` / `await` sin FastAPI, también puedes hacerlo.
 
 ### Escribe tu propio código async { #write-your-own-async-code }
 
-Starlette (y **FastAPI**) están basados en <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, lo que lo hace compatible tanto con el <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> del paquete estándar de Python como con <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
+Starlette (y **FastAPI**) están basados en [AnyIO](https://anyio.readthedocs.io/en/stable/), lo que lo hace compatible tanto con el [asyncio](https://docs.python.org/3/library/asyncio-task.html) del paquete estándar de Python como con [Trio](https://trio.readthedocs.io/en/stable/).
 
-En particular, puedes usar directamente <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> para tus casos de uso avanzados de concurrencia que requieran patrones más avanzados en tu propio código.
+En particular, puedes usar directamente [AnyIO](https://anyio.readthedocs.io/en/stable/) para tus casos de uso avanzados de concurrencia que requieran patrones más avanzados en tu propio código.
 
-E incluso si no estuvieras usando FastAPI, también podrías escribir tus propias aplicaciones asíncronas con <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> para ser altamente compatibles y obtener sus beneficios (p.ej. *concurrencia estructurada*).
+E incluso si no estuvieras usando FastAPI, también podrías escribir tus propias aplicaciones asíncronas con [AnyIO](https://anyio.readthedocs.io/en/stable/) para ser altamente compatibles y obtener sus beneficios (p.ej. *concurrencia estructurada*).
 
-Creé otro paquete sobre AnyIO, como una capa delgada, para mejorar un poco las anotaciones de tipos y obtener mejor **autocompletado**, **errores en línea**, etc. También tiene una introducción amigable y tutorial para ayudarte a **entender** y escribir **tu propio código async**: <a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>. Sería particularmente útil si necesitas **combinar código async con regular** (bloqueante/sincrónico).
+Creé otro paquete sobre AnyIO, como una capa delgada, para mejorar un poco las anotaciones de tipos y obtener mejor **autocompletado**, **errores en línea**, etc. También tiene una introducción amigable y tutorial para ayudarte a **entender** y escribir **tu propio código async**: [Asyncer](https://asyncer.tiangolo.com/). Sería particularmente útil si necesitas **combinar código async con regular** (bloqueante/sincrónico).
 
 ### Otras formas de código asíncrono { #other-forms-of-asynchronous-code }
 
@@ -381,7 +381,7 @@ Esta misma sintaxis (o casi idéntica) también se incluyó recientemente en las
 
 Pero antes de eso, manejar el código asíncrono era mucho más complejo y difícil.
 
-En versiones previas de Python, podrías haber usado hilos o <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>. Pero el código es mucho más complejo de entender, depurar y razonar.
+En versiones previas de Python, podrías haber usado hilos o [Gevent](https://www.gevent.org/). Pero el código es mucho más complejo de entender, depurar y razonar.
 
 En versiones previas de NodeJS / JavaScript en el Navegador, habrías usado "callbacks". Lo que lleva al "callback hell".
 
@@ -407,7 +407,7 @@ Todo eso es lo que impulsa FastAPI (a través de Starlette) y lo que hace que te
 
 Probablemente puedas saltarte esto.
 
-Estos son detalles muy técnicos de cómo funciona **FastAPI** en su interior.
+Estos son detalles muy técnicos de cómo **FastAPI** funciona en su interior.
 
 Si tienes bastante conocimiento técnico (coroutines, hilos, bloqueo, etc.) y tienes curiosidad sobre cómo FastAPI maneja `async def` vs `def` normal, adelante.
 
@@ -419,15 +419,15 @@ Cuando declaras una *path operation function* con `def` normal en lugar de `asyn
 
 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.
+Aun así, en ambas situaciones, es probable que **FastAPI** [siga siendo más rápida](index.md#performance) que (o al menos comparable a) tu framework anterior.
 
 ### Dependencias { #dependencies }
 
-Lo mismo aplica para las [dependencias](tutorial/dependencies/index.md){.internal-link target=_blank}. Si una dependencia es una función estándar `def` en lugar de `async def`, se ejecuta en el threadpool externo.
+Lo mismo aplica para las [dependencias](tutorial/dependencies/index.md). Si una dependencia es una función estándar `def` en lugar de `async def`, se ejecuta en el threadpool externo.
 
 ### Sub-dependencias { #sub-dependencies }
 
-Puedes tener múltiples dependencias y [sub-dependencias](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} requiriéndose mutuamente (como parámetros de las definiciones de funciones), algunas de ellas podrían ser creadas con `async def` y algunas con `def` normal. Aun funcionará, y las que fueron creadas con `def` normal serían llamadas en un hilo externo (del threadpool) en lugar de ser "awaited".
+Puedes tener múltiples dependencias y [sub-dependencias](tutorial/dependencies/sub-dependencies.md) requiriéndose mutuamente (como parámetros de las definiciones de funciones), algunas de ellas podrían ser creadas con `async def` y algunas con `def` normal. Aun funcionará, y las que fueron creadas con `def` normal serían llamadas en un hilo externo (del threadpool) en lugar de ser "awaited".
 
 ### Otras funciones de utilidad { #other-utility-functions }
 
index e6f8f99647cbb1146bab2a04e4292c13e0806105..040dc5812971701a3c9a0c8d3232b85fbf3c7328 100644 (file)
@@ -1,6 +1,6 @@
 # Benchmarks { #benchmarks }
 
-Los benchmarks independientes de TechEmpower muestran aplicaciones de **FastAPI** ejecutándose bajo Uvicorn como <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">uno de los frameworks de Python más rápidos disponibles</a>, solo por debajo de Starlette y Uvicorn en sí mismos (utilizados internamente por FastAPI).
+Los benchmarks independientes de TechEmpower muestran aplicaciones de **FastAPI** ejecutándose bajo Uvicorn como [uno de los frameworks de Python más rápidos disponibles](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), solo por debajo de Starlette y Uvicorn en sí mismos (utilizados internamente por FastAPI).
 
 Pero al revisar benchmarks y comparaciones, debes tener en cuenta lo siguiente.
 
index a3531b97a743553872496e2b654974099b2568f9..266d3cfd23d68371ab7ee97612dc8f346bdcf12f 100644 (file)
@@ -6,7 +6,7 @@ En la mayoría de los casos, los principales proveedores de nube tienen guías p
 
 ## FastAPI Cloud { #fastapi-cloud }
 
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** está construido por el mismo autor y equipo detrás de **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** está construido por el mismo autor y equipo detrás de **FastAPI**.
 
 Simplifica el proceso de **construir**, **desplegar** y **acceder** a una API con un esfuerzo mínimo.
 
@@ -16,9 +16,9 @@ FastAPI Cloud es el sponsor principal y proveedor de financiamiento de los proye
 
 ## Proveedores de Nube - Sponsors { #cloud-providers-sponsors }
 
-Otros proveedores de nube ✨ [**son sponsors de FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ también. 🙇
+Otros proveedores de nube ✨ [**son sponsors de FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ también. 🙇
 
 También podrías considerarlos para seguir sus guías y probar sus servicios:
 
-* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
-* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
+* [Render](https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi)
+* [Railway](https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi)
index 2ec7af19ba78db0d95e0b9d48f523d0240db704e..9b3ac0a340d59e4445dfe1600e5c8c83c515d568 100644 (file)
@@ -25,7 +25,7 @@ Pero por ahora, revisemos estas importantes **ideas conceptuales**. Estos concep
 
 ## Seguridad - HTTPS { #security-https }
 
-En el [capítulo anterior sobre HTTPS](https.md){.internal-link target=_blank} aprendimos sobre cómo HTTPS proporciona cifrado para tu API.
+En el [capítulo anterior sobre HTTPS](https.md) aprendimos sobre cómo HTTPS proporciona cifrado para tu API.
 
 También vimos que HTTPS es normalmente proporcionado por un componente **externo** a tu servidor de aplicaciones, un **Proxy de Terminación TLS**.
 
@@ -190,7 +190,7 @@ Cuando ejecutas **múltiples procesos** del mismo programa de API, comúnmente s
 
 ### Worker Processes y Puertos { #worker-processes-and-ports }
 
-Recuerda de la documentación [Sobre HTTPS](https.md){.internal-link target=_blank} que solo un proceso puede estar escuchando en una combinación de puerto y dirección IP en un servidor.
+Recuerda de la documentación [Sobre HTTPS](https.md) que solo un proceso puede estar escuchando en una combinación de puerto y dirección IP en un servidor.
 
 Esto sigue siendo cierto.
 
@@ -243,7 +243,7 @@ Aquí hay algunas combinaciones y estrategias posibles:
 
 No te preocupes si algunos de estos elementos sobre **contenedores**, Docker, o Kubernetes no tienen mucho sentido todavía.
 
-Te contaré más sobre imágenes de contenedores, Docker, Kubernetes, etc. en un capítulo futuro: [FastAPI en Contenedores - Docker](docker.md){.internal-link target=_blank}.
+Te contaré más sobre imágenes de contenedores, Docker, Kubernetes, etc. en un capítulo futuro: [FastAPI en Contenedores - Docker](docker.md).
 
 ///
 
@@ -281,7 +281,7 @@ Aquí hay algunas ideas posibles:
 
 /// tip | Consejo
 
-Te daré más ejemplos concretos para hacer esto con contenedores en un capítulo futuro: [FastAPI en Contenedores - Docker](docker.md){.internal-link target=_blank}.
+Te daré más ejemplos concretos para hacer esto con contenedores en un capítulo futuro: [FastAPI en Contenedores - Docker](docker.md).
 
 ///
 
index 105a5902b7d07917df349c664d664cc16f0c5824..6ce0e192ac115e4903b41a1cdbfc7470964e5b78 100644 (file)
@@ -1,6 +1,6 @@
 # FastAPI en Contenedores - Docker { #fastapi-in-containers-docker }
 
-Al desplegar aplicaciones de FastAPI, un enfoque común es construir una **imagen de contenedor de Linux**. Normalmente se realiza usando <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Luego puedes desplegar esa imagen de contenedor de varias formas.
+Al desplegar aplicaciones de FastAPI, un enfoque común es construir una **imagen de contenedor de Linux**. Normalmente se realiza usando [**Docker**](https://www.docker.com/). Luego puedes desplegar esa imagen de contenedor de varias formas.
 
 Usar contenedores de Linux tiene varias ventajas, incluyendo **seguridad**, **replicabilidad**, **simplicidad**, y otras.
 
@@ -60,16 +60,16 @@ Y el **contenedor** en sí (en contraste con la **imagen de contenedor**) es la
 
 Docker ha sido una de las herramientas principales para crear y gestionar **imágenes de contenedor** y **contenedores**.
 
-Y hay un <a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a> público con **imágenes de contenedores oficiales** pre-hechas para muchas herramientas, entornos, bases de datos y aplicaciones.
+Y hay un [Docker Hub](https://hub.docker.com/) público con **imágenes de contenedores oficiales** pre-hechas para muchas herramientas, entornos, bases de datos y aplicaciones.
 
-Por ejemplo, hay una <a href="https://hub.docker.com/_/python" class="external-link" target="_blank">Imagen de Python</a> oficial.
+Por ejemplo, hay una [Imagen de Python](https://hub.docker.com/_/python) oficial.
 
 Y hay muchas otras imágenes para diferentes cosas como bases de datos, por ejemplo para:
 
-* <a href="https://hub.docker.com/_/postgres" class="external-link" target="_blank">PostgreSQL</a>
-* <a href="https://hub.docker.com/_/mysql" class="external-link" target="_blank">MySQL</a>
-* <a href="https://hub.docker.com/_/mongo" class="external-link" target="_blank">MongoDB</a>
-* <a href="https://hub.docker.com/_/redis" class="external-link" target="_blank">Redis</a>, etc.
+* [PostgreSQL](https://hub.docker.com/_/postgres)
+* [MySQL](https://hub.docker.com/_/mysql)
+* [MongoDB](https://hub.docker.com/_/mongo)
+* [Redis](https://hub.docker.com/_/redis), etc.
 
 Usando una imagen de contenedor pre-hecha es muy fácil **combinar** y utilizar diferentes herramientas. Por ejemplo, para probar una nueva base de datos. En la mayoría de los casos, puedes usar las **imágenes oficiales**, y simplemente configurarlas con variables de entorno.
 
@@ -111,7 +111,7 @@ Dependería principalmente de la herramienta que uses para **instalar** esos req
 
 La forma más común de hacerlo es tener un archivo `requirements.txt` con los nombres de los paquetes y sus versiones, uno por línea.
 
-Por supuesto, usarías las mismas ideas que leíste en [Acerca de las versiones de FastAPI](versions.md){.internal-link target=_blank} para establecer los rangos de versiones.
+Por supuesto, usarías las mismas ideas que leíste en [Acerca de las versiones de FastAPI](versions.md) para establecer los rangos de versiones.
 
 Por ejemplo, tu `requirements.txt` podría verse así:
 
@@ -238,7 +238,7 @@ Asegúrate de **siempre** usar la **forma exec** de la instrucción `CMD`, como
 
 #### Usar `CMD` - Forma Exec { #use-cmd-exec-form }
 
-La instrucción Docker <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> se puede escribir usando dos formas:
+La instrucción Docker [`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) se puede escribir usando dos formas:
 
 ✅ **Forma Exec**:
 
@@ -254,11 +254,11 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
 CMD fastapi run app/main.py --port 80
 ```
 
-Asegúrate de siempre usar la **forma exec** para garantizar que FastAPI pueda cerrarse de manera adecuada y que [los eventos de lifespan](../advanced/events.md){.internal-link target=_blank} sean disparados.
+Asegúrate de siempre usar la **forma exec** para garantizar que FastAPI pueda cerrarse de manera adecuada y que [los eventos de lifespan](../advanced/events.md) sean disparados.
 
-Puedes leer más sobre esto en las <a href="https://docs.docker.com/reference/dockerfile/#shell-and-exec-form" class="external-link" target="_blank">documentación de Docker para formas de shell y exec</a>.
+Puedes leer más sobre esto en la [documentación de Docker para formas de shell y exec](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form).
 
-Esto puede ser bastante notorio al usar `docker compose`. Consulta esta sección de preguntas frecuentes de Docker Compose para más detalles técnicos: <a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">¿Por qué mis servicios tardan 10 segundos en recrearse o detenerse?</a>.
+Esto puede ser bastante notorio al usar `docker compose`. Consulta esta sección de preguntas frecuentes de Docker Compose para más detalles técnicos: [¿Por qué mis servicios tardan 10 segundos en recrearse o detenerse?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop).
 
 #### Estructura de Directorios { #directory-structure }
 
@@ -352,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
 
 ## Revísalo { #check-it }
 
-Deberías poder revisarlo en la URL de tu contenedor de Docker, por ejemplo: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> o <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (o equivalente, usando tu host de Docker).
+Deberías poder revisarlo en la URL de tu contenedor de Docker, por ejemplo: [http://192.168.99.100/items/5?q=somequery](http://192.168.99.100/items/5?q=somequery) o [http://127.0.0.1/items/5?q=somequery](http://127.0.0.1/items/5?q=somequery) (o equivalente, usando tu host de Docker).
 
 Verás algo como:
 
@@ -362,17 +362,17 @@ Verás algo como:
 
 ## Documentación Interactiva de la API { #interactive-api-docs }
 
-Ahora puedes ir a <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> o <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (o equivalente, usando tu host de Docker).
+Ahora puedes ir a [http://192.168.99.100/docs](http://192.168.99.100/docs) o [http://127.0.0.1/docs](http://127.0.0.1/docs) (o equivalente, usando tu host de Docker).
 
-Verás la documentación interactiva automática de la API (proporcionada por <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
+Verás la documentación interactiva automática de la API (proporcionada por [Swagger UI](https://github.com/swagger-api/swagger-ui)):
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
 ## Documentación Alternativa de la API { #alternative-api-docs }
 
-Y también puedes ir a <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> o <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (o equivalente, usando tu host de Docker).
+Y también puedes ir a [http://192.168.99.100/redoc](http://192.168.99.100/redoc) o [http://127.0.0.1/redoc](http://127.0.0.1/redoc) (o equivalente, usando tu host de Docker).
 
-Verás la documentación alternativa automática (proporcionada por <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
+Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Rebilly/ReDoc)):
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
@@ -413,7 +413,7 @@ Cuando pasas el archivo a `fastapi run`, detectará automáticamente que es un a
 
 ## Conceptos de Despliegue { #deployment-concepts }
 
-Hablemos nuevamente de algunos de los mismos [Conceptos de Despliegue](concepts.md){.internal-link target=_blank} en términos de contenedores.
+Hablemos nuevamente de algunos de los mismos [Conceptos de Despliegue](concepts.md) en términos de contenedores.
 
 Los contenedores son principalmente una herramienta para simplificar el proceso de **construcción y despliegue** de una aplicación, pero no imponen un enfoque particular para manejar estos **conceptos de despliegue**, y hay varias estrategias posibles.
 
@@ -432,7 +432,7 @@ Revisemos estos **conceptos de despliegue** en términos de contenedores:
 
 Si nos enfocamos solo en la **imagen de contenedor** para una aplicación FastAPI (y luego el **contenedor** en ejecución), HTTPS normalmente sería manejado **externamente** por otra herramienta.
 
-Podría ser otro contenedor, por ejemplo, con <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>, manejando **HTTPS** y la adquisición **automática** de **certificados**.
+Podría ser otro contenedor, por ejemplo, con [Traefik](https://traefik.io/), manejando **HTTPS** y la adquisición **automática** de **certificados**.
 
 /// tip | Consejo
 
@@ -558,7 +558,7 @@ Si tienes **múltiples contenedores**, probablemente cada uno ejecutando un **pr
 
 /// info | Información
 
-Si estás usando Kubernetes, probablemente sería un <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Contenedor de Inicialización</a>.
+Si estás usando Kubernetes, probablemente sería un [Contenedor de Inicialización](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
 
 ///
 
@@ -570,7 +570,7 @@ Si tienes una configuración simple, con un **contenedor único** que luego inic
 
 ### Imagen Base de Docker { #base-docker-image }
 
-Solía haber una imagen official de Docker de FastAPI: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Pero ahora está obsoleta. ⛔️
+Solía haber una imagen oficial de Docker de FastAPI: [tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker). Pero ahora está obsoleta. ⛔️
 
 Probablemente **no** deberías usar esta imagen base de Docker (o cualquier otra similar).
 
@@ -600,7 +600,7 @@ Por ejemplo:
 
 ## Imagen de Docker con `uv` { #docker-image-with-uv }
 
-Si estás usando <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> para instalar y gestionar tu proyecto, puedes seguir su <a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">guía de Docker de uv</a>.
+Si estás usando [uv](https://github.com/astral-sh/uv) para instalar y gestionar tu proyecto, puedes seguir su [guía de Docker de uv](https://docs.astral.sh/uv/guides/integration/docker/).
 
 ## Resumen { #recap }
 
index 9763af48c52cdfe161282239366c6baf3720e648..fc770d1eed29fbb0b69d0604274bab29c967a055 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 [FastAPI Cloud](https://fastapicloud.com) con **un solo comando**; ve y únete a la lista de espera si aún no lo has hecho. 🚀
 
 ## Iniciar sesión { #login }
 
@@ -40,7 +40,7 @@ Deploying to FastAPI Cloud...
 
 ## Acerca de FastAPI Cloud { #about-fastapi-cloud }
 
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** está creado por el mismo autor y equipo detrás de **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** está creado por el mismo autor y equipo detrás de **FastAPI**.
 
 Agiliza el proceso de **crear**, **desplegar** y **acceder** a una API con el mínimo esfuerzo.
 
index d7a244107c17955fb60fefa14ef0f0abf7956a37..227aab0d6ac7124a4616980ca2ad6a8e0b3880f2 100644 (file)
@@ -10,7 +10,7 @@ Si tienes prisa o no te importa, continúa con las siguientes secciones para ver
 
 ///
 
-Para **aprender los conceptos básicos de HTTPS**, desde una perspectiva de consumidor, revisa <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
+Para **aprender los conceptos básicos de HTTPS**, desde una perspectiva de consumidor, revisa [https://howhttps.works/](https://howhttps.works/).
 
 Ahora, desde una **perspectiva de desarrollador**, aquí hay varias cosas a tener en cuenta al pensar en HTTPS:
 
@@ -28,13 +28,13 @@ Ahora, desde una **perspectiva de desarrollador**, aquí hay varias cosas a tene
 * **Por defecto**, eso significaría que solo puedes tener **un certificado HTTPS por dirección IP**.
     * No importa cuán grande sea tu servidor o qué tan pequeña pueda ser cada aplicación que tengas en él.
     * Sin embargo, hay una **solución** para esto.
-* Hay una **extensión** para el protocolo **TLS** (el que maneja la encriptación a nivel de TCP, antes de HTTP) llamada **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication – Indicación del nombre del servidor">SNI</abbr></a>**.
+* Hay una **extensión** para el protocolo **TLS** (el que maneja la encriptación a nivel de TCP, antes de HTTP) llamada **[<abbr title="Server Name Indication - Indicación del nombre del servidor">SNI</abbr>](https://en.wikipedia.org/wiki/Server_Name_Indication)**.
     * Esta extensión SNI permite que un solo servidor (con una **sola dirección IP**) tenga **varios certificados HTTPS** y sirva **múltiples dominios/aplicaciones HTTPS**.
     * Para que esto funcione, un componente (programa) **único** que se ejecute en el servidor, escuchando en la **dirección IP pública**, debe tener **todos los certificados HTTPS** en el servidor.
 * **Después** de obtener una conexión segura, el protocolo de comunicación sigue siendo **HTTP**.
     * Los contenidos están **encriptados**, aunque se envién con el **protocolo HTTP**.
 
-Es una práctica común tener **un programa/servidor HTTP** ejecutándose en el servidor (la máquina, host, etc.) y **gestionando todas las partes de HTTPS**: recibiendo los **requests HTTPS encriptados**, enviando los **requests HTTP desencriptados** a la aplicación HTTP real que se ejecuta en el mismo servidor (la aplicación **FastAPI**, en este caso), tomando el **response HTTP** de la aplicación, **encriptándolo** usando el **certificado HTTPS** adecuado y enviándolo de vuelta al cliente usando **HTTPS**. Este servidor a menudo se llama un **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>**.
+Es una práctica común tener **un programa/servidor HTTP** ejecutándose en el servidor (la máquina, host, etc.) y **gestionando todas las partes de HTTPS**: recibiendo los **requests HTTPS encriptados**, enviando los **requests HTTP desencriptados** a la aplicación HTTP real que se ejecuta en el mismo servidor (la aplicación **FastAPI**, en este caso), tomando el **response HTTP** de la aplicación, **encriptándolo** usando el **certificado HTTPS** adecuado y enviándolo de vuelta al cliente usando **HTTPS**. Este servidor a menudo se llama un **[TLS Termination Proxy](https://en.wikipedia.org/wiki/TLS_termination_proxy)**.
 
 Algunas de las opciones que podrías usar como un TLS Termination Proxy son:
 
@@ -49,7 +49,7 @@ Antes de Let's Encrypt, estos **certificados HTTPS** eran vendidos por terceros.
 
 El proceso para adquirir uno de estos certificados solía ser complicado, requerir bastante papeleo y los certificados eran bastante costosos.
 
-Pero luego se creó **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>**.
+Pero luego se creó **[Let's Encrypt](https://letsencrypt.org/)**.
 
 Es un proyecto de la Linux Foundation. Proporciona **certificados HTTPS de forma gratuita**, de manera automatizada. Estos certificados usan toda la seguridad criptográfica estándar, y tienen una corta duración (aproximadamente 3 meses), por lo que la **seguridad es en realidad mejor** debido a su lifespan reducida.
 
@@ -200,9 +200,9 @@ Este **proxy** normalmente configuraría algunos headers HTTP sobre la marcha an
 
 Los headers del proxy son:
 
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
+* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
+* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
+* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
 
 ///
 
@@ -218,7 +218,7 @@ Esto sería útil, por ejemplo, para manejar correctamente redirecciones.
 
 /// tip | Consejo
 
-Puedes aprender más sobre esto en la documentación de [Detrás de un proxy - Habilitar headers reenviados por el proxy](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
+Puedes aprender más sobre esto en la documentación de [Detrás de un proxy - Habilitar headers reenviados por el proxy](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers)
 
 ///
 
index 1260c68b98390dca28b9bc6bce7d0ebac383c84d..c4025deaa66d69eae10bc07c1cb810503d2db181 100644 (file)
@@ -16,7 +16,7 @@ Hay varias maneras de hacerlo dependiendo de tu caso de uso específico y las he
 
 Podrías **desplegar un servidor** tú mismo utilizando una combinación de herramientas, podrías usar un **servicio en la nube** que hace parte del trabajo por ti, u otras opciones posibles.
 
-Por ejemplo, nosotros, el equipo detrás de FastAPI, construimos <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, para hacer que desplegar aplicaciones de FastAPI en la nube sea lo más ágil posible, con la misma experiencia de desarrollador de trabajar con FastAPI.
+Por ejemplo, nosotros, el equipo detrás de FastAPI, construimos [**FastAPI Cloud**](https://fastapicloud.com), para hacer que desplegar aplicaciones de FastAPI en la nube sea lo más ágil posible, con la misma experiencia de desarrollador de trabajar con FastAPI.
 
 Te mostraré algunos de los conceptos principales que probablemente deberías tener en cuenta al desplegar una aplicación **FastAPI** (aunque la mayoría se aplica a cualquier otro tipo de aplicación web).
 
index 3c597ff69ee0c86c520772733ad1cfd3a6b2f824..f3c771a5152f6c91416897b6dab21409af04ad8f 100644 (file)
@@ -52,11 +52,11 @@ Lo principal que necesitas para ejecutar una aplicación **FastAPI** (o cualquie
 
 Hay varias alternativas, incluyendo:
 
-* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>: un servidor ASGI de alto rendimiento.
-* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>: un servidor ASGI compatible con HTTP/2 y Trio entre otras funcionalidades.
-* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>: el servidor ASGI construido para Django Channels.
-* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>: Un servidor HTTP Rust para aplicaciones en Python.
-* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>: NGINX Unit es un runtime para aplicaciones web ligero y versátil.
+* [Uvicorn](https://www.uvicorn.dev/): un servidor ASGI de alto rendimiento.
+* [Hypercorn](https://hypercorn.readthedocs.io/): un servidor ASGI compatible con HTTP/2 y Trio entre otras funcionalidades.
+* [Daphne](https://github.com/django/daphne): el servidor ASGI construido para Django Channels.
+* [Granian](https://github.com/emmett-framework/granian): Un servidor HTTP Rust para aplicaciones en Python.
+* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit es un runtime para aplicaciones web ligero y versátil.
 
 ## Máquina Servidor y Programa Servidor { #server-machine-and-server-program }
 
@@ -74,7 +74,7 @@ Cuando instalas FastAPI, viene con un servidor de producción, Uvicorn, y puedes
 
 Pero también puedes instalar un servidor ASGI manualmente.
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo, y luego puedes instalar la aplicación del servidor.
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), actívalo, y luego puedes instalar la aplicación del servidor.
 
 Por ejemplo, para instalar Uvicorn:
 
index 9cdd79bc0ff47f14b92591ffba48c596656b47e3..3e3a1898befb911012a54f06f74747773ec8336a 100644 (file)
@@ -13,13 +13,13 @@ Hasta este punto, con todos los tutoriales en la documentación, probablemente h
 
 Al desplegar aplicaciones probablemente querrás tener algo de **replicación de procesos** para aprovechar **múltiples núcleos** y poder manejar más requests.
 
-Como viste en el capítulo anterior sobre [Conceptos de Despliegue](concepts.md){.internal-link target=_blank}, hay múltiples estrategias que puedes usar.
+Como viste en el capítulo anterior sobre [Conceptos de Despliegue](concepts.md), hay múltiples estrategias que puedes usar.
 
 Aquí te mostraré cómo usar **Uvicorn** con **worker processes** usando el comando `fastapi` o el comando `uvicorn` directamente.
 
 /// info | Información
 
-Si estás usando contenedores, por ejemplo con Docker o Kubernetes, te contaré más sobre eso en el próximo capítulo: [FastAPI en Contenedores - Docker](docker.md){.internal-link target=_blank}.
+Si estás usando contenedores, por ejemplo con Docker o Kubernetes, te contaré más sobre eso en el próximo capítulo: [FastAPI en Contenedores - Docker](docker.md).
 
 En particular, cuando corras en **Kubernetes** probablemente **no** querrás usar workers y en cambio correr **un solo proceso de Uvicorn por contenedor**, pero te contaré sobre eso más adelante en ese capítulo.
 
@@ -126,7 +126,7 @@ De la lista de conceptos de despliegue de antes, usar workers ayudaría principa
 
 ## Contenedores y Docker { #containers-and-docker }
 
-En el próximo capítulo sobre [FastAPI en Contenedores - Docker](docker.md){.internal-link target=_blank} te explicaré algunas estrategias que podrías usar para manejar los otros **conceptos de despliegue**.
+En el próximo capítulo sobre [FastAPI en Contenedores - Docker](docker.md) te explicaré algunas estrategias que podrías usar para manejar los otros **conceptos de despliegue**.
 
 Te mostraré cómo **construir tu propia imagen desde cero** para ejecutar un solo proceso de Uvicorn. Es un proceso sencillo y probablemente es lo que querrías hacer al usar un sistema de gestión de contenedores distribuido como **Kubernetes**.
 
index 193654b2d2b1fb7e887763c162b703e717bee62c..02792f1f8b97941978a82b78d54d1775b75a1b7e 100644 (file)
@@ -4,7 +4,7 @@
 
 Se añaden nuevas funcionalidades con frecuencia, se corrigen bugs regularmente, y el código sigue mejorando continuamente.
 
-Por eso las versiones actuales siguen siendo `0.x.x`, esto refleja que cada versión podría tener potencialmente cambios incompatibles. Esto sigue las convenciones de <a href="https://semver.org/" class="external-link" target="_blank">Semantic Versioning</a>.
+Por eso las versiones actuales siguen siendo `0.x.x`, esto refleja que cada versión podría tener potencialmente cambios incompatibles. Esto sigue las convenciones de [Semantic Versioning](https://semver.org/).
 
 Puedes crear aplicaciones de producción con **FastAPI** ahora mismo (y probablemente ya lo has estado haciendo desde hace algún tiempo), solo debes asegurarte de que utilizas una versión que funciona correctamente con el resto de tu código.
 
@@ -34,7 +34,7 @@ Si utilizas cualquier otra herramienta para gestionar tus instalaciones, como `u
 
 ## Versiones disponibles { #available-versions }
 
-Puedes ver las versiones disponibles (por ejemplo, para revisar cuál es la más reciente) en las [Release Notes](../release-notes.md){.internal-link target=_blank}.
+Puedes ver las versiones disponibles (por ejemplo, para revisar cuál es la más reciente) en las [Release Notes](../release-notes.md).
 
 ## Sobre las versiones { #about-versions }
 
@@ -66,7 +66,7 @@ El "MINOR" es el número en el medio, por ejemplo, en `0.2.3`, la versión MINOR
 
 Deberías añadir tests para tu aplicación.
 
-Con **FastAPI** es muy fácil (gracias a Starlette), revisa la documentación: [Testing](../tutorial/testing.md){.internal-link target=_blank}
+Con **FastAPI** es muy fácil (gracias a Starlette), revisa la documentación: [Escribir pruebas](../tutorial/testing.md)
 
 Después de tener tests, puedes actualizar la versión de **FastAPI** a una más reciente, y asegurarte de que todo tu código está funcionando correctamente ejecutando tus tests.
 
index 1b0941a7f5d025b1a045910d6475e9b1ba9a3a00..5c58771d987935b0fc0201c03c1a24206bfc08d1 100644 (file)
@@ -65,7 +65,7 @@ print(f"Hello {name} from Python")
 
 /// tip | Consejo
 
-El segundo argumento de <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> es el valor por defecto a retornar.
+El segundo argumento de [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) es el valor por defecto a retornar.
 
 Si no se proporciona, es `None` por defecto; aquí proporcionamos `"World"` como el valor por defecto para usar.
 
@@ -153,7 +153,7 @@ Hello World from Python
 
 /// tip | Consejo
 
-Puedes leer más al respecto en <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>.
+Puedes leer más al respecto en [The Twelve-Factor App: Config](https://12factor.net/config).
 
 ///
 
@@ -163,7 +163,7 @@ Estas variables de entorno solo pueden manejar **strings de texto**, ya que son
 
 Esto significa que **cualquier valor** leído en Python desde una variable de entorno **será un `str`**, y cualquier conversión a un tipo diferente o cualquier validación tiene que hacerse en el código.
 
-Aprenderás más sobre cómo usar variables de entorno para manejar **configuraciones de aplicación** en la [Guía del Usuario Avanzado - Ajustes y Variables de Entorno](./advanced/settings.md){.internal-link target=_blank}.
+Aprenderás más sobre cómo usar variables de entorno para manejar **configuraciones de aplicación** en la [Guía del Usuario Avanzado - Ajustes y Variables de Entorno](./advanced/settings.md).
 
 ## Variable de Entorno `PATH` { #path-environment-variable }
 
@@ -285,13 +285,13 @@ $ C:\opt\custompython\bin\python
 
 ////
 
-Esta información será útil al aprender sobre [Entornos Virtuales](virtual-environments.md){.internal-link target=_blank}.
+Esta información será útil al aprender sobre [Entornos Virtuales](virtual-environments.md).
 
 ## Conclusión { #conclusion }
 
 Con esto deberías tener una comprensión básica de qué son las **variables de entorno** y cómo usarlas en Python.
 
-También puedes leer más sobre ellas en la <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia para Variable de Entorno</a>.
+También puedes leer más sobre ellas en la [Wikipedia para Variable de Entorno](https://en.wikipedia.org/wiki/Environment_variable).
 
 En muchos casos no es muy obvio cómo las variables de entorno serían útiles y aplicables de inmediato. Pero siguen apareciendo en muchos escenarios diferentes cuando estás desarrollando, así que es bueno conocerlas.
 
index 7866254223b17eddcbf5c3590c62c6a6a604df25..e8d6ad6c80b71d79bccacd8f2bd91dd3735fda72 100644 (file)
@@ -1,15 +1,15 @@
 # FastAPI CLI { #fastapi-cli }
 
-**FastAPI CLI** es un programa de línea de comandos que puedes usar para servir tu aplicación FastAPI, gestionar tu proyecto FastAPI, y más.
+**FastAPI <abbr title="command line interface - interfaz de línea de comandos">CLI</abbr>** es un programa de línea de comandos que puedes usar para servir tu aplicación FastAPI, gestionar tu proyecto FastAPI, y más.
 
-Cuando instalas FastAPI (por ejemplo, con `pip install "fastapi[standard]"`), incluye un paquete llamado `fastapi-cli`, este paquete proporciona el comando `fastapi` en la terminal.
+Cuando instalas FastAPI (por ejemplo, con `pip install "fastapi[standard]"`), viene con un programa de línea de comandos que puedes ejecutar en la terminal.
 
 Para ejecutar tu aplicación FastAPI en modo de desarrollo, puedes usar el comando `fastapi dev`:
 
 <div class="termy">
 
 ```console
-$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+$ <font color="#4E9A06">fastapi</font> dev
 
   <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server 🚀
 
@@ -46,13 +46,66 @@ $ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid
 
 </div>
 
-El programa de línea de comandos llamado `fastapi` es **FastAPI CLI**.
+/// tip | Consejo
+
+Para producción usarías `fastapi run` en lugar de `fastapi dev`. 🚀
+
+///
+
+Internamente, **FastAPI CLI** usa [Uvicorn](https://www.uvicorn.dev), un servidor ASGI de alto rendimiento y listo para producción. 😎
+
+El CLI `fastapi` intentará detectar automáticamente la app de FastAPI que debe ejecutar, asumiendo que es un objeto llamado `app` en un archivo `main.py` (o un par de variantes más).
+
+Pero puedes configurar explícitamente la app a usar.
+
+## Configura el `entrypoint` de la app en `pyproject.toml` { #configure-the-app-entrypoint-in-pyproject-toml }
+
+Puedes configurar dónde está tu app en un archivo `pyproject.toml` así:
+
+```toml
+[tool.fastapi]
+entrypoint = "main:app"
+```
+
+Ese `entrypoint` le dirá al comando `fastapi` que debe importar la app así:
+
+```python
+from main import app
+```
 
-FastAPI CLI toma el path de tu programa Python (por ejemplo, `main.py`), detecta automáticamente la `FastAPI` instance (comúnmente llamada `app`), determina el proceso de import correcto, y luego la sirve.
+Si tu código estuviera estructurado así:
+
+```
+.
+├── backend
+│   ├── main.py
+│   ├── __init__.py
+```
+
+Entonces establecerías el `entrypoint` como:
+
+```toml
+[tool.fastapi]
+entrypoint = "backend.main:app"
+```
+
+lo cual sería equivalente a:
+
+```python
+from backend.main import app
+```
+
+### `fastapi dev` con path { #fastapi-dev-with-path }
+
+También puedes pasar el path del archivo al comando `fastapi dev`, y adivinará el objeto app de FastAPI a usar:
+
+```console
+$ fastapi dev main.py
+```
 
-Para producción usarías `fastapi run` en su lugar. 🚀
+Pero tendrías que recordar pasar el path correcto cada vez que llames al comando `fastapi`.
 
-Internamente, **FastAPI CLI** usa <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>, un servidor ASGI de alto rendimiento y listo para producción. 😎
+Adicionalmente, otras herramientas podrían no ser capaces de encontrarla, por ejemplo la [Extensión de VS Code](editor-support.md) o [FastAPI Cloud](https://fastapicloud.com), así que se recomienda usar el `entrypoint` en `pyproject.toml`.
 
 ## `fastapi dev` { #fastapi-dev }
 
@@ -70,6 +123,6 @@ En la mayoría de los casos tendrías (y deberías) tener un "proxy de terminaci
 
 /// tip | Consejo
 
-Puedes aprender más al respecto en la [documentación de despliegue](deployment/index.md){.internal-link target=_blank}.
+Puedes aprender más al respecto en la [documentación de despliegue](deployment/index.md).
 
 ///
index 947ef312dba73a38a9fad18e02f12150807b0677..754099c8d6acaa3d354a81047c0718ef59e04bf3 100644 (file)
@@ -6,8 +6,8 @@
 
 ### 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 <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).
+* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) 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 [**JSON Schema**](https://json-schema.org/) (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.
 
 
 Interfaces web de documentación y exploración de APIs interactivas. Como el framework está basado en OpenAPI, hay múltiples opciones, 2 incluidas por defecto.
 
-* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, con exploración interactiva, llama y prueba tu API directamente desde el navegador.
+* [**Swagger UI**](https://github.com/swagger-api/swagger-ui), con exploración interactiva, llama y prueba tu API directamente desde el navegador.
 
 ![Interacción Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
 
-* Documentación alternativa de API con <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
+* Documentación alternativa de API con [**ReDoc**](https://github.com/Rebilly/ReDoc).
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
 
@@ -27,7 +27,7 @@ Interfaces web de documentación y exploración de APIs interactivas. Como el fr
 
 Todo está basado en declaraciones estándar de **tipos en Python** (gracias a Pydantic). Sin nueva sintaxis que aprender. Solo Python moderno estándar.
 
-Si necesitas un repaso de 2 minutos sobre cómo usar tipos en Python (aunque no uses FastAPI), revisa el tutorial corto: [Tipos en Python](python-types.md){.internal-link target=_blank}.
+Si necesitas un repaso de 2 minutos sobre cómo usar tipos en Python (aunque no uses FastAPI), revisa el tutorial corto: [Tipos en Python](python-types.md).
 
 Escribes Python estándar con tipos:
 
@@ -75,7 +75,7 @@ Pasa las claves y valores del dict `second_user_data` directamente como argument
 
 Todo el framework fue diseñado para ser fácil e intuitivo de usar, todas las decisiones fueron probadas en múltiples editores incluso antes de comenzar el desarrollo, para asegurar la mejor experiencia de desarrollo.
 
-En las encuestas a desarrolladores de Python, es claro <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">que una de las funcionalidades más usadas es el "autocompletado"</a>.
+En las encuestas a desarrolladores de Python, es claro [que una de las funcionalidades más usadas es el "autocompletado"](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features).
 
 Todo el framework **FastAPI** está basado para satisfacer eso. El autocompletado funciona en todas partes.
 
@@ -83,11 +83,11 @@ Rara vez necesitarás regresar a la documentación.
 
 Aquí está cómo tu editor podría ayudarte:
 
-* en <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
+* en [Visual Studio Code](https://code.visualstudio.com/):
 
 ![soporte del editor](https://fastapi.tiangolo.com/img/vscode-completion.png)
 
-* en <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
+* en [PyCharm](https://www.jetbrains.com/pycharm/):
 
 ![soporte del editor](https://fastapi.tiangolo.com/img/pycharm-completion.png)
 
@@ -124,7 +124,7 @@ Seguridad y autenticación integradas. Sin ningún compromiso con bases de datos
 Todos los esquemas de seguridad definidos en OpenAPI, incluyendo:
 
 * HTTP Básico.
-* **OAuth2** (también con **tokens JWT**). Revisa el tutorial sobre [OAuth2 con JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* **OAuth2** (también con **tokens JWT**). Revisa el tutorial sobre [OAuth2 con JWT](tutorial/security/oauth2-jwt.md).
 * API keys en:
     * Headers.
     * Parámetros de query.
@@ -159,13 +159,13 @@ Cualquier integración está diseñada para ser tan simple de usar (con dependen
 
 ## Funcionalidades de Starlette { #starlette-features }
 
-**FastAPI** es totalmente compatible con (y está basado en) <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Así que, cualquier código adicional de Starlette que tengas, también funcionará.
+**FastAPI** es totalmente compatible con (y está basado en) [**Starlette**](https://www.starlette.dev/). Así que, cualquier código adicional de Starlette que tengas, también funcionará.
 
 `FastAPI` es en realidad una subclase de `Starlette`. Así que, si ya conoces o usas Starlette, la mayoría de las funcionalidades funcionarán de la misma manera.
 
 Con **FastAPI** obtienes todas las funcionalidades de **Starlette** (ya que FastAPI es simplemente Starlette potenciado):
 
-* Rendimiento seriamente impresionante. Es <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">uno de los frameworks de Python más rápidos disponibles, a la par de **NodeJS** y **Go**</a>.
+* Rendimiento seriamente impresionante. Es [uno de los frameworks de Python más rápidos disponibles, a la par de **NodeJS** y **Go**](https://github.com/encode/starlette#performance).
 * Soporte para **WebSocket**.
 * Tareas en segundo plano en el mismo proceso.
 * Eventos de inicio y apagado.
@@ -177,7 +177,7 @@ Con **FastAPI** obtienes todas las funcionalidades de **Starlette** (ya que Fast
 
 ## Funcionalidades de Pydantic { #pydantic-features }
 
-**FastAPI** es totalmente compatible con (y está basado en) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Por lo tanto, cualquier código adicional de Pydantic que tengas, también funcionará.
+**FastAPI** es totalmente compatible con (y está basado en) [**Pydantic**](https://docs.pydantic.dev/). Por lo tanto, cualquier código adicional de Pydantic que tengas, también funcionará.
 
 Incluyendo paquetes externos también basados en Pydantic, como <abbr title="Object-Relational Mapper – Mapeador Objeto-Relacional">ORM</abbr>s, <abbr title="Object-Document Mapper – Mapeador Objeto-Documento">ODM</abbr>s para bases de datos.
 
index 9b727dab087625de2367ac719134dfcdb2725c17..66b00fc8b6b27d2fd0cce6430d9bff6ff202d9c2 100644 (file)
@@ -12,7 +12,7 @@ Y también hay varias formas de conseguir ayuda.
 
 ## Suscríbete al boletín { #subscribe-to-the-newsletter }
 
-Puedes suscribirte al (esporádico) boletín [**FastAPI and friends**](newsletter.md){.internal-link target=_blank} para mantenerte al día sobre:
+Puedes suscribirte al (esporádico) [boletín **FastAPI and friends**](newsletter.md) para mantenerte al día sobre:
 
 * Noticias sobre FastAPI y amigos 🚀
 * Guías 📝
@@ -22,17 +22,17 @@ Puedes suscribirte al (esporádico) boletín [**FastAPI and friends**](newslette
 
 ## Sigue a FastAPI en X (Twitter) { #follow-fastapi-on-x-twitter }
 
-<a href="https://x.com/fastapi" class="external-link" target="_blank">Sigue a @fastapi en **X (Twitter)**</a> para obtener las últimas noticias sobre **FastAPI**. 🐦
+[Sigue a @fastapi en **X (Twitter)**](https://x.com/fastapi) para obtener las últimas noticias sobre **FastAPI**. 🐦
 
 ## Dale una estrella a **FastAPI** en GitHub { #star-fastapi-in-github }
 
-Puedes "darle una estrella" a FastAPI en GitHub (haciendo clic en el botón de estrella en la parte superior derecha): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️
+Puedes "darle una estrella" a FastAPI en GitHub (haciendo clic en el botón de estrella en la parte superior derecha): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). ⭐️
 
 Al agregar una estrella, otros usuarios podrán encontrarlo más fácilmente y ver que ya ha sido útil para otros.
 
 ## Observa el repositorio de GitHub para lanzamientos { #watch-the-github-repository-for-releases }
 
-Puedes "observar" FastAPI en GitHub (haciendo clic en el botón "watch" en la parte superior derecha): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
+Puedes "observar" FastAPI en GitHub (haciendo clic en el botón "watch" en la parte superior derecha): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). 👀
 
 Allí puedes seleccionar "Releases only".
 
@@ -40,45 +40,45 @@ Al hacerlo, recibirás notificaciones (en tu email) cada vez que haya un nuevo l
 
 ## Conéctate con el autor { #connect-with-the-author }
 
-Puedes conectar <a href="https://tiangolo.com" class="external-link" target="_blank">conmigo (Sebastián Ramírez / `tiangolo`)</a>, el autor.
+Puedes conectar [conmigo (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com), el autor.
 
 Puedes:
 
-* <a href="https://github.com/tiangolo" class="external-link" target="_blank">Seguirme en **GitHub**</a>.
+* [Seguirme en **GitHub**](https://github.com/tiangolo).
     * Ver otros proyectos de Código Abierto que he creado y que podrían ayudarte.
     * Seguirme para ver cuándo creo un nuevo proyecto de Código Abierto.
-* <a href="https://x.com/tiangolo" class="external-link" target="_blank">Seguirme en **X (Twitter)**</a> o <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>.
+* [Seguirme en **X (Twitter)**](https://x.com/tiangolo) o [Mastodon](https://fosstodon.org/@tiangolo).
     * Contarme cómo usas FastAPI (me encanta oír eso).
     * Enterarte cuando hago anuncios o lanzo nuevas herramientas.
-    * También puedes <a href="https://x.com/fastapi" class="external-link" target="_blank">seguir @fastapi en X (Twitter)</a> (una cuenta aparte).
-* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Seguirme en **LinkedIn**</a>.
+    * También puedes [seguir @fastapi en X (Twitter)](https://x.com/fastapi) (una cuenta aparte).
+* [Seguirme en **LinkedIn**](https://www.linkedin.com/in/tiangolo/).
     * Enterarte cuando hago anuncios o lanzo nuevas herramientas (aunque uso X (Twitter) más a menudo 🤷‍♂).
-* Leer lo que escribo (o seguirme) en <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> o <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
+* Leer lo que escribo (o seguirme) en [**Dev.to**](https://dev.to/tiangolo) o [**Medium**](https://medium.com/@tiangolo).
     * Leer otras ideas, artículos, y leer sobre las herramientas que he creado.
     * Seguirme para leer lo que publico nuevo.
 
 ## Twittea sobre **FastAPI** { #tweet-about-fastapi }
 
-<a href="https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">Twittea sobre **FastAPI**</a> y dime a mí y a otros por qué te gusta. 🎉
+[Twittea sobre **FastAPI**](https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi) y dime a mí y a otros por qué te gusta. 🎉
 
 Me encanta escuchar cómo se está utilizando **FastAPI**, qué te ha gustado, en qué proyecto/empresa lo estás usando, etc.
 
 ## Vota por FastAPI { #vote-for-fastapi }
 
-* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Vota por **FastAPI** en Slant</a>.
-* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">Vota por **FastAPI** en AlternativeTo</a>.
-* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">Di que usas **FastAPI** en StackShare</a>.
+* [Vota por **FastAPI** en Slant](https://www.slant.co/options/34241/~fastapi-review).
+* [Vota por **FastAPI** en AlternativeTo](https://alternativeto.net/software/fastapi/about/).
+* [Di que usas **FastAPI** en StackShare](https://stackshare.io/pypi-fastapi).
 
 ## Ayuda a otros con preguntas en GitHub { #help-others-with-questions-in-github }
 
 Puedes intentar ayudar a otros con sus preguntas en:
 
-* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
-* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
+* [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered)
+* [GitHub Issues](https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+)
 
 En muchos casos, probablemente ya conozcas la respuesta a esas preguntas. 🤓
 
-Si estás ayudando mucho a la gente con sus preguntas, te convertirás en un [FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank} oficial. 🎉
+Si estás ayudando mucho a la gente con sus preguntas, te convertirás en un [FastAPI Expert](fastapi-people.md#fastapi-experts) oficial. 🎉
 
 Solo recuerda, el punto más importante es: trata de ser amable. La gente llega con sus frustraciones y, en muchos casos, no pregunta de la mejor manera, pero haz todo lo posible por ser amable. 🤗
 
@@ -104,7 +104,7 @@ En la mayoría de los casos y preguntas hay algo relacionado con el **código or
 
 En muchos casos solo copiarán un fragmento del código, pero eso no es suficiente para **reproducir el problema**.
 
-* Puedes pedirles que proporcionen un <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">ejemplo mínimo, reproducible</a>, que puedas **copiar-pegar** y ejecutar localmente para ver el mismo error o comportamiento que están viendo, o para entender mejor su caso de uso.
+* Puedes pedirles que proporcionen un [ejemplo mínimo, reproducible](https://stackoverflow.com/help/minimal-reproducible-example), que puedas **copiar-pegar** y ejecutar localmente para ver el mismo error o comportamiento que están viendo, o para entender mejor su caso de uso.
 
 * Si te sientes muy generoso, puedes intentar **crear un ejemplo** así tú mismo, solo basado en la descripción del problema. Solo ten en cuenta que esto podría llevar mucho tiempo y podría ser mejor pedirles que aclaren el problema primero.
 
@@ -125,7 +125,7 @@ Si responden, hay una alta probabilidad de que hayas resuelto su problema, felic
 
 ## Observa el repositorio de GitHub { #watch-the-github-repository }
 
-Puedes "observar" FastAPI en GitHub (haciendo clic en el botón "watch" en la parte superior derecha): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
+Puedes "observar" FastAPI en GitHub (haciendo clic en el botón "watch" en la parte superior derecha): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). 👀
 
 Si seleccionas "Watching" en lugar de "Releases only", recibirás notificaciones cuando alguien cree un nuevo issue o pregunta. También puedes especificar que solo deseas que te notifiquen sobre nuevos issues, discusiones, PRs, etc.
 
@@ -133,7 +133,7 @@ Luego puedes intentar ayudarlos a resolver esas preguntas.
 
 ## Haz preguntas { #ask-questions }
 
-Puedes <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">crear una nueva pregunta</a> en el repositorio de GitHub, por ejemplo, para:
+Puedes [crear una nueva pregunta](https://github.com/fastapi/fastapi/discussions/new?category=questions) en el repositorio de GitHub, por ejemplo, para:
 
 * Hacer una **pregunta** o preguntar sobre un **problema**.
 * Sugerir una nueva **funcionalidad**.
@@ -196,12 +196,12 @@ Así que, es realmente importante que realmente leas y ejecutes el código, y me
 
 ## Crea un Pull Request { #create-a-pull-request }
 
-Puedes [contribuir](contributing.md){.internal-link target=_blank} al código fuente con Pull Requests, por ejemplo:
+Puedes [contribuir](contributing.md) al código fuente con Pull Requests, por ejemplo:
 
 * Para corregir un error tipográfico que encontraste en la documentación.
-* Para compartir un artículo, video o podcast que creaste o encontraste sobre FastAPI <a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">editando este archivo</a>.
+* Para compartir un artículo, video o podcast que creaste o encontraste sobre FastAPI [editando este archivo](https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml).
     * Asegúrate de agregar tu enlace al inicio de la sección correspondiente.
-* Para ayudar a [traducir la documentación](contributing.md#translations){.internal-link target=_blank} a tu idioma.
+* Para ayudar a [traducir la documentación](contributing.md#translations) a tu idioma.
     * También puedes ayudar a revisar las traducciones creadas por otros.
 * Para proponer nuevas secciones de documentación.
 * Para corregir un issue/bug existente.
@@ -218,8 +218,8 @@ Hay mucho trabajo por hacer, y para la mayoría de ello, **TÚ** puedes hacerlo.
 
 Las tareas principales que puedes hacer ahora son:
 
-* [Ayudar a otros con preguntas en GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (ver la sección arriba).
-* [Revisar Pull Requests](#review-pull-requests){.internal-link target=_blank} (ver la sección arriba).
+* [Ayudar a otros con preguntas en GitHub](#help-others-with-questions-in-github) (ver la sección arriba).
+* [Revisar Pull Requests](#review-pull-requests) (ver la sección arriba).
 
 Esas dos tareas son las que **consumen más tiempo**. Ese es el trabajo principal de mantener FastAPI.
 
@@ -227,11 +227,11 @@ Si puedes ayudarme con eso, **me estás ayudando a mantener FastAPI** y aseguran
 
 ## Únete al chat { #join-the-chat }
 
-Únete al servidor de chat 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord</a> 👥 y charla con otros en la comunidad de FastAPI.
+Únete al servidor de chat 👥 [Discord](https://discord.gg/VQjSZaeJmf) 👥 y charla con otros en la comunidad de FastAPI.
 
 /// tip | Consejo
 
-Para preguntas, házlas en <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a>, hay muchas más probabilidades de que recibas ayuda de parte de los [FastAPI Experts](fastapi-people.md#fastapi-experts){.internal-link target=_blank}.
+Para preguntas, házlas en [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/new?category=questions), hay muchas más probabilidades de que recibas ayuda de parte de los [FastAPI Experts](fastapi-people.md#fastapi-experts).
 
 Usa el chat solo para otras conversaciones generales.
 
@@ -243,13 +243,13 @@ Ten en cuenta que dado que los chats permiten una "conversación más libre", es
 
 En GitHub, la plantilla te guiará para escribir la pregunta correcta para que puedas obtener más fácilmente una buena respuesta, o incluso resolver el problema por ti mismo antes de preguntar. Y en GitHub puedo asegurarme de responder siempre todo, incluso si lleva tiempo. No puedo hacer eso personalmente con los sistemas de chat. 😅
 
-Las conversaciones en los sistemas de chat tampoco son tan fácilmente buscables como en GitHub, por lo que las preguntas y respuestas podrían perderse en la conversación. Y solo las que están en GitHub cuentan para convertirse en un [FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, por lo que probablemente recibirás más atención en GitHub.
+Las conversaciones en los sistemas de chat tampoco son tan fácilmente buscables como en GitHub, por lo que las preguntas y respuestas podrían perderse en la conversación. Y solo las que están en GitHub cuentan para convertirse en un [FastAPI Expert](fastapi-people.md#fastapi-experts), por lo que probablemente recibirás más atención en GitHub.
 
 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. 😄
 
 ## 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 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. 🎁
+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 [GitHub sponsors](https://github.com/sponsors/tiangolo). Según el nivel, podrías obtener algunos beneficios extra, como una insignia en la documentación. 🎁
 
 ---
 
index 79835440bb26dd8115b1b2d405c3f905a973fbe9..fc1782f98850f9a749f46ddc33d846d34d6161c4 100644 (file)
@@ -1,6 +1,6 @@
 # Historia, Diseño y Futuro { #history-design-and-future }
 
-Hace algún tiempo, <a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">un usuario de **FastAPI** preguntó</a>:
+Hace algún tiempo, [un usuario de **FastAPI** preguntó](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920):
 
 > ¿Cuál es la historia de este proyecto? Parece haber surgido de la nada y ser increíble en pocas semanas [...]
 
@@ -14,7 +14,7 @@ Como parte de eso, necesitaba investigar, probar y usar muchas alternativas.
 
 La historia de **FastAPI** es en gran parte la historia de sus predecesores.
 
-Como se dice en la sección [Alternativas](alternatives.md){.internal-link target=_blank}:
+Como se dice en la sección [Alternativas](alternatives.md):
 
 <blockquote markdown="1">
 
@@ -44,7 +44,7 @@ Luego pasé algún tiempo diseñando la "API" de desarrollador que quería tener
 
 Probé varias ideas en los editores de Python más populares: PyCharm, VS Code, editores basados en Jedi.
 
-Según la última <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">Encuesta de Desarrolladores de Python</a>, estos editores cubren alrededor del 80% de los usuarios.
+Según la última [Encuesta de Desarrolladores de Python](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools), estos editores cubren alrededor del 80% de los usuarios.
 
 Esto significa que **FastAPI** fue específicamente probado con los editores usados por el 80% de los desarrolladores de Python. Y como la mayoría de los otros editores tienden a funcionar de manera similar, todos sus beneficios deberían funcionar prácticamente para todos los editores.
 
@@ -54,11 +54,11 @@ Todo de una manera que proporcionara la mejor experiencia de desarrollo para tod
 
 ## Requisitos { #requirements }
 
-Después de probar varias alternativas, decidí que iba a usar <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">**Pydantic**</a> por sus ventajas.
+Después de probar varias alternativas, decidí que iba a usar [**Pydantic**](https://docs.pydantic.dev/) por sus ventajas.
 
 Luego contribuí a este, para hacerlo totalmente compatible con JSON Schema, para soportar diferentes maneras de definir declaraciones de restricciones, y para mejorar el soporte de los editores (chequeo de tipos, autocompletado) basado en las pruebas en varios editores.
 
-Durante el desarrollo, también contribuí a <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>, el otro requisito clave.
+Durante el desarrollo, también contribuí a [**Starlette**](https://www.starlette.dev/), el otro requisito clave.
 
 ## Desarrollo { #development }
 
@@ -76,4 +76,4 @@ Pero aún así, hay muchas mejoras y funcionalidades por venir.
 
 **FastAPI** tiene un gran futuro por delante.
 
-Y [tu ayuda](help-fastapi.md){.internal-link target=_blank} es muy apreciada.
+Y [tu ayuda](help-fastapi.md) es muy apreciada.
index 54afcec8cbd9e9ed63db781cb86c7e0545564a76..600c30d2635f48586cee40c49219fee17082d1cb 100644 (file)
@@ -2,7 +2,7 @@
 
 Antes de FastAPI versión `0.122.0`, cuando las utilidades de seguridad integradas devolvían un error al cliente después de una autenticación fallida, usaban el código de estado HTTP `403 Forbidden`.
 
-A partir de FastAPI versión `0.122.0`, usan el código de estado HTTP `401 Unauthorized`, más apropiado, y devuelven un `WWW-Authenticate` header adecuado en la response, siguiendo las especificaciones HTTP, <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>, <a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>.
+A partir de FastAPI versión `0.122.0`, usan el código de estado HTTP `401 Unauthorized`, más apropiado, y devuelven un `WWW-Authenticate` header adecuado en la response, siguiendo las especificaciones HTTP, [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1), [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized).
 
 Pero si por alguna razón tus clientes dependen del comportamiento anterior, puedes volver a él sobrescribiendo el método `make_not_authenticated_error` en tus clases de seguridad.
 
index 671100cf8b121949036ef1f3ebf3fd521fe7f1a0..cdf569805069b5860b63edac267fb2ffb7bdff81 100644 (file)
@@ -10,7 +10,7 @@ Eso no añade ninguna seguridad extra a tu API, las *path operations* seguirán
 
 Si hay una falla de seguridad en tu código, seguirá existiendo.
 
-Ocultar la documentación solo hace que sea más difícil entender cómo interactuar con tu API y podría dificultar más depurarla en producción. Podría considerarse simplemente una forma de <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">Seguridad mediante oscuridad</a>.
+Ocultar la documentación solo hace que sea más difícil entender cómo interactuar con tu API y podría dificultar más depurarla en producción. Podría considerarse simplemente una forma de [Seguridad mediante oscuridad](https://en.wikipedia.org/wiki/Security_through_obscurity).
 
 Si quieres asegurar tu API, hay varias cosas mejores que puedes hacer, por ejemplo:
 
index 092c310011ca73c10197674d883af875914fb4d8..8230f4a146b273072485d0f30c924d211e0d4a5f 100644 (file)
@@ -1,6 +1,6 @@
 # Configurar Swagger UI { #configure-swagger-ui }
 
-Puedes configurar algunos <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">parámetros adicionales de Swagger UI</a>.
+Puedes configurar algunos [parámetros adicionales de Swagger UI](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/).
 
 Para configurarlos, pasa el argumento `swagger_ui_parameters` al crear el objeto de la app `FastAPI()` o a la función `get_swagger_ui_html()`.
 
@@ -50,7 +50,7 @@ Por ejemplo, para desactivar `deepLinking` podrías pasar estas configuraciones
 
 ## Otros parámetros de Swagger UI { #other-swagger-ui-parameters }
 
-Para ver todas las demás configuraciones posibles que puedes usar, lee la <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">documentación oficial de los parámetros de Swagger UI</a>.
+Para ver todas las demás configuraciones posibles que puedes usar, lee la [documentación oficial de los parámetros de Swagger UI](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/).
 
 ## Configuraciones solo de JavaScript { #javascript-only-settings }
 
index faddab0d839b0b88c91e24678f206b4c07643321..e9a34c5e4d13e840ca4b1469b82a0149ac56079c 100644 (file)
@@ -2,13 +2,13 @@
 
 La documentación de la API utiliza **Swagger UI** y **ReDoc**, y cada uno de estos necesita algunos archivos JavaScript y CSS.
 
-Por defecto, esos archivos se sirven desde un <abbr title="Content Delivery Network  Red de entrega de contenidos: Un servicio, normalmente compuesto de varios servidores, que proporciona archivos estáticos, como JavaScript y CSS. Se usa comúnmente para servir esos archivos desde el servidor más cercano al cliente, mejorando el rendimiento.">CDN</abbr>.
+Por defecto, esos archivos se sirven desde un <abbr title="Content Delivery Network - Red de entrega de contenidos: Un servicio, normalmente compuesto de varios servidores, que proporciona archivos estáticos, como JavaScript y CSS. Se usa comúnmente para servir esos archivos desde el servidor más cercano al cliente, mejorando el rendimiento.">CDN</abbr>.
 
 Pero es posible personalizarlo, puedes establecer un CDN específico, o servir los archivos tú mismo.
 
 ## CDN Personalizado para JavaScript y CSS { #custom-cdn-for-javascript-and-css }
 
-Digamos que quieres usar un <abbr title="Content Delivery Network  Red de entrega de contenidos">CDN</abbr> diferente, por ejemplo, quieres usar `https://unpkg.com/`.
+Digamos que quieres usar un <abbr title="Content Delivery Network - Red de entrega de contenidos">CDN</abbr> diferente, por ejemplo, quieres usar `https://unpkg.com/`.
 
 Esto podría ser útil si, por ejemplo, vives en un país que restringe algunas URLs.
 
@@ -54,7 +54,7 @@ Ahora, para poder probar que todo funciona, crea una *path operation*:
 
 ### Pruébalo { #test-it }
 
-Ahora, deberías poder ir a tu documentación en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, y recargar la página, cargará esos recursos desde el nuevo CDN.
+Ahora, deberías poder ir a tu documentación en [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs), y recargar la página, cargará esos recursos desde el nuevo CDN.
 
 ## self hosting de JavaScript y CSS para la documentación { #self-hosting-javascript-and-css-for-docs }
 
@@ -93,12 +93,12 @@ Probablemente puedas hacer clic derecho en cada enlace y seleccionar una opción
 
 **Swagger UI** utiliza los archivos:
 
-* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
-* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
+* [`swagger-ui-bundle.js`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js)
+* [`swagger-ui.css`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css)
 
 Y **ReDoc** utiliza el archivo:
 
-* <a href="https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
+* [`redoc.standalone.js`](https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js)
 
 Después de eso, tu estructura de archivos podría verse así:
 
@@ -122,7 +122,7 @@ Después de eso, tu estructura de archivos podría verse así:
 
 ### Prueba los archivos estáticos { #test-the-static-files }
 
-Inicia tu aplicación y ve a <a href="http://127.0.0.1:8000/static/redoc.standalone.js" class="external-link" target="_blank">http://127.0.0.1:8000/static/redoc.standalone.js</a>.
+Inicia tu aplicación y ve a [http://127.0.0.1:8000/static/redoc.standalone.js](http://127.0.0.1:8000/static/redoc.standalone.js).
 
 Deberías ver un archivo JavaScript muy largo de **ReDoc**.
 
@@ -180,6 +180,6 @@ Ahora, para poder probar que todo funciona, crea una *path operation*:
 
 ### Prueba la UI de Archivos Estáticos { #test-static-files-ui }
 
-Ahora, deberías poder desconectar tu WiFi, ir a tu documentación en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, y recargar la página.
+Ahora, deberías poder desconectar tu WiFi, ir a tu documentación en [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs), y recargar la página.
 
 E incluso sin Internet, podrás ver la documentación de tu API e interactuar con ella.
index ff13196f8adfcb83543320e94e774ddd74e19547..56013a5c7b156c1be4f49311372c26f20e1b8d6c 100644 (file)
@@ -18,7 +18,7 @@ Si apenas estás comenzando con **FastAPI**, quizás quieras saltar esta secció
 
 Algunos casos de uso incluyen:
 
-* Convertir cuerpos de requests no-JSON a JSON (por ejemplo, <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>).
+* Convertir cuerpos de requests no-JSON a JSON (por ejemplo, [`msgpack`](https://msgpack.org/index.html)).
 * Descomprimir cuerpos de requests comprimidos con gzip.
 * Registrar automáticamente todos los request bodies.
 
@@ -32,13 +32,13 @@ Y una subclase de `APIRoute` para usar esa clase de request personalizada.
 
 /// tip | Consejo
 
-Este es un ejemplo sencillo para demostrar cómo funciona. Si necesitas soporte para Gzip, puedes usar el [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank} proporcionado.
+Este es un ejemplo sencillo para demostrar cómo funciona. Si necesitas soporte para Gzip, puedes usar el [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware) proporcionado.
 
 ///
 
-Primero, creamos una clase `GzipRequest`, que sobrescribirá el método `Request.body()` para descomprimir el cuerpo si hay un header apropiado.
+Primero, creamos una clase `GzipRequest`, que sobrescribirá el método `Request.body()` para descomprimir el request body si hay un header apropiado.
 
-Si no hay `gzip` en el header, no intentará descomprimir el cuerpo.
+Si no hay `gzip` en el header, no intentará descomprimir el request body.
 
 De esa manera, la misma clase de ruta puede manejar requests comprimidos con gzip o no comprimidos.
 
@@ -60,13 +60,13 @@ Aquí lo usamos para crear un `GzipRequest` a partir del request original.
 
 Un `Request` tiene un atributo `request.scope`, que es simplemente un `dict` de Python que contiene los metadatos relacionados con el request.
 
-Un `Request` también tiene un `request.receive`, que es una función para "recibir" el cuerpo del request.
+Un `Request` también tiene un `request.receive`, que es una función para "recibir" el request body.
 
 El `dict` `scope` y la función `receive` son ambos parte de la especificación ASGI.
 
 Y esas dos cosas, `scope` y `receive`, son lo que se necesita para crear una nueva *Request instance*.
 
-Para aprender más sobre el `Request`, revisa <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">la documentación de Starlette sobre Requests</a>.
+Para aprender más sobre el `Request`, revisa [la documentación de Starlette sobre Requests](https://www.starlette.dev/requests/).
 
 ///
 
@@ -82,7 +82,7 @@ Pero debido a nuestros cambios en `GzipRequest.body`, el request body se descomp
 
 /// tip | Consejo
 
-Para resolver este mismo problema, probablemente sea mucho más fácil usar el `body` en un manejador personalizado para `RequestValidationError` ([Manejo de Errores](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
+Para resolver este mismo problema, probablemente sea mucho más fácil usar el `body` en un manejador personalizado para `RequestValidationError` ([Manejo de Errores](../tutorial/handling-errors.md#use-the-requestvalidationerror-body)).
 
 Pero este ejemplo sigue siendo válido y muestra cómo interactuar con los componentes internos.
 
index d08fae073abb209bef34f234d3b504babfd7ce97..d00455afd7920c156129600db67e670043debd8e 100644 (file)
@@ -37,7 +37,7 @@ El parámetro `summary` está disponible en OpenAPI 3.1.0 y versiones superiores
 
 Usando la información anterior, puedes usar la misma función de utilidad para generar el esquema de OpenAPI y sobrescribir cada parte que necesites.
 
-Por ejemplo, vamos a añadir <a href="https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo" class="external-link" target="_blank">la extensión OpenAPI de ReDoc para incluir un logo personalizado</a>.
+Por ejemplo, vamos a añadir [la extensión OpenAPI de ReDoc para incluir un logo personalizado](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo).
 
 ### **FastAPI** normal { #normal-fastapi }
 
@@ -75,6 +75,6 @@ Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
 
 ### Revisa { #check-it }
 
-Una vez que vayas a <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> verás que estás usando tu logo personalizado (en este ejemplo, el logo de **FastAPI**):
+Una vez que vayas a [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) verás que estás usando tu logo personalizado (en este ejemplo, el logo de **FastAPI**):
 
 <img src="/img/tutorial/extending-openapi/image01.png">
index 3a3dc82943758927cf35ada2bbf71eca9067b243..03fe8441e4ff3a5e1278d069dc49e29ec253cc7e 100644 (file)
@@ -4,36 +4,40 @@ Aquí tienes varias indicaciones hacia otros lugares en la documentación, para
 
 ## Filtrar Datos - Seguridad { #filter-data-security }
 
-Para asegurarte de que no devuelves más datos de los que deberías, lee la documentación para [Tutorial - Modelo de Response - Tipo de Retorno](../tutorial/response-model.md){.internal-link target=_blank}.
+Para asegurarte de que no devuelves más datos de los que deberías, lee la documentación para [Tutorial - Modelo de Response - Tipo de Retorno](../tutorial/response-model.md).
+
+## Optimizar el Rendimiento del Response - Modelo de Response - Tipo de Retorno { #optimize-response-performance-response-model-return-type }
+
+Para optimizar el rendimiento al devolver datos JSON, usa un tipo de retorno o un modelo de Response; de esa manera Pydantic se encargará de la serialización a JSON del lado de Rust, sin pasar por Python. Lee más en la documentación para [Tutorial - Modelo de Response - Tipo de Retorno](../tutorial/response-model.md).
 
 ## Etiquetas de Documentación - OpenAPI { #documentation-tags-openapi }
 
-Para agregar etiquetas a tus *path operations*, y agruparlas en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Etiquetas](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}.
+Para agregar etiquetas a tus *path operations*, y agruparlas en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Etiquetas](../tutorial/path-operation-configuration.md#tags).
 
 ## Resumen y Descripción de Documentación - OpenAPI { #documentation-summary-and-description-openapi }
 
-Para agregar un resumen y descripción a tus *path operations*, y mostrarlos en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Resumen y Descripción](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}.
+Para agregar un resumen y descripción a tus *path operations*, y mostrarlos en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Resumen y Descripción](../tutorial/path-operation-configuration.md#summary-and-description).
 
 ## Documentación de Descripción de Response - OpenAPI { #documentation-response-description-openapi }
 
-Para definir la descripción del response, mostrada en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Descripción del Response](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}.
+Para definir la descripción del response, mostrada en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Descripción del Response](../tutorial/path-operation-configuration.md#response-description).
 
 ## Documentar la Deprecación de una *Path Operation* - OpenAPI { #documentation-deprecate-a-path-operation-openapi }
 
-Para deprecar una *path operation*, y mostrarla en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Deprecación](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}.
+Para deprecar una *path operation*, y mostrarla en la interfaz de usuario de la documentación, lee la documentación para [Tutorial - Configuraciones de Path Operation - Deprecación](../tutorial/path-operation-configuration.md#deprecate-a-path-operation).
 
 ## Convertir cualquier Dato a Compatible con JSON { #convert-any-data-to-json-compatible }
 
-Para convertir cualquier dato a compatible con JSON, lee la documentación para [Tutorial - Codificador Compatible con JSON](../tutorial/encoder.md){.internal-link target=_blank}.
+Para convertir cualquier dato a compatible con JSON, lee la documentación para [Tutorial - Codificador Compatible con JSON](../tutorial/encoder.md).
 
 ## Metadatos OpenAPI - Documentación { #openapi-metadata-docs }
 
-Para agregar metadatos a tu esquema de OpenAPI, incluyendo una licencia, versión, contacto, etc, lee la documentación para [Tutorial - Metadatos y URLs de Documentación](../tutorial/metadata.md){.internal-link target=_blank}.
+Para agregar metadatos a tu esquema de OpenAPI, incluyendo una licencia, versión, contacto, etc, lee la documentación para [Tutorial - Metadatos y URLs de Documentación](../tutorial/metadata.md).
 
 ## URL Personalizada de OpenAPI { #openapi-custom-url }
 
-Para personalizar la URL de OpenAPI (o eliminarla), lee la documentación para [Tutorial - Metadatos y URLs de Documentación](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}.
+Para personalizar la URL de OpenAPI (o eliminarla), lee la documentación para [Tutorial - Metadatos y URLs de Documentación](../tutorial/metadata.md#openapi-url).
 
 ## URLs de Documentación de OpenAPI { #openapi-docs-urls }
 
-Para actualizar las URLs usadas para las interfaces de usuario de documentación generadas automáticamente, lee la documentación para [Tutorial - Metadatos y URLs de Documentación](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
+Para actualizar las URLs usadas para las interfaces de usuario de documentación generadas automáticamente, lee la documentación para [Tutorial - Metadatos y URLs de Documentación](../tutorial/metadata.md#docs-urls).
index ee77570b3f56cec00ded8c4b1a205290592d1a1e..11c0cc23c5a26a260838fd7d787a8b336b84f027 100644 (file)
@@ -18,18 +18,18 @@ Asegúrate de evaluar si los **beneficios** para tu caso de uso compensan los **
 
 Aquí algunos de los paquetes de **GraphQL** que tienen soporte **ASGI**. Podrías usarlos con **FastAPI**:
 
-* <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a> 🍓
-    * Con <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">documentación para FastAPI</a>
-* <a href="https://ariadnegraphql.org/" class="external-link" target="_blank">Ariadne</a>
-    * Con <a href="https://ariadnegraphql.org/docs/fastapi-integration" class="external-link" target="_blank">documentación para FastAPI</a>
-* <a href="https://tartiflette.io/" class="external-link" target="_blank">Tartiflette</a>
-    * Con <a href="https://tartiflette.github.io/tartiflette-asgi/" class="external-link" target="_blank">Tartiflette ASGI</a> para proporcionar integración con ASGI
-* <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>
-    * Con <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>
+* [Strawberry](https://strawberry.rocks/) 🍓
+    * Con [documentación para FastAPI](https://strawberry.rocks/docs/integrations/fastapi)
+* [Ariadne](https://ariadnegraphql.org/)
+    * Con [documentación para FastAPI](https://ariadnegraphql.org/docs/fastapi-integration)
+* [Tartiflette](https://tartiflette.io/)
+    * Con [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) para proporcionar integración con ASGI
+* [Graphene](https://graphene-python.org/)
+    * Con [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3)
 
 ## GraphQL con Strawberry { #graphql-with-strawberry }
 
-Si necesitas o quieres trabajar con **GraphQL**, <a href="https://strawberry.rocks/" class="external-link" target="_blank">**Strawberry**</a> es el paquete **recomendado** ya que tiene un diseño muy similar al diseño de **FastAPI**, todo basado en **anotaciones de tipos**.
+Si necesitas o quieres trabajar con **GraphQL**, [**Strawberry**](https://strawberry.rocks/) es el paquete **recomendado** ya que tiene un diseño muy similar al diseño de **FastAPI**, todo basado en **anotaciones de tipos**.
 
 Dependiendo de tu caso de uso, podrías preferir usar un paquete diferente, pero si me preguntas, probablemente te sugeriría probar **Strawberry**.
 
@@ -37,24 +37,24 @@ Aquí tienes una pequeña vista previa de cómo podrías integrar Strawberry con
 
 {* ../../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>.
+Puedes aprender más sobre Strawberry en la [documentación de Strawberry](https://strawberry.rocks/).
 
-Y también la documentación sobre <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">Strawberry con FastAPI</a>.
+Y también la documentación sobre [Strawberry con FastAPI](https://strawberry.rocks/docs/integrations/fastapi).
 
 ## `GraphQLApp` viejo de Starlette { #older-graphqlapp-from-starlette }
 
-Las versiones anteriores de Starlette incluían una clase `GraphQLApp` para integrar con <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>.
+Las versiones anteriores de Starlette incluían una clase `GraphQLApp` para integrar con [Graphene](https://graphene-python.org/).
 
-Fue deprecada de Starlette, pero si tienes código que lo usaba, puedes fácilmente **migrar** a <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>, que cubre el mismo caso de uso y tiene una **interfaz casi idéntica**.
+Fue deprecada de Starlette, pero si tienes código que lo usaba, puedes fácilmente **migrar** a [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3), que cubre el mismo caso de uso y tiene una **interfaz casi idéntica**.
 
 /// tip | Consejo
 
-Si necesitas GraphQL, aún te recomendaría revisar <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a>, ya que se basa en anotaciones de tipos en lugar de clases y tipos personalizados.
+Si necesitas GraphQL, aún te recomendaría revisar [Strawberry](https://strawberry.rocks/), ya que se basa en anotaciones de tipos en lugar de clases y tipos personalizados.
 
 ///
 
 ## Aprende Más { #learn-more }
 
-Puedes aprender más sobre **GraphQL** en la <a href="https://graphql.org/" class="external-link" target="_blank">documentación oficial de GraphQL</a>.
+Puedes aprender más sobre **GraphQL** en la [documentación oficial de GraphQL](https://graphql.org/).
 
 También puedes leer más sobre cada uno de esos paquetes descritos arriba en sus enlaces.
index 6f5988049aafee1d89837ee391afe6c61c559d2d..464028ff24b1654779d87044854c5138120f7956 100644 (file)
@@ -8,6 +8,6 @@ Si algo parece interesante y útil para tu proyecto, adelante y revísalo, pero
 
 /// tip | Consejo
 
-Si quieres **aprender FastAPI** de una manera estructurada (recomendado), ve y lee el [Tutorial - Guía de Usuario](../tutorial/index.md){.internal-link target=_blank} capítulo por capítulo en su lugar.
+Si quieres **aprender FastAPI** de una manera estructurada (recomendado), ve y lee el [Tutorial - Guía de Usuario](../tutorial/index.md) capítulo por capítulo en su lugar.
 
 ///
index c862ace902a230cbe968b55259b0aca3841358d6..22d51674d06c420145954e7f3296c10f0642a5a8 100644 (file)
@@ -22,7 +22,7 @@ Si tienes una app de FastAPI antigua con Pydantic v1, aquí te muestro cómo mig
 
 ## Guía oficial { #official-guide }
 
-Pydantic tiene una <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">Guía de migración</a> oficial de v1 a v2.
+Pydantic tiene una [Guía de migración](https://docs.pydantic.dev/latest/migration/) oficial de v1 a v2.
 
 También incluye qué cambió, cómo las validaciones ahora son más correctas y estrictas, posibles consideraciones, etc.
 
@@ -30,7 +30,7 @@ Puedes leerla para entender mejor qué cambió.
 
 ## Tests { #tests }
 
-Asegúrate de tener [tests](../tutorial/testing.md){.internal-link target=_blank} para tu app y de ejecutarlos en integración continua (CI).
+Asegúrate de tener [tests](../tutorial/testing.md) para tu app y de ejecutarlos en integración continua (CI).
 
 Así podrás hacer la actualización y asegurarte de que todo sigue funcionando como esperas.
 
@@ -38,7 +38,7 @@ Así podrás hacer la actualización y asegurarte de que todo sigue funcionando
 
 En muchos casos, cuando usas modelos de Pydantic normales sin personalizaciones, podrás automatizar gran parte del proceso de migración de Pydantic v1 a Pydantic v2.
 
-Puedes usar <a href="https://github.com/pydantic/bump-pydantic" class="external-link" target="_blank">`bump-pydantic`</a> del mismo equipo de Pydantic.
+Puedes usar [`bump-pydantic`](https://github.com/pydantic/bump-pydantic) del mismo equipo de Pydantic.
 
 Esta herramienta te ayudará a cambiar automáticamente la mayor parte del código que necesita cambiarse.
 
index 0717ea5ff78add78602b43cc2d846aaf9e219cae..8dab2ffd9330d4a1d19b9ab1b3a843cd092f50cb 100644 (file)
@@ -1,7 +1,7 @@
-# Escribiendo pruebas para una base de datos { #testing-a-database }
+# Escribir 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>. 🤓
+Puedes estudiar sobre bases de datos, SQL y SQLModel en la [documentación de SQLModel](https://sqlmodel.tiangolo.com/). 🤓
 
-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>. ✨
+Hay un mini [tutorial sobre el uso de SQLModel con FastAPI](https://sqlmodel.tiangolo.com/tutorial/fastapi/). ✨
 
-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>. 😎
+Ese tutorial incluye una sección sobre [escribir pruebas para bases de datos SQL](https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/). 😎
index 0544eb9ba4f90f7e4b941da8a1686dbefd1ee971..6aea221427663c736d8278906aa0126e65185254 100644 (file)
     <em>FastAPI framework, alto rendimiento, fácil de aprender, rápido de programar, listo para producción</em>
 </p>
 <p align="center">
-<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
+<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster">
     <img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
 </a>
-<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
+<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi">
     <img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
 </a>
-<a href="https://pypi.org/project/fastapi" target="_blank">
+<a href="https://pypi.org/project/fastapi">
     <img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
 </a>
-<a href="https://pypi.org/project/fastapi" target="_blank">
+<a href="https://pypi.org/project/fastapi">
     <img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
 </a>
 </p>
 
 ---
 
-**Documentación**: <a href="https://fastapi.tiangolo.com/es" target="_blank">https://fastapi.tiangolo.com</a>
+**Documentación**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com/es)
 
-**Código Fuente**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
+**Código Fuente**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)
 
 ---
 
@@ -40,11 +40,11 @@ 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. <dfn title="también conocido como: autocompletado, IntelliSense">Autocompletado</dfn> en todas partes. Menos tiempo depurando.
+* **Intuitivo**: Gran soporte para editores. <dfn title="también conocido como: auto-complete, 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.
-* **Basado en estándares**: Basado (y completamente compatible) con los estándares abiertos para APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (anteriormente conocido como Swagger) y <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
+* **Basado en estándares**: Basado (y completamente compatible) con los estándares abiertos para APIs: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (anteriormente conocido como Swagger) y [JSON Schema](https://json-schema.org/).
 
 <small>* estimación basada en pruebas con un equipo de desarrollo interno, construyendo aplicaciones de producción.</small>
 
@@ -55,51 +55,51 @@ Las funcionalidades clave son:
 ### Sponsor Keystone { #keystone-sponsor }
 
 {% for sponsor in sponsors.keystone -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor -%}
 
 ### Sponsors Oro y Plata { #gold-and-silver-sponsors }
 
 {% for sponsor in sponsors.gold -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor -%}
 {%- for sponsor in sponsors.silver -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor %}
 
 <!-- /sponsors -->
 
-<a href="https://fastapi.tiangolo.com/es/fastapi-people/#sponsors" class="external-link" target="_blank">Otros sponsors</a>
+[Otros sponsors](https://fastapi.tiangolo.com/es/fastapi-people/#sponsors)
 
 ## Opiniones { #opinions }
 
 "_[...] Estoy usando **FastAPI** un montón estos días. [...] De hecho, estoy planeando usarlo para todos los servicios de **ML de mi equipo en Microsoft**. Algunos de ellos se están integrando en el núcleo del producto **Windows** y algunos productos de **Office**._"
 
-<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div>
 
 ---
 
 "_Adoptamos el paquete **FastAPI** para crear un servidor **REST** que pueda ser consultado para obtener **predicciones**. [para Ludwig]_"
 
-<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, y Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, y Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div>
 
 ---
 
 "_**Netflix** se complace en anunciar el lanzamiento de código abierto de nuestro framework de orquestación de **gestión de crisis**: **Dispatch**! [construido con **FastAPI**]_"
 
-<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(ref)</small></a></div>
 
 ---
 
 "_Estoy súper emocionado con **FastAPI**. ¡Es tan divertido!_"
 
-<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> host del podcast</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>[Python Bytes](https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855) host del podcast</strong> <a href="https://x.com/brianokken/status/1112220079972728832"><small>(ref)</small></a></div>
 
 ---
 
 "_Honestamente, lo que has construido parece súper sólido y pulido. En muchos aspectos, es lo que quería que **Hug** fuera; es realmente inspirador ver a alguien construir eso._"
 
-<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creador</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>[Hug](https://github.com/hugapi/hug) creador</strong> <a href="https://news.ycombinator.com/item?id=19455465"><small>(ref)</small></a></div>
 
 ---
 
@@ -107,27 +107,27 @@ Las funcionalidades clave son:
 
 "_Nos hemos cambiado a **FastAPI** para nuestras **APIs** [...] Creo que te gustará [...]_"
 
-<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">fundadores de Explosion AI</a> - <a href="https://spacy.io" target="_blank">creadores de spaCy</a></strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>[fundadores de Explosion AI](https://explosion.ai) - [creadores de spaCy](https://spacy.io)</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680"><small>(ref)</small></a></div>
 
 ---
 
 "_Si alguien está buscando construir una API de Python para producción, altamente recomendaría **FastAPI**. Está **hermosamente diseñado**, es **simple de usar** y **altamente escalable**, se ha convertido en un **componente clave** en nuestra estrategia de desarrollo API primero y está impulsando muchas automatizaciones y servicios como nuestro Ingeniero Virtual TAC._"
 
-<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
 
 ---
 
 ## Mini documental de FastAPI { #fastapi-mini-documentary }
 
-Hay un <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">mini documental de FastAPI</a> lanzado a finales de 2025, puedes verlo online:
+Hay un [mini documental de FastAPI](https://www.youtube.com/watch?v=mpR8ngthqiE) lanzado a finales de 2025, puedes verlo online:
 
-<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
+<a href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
 
 ## **Typer**, el FastAPI de las CLIs { #typer-the-fastapi-of-clis }
 
-<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
+<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
 
-Si estás construyendo una aplicación de <abbr title="Command Line Interface – Interfaz de Línea de Comandos">CLI</abbr> para ser usada en la terminal en lugar de una API web, revisa <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
+Si estás construyendo una aplicación de <abbr title="Command Line Interface - Interfaz de Línea de Comandos">CLI</abbr> para ser usada en la terminal en lugar de una API web, revisa [**Typer**](https://typer.tiangolo.com/).
 
 **Typer** es el hermano pequeño de FastAPI. Y está destinado a ser el **FastAPI de las CLIs**. ⌨️ 🚀
 
@@ -135,12 +135,12 @@ Si estás construyendo una aplicación de <abbr title="Command Line Interface 
 
 FastAPI se apoya en hombros de gigantes:
 
-* <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> para las partes web.
-* <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> para las partes de datos.
+* [Starlette](https://www.starlette.dev/) para las partes web.
+* [Pydantic](https://docs.pydantic.dev/) para las partes de datos.
 
 ## Instalación { #installation }
 
-Crea y activa un <a href="https://fastapi.tiangolo.com/es/virtual-environments/" class="external-link" target="_blank">entorno virtual</a> y luego instala FastAPI:
+Crea y activa un [entorno virtual](https://fastapi.tiangolo.com/es/virtual-environments/) y luego instala FastAPI:
 
 <div class="termy">
 
@@ -199,7 +199,7 @@ async def read_item(item_id: int, q: str | None = None):
 
 **Nota**:
 
-Si no lo sabes, revisa la sección _"¿Con prisa?"_ sobre <a href="https://fastapi.tiangolo.com/es/async/#in-a-hurry" target="_blank">`async` y `await` en la documentación</a>.
+Si no lo sabes, revisa la sección _"¿Con prisa?"_ sobre [`async` y `await` en la documentación](https://fastapi.tiangolo.com/es/async/#in-a-hurry).
 
 </details>
 
@@ -210,7 +210,7 @@ Corre el servidor con:
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
  ╭────────── FastAPI CLI - Development mode ───────────╮
  │                                                     │
@@ -235,19 +235,19 @@ INFO:     Application startup complete.
 </div>
 
 <details markdown="1">
-<summary>Acerca del comando <code>fastapi dev main.py</code>...</summary>
+<summary>Acerca del comando <code>fastapi dev</code>...</summary>
 
-El comando `fastapi dev` lee tu archivo `main.py`, detecta la app **FastAPI** en él y arranca un servidor usando <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
+El comando `fastapi dev` lee tu archivo `main.py` automáticamente, detecta la app **FastAPI** en él y arranca un servidor usando [Uvicorn](https://www.uvicorn.dev).
 
 Por defecto, `fastapi dev` comenzará con auto-recarga habilitada para el desarrollo local.
 
-Puedes leer más sobre esto en la <a href="https://fastapi.tiangolo.com/es/fastapi-cli/" target="_blank">documentación del CLI de FastAPI</a>.
+Puedes leer más sobre esto en la [documentación del CLI de FastAPI](https://fastapi.tiangolo.com/es/fastapi-cli/).
 
 </details>
 
 ### Revísalo { #check-it }
 
-Abre tu navegador en <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
+Abre tu navegador en [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery).
 
 Verás el response JSON como:
 
@@ -264,17 +264,17 @@ Ya creaste una API que:
 
 ### Documentación interactiva de la API { #interactive-api-docs }
 
-Ahora ve a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ahora ve a [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
-Verás la documentación interactiva automática de la API (proporcionada por <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
+Verás la documentación interactiva automática de la API (proporcionada por [Swagger UI](https://github.com/swagger-api/swagger-ui)):
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
 ### Documentación alternativa de la API { #alternative-api-docs }
 
-Y ahora, ve a <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Y ahora, ve a [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
 
-Verás la documentación alternativa automática (proporcionada por <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
+Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Rebilly/ReDoc)):
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
@@ -316,7 +316,7 @@ El servidor `fastapi dev` debería recargarse automáticamente.
 
 ### Actualización de la documentación interactiva de la API { #interactive-api-docs-upgrade }
 
-Ahora ve a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ahora ve a [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 * La documentación interactiva de la API se actualizará automáticamente, incluyendo el nuevo body:
 
@@ -332,7 +332,7 @@ Ahora ve a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_b
 
 ### Actualización de la documentación alternativa de la API { #alternative-api-docs-upgrade }
 
-Y ahora, ve a <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Y ahora, ve a [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
 
 * La documentación alternativa también reflejará el nuevo parámetro de query y body:
 
@@ -374,7 +374,7 @@ item: Item
     * Parámetros de query.
     * Cookies.
     * Headers.
-    * Forms.
+    * Formularios.
     * Archivos.
 * <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).
@@ -442,7 +442,7 @@ Para un ejemplo más completo incluyendo más funcionalidades, ve al <a href="ht
 * 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.
+* Integración con **GraphQL** usando [Strawberry](https://strawberry.rocks) y otros paquetes.
 * Muchas funcionalidades extra (gracias a Starlette) como:
     * **WebSockets**
     * pruebas extremadamente fáciles basadas en HTTPX y `pytest`
@@ -452,24 +452,10 @@ Para un ejemplo más completo incluyendo más funcionalidades, ve al <a href="ht
 
 ### Despliega tu app (opcional) { #deploy-your-app-optional }
 
-Opcionalmente puedes desplegar tu app de FastAPI en <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, ve y únete a la lista de espera si no lo has hecho. 🚀
+Opcionalmente puedes desplegar tu app de FastAPI en [FastAPI Cloud](https://fastapicloud.com), ve y únete a la lista de espera si no lo has hecho. 🚀
 
 Si ya tienes una cuenta de **FastAPI Cloud** (te invitamos desde la lista de espera 😉), puedes desplegar tu aplicación con un solo comando.
 
-Antes de desplegar, asegúrate de haber iniciado sesión:
-
-<div class="termy">
-
-```console
-$ fastapi login
-
-You are logged in to FastAPI Cloud 🚀
-```
-
-</div>
-
-Luego despliega tu app:
-
 <div class="termy">
 
 ```console
@@ -488,7 +474,7 @@ Deploying to FastAPI Cloud...
 
 #### Acerca de FastAPI Cloud { #about-fastapi-cloud }
 
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** está construido por el mismo autor y equipo detrás de **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** está construido por el mismo autor y equipo detrás de **FastAPI**.
 
 Optimiza el proceso de **construir**, **desplegar** y **acceder** a una API con un esfuerzo mínimo.
 
@@ -504,9 +490,9 @@ Sigue las guías de tu proveedor de cloud para desplegar apps de FastAPI con ell
 
 ## Rendimiento { #performance }
 
-Benchmarks independientes de TechEmpower muestran aplicaciones **FastAPI** ejecutándose bajo Uvicorn como <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">uno de los frameworks Python más rápidos disponibles</a>, solo por debajo de Starlette y Uvicorn (usados internamente por FastAPI). (*)
+Benchmarks independientes de TechEmpower muestran aplicaciones **FastAPI** ejecutándose bajo Uvicorn como [uno de los frameworks Python más rápidos disponibles](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), solo por debajo de Starlette y Uvicorn (usados internamente por FastAPI). (*)
 
-Para entender más sobre esto, ve la sección <a href="https://fastapi.tiangolo.com/es/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
+Para entender más sobre esto, ve la sección [Benchmarks](https://fastapi.tiangolo.com/es/benchmarks/).
 
 ## Dependencias { #dependencies }
 
@@ -518,19 +504,19 @@ Cuando instalas FastAPI con `pip install "fastapi[standard]"` viene con el grupo
 
 Usadas por Pydantic:
 
-* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - para validación de correos electrónicos.
+* [`email-validator`](https://github.com/JoshData/python-email-validator) - para validación de correos electrónicos.
 
 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 form <dfn title="convertir el string que viene de un request HTTP en datos de Python">"parsing"</dfn>, con `request.form()`.
+* [`httpx`](https://www.python-httpx.org) - Requerido si deseas usar el `TestClient`.
+* [`jinja2`](https://jinja.palletsprojects.com) - Requerido si deseas usar la configuración de plantilla por defecto.
+* [`python-multipart`](https://github.com/Kludex/python-multipart) - 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:
 
-* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - para el servidor que carga y sirve tu aplicación. Esto incluye `uvicorn[standard]`, que incluye algunas dependencias (por ejemplo, `uvloop`) necesarias para servir con alto rendimiento.
+* [`uvicorn`](https://www.uvicorn.dev) - para el servidor que carga y sirve tu aplicación. Esto incluye `uvicorn[standard]`, que incluye algunas dependencias (por ejemplo, `uvloop`) necesarias para servir con alto rendimiento.
 * `fastapi-cli[standard]` - para proporcionar el comando `fastapi`.
-    * Esto incluye `fastapi-cloud-cli`, que te permite desplegar tu aplicación de FastAPI en <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
+    * Esto incluye `fastapi-cloud-cli`, que te permite desplegar tu aplicación de FastAPI en [FastAPI Cloud](https://fastapicloud.com).
 
 ### Sin Dependencias `standard` { #without-standard-dependencies }
 
@@ -546,13 +532,13 @@ Existen algunas dependencias adicionales que podrías querer instalar.
 
 Dependencias opcionales adicionales de Pydantic:
 
-* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - para la gestión de configuraciones.
-* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - para tipos extra para ser usados con Pydantic.
+* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) - para la gestión de configuraciones.
+* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) - para tipos extra para ser usados con Pydantic.
 
 Dependencias opcionales adicionales de FastAPI:
 
-* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Requerido si deseas usar `ORJSONResponse`.
-* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Requerido si deseas usar `UJSONResponse`.
+* [`orjson`](https://github.com/ijl/orjson) - Requerido si deseas usar `ORJSONResponse`.
+* [`ujson`](https://github.com/esnme/ultrajson) - Requerido si deseas usar `UJSONResponse`.
 
 ## Licencia { #license }
 
index 6d48d0be54f72bda3af94163b0d81cb57db1e06d..11a560eba6936427b26a5f69ca7f50a7f5584518 100644 (file)
@@ -4,7 +4,7 @@ Las plantillas, aunque normalmente vienen con una configuración específica, es
 
 Puedes usar esta plantilla para comenzar, ya que incluye gran parte de la configuración inicial, seguridad, base de datos y algunos endpoints de API ya hechos para ti.
 
-Repositorio de GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Plantilla Full Stack FastAPI</a>
+Repositorio de GitHub: [Plantilla Full Stack FastAPI](https://github.com/tiangolo/full-stack-fastapi-template)
 
 ## Plantilla Full Stack FastAPI - Stack de tecnología y funcionalidades { #full-stack-fastapi-template-technology-stack-and-features }
 
index 28e2953d3591b6933ca53c7c3618df3a80025afa..5d60ea22c49e2d798bee4d9f853ca23495728f4b 100644 (file)
@@ -80,7 +80,7 @@ Esas son las "anotaciones de tipos":
 
 {* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
 
-Eso no es lo mismo que declarar valores predeterminados como sería con:
+Eso no es lo mismo que declarar valores por defecto como sería con:
 
 ```Python
     first_name="john", last_name="doe"
@@ -269,7 +269,7 @@ No significa "`one_person` es la **clase** llamada `Person`".
 
 ## Modelos Pydantic { #pydantic-models }
 
-<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> es un paquete de Python para realizar la validación de datos.
+[Pydantic](https://docs.pydantic.dev/) es un paquete de Python para realizar la validación de datos.
 
 Declaras la "forma" de los datos como clases con atributos.
 
@@ -285,13 +285,13 @@ Un ejemplo de la documentación oficial de Pydantic:
 
 /// info | Información
 
-Para saber más sobre <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic, revisa su documentación</a>.
+Para saber más sobre [Pydantic, revisa su documentación](https://docs.pydantic.dev/).
 
 ///
 
 **FastAPI** está completamente basado en Pydantic.
 
-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}.
+Verás mucho más de todo esto en práctica en el [Tutorial - Guía del Usuario](tutorial/index.md).
 
 ## Anotaciones de tipos con metadata { #type-hints-with-metadata-annotations }
 
@@ -337,12 +337,12 @@ Con **FastAPI** declaras parámetros con anotaciones de tipos y obtienes:
 * **Documentar** la API usando OpenAPI:
     * Que luego es usada por las interfaces de documentación interactiva automática.
 
-Todo esto puede sonar abstracto. No te preocupes. Verás todo esto en acción en el [Tutorial - Guía del Usuario](tutorial/index.md){.internal-link target=_blank}.
+Todo esto puede sonar abstracto. No te preocupes. Verás todo esto en acción en el [Tutorial - Guía del Usuario](tutorial/index.md).
 
 Lo importante es que al usar tipos estándar de Python, en un solo lugar (en lugar de agregar más clases, decoradores, etc.), **FastAPI** hará gran parte del trabajo por ti.
 
 /// info | Información
 
-Si ya revisaste todo el tutorial y volviste para ver más sobre tipos, un buen recurso es <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">la "cheat sheet" de `mypy`</a>.
+Si ya revisaste todo el tutorial y volviste para ver más sobre tipos, un buen recurso es [la "cheat sheet" de `mypy`](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html).
 
 ///
index 10ad4b5ebba5a026b423f91b5e64d670669350e8..6ae265b919a6e6ee2ba393d09f4a19d216aeffeb 100644 (file)
@@ -61,7 +61,7 @@ Y luego otra tarea en segundo plano generada en la *path operation function* esc
 
 ## Detalles Técnicos { #technical-details }
 
-La clase `BackgroundTasks` proviene directamente de <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>.
+La clase `BackgroundTasks` proviene directamente de [`starlette.background`](https://www.starlette.dev/background/).
 
 Se importa/incluye directamente en FastAPI para que puedas importarla desde `fastapi` y evitar importar accidentalmente la alternativa `BackgroundTask` (sin la `s` al final) de `starlette.background`.
 
@@ -69,11 +69,11 @@ Al usar solo `BackgroundTasks` (y no `BackgroundTask`), es posible usarla como u
 
 Todavía es posible usar `BackgroundTask` solo en FastAPI, pero debes crear el objeto en tu código y devolver una `Response` de Starlette incluyéndolo.
 
-Puedes ver más detalles en <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">la documentación oficial de Starlette sobre Background Tasks</a>.
+Puedes ver más detalles en [la documentación oficial de Starlette sobre Background Tasks](https://www.starlette.dev/background/).
 
 ## Advertencia { #caveat }
 
-Si necesitas realizar una computación intensa en segundo plano y no necesariamente necesitas que se ejecute por el mismo proceso (por ejemplo, no necesitas compartir memoria, variables, etc.), podrías beneficiarte del uso de otras herramientas más grandes como <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
+Si necesitas realizar una computación intensa en segundo plano y no necesariamente necesitas que se ejecute por el mismo proceso (por ejemplo, no necesitas compartir memoria, variables, etc.), podrías beneficiarte del uso de otras herramientas más grandes como [Celery](https://docs.celeryq.dev).
 
 Tienden a requerir configuraciones más complejas, un gestor de cola de mensajes/trabajos, como RabbitMQ o Redis, pero te permiten ejecutar tareas en segundo plano en múltiples procesos, y especialmente, en múltiples servidores.
 
index 96b58a7207a13ae710f931758f7f9dba875021f5..27a034f47d0014f9ea8797933ec57ea4d5b6137f 100644 (file)
@@ -123,7 +123,7 @@ Ahora utilizaremos una dependencia simple para leer un header `X-Token` personal
 
 Estamos usando un header inventado para simplificar este ejemplo.
 
-Pero en casos reales obtendrás mejores resultados usando las [utilidades de Seguridad](security/index.md){.internal-link target=_blank} integradas.
+Pero en casos reales obtendrás mejores resultados usando las [utilidades de Seguridad](security/index.md) integradas.
 
 ///
 
@@ -169,7 +169,7 @@ Y podemos agregar una lista de `dependencies` que se añadirá a todas las *path
 
 /// tip | Consejo
 
-Nota que, al igual que [dependencias en decoradores de *path operations*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, ningún valor será pasado a tu *path operation function*.
+Nota que, al igual que [dependencias en decoradores de *path operations*](dependencies/dependencies-in-path-operation-decorators.md), ningún valor será pasado a tu *path operation function*.
 
 ///
 
@@ -185,8 +185,8 @@ El resultado final es que los paths de item son ahora:
 * Todos incluirán las `responses` predefinidas.
 * Todas estas *path operations* tendrán la lista de `dependencies` evaluadas/ejecutadas antes de ellas.
   * Si también declaras dependencias en una *path operation* específica, **también se ejecutarán**.
-  * Las dependencias del router se ejecutan primero, luego las [`dependencies` en el decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, y luego las dependencias de parámetros normales.
-  * También puedes agregar [dependencias de `Security` con `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
+  * Las dependencias del router se ejecutan primero, luego las [`dependencies` en el decorador](dependencies/dependencies-in-path-operation-decorators.md), y luego las dependencias de parámetros normales.
+  * También puedes agregar [dependencias de `Security` con `scopes`](../advanced/security/oauth2-scopes.md).
 
 /// tip | Consejo
 
@@ -303,7 +303,7 @@ Y como la mayor parte de tu lógica ahora vivirá en su propio módulo específi
 
 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`:
+Y podemos incluso declarar [dependencias globales](dependencies/global-dependencies.md) que se combinarán con las dependencias para cada `APIRouter`:
 
 {* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
 
@@ -353,7 +353,7 @@ La segunda versión es un "import absoluto":
 from app.routers import items, users
 ```
 
-Para aprender más sobre Paquetes y Módulos de Python, lee <a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">la documentación oficial de Python sobre Módulos</a>.
+Para aprender más sobre Paquetes y Módulos de Python, lee [la documentación oficial de Python sobre Módulos](https://docs.python.org/3/tutorial/modules.html).
 
 ///
 
@@ -465,6 +465,37 @@ Como no podemos simplemente aislarlos y "montarlos" independientemente del resto
 
 ///
 
+## Configurar el `entrypoint` en `pyproject.toml` { #configure-the-entrypoint-in-pyproject-toml }
+
+Como tu objeto `app` de FastAPI vive en `app/main.py`, puedes configurar el `entrypoint` en tu archivo `pyproject.toml` así:
+
+```toml
+[tool.fastapi]
+entrypoint = "app.main:app"
+```
+
+que es equivalente a importar como:
+
+```python
+from app.main import app
+```
+
+De esa manera el comando `fastapi` sabrá dónde encontrar tu app.
+
+/// Note | Nota
+
+También podrías pasar la ruta al comando, como:
+
+```console
+$ fastapi dev app/main.py
+```
+
+Pero tendrías que recordar pasar la ruta correcta cada vez que llames al comando `fastapi`.
+
+Además, otras herramientas podrían no ser capaces de encontrarla, por ejemplo la [Extensión de VS Code](../editor-support.md) o [FastAPI Cloud](https://fastapicloud.com), así que se recomienda usar el `entrypoint` en `pyproject.toml`.
+
+///
+
 ## Revisa la documentación automática de la API { #check-the-automatic-api-docs }
 
 Ahora, ejecuta tu app:
@@ -472,14 +503,14 @@ Ahora, ejecuta tu app:
 <div class="termy">
 
 ```console
-$ fastapi dev app/main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
 
 </div>
 
-Y abre la documentación en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Y abre la documentación en [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 Verás la documentación automática de la API, incluyendo los paths de todos los submódulos, usando los paths correctos (y prefijos) y los tags correctos:
 
index 5f723e4c9f07bf3cb0f1edf3a4a3bc13e1286bc6..742f78d420eeb68475506da146e31b6da1ae5c7b 100644 (file)
@@ -1,6 +1,6 @@
 # Cuerpo - Modelos Anidados { #body-nested-models }
 
-Con **FastAPI**, puedes definir, validar, documentar y usar modelos anidados de manera arbitraria (gracias a Pydantic).
+Con **FastAPI**, puedes definir, validar, documentar y usar modelos profundamente anidados de manera arbitraria (gracias a Pydantic).
 
 ## Campos de lista { #list-fields }
 
@@ -96,7 +96,7 @@ Nuevamente, haciendo solo esa declaración, con **FastAPI** obtienes:
 
 Además de tipos singulares normales como `str`, `int`, `float`, etc., puedes usar tipos singulares más complejos que heredan de `str`.
 
-Para ver todas las opciones que tienes, revisa el <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">Overview de Tipos de Pydantic</a>. Verás algunos ejemplos en el siguiente capítulo.
+Para ver todas las opciones que tienes, Revisa [Resumen de tipos de Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Verás algunos ejemplos en el siguiente capítulo.
 
 Por ejemplo, como en el modelo `Image` tenemos un campo `url`, podemos declararlo como una instance de `HttpUrl` de Pydantic en lugar de un `str`:
 
index e75e29b54bdd9fb8bb2092a532c6d0da73855523..1b309ebbf40599bae0c84eed3ddbebe5c02070cb 100644 (file)
@@ -2,7 +2,7 @@
 
 ## Actualización reemplazando con `PUT` { #update-replacing-with-put }
 
-Para actualizar un ítem puedes utilizar la operación de <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
+Para actualizar un ítem puedes utilizar la operación de [HTTP `PUT`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT).
 
 Puedes usar el `jsonable_encoder` para convertir los datos de entrada en datos que se puedan almacenar como JSON (por ejemplo, con una base de datos NoSQL). Por ejemplo, convirtiendo `datetime` a `str`.
 
@@ -28,7 +28,7 @@ Y los datos se guardarían con ese "nuevo" `tax` de `10.5`.
 
 ## Actualizaciones parciales con `PATCH` { #partial-updates-with-patch }
 
-También puedes usar la operación de <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> para actualizar *parcialmente* datos.
+También puedes usar la operación de [HTTP `PATCH`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) para actualizar *parcialmente* datos.
 
 Esto significa que puedes enviar solo los datos que deseas actualizar, dejando el resto intacto.
 
@@ -95,6 +95,6 @@ Observa que el modelo de entrada sigue siendo validado.
 
 Entonces, si deseas recibir actualizaciones parciales que puedan omitir todos los atributos, necesitas tener un modelo con todos los atributos marcados como opcionales (con valores por defecto o `None`).
 
-Para distinguir entre los modelos con todos los valores opcionales para **actualizaciones** y modelos con valores requeridos para **creación**, puedes utilizar las ideas descritas en [Modelos Extra](extra-models.md){.internal-link target=_blank}.
+Para distinguir entre los modelos con todos los valores opcionales para **actualizaciones** y modelos con valores requeridos para **creación**, puedes utilizar las ideas descritas en [Modelos Extra](extra-models.md).
 
 ///
index 3adf2e65c533d8c5be47143a63f508efdc83da42..7c3b8e9d9157b9248cafe375dbac3c6269fb37e4 100644 (file)
@@ -6,7 +6,7 @@ Un **request** body es un dato enviado por el cliente a tu API. Un **response**
 
 Tu API casi siempre tiene que enviar un **response** body. Pero los clientes no necesariamente necesitan enviar **request bodies** todo el tiempo, a veces solo solicitan un path, quizás con algunos parámetros de query, pero no envían un body.
 
-Para declarar un **request** body, usas modelos de <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> con todo su poder y beneficios.
+Para declarar un **request** body, usas modelos de [Pydantic](https://docs.pydantic.dev/) con todo su poder y beneficios.
 
 /// info | Información
 
@@ -73,7 +73,7 @@ Con solo esa declaración de tipo en Python, **FastAPI** hará lo siguiente:
     * Si los datos son inválidos, devolverá un error claro e indicado, señalando exactamente dónde y qué fue lo incorrecto.
 * 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.
+* Generar definiciones de [JSON Schema](https://json-schema.org) 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.
 
 ## Documentación automática { #automatic-docs }
@@ -102,15 +102,15 @@ Y fue rigurosamente probado en la fase de diseño, antes de cualquier implementa
 
 Incluso se hicieron algunos cambios en Pydantic para admitir esto.
 
-Las capturas de pantalla anteriores se tomaron con <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>.
+Las capturas de pantalla anteriores se tomaron con [Visual Studio Code](https://code.visualstudio.com).
 
-Pero obtendrías el mismo soporte en el editor con <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> y la mayoría de los otros editores de Python:
+Pero obtendrías el mismo soporte en el editor con [PyCharm](https://www.jetbrains.com/pycharm/) y la mayoría de los otros editores de Python:
 
 <img src="/img/tutorial/body/image05.png">
 
 /// tip | Consejo
 
-Si usas <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> como tu editor, puedes usar el <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
+Si usas [PyCharm](https://www.jetbrains.com/pycharm/) como tu editor, puedes usar el [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/).
 
 Mejora el soporte del editor para modelos de Pydantic, con:
 
@@ -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 - Múltiples parámetros: Valores singulares en el 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).
index a118d814b03dc2e3d2b136fbd81b43017934b346..ec547178be1e2230b46583f871ba17cfb30dee9a 100644 (file)
@@ -1,6 +1,6 @@
 # CORS (Cross-Origin Resource Sharing) { #cors-cross-origin-resource-sharing }
 
-<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS o "Cross-Origin Resource Sharing"</a> se refiere a situaciones en las que un frontend que se ejecuta en un navegador tiene código JavaScript que se comunica con un backend, y el backend está en un "origen" diferente al frontend.
+[CORS o "Cross-Origin Resource Sharing"](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) se refiere a situaciones en las que un frontend que se ejecuta en un navegador tiene código JavaScript que se comunica con un backend, y el backend está en un "origen" diferente al frontend.
 
 ## Origen { #origin }
 
@@ -56,10 +56,10 @@ Se admiten los siguientes argumentos:
 * `allow_origins` - Una lista de orígenes que deberían estar permitidos para hacer requests cross-origin. Por ejemplo, `['https://example.org', 'https://www.example.org']`. Puedes usar `['*']` para permitir cualquier origen.
 * `allow_origin_regex` - Una cadena regex para coincidir con orígenes que deberían estar permitidos para hacer requests cross-origin. por ejemplo, `'https://.*\.example\.org'`.
 * `allow_methods` - Una lista de métodos HTTP que deberían estar permitidos para requests cross-origin. Por defecto es `['GET']`. Puedes usar `['*']` para permitir todos los métodos estándar.
-* `allow_headers` - Una lista de headers de request HTTP que deberían estar soportados para requests cross-origin. Por defecto es `[]`. Puedes usar `['*']` para permitir todos los headers. Los headers `Accept`, `Accept-Language`, `Content-Language` y `Content-Type` siempre están permitidos para <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">requests CORS simples</a>.
+* `allow_headers` - Una lista de headers de request HTTP que deberían estar soportados para requests cross-origin. Por defecto es `[]`. Puedes usar `['*']` para permitir todos los headers. Los headers `Accept`, `Accept-Language`, `Content-Language` y `Content-Type` siempre están permitidos para [requests CORS simples](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests).
 * `allow_credentials` - Indica que las cookies deberían estar soportadas para requests cross-origin. Por defecto es `False`.
 
-    Ninguno de `allow_origins`, `allow_methods` y `allow_headers` puede establecerse a `['*']` si `allow_credentials` está configurado a `True`. Todos deben ser <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards" class="external-link" rel="noopener" target="_blank">especificados explícitamente</a>.
+    Ninguno de `allow_origins`, `allow_methods` y `allow_headers` puede establecerse a `['*']` si `allow_credentials` está configurado a `True`. Todos deben ser [especificados explícitamente](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards).
 
 * `expose_headers` - Indica cualquier header de response que debería ser accesible para el navegador. Por defecto es `[]`.
 * `max_age` - Establece un tiempo máximo en segundos para que los navegadores almacenen en caché los responses CORS. Por defecto es `600`.
@@ -78,7 +78,7 @@ Cualquier request con un header `Origin`. En este caso, el middleware pasará el
 
 ## Más info { #more-info }
 
-Para más información sobre <abbr title="Cross-Origin Resource Sharing">CORS</abbr>, revisa la <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">documentación de CORS de Mozilla</a>.
+Para más información sobre <abbr title="Cross-Origin Resource Sharing">CORS</abbr>, revisa la [documentación de CORS de Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
 
 /// note | Detalles Técnicos
 
index a2d47f2da7ac2689fb48b7fc9c660c830bde9231..b5d0704e066b9e8b25de0191e3d3fd370273554a 100644 (file)
@@ -74,7 +74,7 @@ no se ejecutará.
 
 /// info | Información
 
-Para más información, revisa <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">la documentación oficial de Python</a>.
+Para más información, revisa [la documentación oficial de Python](https://docs.python.org/3/library/__main__.html).
 
 ///
 
index 5eadbe7e1f411e96f7e13f6f19e62403232a45ef..72e4e973e954a27d337f947e3d1bac363b0bd1b7 100644 (file)
@@ -32,7 +32,7 @@ También puede ayudar a evitar confusiones para nuevos desarrolladores que vean
 
 En este ejemplo usamos headers personalizados inventados `X-Key` y `X-Token`.
 
-Pero en casos reales, al implementar seguridad, obtendrías más beneficios usando las [Utilidades de Seguridad integradas (el próximo capítulo)](../security/index.md){.internal-link target=_blank}.
+Pero en casos reales, al implementar seguridad, obtendrías más beneficios usando las [Utilidades de Seguridad integradas (el próximo capítulo)](../security/index.md).
 
 ///
 
@@ -62,7 +62,7 @@ Así que, puedes reutilizar una dependencia normal (que devuelve un valor) que y
 
 ## Dependencias para un grupo de *path operations* { #dependencies-for-a-group-of-path-operations }
 
-Más adelante, cuando leas sobre cómo estructurar aplicaciones más grandes ([Aplicaciones Más Grandes - Múltiples Archivos](../../tutorial/bigger-applications.md){.internal-link target=_blank}), posiblemente con múltiples archivos, aprenderás cómo declarar un único parámetro `dependencies` para un grupo de *path operations*.
+Más adelante, cuando leas sobre cómo estructurar aplicaciones más grandes ([Aplicaciones Más Grandes - Múltiples Archivos](../../tutorial/bigger-applications.md)), posiblemente con múltiples archivos, aprenderás cómo declarar un único parámetro `dependencies` para un grupo de *path operations*.
 
 ## Dependencias Globales { #global-dependencies }
 
index 2cd68eddd23a4df3fbdff4cf27dc1b587467559c..084d72aa40c08876ea2d4114ae84285a66b28cbd 100644 (file)
@@ -14,8 +14,8 @@ Asegúrate de usar `yield` una sola vez por dependencia.
 
 Cualquier función que sea válida para usar con:
 
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> o
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
+* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) o
+* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
 
 sería válida para usar como una dependencia en **FastAPI**.
 
@@ -27,7 +27,7 @@ De hecho, FastAPI usa esos dos decoradores internamente.
 
 Por ejemplo, podrías usar esto para crear una sesión de base de datos y cerrarla después de finalizar.
 
-Solo el código anterior e incluyendo la declaración `yield` se ejecuta antes de crear un response:
+Solo el código anterior e incluyendo el `yield` statement se ejecuta antes de crear un response:
 
 {* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
 
@@ -35,7 +35,7 @@ El valor generado es lo que se inyecta en *path operations* y otras dependencias
 
 {* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
 
-El código posterior a la declaración `yield` se ejecuta después del response:
+El código posterior al `yield` statement se ejecuta después del response:
 
 {* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
 
@@ -87,7 +87,7 @@ Puedes tener cualquier combinación de dependencias que quieras.
 
 /// note | Detalles técnicos
 
-Esto funciona gracias a los <a href="https://docs.python.org/3/library/contextlib.html" class="external-link" target="_blank">Context Managers</a> de Python.
+Esto funciona gracias a los [Context Managers](https://docs.python.org/3/library/contextlib.html) de Python.
 
 **FastAPI** los utiliza internamente para lograr esto.
 
@@ -111,7 +111,7 @@ Pero está ahí para ti si la necesitas. 🤓
 
 {* ../../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}.
+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).
 
 ## Dependencias con `yield` y `except` { #dependencies-with-yield-and-except }
 
@@ -233,14 +233,14 @@ 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}.
+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).
 ## Context Managers { #context-managers }
 
 ### Qué son los "Context Managers" { #what-are-context-managers }
 
-Los "Context Managers" son aquellos objetos de Python que puedes usar en una declaración `with`.
+Los "Context Managers" son aquellos objetos de Python que puedes usar en un `with` statement.
 
-Por ejemplo, <a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files" class="external-link" target="_blank">puedes usar `with` para leer un archivo</a>:
+Por ejemplo, [puedes usar `with` para leer un archivo](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files):
 
 ```Python
 with open("./somefile.txt") as f:
@@ -264,7 +264,7 @@ Si apenas estás comenzando con **FastAPI**, podrías querer omitirlo por ahora.
 
 ///
 
-En Python, puedes crear Context Managers <a href="https://docs.python.org/3/reference/datamodel.html#context-managers" class="external-link" target="_blank">creando una clase con dos métodos: `__enter__()` y `__exit__()`</a>.
+En Python, puedes crear Context Managers [creando una clase con dos métodos: `__enter__()` y `__exit__()`](https://docs.python.org/3/reference/datamodel.html#context-managers).
 
 También puedes usarlos dentro de las dependencias de **FastAPI** con `yield` usando
 `with` o `async with` en la función de dependencia:
@@ -275,8 +275,8 @@ También puedes usarlos dentro de las dependencias de **FastAPI** con `yield` us
 
 Otra manera de crear un context manager es con:
 
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> o
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
+* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) o
+* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
 
 usándolos para decorar una función con un solo `yield`.
 
index 567e69cf0c0e10837a3982bcc3c5ea9c63326ffe..661474f71648f9820652168ecd2308e50cc5ed3d 100644 (file)
@@ -2,14 +2,14 @@
 
 Para algunos tipos de aplicaciones, podrías querer agregar dependencias a toda la aplicación.
 
-Similar a como puedes [agregar `dependencies` a los *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, puedes agregarlos a la aplicación de `FastAPI`.
+Similar a como puedes [agregar `dependencies` a los *path operation decorators*](dependencies-in-path-operation-decorators.md), puedes agregarlos a la aplicación de `FastAPI`.
 
 En ese caso, se aplicarán a todas las *path operations* en la aplicación:
 
 {* ../../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.
+Y todas las ideas en la sección sobre [agregar `dependencies` a los *path operation decorators*](dependencies-in-path-operation-decorators.md) siguen aplicándose, pero en este caso, a todas las *path operations* en la app.
 
 ## Dependencias para grupos de *path operations* { #dependencies-for-groups-of-path-operations }
 
-Más adelante, al leer sobre cómo estructurar aplicaciones más grandes ([Aplicaciones Más Grandes - Múltiples Archivos](../../tutorial/bigger-applications.md){.internal-link target=_blank}), posiblemente con múltiples archivos, aprenderás cómo declarar un solo parámetro de `dependencies` para un grupo de *path operations*.
+Más adelante, al leer sobre cómo estructurar aplicaciones más grandes ([Aplicaciones Más Grandes - Múltiples Archivos](../../tutorial/bigger-applications.md)), posiblemente con múltiples archivos, aprenderás cómo declarar un solo parámetro de `dependencies` para un grupo de *path operations*.
index 4eb31196f7c61c70e363df8423cbcf8ac015fb3e..ed5783f39d39b426971f882bd9cd0e9b4f37200c 100644 (file)
@@ -57,7 +57,7 @@ FastAPI agregó soporte para `Annotated` (y comenzó a recomendarlo) en la versi
 
 Si tienes una versión anterior, obtendrás errores al intentar usar `Annotated`.
 
-Asegúrate de [Actualizar la versión de FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} al menos a la 0.95.1 antes de usar `Annotated`.
+Asegúrate de [Actualizar la versión de FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions) al menos a la 0.95.1 antes de usar `Annotated`.
 
 ///
 
@@ -152,7 +152,7 @@ No importa. **FastAPI** sabrá qué hacer.
 
 /// note | Nota
 
-Si no lo sabes, revisa la sección [Async: *"¿Con prisa?"*](../../async.md#in-a-hurry){.internal-link target=_blank} sobre `async` y `await` en la documentación.
+Si no lo sabes, revisa la sección [Async: *"¿Con prisa?"*](../../async.md#in-a-hurry) sobre `async` y `await` en la documentación.
 
 ///
 
index df6099a8b9efc14d3bb3bec99ec4d66918eb73fc..2a83153a6c6c945f37c368a4ce47ae64c7ae28dc 100644 (file)
@@ -12,7 +12,7 @@ Imaginemos que tienes una base de datos `fake_db` que solo recibe datos compatib
 
 Por ejemplo, no recibe objetos `datetime`, ya que no son compatibles con JSON.
 
-Entonces, un objeto `datetime` tendría que ser convertido a un `str` que contenga los datos en <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">formato ISO</a>.
+Entonces, un objeto `datetime` tendría que ser convertido a un `str` que contenga los datos en [formato ISO](https://en.wikipedia.org/wiki/ISO_8601).
 
 De la misma manera, esta base de datos no recibiría un modelo de Pydantic (un objeto con atributos), solo un `dict`.
 
@@ -24,7 +24,7 @@ Recibe un objeto, como un modelo de Pydantic, y devuelve una versión compatible
 
 En este ejemplo, convertiría el modelo de Pydantic a un `dict`, y el `datetime` a un `str`.
 
-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>.
+El resultado de llamarlo es algo que puede ser codificado con la función estándar de Python [`json.dumps()`](https://docs.python.org/3/library/json.html#json.dumps).
 
 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.
 
index e876921ba4e1d551da492abf1034b4971375b708..b92d0fcd485f06249686d6e7ef286bd391e6fff1 100644 (file)
@@ -36,7 +36,7 @@ Aquí hay algunos de los tipos de datos adicionales que puedes usar:
 * `datetime.timedelta`:
     * Un `datetime.timedelta` de Python.
     * En requests y responses se representará como un `float` de segundos totales.
-    * Pydantic también permite representarlo como una "codificación de diferencia horaria ISO 8601", <a href="https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers" class="external-link" target="_blank">consulta la documentación para más información</a>.
+    * Pydantic también permite representarlo como una "codificación de diferencia horaria ISO 8601", [consulta la documentación para más información](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
 * `frozenset`:
     * En requests y responses, tratado igual que un `set`:
         * En requests, se leerá una list, eliminando duplicados y convirtiéndola en un `set`.
@@ -45,11 +45,11 @@ Aquí hay algunos de los tipos de datos adicionales que puedes usar:
 * `bytes`:
     * `bytes` estándar de Python.
     * En requests y responses se tratará como `str`.
-    * El esquema generado especificará que es un `str` con "binary" como "format".
+    * El esquema generado especificará que es un `str` con `binary` como "format".
 * `Decimal`:
     * `Decimal` estándar de Python.
     * En requests y responses, manejado igual que un `float`.
-* Puedes revisar todos los tipos de datos válidos de Pydantic aquí: <a href="https://docs.pydantic.dev/latest/usage/types/types/" class="external-link" target="_blank">Tipos de datos de Pydantic</a>.
+* Puedes revisar todos los tipos de datos válidos de Pydantic aquí: [Tipos de datos de Pydantic](https://docs.pydantic.dev/latest/usage/types/types/).
 
 ## Ejemplo { #example }
 
index 4621b2db2e7d47e90d4c27ef439180e21f9ff78d..4a3b75b5bc1e4be1a28c501bc2e9262e9d58f347 100644 (file)
@@ -12,7 +12,7 @@ Esto es especialmente el caso para los modelos de usuario, porque:
 
 Nunca almacenes contraseñas de usuarios en texto plano. Siempre almacena un "hash seguro" que puedas verificar luego.
 
-Si no lo sabes, aprenderás qué es un "hash de contraseña" en los [capítulos de seguridad](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
+Si no lo sabes, aprenderás qué es un "hash de contraseña" en los [capítulos de seguridad](security/simple-oauth2.md#password-hashing).
 
 ///
 
@@ -162,11 +162,11 @@ Puedes declarar un response que sea la `Union` de dos o más tipos, eso signific
 
 Se definirá en OpenAPI con `anyOf`.
 
-Para hacerlo, usa la anotación de tipos estándar de Python <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>:
+Para hacerlo, usa la anotación de tipos estándar de Python [`typing.Union`](https://docs.python.org/3/library/typing.html#typing.Union):
 
 /// note | Nota
 
-Al definir una <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>, incluye el tipo más específico primero, seguido por el tipo menos específico. En el ejemplo a continuación, el más específico `PlaneItem` viene antes de `CarItem` en `Union[PlaneItem, CarItem]`.
+Al definir una [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions), incluye el tipo más específico primero, seguido por el tipo menos específico. En el ejemplo a continuación, el más específico `PlaneItem` viene antes de `CarItem` en `Union[PlaneItem, CarItem]`.
 
 ///
 
index b7ffd2c2abf315c7dbe5b6b2c06c62723ab05b82..1fcfdc140237a960537ff9fd7d559dfbb70add4d 100644 (file)
@@ -11,7 +11,7 @@ Ejecuta el servidor en vivo:
 <div class="termy">
 
 ```console
-$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+$ <font color="#4E9A06">fastapi</font> dev
 
   <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server 🚀
 
@@ -58,7 +58,7 @@ Esa línea muestra la URL donde tu aplicación está siendo servida, en tu máqu
 
 ### 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>.
+Abre tu navegador en [http://127.0.0.1:8000](http://127.0.0.1:8000).
 
 Verás el response JSON como:
 
@@ -68,17 +68,17 @@ Verás el response JSON como:
 
 ### Documentación interactiva de la API { #interactive-api-docs }
 
-Ahora ve a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ahora ve a [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
-Verás la documentación interactiva automática de la API (proporcionada por <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
+Verás la documentación interactiva automática de la API (proporcionada por [Swagger UI](https://github.com/swagger-api/swagger-ui)):
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
 ### Documentación alternativa de la API { #alternative-api-docs }
 
-Y ahora, ve a <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Y ahora, ve a [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
 
-Verás la documentación alternativa automática (proporcionada por <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
+Verás la documentación alternativa automática (proporcionada por [ReDoc](https://github.com/Rebilly/ReDoc)):
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
@@ -92,7 +92,7 @@ Un "esquema" es una definición o descripción de algo. No el código que lo imp
 
 #### Esquema de la API { #api-schema }
 
-En este caso, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> es una especificación que dicta cómo definir un esquema de tu API.
+En este caso, [OpenAPI](https://github.com/OAI/OpenAPI-Specification) es una especificación que dicta cómo definir un esquema de tu API.
 
 Esta definición de esquema incluye los paths de tu API, los posibles parámetros que toman, etc.
 
@@ -110,7 +110,7 @@ OpenAPI define un esquema de API para tu API. Y ese esquema incluye definiciones
 
 Si tienes curiosidad por cómo se ve el esquema OpenAPI en bruto, FastAPI automáticamente genera un JSON (esquema) con las descripciones de toda tu API.
 
-Puedes verlo directamente en: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
+Puedes verlo directamente en: [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json).
 
 Mostrará un JSON que empieza con algo como:
 
@@ -143,9 +143,58 @@ Y hay docenas de alternativas, todas basadas en OpenAPI. Podrías añadir fácil
 
 También podrías usarlo para generar código automáticamente, para clientes que se comuniquen con tu API. Por ejemplo, aplicaciones frontend, móviles o IoT.
 
+### Configura el `entrypoint` de la app en `pyproject.toml` { #configure-the-app-entrypoint-in-pyproject-toml }
+
+Puedes configurar dónde está tu app en un archivo `pyproject.toml` así:
+
+```toml
+[tool.fastapi]
+entrypoint = "main:app"
+```
+
+Ese `entrypoint` le dirá al comando `fastapi` que debe hacer el import de la app así:
+
+```python
+from main import app
+```
+
+Si tu código estuviera estructurado así:
+
+```
+.
+├── backend
+│   ├── main.py
+│   ├── __init__.py
+```
+
+Entonces pondrías el `entrypoint` como:
+
+```toml
+[tool.fastapi]
+entrypoint = "backend.main:app"
+```
+
+lo cual sería equivalente a:
+
+```python
+from backend.main import app
+```
+
+### `fastapi dev` con path { #fastapi-dev-with-path }
+
+También puedes pasar el path del archivo al comando `fastapi dev`, y adivinará el objeto app de FastAPI que debe usar:
+
+```console
+$ fastapi dev main.py
+```
+
+Pero tendrías que recordar pasar el path correcto cada vez que llames al comando `fastapi`.
+
+Además, otras herramientas podrían no ser capaces de encontrarlo, por ejemplo la [Extensión de VS Code](../editor-support.md) o [FastAPI Cloud](https://fastapicloud.com), así que se recomienda usar el `entrypoint` en `pyproject.toml`.
+
 ### Despliega tu app (opcional) { #deploy-your-app-optional }
 
-Opcionalmente puedes desplegar tu app de FastAPI en <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, ve y únete a la lista de espera si aún no lo has hecho. 🚀
+Opcionalmente puedes desplegar tu app de FastAPI en [FastAPI Cloud](https://fastapicloud.com), ve y únete a la lista de espera si aún no lo has hecho. 🚀
 
 Si ya tienes una cuenta de **FastAPI Cloud** (te invitamos desde la lista de espera 😉), puedes desplegar tu aplicación con un solo comando.
 
@@ -191,7 +240,7 @@ Deploying to FastAPI Cloud...
 
 `FastAPI` es una clase que hereda directamente de `Starlette`.
 
-Puedes usar toda la funcionalidad de <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> con `FastAPI` también.
+Puedes usar toda la funcionalidad de [Starlette](https://www.starlette.dev/) con `FastAPI` también.
 
 ///
 
@@ -336,7 +385,7 @@ También podrías definirla como una función normal en lugar de `async def`:
 
 /// note | Nota
 
-Si no sabes la diferencia, Revisa la sección [Async: *"¿Tienes prisa?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+Si no sabes la diferencia, Revisa la sección [Async: *"¿Tienes prisa?"*](../async.md#in-a-hurry).
 
 ///
 
@@ -352,11 +401,11 @@ Hay muchos otros objetos y modelos que serán automáticamente convertidos a JSO
 
 ### Paso 6: Despliégalo { #step-6-deploy-it }
 
-Despliega tu app en **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** con un solo comando: `fastapi deploy`. 🎉
+Despliega tu app en **[FastAPI Cloud](https://fastapicloud.com)** con un solo comando: `fastapi deploy`. 🎉
 
 #### Sobre FastAPI Cloud { #about-fastapi-cloud }
 
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** está construido por el mismo autor y equipo detrás de **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** está construido por el mismo autor y equipo detrás de **FastAPI**.
 
 Agiliza el proceso de **construir**, **desplegar** y **acceder** a una API con el mínimo esfuerzo.
 
index 265269e8746dfd2ada1b6eb74c553bf9c778c915..737c43e41bb57c01c412cb0b07a91fb366c3bced 100644 (file)
@@ -81,7 +81,7 @@ Pero en caso de que los necesites para un escenario avanzado, puedes agregar hea
 
 ## Instalar manejadores de excepciones personalizados { #install-custom-exception-handlers }
 
-Puedes agregar manejadores de excepciones personalizados con <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">las mismas utilidades de excepciones de Starlette</a>.
+Puedes agregar manejadores de excepciones personalizados con [las mismas utilidades de excepciones de Starlette](https://www.starlette.dev/exceptions/).
 
 Supongamos que tienes una excepción personalizada `UnicornException` que tú (o un paquete que usas) podrías lanzar.
 
index 7804b6854d67a268dacc7214cecf90e610de52c5..414e865b27b4a7aae47016e061f037f129ec9902 100644 (file)
@@ -10,12 +10,12 @@ También está diseñado para funcionar como una referencia futura para que pued
 
 Todos los bloques de código pueden ser copiados y usados directamente (de hecho, son archivos Python probados).
 
-Para ejecutar cualquiera de los ejemplos, copia el código a un archivo `main.py`, y comienza `fastapi dev` con:
+Para ejecutar cualquiera de los ejemplos, copia el código a un archivo `main.py`, y comienza `fastapi dev`:
 
 <div class="termy">
 
 ```console
-$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+$ <font color="#4E9A06">fastapi</font> dev
 
   <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server 🚀
 
@@ -62,7 +62,7 @@ Usarlo en tu editor es lo que realmente te muestra los beneficios de FastAPI, al
 
 El primer paso es instalar FastAPI.
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo, y luego **instala FastAPI**:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), actívalo, y luego **instala FastAPI**:
 
 <div class="termy">
 
@@ -76,7 +76,7 @@ $ pip install "fastapi[standard]"
 
 /// note | Nota
 
-Cuando instalas con `pip install "fastapi[standard]"` viene con algunas dependencias opcionales estándar por defecto, incluyendo `fastapi-cloud-cli`, que te permite hacer deploy a <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
+Cuando instalas con `pip install "fastapi[standard]"` viene con algunas dependencias opcionales estándar por defecto, incluyendo `fastapi-cloud-cli`, que te permite hacer deploy a [FastAPI Cloud](https://fastapicloud.com).
 
 Si no quieres tener esas dependencias opcionales, en su lugar puedes instalar `pip install fastapi`.
 
@@ -84,6 +84,12 @@ Si quieres instalar las dependencias estándar pero sin `fastapi-cloud-cli`, pue
 
 ///
 
+/// tip | Consejo
+
+FastAPI tiene una [extensión oficial para VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (y Cursor), que ofrece muchas funcionalidades, incluyendo un explorador de path operation, búsqueda de path operation, navegación de CodeLens en tests (saltar a la definición desde tests), y deploy y logs de FastAPI Cloud, todo desde tu editor.
+
+///
+
 ## Guía Avanzada del Usuario { #advanced-user-guide }
 
 También hay una **Guía Avanzada del Usuario** que puedes leer después de esta **Tutorial - Guía del Usuario**.
index 2163a1cb2275d9affd90ab9f0d58b66fbedc5bb2..35bc98a26da268f1842447e89c1bd6cb31201c4b 100644 (file)
@@ -14,7 +14,7 @@ Puedes establecer los siguientes campos que se usan en la especificación OpenAP
 | `version` | `string` | La versión de la API. Esta es la versión de tu propia aplicación, no de OpenAPI. Por ejemplo, `2.5.0`. |
 | `terms_of_service` | `str` | Una URL a los Términos de Servicio para la API. Si se proporciona, debe ser una URL. |
 | `contact` | `dict` | La información de contacto para la API expuesta. Puede contener varios campos. <details><summary><code>contact</code> fields</summary><table><thead><tr><th>Parámetro</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>El nombre identificativo de la persona/organización de contacto.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>La URL que apunta a la información de contacto. DEBE tener el formato de una URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>La dirección de correo electrónico de la persona/organización de contacto. DEBE tener el formato de una dirección de correo.</td></tr></tbody></table></details> |
-| `license_info` | `dict` | La información de la licencia para la API expuesta. Puede contener varios campos. <details><summary><code>license_info</code> fields</summary><table><thead><tr><th>Parámetro</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>REQUERIDO</strong> (si se establece un <code>license_info</code>). El nombre de la licencia utilizada para la API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Una expresión de licencia <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> para la API. El campo <code>identifier</code> es mutuamente excluyente del campo <code>url</code>. <small>Disponible desde OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>Una URL a la licencia utilizada para la API. DEBE tener el formato de una URL.</td></tr></tbody></table></details> |
+| `license_info` | `dict` | La información de la licencia para la API expuesta. Puede contener varios campos. <details><summary><code>license_info</code> fields</summary><table><thead><tr><th>Parámetro</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>REQUERIDO</strong> (si se establece un <code>license_info</code>). El nombre de la licencia utilizada para la API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Una expresión de licencia [SPDX](https://spdx.org/licenses/) para la API. El campo <code>identifier</code> es mutuamente excluyente del campo <code>url</code>. <small>Disponible desde OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>Una URL a la licencia utilizada para la API. DEBE tener el formato de una URL.</td></tr></tbody></table></details> |
 
 Puedes configurarlos de la siguiente manera:
 
@@ -76,7 +76,7 @@ Usa el parámetro `tags` con tus *path operations* (y `APIRouter`s) para asignar
 
 /// info | Información
 
-Lee más sobre etiquetas en [Configuración de Path Operation](path-operation-configuration.md#tags){.internal-link target=_blank}.
+Lee más sobre etiquetas en [Configuración de Path Operation](path-operation-configuration.md#tags).
 
 ///
 
index 766e30cad650bf84c3719d7057d3d4b199d782fb..4729cadc004484f894e8104339b58e57caa432b9 100644 (file)
@@ -15,7 +15,7 @@ Un "middleware" es una función que trabaja con cada **request** antes de que se
 
 Si tienes dependencias con `yield`, el código de salida se ejecutará *después* del middleware.
 
-Si hubiera tareas en segundo plano (cubiertas en la sección [Tareas en segundo plano](background-tasks.md){.internal-link target=_blank}, lo verás más adelante), se ejecutarán *después* de todo el middleware.
+Si hubiera tareas en segundo plano (cubiertas en la sección [Tareas en segundo plano](background-tasks.md), lo verás más adelante), se ejecutarán *después* de todo el middleware.
 
 ///
 
@@ -35,9 +35,9 @@ La función middleware recibe:
 
 /// tip | Consejo
 
-Ten en cuenta que los custom proprietary headers se pueden añadir <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">usando el prefijo `X-`</a>.
+Ten en cuenta que los custom proprietary headers se pueden añadir [usando el prefijo `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
 
-Pero si tienes custom headers que deseas que un cliente en un navegador pueda ver, necesitas añadirlos a tus configuraciones de CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) usando el parámetro `expose_headers` documentado en <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">la documentación de CORS de Starlette</a>.
+Pero si tienes custom headers que deseas que un cliente en un navegador pueda ver, necesitas añadirlos a tus configuraciones de CORS ([CORS (Cross-Origin Resource Sharing)](cors.md)) usando el parámetro `expose_headers` documentado en [la documentación de CORS de Starlette](https://www.starlette.dev/middleware/#corsmiddleware).
 
 ///
 
@@ -61,7 +61,7 @@ Por ejemplo, podrías añadir un custom header `X-Process-Time` que contenga el
 
 /// tip | Consejo
 
-Aquí usamos <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> en lugar de `time.time()` porque puede ser más preciso para estos casos de uso. 🤓
+Aquí usamos [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) en lugar de `time.time()` porque puede ser más preciso para estos casos de uso. 🤓
 
 ///
 
@@ -90,6 +90,6 @@ Este comportamiento de apilamiento asegura que los middlewares se ejecuten en un
 
 ## Otros middlewares { #other-middlewares }
 
-Más adelante puedes leer sobre otros middlewares en la [Guía del Usuario Avanzado: Middleware Avanzado](../advanced/middleware.md){.internal-link target=_blank}.
+Más adelante puedes leer sobre otros middlewares en la [Guía del Usuario Avanzado: Middleware Avanzado](../advanced/middleware.md).
 
 Leerás sobre cómo manejar <abbr title="Cross-Origin Resource Sharing">CORS</abbr> con un middleware en la siguiente sección.
index 90e4335b3b506f685606640dbe80e9a3a41f2c18..21fd503bb747e09824f3e063ec38ae6af7f19c19 100644 (file)
@@ -58,7 +58,7 @@ Puedes añadir un `summary` y `description`:
 
 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).
+Puedes escribir [Markdown](https://en.wikipedia.org/wiki/Markdown) en el docstring, se interpretará y mostrará correctamente (teniendo en cuenta la indentación del docstring).
 
 {* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
 
index 3a38d1d63c4dd7fcf81499b9579074f177c2fcc9..5e7b9a97828f145f5effc0b09b57631b726a5981 100644 (file)
@@ -14,7 +14,7 @@ FastAPI agregó soporte para `Annotated` (y comenzó a recomendar su uso) en la
 
 Si tienes una versión anterior, obtendrás errores al intentar usar `Annotated`.
 
-Asegúrate de [Actualizar la versión de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} a al menos la 0.95.1 antes de usar `Annotated`.
+Asegúrate de [Actualizar la versión de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions) a al menos la 0.95.1 antes de usar `Annotated`.
 
 ///
 
@@ -122,7 +122,7 @@ Y lo mismo para <abbr title="less than - menor que"><code>lt</code></abbr>.
 
 ## Resumen { #recap }
 
-Con `Query`, `Path` (y otros que aún no has visto) puedes declarar metadatos y validaciones de string de las mismas maneras que con [Parámetros de Query y Validaciones de String](query-params-str-validations.md){.internal-link target=_blank}.
+Con `Query`, `Path` (y otros que aún no has visto) puedes declarar metadatos y validaciones de string de las mismas maneras que con [Parámetros de Query y Validaciones de String](query-params-str-validations.md).
 
 Y también puedes declarar validaciones numéricas:
 
index 8dc3db351d3c02f0e7d3d31aa3fd4d2c090db40d..f1aa4ef8b4391e156d63720723eafa6d42bfe590 100644 (file)
@@ -6,7 +6,7 @@ Puedes declarar "parámetros" o "variables" de path con la misma sintaxis que se
 
 El valor del parámetro de path `item_id` se pasará a tu función como el argumento `item_id`.
 
-Así que, si ejecutas este ejemplo y vas a <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, verás un response de:
+Así que, si ejecutas este ejemplo y vas a [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo), verás un response de:
 
 ```JSON
 {"item_id":"foo"}
@@ -28,7 +28,7 @@ Esto te dará soporte del editor dentro de tu función, con chequeo de errores,
 
 ## <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:
+Si ejecutas este ejemplo y abres tu navegador en [http://127.0.0.1:8000/items/3](http://127.0.0.1:8000/items/3), verás un response de:
 
 ```JSON
 {"item_id":3}
@@ -44,7 +44,7 @@ Entonces, con esa declaración de tipo, **FastAPI** te ofrece <dfn title="conver
 
 ## Validación de datos { #data-validation }
 
-Pero si vas al navegador en <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, verás un bonito error HTTP de:
+Pero si vas al navegador en [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo), verás un bonito error HTTP de:
 
 ```JSON
 {
@@ -64,7 +64,7 @@ Pero si vas al navegador en <a href="http://127.0.0.1:8000/items/foo" class="ext
 
 porque el parámetro de path `item_id` tenía un valor de `"foo"`, que no es un `int`.
 
-El mismo error aparecería si proporcionaras un `float` en lugar de un `int`, como en: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
+El mismo error aparecería si proporcionaras un `float` en lugar de un `int`, como en: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
 
 /// check | Revisa
 
@@ -78,7 +78,7 @@ Esto es increíblemente útil mientras desarrollas y depuras código que interac
 
 ## Documentación { #documentation }
 
-Y cuando abras tu navegador en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, verás una documentación de API automática e interactiva como:
+Y cuando abras tu navegador en [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs), verás una documentación de API automática e interactiva como:
 
 <img src="/img/tutorial/path-params/image01.png">
 
@@ -92,9 +92,9 @@ Nota que el parámetro de path está declarado como un entero.
 
 ## Beneficios basados en estándares, documentación alternativa { #standards-based-benefits-alternative-documentation }
 
-Y porque el esquema generado es del estándar <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a>, hay muchas herramientas compatibles.
+Y porque el esquema generado es del estándar [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md), hay muchas herramientas compatibles.
 
-Debido a esto, el propio **FastAPI** proporciona una documentación de API alternativa (usando ReDoc), a la cual puedes acceder en <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>:
+Debido a esto, el propio **FastAPI** proporciona una documentación de API alternativa (usando ReDoc), a la cual puedes acceder en [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc):
 
 <img src="/img/tutorial/path-params/image02.png">
 
@@ -102,7 +102,7 @@ De la misma manera, hay muchas herramientas compatibles. Incluyendo herramientas
 
 ## Pydantic { #pydantic }
 
-Toda la validación de datos se realiza internamente con <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, así que obtienes todos los beneficios de esta. Y sabes que estás en buenas manos.
+Toda la validación de datos se realiza internamente con [Pydantic](https://docs.pydantic.dev/), así que obtienes todos los beneficios de esta. Y sabes que estás en buenas manos.
 
 Puedes usar las mismas declaraciones de tipo con `str`, `float`, `bool` y muchos otros tipos de datos complejos.
 
index b4339e1931a792d1b105c75b36efbde9a3cf6d48..44beba2d3e5294e454824785074a0d25ead39036 100644 (file)
@@ -35,13 +35,13 @@ FastAPI añadió soporte para `Annotated` (y empezó a recomendarlo) en la versi
 
 Si tienes una versión más antigua, obtendrás errores al intentar usar `Annotated`.
 
-Asegúrate de [Actualizar la versión de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} a al menos 0.95.1 antes de usar `Annotated`.
+Asegúrate de [Actualizar la versión de FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions) a al menos 0.95.1 antes de usar `Annotated`.
 
 ///
 
 ## Usar `Annotated` en el tipo del parámetro `q` { #use-annotated-in-the-type-for-the-q-parameter }
 
-¿Recuerdas que te dije antes que `Annotated` puede usarse para agregar metadatos a tus parámetros en la [Introducción a Tipos de Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}?
+¿Recuerdas que te dije antes que `Annotated` puede usarse para agregar metadatos a tus parámetros en la [Introducción a Tipos de Python](../python-types.md#type-hints-with-metadata-annotations)?
 
 Ahora es el momento de usarlo con FastAPI. 🚀
 
@@ -158,7 +158,7 @@ Podrías llamar a esa misma función en otros lugares sin FastAPI, y funcionarí
 
 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>. 🚀
+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 [Typer](https://typer.tiangolo.com/). 🚀
 
 ## Agregar más validaciones { #add-more-validations }
 
@@ -296,9 +296,9 @@ También puedes usar `list` directamente en lugar de `list[str]`:
 
 /// note | Nota
 
-Ten en cuenta que en este caso, FastAPI no comprobará el contenido de la lista.
+Ten en cuenta que en este caso, FastAPI no comprobará el contenido de la list.
 
-Por ejemplo, `list[int]` comprobaría (y documentaría) que el contenido de la lista son enteros. Pero `list` sola no lo haría.
+Por ejemplo, `list[int]` comprobaría (y documentaría) que el contenido de la list son enteros. Pero `list` sola no lo haría.
 
 ///
 
@@ -370,11 +370,11 @@ Podría haber casos donde necesites hacer alguna validación personalizada que n
 
 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`.
+Puedes lograr eso usando [`AfterValidator` de Pydantic](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) dentro de `Annotated`.
 
 /// tip | Consejo
 
-Pydantic también tiene <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> y otros. 🤓
+Pydantic también tiene [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) y otros. 🤓
 
 ///
 
index edbe51a0ea9ee3f86a573ee44e4d603f9713debc..2dbb04ef45f87f846cbf34c7f50082fe3c1520c6 100644 (file)
@@ -182,6 +182,6 @@ En este caso, hay 3 parámetros de query:
 
 /// tip | Consejo
 
-También podrías usar `Enum`s de la misma manera que con [Parámetros de Path](path-params.md#predefined-values){.internal-link target=_blank}.
+También podrías usar `Enum`s de la misma manera que con [Parámetros de Path](path-params.md#predefined-values).
 
 ///
index 717968d7418a0e29ca669b62fe1e6c9a58da6b2c..8bfc7a772ee380f5749c1b0d0a8a7d7d9f34e06d 100644 (file)
@@ -4,9 +4,9 @@ Puedes definir archivos que serán subidos por el cliente utilizando `File`.
 
 /// info | Información
 
-Para recibir archivos subidos, primero instala <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Para recibir archivos subidos, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo y luego instalarlo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo y luego instalarlo, por ejemplo:
 
 ```console
 $ pip install python-multipart
@@ -63,8 +63,8 @@ Usar `UploadFile` tiene varias ventajas sobre `bytes`:
     * Un archivo almacenado en memoria hasta un límite de tamaño máximo, y después de superar este límite, se almacenará en el disco.
 * Esto significa que funcionará bien para archivos grandes como imágenes, videos, binarios grandes, etc. sin consumir toda la memoria.
 * Puedes obtener metadatos del archivo subido.
-* Tiene una interfaz `async` <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">parecida a un archivo</a>.
-* Expone un objeto Python real <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> que puedes pasar directamente a otros paquetes que esperan un objeto parecido a un archivo.
+* Tiene una interfaz `async` [parecida a un archivo](https://docs.python.org/3/glossary.html#term-file-like-object).
+* Expone un objeto Python real [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) que puedes pasar directamente a otros paquetes que esperan un objeto parecido a un archivo.
 
 ### `UploadFile` { #uploadfile }
 
@@ -72,7 +72,7 @@ Usar `UploadFile` tiene varias ventajas sobre `bytes`:
 
 * `filename`: Un `str` con el nombre original del archivo que fue subido (por ejemplo, `myimage.jpg`).
 * `content_type`: Un `str` con el tipo de contenido (MIME type / media type) (por ejemplo, `image/jpeg`).
-* `file`: Un <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> (un objeto <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">parecido a un archivo</a>). Este es el objeto de archivo Python real que puedes pasar directamente a otras funciones o paquetes que esperan un objeto "parecido a un archivo".
+* `file`: Un [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) (un objeto [parecido a un archivo](https://docs.python.org/3/glossary.html#term-file-like-object)). Este es el objeto de archivo Python real que puedes pasar directamente a otras funciones o paquetes que esperan un objeto "parecido a un archivo".
 
 `UploadFile` tiene los siguientes métodos `async`. Todos ellos llaman a los métodos correspondientes del archivo por debajo (usando el `SpooledTemporaryFile` interno).
 
@@ -111,7 +111,7 @@ El `UploadFile` de **FastAPI** hereda directamente del `UploadFile` de **Starlet
 
 ## Qué es "Form Data" { #what-is-form-data }
 
-La manera en que los forms de HTML (`<form></form>`) envían los datos al servidor normalmente utiliza una codificación "especial" para esos datos, es diferente de JSON.
+La manera en que los formularios de HTML (`<form></form>`) envían los datos al servidor normalmente utiliza una codificación "especial" para esos datos, es diferente de JSON.
 
 **FastAPI** se asegurará de leer esos datos del lugar correcto en lugar de JSON.
 
@@ -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 [<abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla">MDN</abbr> web docs para `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
 
 ///
 
index 9afadf0b2ee7de1d20e73e7255f4be5d8a97c8a0..b20421bd01095cfae95ee3145189e4071982b2a8 100644 (file)
@@ -4,9 +4,9 @@ Puedes usar **modelos de Pydantic** para declarar **campos de formulario** en Fa
 
 /// info | Información
 
-Para usar formularios, primero instala <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Para usar formularios, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo, y luego instalarlo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo, y luego instalarlo, por ejemplo:
 
 ```console
 $ pip install python-multipart
index 738a2bc4b404b38deedd0090d5be08304034a8f9..f7b5000b7c4ae704cdbbbcde9fb3df4587322e97 100644 (file)
@@ -4,9 +4,9 @@ Puedes definir archivos y campos de formulario al mismo tiempo usando `File` y `
 
 /// info | Información
 
-Para recibir archivos subidos y/o form data, primero instala <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Para recibir archivos subidos y/o form data, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo y luego instálalo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), actívalo y luego instálalo, por ejemplo:
 
 ```console
 $ pip install python-multipart
index cc29296eed5a5c273caba3479f5bf29b9d970069..7b78aee69a945ad62f48516897846defa06ecc55 100644 (file)
@@ -4,9 +4,9 @@ Cuando necesitas recibir campos de formulario en lugar de JSON, puedes usar `For
 
 /// info | Información
 
-Para usar formularios, primero instala <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Para usar formularios, primero instala [`python-multipart`](https://github.com/Kludex/python-multipart).
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo, y luego instalarlo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo, y luego instalarlo, por ejemplo:
 
 ```console
 $ pip install python-multipart
@@ -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 las [<abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla">MDN</abbr> web docs para `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
 
 ///
 
index c9e931d47765bec328dab74076b33d12d5107007..fc9028bee8d7fc609dd39a1e4761d33d4172c0ca 100644 (file)
@@ -13,6 +13,7 @@ FastAPI usará este tipo de retorno para:
 * Agregar un **JSON Schema** para el response, en la *path operation* de OpenAPI.
     * Esto será utilizado por la **documentación automática**.
     * También será utilizado por herramientas de generación automática de código de cliente.
+* **Serializar** los datos devueltos a JSON usando Pydantic, que está escrito en **Rust**, por lo que será **mucho más rápido**.
 
 Pero lo más importante:
 
@@ -73,9 +74,9 @@ Aquí estamos declarando un modelo `UserIn`, contendrá una contraseña en texto
 
 /// info | Información
 
-Para usar `EmailStr`, primero instala <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a>.
+Para usar `EmailStr`, primero instala [`email-validator`](https://github.com/JoshData/python-email-validator).
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo, y luego instalarlo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo, y luego instalarlo, por ejemplo:
 
 ```console
 $ pip install email-validator
@@ -181,7 +182,7 @@ Podría haber casos en los que devuelvas algo que no es un campo válido de Pyda
 
 ### Devolver un Response Directamente { #return-a-response-directly }
 
-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}.
+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).
 
 {* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
 
@@ -257,7 +258,7 @@ También puedes usar:
 * `response_model_exclude_defaults=True`
 * `response_model_exclude_none=True`
 
-como se describe en <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">la documentación de Pydantic</a> para `exclude_defaults` y `exclude_none`.
+como se describe en [la documentación de Pydantic](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict) para `exclude_defaults` y `exclude_none`.
 
 ///
 
index 35235eb883fd6615dd7194bb883ae52923e30f3f..a070819bb16521194bc9879d42a8c8c2061b918c 100644 (file)
@@ -20,7 +20,7 @@ El parámetro `status_code` recibe un número con el código de estado HTTP.
 
 /// info | Información
 
-`status_code` también puede recibir un `IntEnum`, como por ejemplo el <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a> de Python.
+`status_code` también puede recibir un `IntEnum`, como por ejemplo el [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus) de Python.
 
 ///
 
@@ -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 [documentación de <abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla">MDN</abbr> sobre códigos de estado HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
 
 ///
 
@@ -98,4 +98,4 @@ También podrías usar `from starlette import status`.
 
 ## Cambiando el valor por defecto { #changing-the-default }
 
-Más adelante, en la [Guía de Usuario Avanzada](../advanced/response-change-status-code.md){.internal-link target=_blank}, verás cómo devolver un código de estado diferente al valor por defecto que estás declarando aquí.
+Más adelante, en la [Guía de Usuario Avanzada](../advanced/response-change-status-code.md), verás cómo devolver un código de estado diferente al valor por defecto que estás declarando aquí.
index 9af8261380d94539b5833adeda14ad589b2da9a7..73d0cdbe4657ffe12df4a4f61b6fbb7b65c4cd6f 100644 (file)
@@ -1,4 +1,4 @@
-# Declarar Ejemplos de Request { #declare-request-example-data }
+# Declarar Datos de Ejemplo de Request { #declare-request-example-data }
 
 Puedes declarar ejemplos de los datos que tu aplicación puede recibir.
 
@@ -12,7 +12,7 @@ Puedes declarar `examples` para un modelo de Pydantic que se añadirá al JSON S
 
 Esa información extra se añadirá tal cual al **JSON Schema** resultante para ese modelo, y se usará en la documentación de la API.
 
-Puedes usar el atributo `model_config` que toma un `dict` como se describe en <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">la documentación de Pydantic: Configuración</a>.
+Puedes usar el atributo `model_config` que toma un `dict` como se describe en [Documentación de Pydantic: Configuración](https://docs.pydantic.dev/latest/api/config/).
 
 Puedes establecer `"json_schema_extra"` con un `dict` que contenga cualquier dato adicional que te gustaría que aparezca en el JSON Schema generado, incluyendo `examples`.
 
@@ -145,12 +145,12 @@ JSON Schema no tenía `examples`, así que OpenAPI añadió su propio campo `exa
 
 OpenAPI también añadió los campos `example` y `examples` a otras partes de la especificación:
 
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`Parameter Object` (en la especificación)</a> que era usado por FastAPI:
+* [`Parameter Object` (en la especificación)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object) que era usado por FastAPI:
     * `Path()`
     * `Query()`
     * `Header()`
     * `Cookie()`
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">`Request Body Object`, en el campo `content`, sobre el `Media Type Object` (en la especificación)</a> que era usado por FastAPI:
+* [`Request Body Object`, en el campo `content`, sobre el `Media Type Object` (en la especificación)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object) que era usado por FastAPI:
     * `Body()`
     * `File()`
     * `Form()`
@@ -163,7 +163,7 @@ Este viejo parámetro `examples` específico de OpenAPI ahora es `openapi_exampl
 
 ### Campo `examples` de JSON Schema { #json-schemas-examples-field }
 
-Pero luego JSON Schema añadió un <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">campo `examples`</a> a una nueva versión de la especificación.
+Pero luego JSON Schema añadió un [campo `examples`](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5) a una nueva versión de la especificación.
 
 Y entonces el nuevo OpenAPI 3.1.0 se basó en la última versión (JSON Schema 2020-12) que incluía este nuevo campo `examples`.
 
index 909f14765cb326e6fbfbeba11beafd6a8eb1e497..8118906e5daa6d41aefffc9925b733b4d927d2bc 100644 (file)
@@ -26,11 +26,11 @@ Copia el ejemplo en un archivo `main.py`:
 
 /// info | Información
 
-El paquete <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> se instala automáticamente con **FastAPI** cuando ejecutas el comando `pip install "fastapi[standard]"`.
+El paquete [`python-multipart`](https://github.com/Kludex/python-multipart) se instala automáticamente con **FastAPI** cuando ejecutas el comando `pip install "fastapi[standard]"`.
 
 Sin embargo, si usas el comando `pip install fastapi`, el paquete `python-multipart` no se incluye por defecto.
 
-Para instalarlo manualmente, asegúrate de crear un [entorno virtual](../../virtual-environments.md){.internal-link target=_blank}, activarlo, y luego instalarlo con:
+Para instalarlo manualmente, asegúrate de crear un [entorno virtual](../../virtual-environments.md), activarlo, y luego instalarlo con:
 
 ```console
 $ pip install python-multipart
@@ -45,7 +45,7 @@ Ejecuta el ejemplo con:
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -54,7 +54,7 @@ $ fastapi dev main.py
 
 ## Revisa { #check-it }
 
-Ve a la documentación interactiva en: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ve a la documentación interactiva en: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 Verás algo así:
 
@@ -140,7 +140,7 @@ Aquí `tokenUrl="token"` se refiere a una URL relativa `token` que aún no hemos
 
 Porque estamos usando una URL relativa, si tu API estuviera ubicada en `https://example.com/`, entonces se referiría a `https://example.com/token`. Pero si tu API estuviera ubicada en `https://example.com/api/v1/`, entonces se referiría a `https://example.com/api/v1/token`.
 
-Usar una URL relativa es importante para asegurarse de que tu aplicación siga funcionando incluso en un caso de uso avanzado como [Detrás de un Proxy](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+Usar una URL relativa es importante para asegurarse de que tu aplicación siga funcionando incluso en un caso de uso avanzado como [Detrás de un Proxy](../../advanced/behind-a-proxy.md).
 
 ///
 
index e481fb6462cd01e7f2cba05ee15707d3c5b1973a..af1140d1bad5242ddbdc3a04ff4c05a413de7ff6 100644 (file)
@@ -24,13 +24,13 @@ De esta manera, puedes crear un token con una expiración de, digamos, 1 semana.
 
 Después de una semana, el token estará expirado y el usuario no estará autorizado y tendrá que iniciar sesión nuevamente para obtener un nuevo token. Y si el usuario (o un tercero) intenta modificar el token para cambiar la expiración, podrás descubrirlo, porque las firmas no coincidirían.
 
-Si quieres jugar con tokens JWT y ver cómo funcionan, revisa <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>.
+Si quieres jugar con tokens JWT y ver cómo funcionan, revisa [https://jwt.io](https://jwt.io/).
 
 ## Instalar `PyJWT` { #install-pyjwt }
 
 Necesitamos instalar `PyJWT` para generar y verificar los tokens JWT en Python.
 
-Asegúrate de crear un [entorno virtual](../../virtual-environments.md){.internal-link target=_blank}, activarlo y luego instalar `pyjwt`:
+Asegúrate de crear un [entorno virtual](../../virtual-environments.md), activarlo y luego instalar `pyjwt`:
 
 <div class="termy">
 
@@ -46,7 +46,7 @@ $ pip install pyjwt
 
 Si planeas usar algoritmos de firma digital como RSA o ECDSA, deberías instalar la dependencia del paquete de criptografía `pyjwt[crypto]`.
 
-Puedes leer más al respecto en la <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">documentación de instalación de PyJWT</a>.
+Puedes leer más al respecto en la [documentación de instalación de PyJWT](https://pyjwt.readthedocs.io/en/latest/installation.html).
 
 ///
 
@@ -72,7 +72,7 @@ Soporta muchos algoritmos de hashing seguros y utilidades para trabajar con ello
 
 El algoritmo recomendado es "Argon2".
 
-Asegúrate de crear un [entorno virtual](../../virtual-environments.md){.internal-link target=_blank}, activarlo y luego instalar pwdlib con Argon2:
+Asegúrate de crear un [entorno virtual](../../virtual-environments.md), activarlo y luego instalar pwdlib con Argon2:
 
 <div class="termy">
 
@@ -200,7 +200,7 @@ Lo importante a tener en cuenta es que la clave `sub` debería tener un identifi
 
 ## Revisa { #check-it }
 
-Ejecuta el servidor y ve a la documentación: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Ejecuta el servidor y ve a la documentación: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 Verás la interfaz de usuario como:
 
index ac3d9e297553cc37b01a6b321b34bc0e00e47102..15c7146bd7ea5cd5992f54699234242e32811fa3 100644 (file)
@@ -146,7 +146,7 @@ UserInDB(
 
 /// info | Información
 
-Para una explicación más completa de `**user_dict` revisa en [la documentación para **Extra Models**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}.
+Para una explicación más completa de `**user_dict` revisa en [la documentación para **Extra Models**](../extra-models.md#about-user-in-dict).
 
 ///
 
@@ -216,7 +216,7 @@ Ese es el beneficio de los estándares...
 
 ## Verlo en acción { #see-it-in-action }
 
-Abre la documentación interactiva: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Abre la documentación interactiva: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
 
 ### Autenticar { #authenticate }
 
index b57ebdbbe5a6d6a36e0f410ee79159a2406a72f5..7131716ee8668c3a56267c4dc19a914a877a01cc 100644 (file)
@@ -2,9 +2,9 @@
 
 **FastAPI** no requiere que uses una base de datos SQL (relacional). Pero puedes utilizar **cualquier base de datos** que desees.
 
-Aquí veremos un ejemplo usando <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a>.
+Aquí veremos un ejemplo usando [SQLModel](https://sqlmodel.tiangolo.com/).
 
-**SQLModel** está construido sobre <a href="https://www.sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a> y Pydantic. Fue creado por el mismo autor de **FastAPI** para ser la combinación perfecta para aplicaciones de FastAPI que necesiten usar **bases de datos SQL**.
+**SQLModel** está construido sobre [SQLAlchemy](https://www.sqlalchemy.org/) y Pydantic. Fue creado por el mismo autor de **FastAPI** para ser la combinación perfecta para aplicaciones de FastAPI que necesiten usar **bases de datos SQL**.
 
 /// tip | Consejo
 
@@ -26,15 +26,15 @@ Más adelante, para tu aplicación en producción, es posible que desees usar un
 
 /// tip | Consejo
 
-Hay un generador de proyectos oficial con **FastAPI** y **PostgreSQL** que incluye un frontend y más herramientas: <a href="https://github.com/fastapi/full-stack-fastapi-template" class="external-link" target="_blank">https://github.com/fastapi/full-stack-fastapi-template</a>
+Hay un generador de proyectos oficial con **FastAPI** y **PostgreSQL** que incluye un frontend y más herramientas: [https://github.com/fastapi/full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template)
 
 ///
 
-Este es un tutorial muy simple y corto, si deseas aprender sobre bases de datos en general, sobre SQL o más funcionalidades avanzadas, ve a la <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">documentación de SQLModel</a>.
+Este es un tutorial muy simple y corto, si deseas aprender sobre bases de datos en general, sobre SQL o más funcionalidades avanzadas, ve a la [documentación de SQLModel](https://sqlmodel.tiangolo.com/).
 
 ## Instalar `SQLModel` { #install-sqlmodel }
 
-Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo, y luego instala `sqlmodel`:
+Primero, asegúrate de crear tu [entorno virtual](../virtual-environments.md), actívalo, y luego instala `sqlmodel`:
 
 <div class="termy">
 
@@ -65,7 +65,7 @@ Hay algunas diferencias:
 
 * `Field(primary_key=True)` le dice a SQLModel que `id` es la **clave primaria** en la base de datos SQL (puedes aprender más sobre claves primarias de SQL en la documentación de SQLModel).
 
-    Nota: Usamos `int | None` para el campo de clave primaria para que en el código Python podamos *crear un objeto sin un `id`* (`id=None`), asumiendo que la base de datos lo *generará al guardar*. SQLModel entiende que la base de datos proporcionará el `id` y *define la columna como un `INTEGER` no nulo* en el esquema de la base de datos. Consulta la <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">documentación de SQLModel sobre claves primarias</a> para más detalles.
+    Nota: Usamos `int | None` para el campo de clave primaria para que en el código Python podamos *crear un objeto sin un `id`* (`id=None`), asumiendo que la base de datos lo *generará al guardar*. SQLModel entiende que la base de datos proporcionará el `id` y *define la columna como un `INTEGER` no nulo* en el esquema de la base de datos. Consulta la [documentación de SQLModel sobre claves primarias](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id) para más detalles.
 
 * `Field(index=True)` le dice a SQLModel que debe crear un **índice SQL** para esta columna, lo que permitirá búsquedas más rápidas en la base de datos cuando se lean datos filtrados por esta columna.
 
@@ -111,7 +111,7 @@ Para producción probablemente usarías un script de migración que se ejecuta a
 
 /// tip | Consejo
 
-SQLModel tendrá utilidades de migración envolviendo Alembic, pero por ahora, puedes usar <a href="https://alembic.sqlalchemy.org/en/latest/" class="external-link" target="_blank">Alembic</a> directamente.
+SQLModel tendrá utilidades de migración envolviendo Alembic, pero por ahora, puedes usar [Alembic](https://alembic.sqlalchemy.org/en/latest/) directamente.
 
 ///
 
@@ -152,7 +152,7 @@ Puedes ejecutar la aplicación:
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -337,7 +337,7 @@ Puedes ejecutar la aplicación de nuevo:
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
 <span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 ```
@@ -352,6 +352,6 @@ Si vas a la interfaz de `/docs` de la API, verás que ahora está actualizada, y
 
 ## Resumen { #recap }
 
-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 usar [**SQLModel**](https://sqlmodel.tiangolo.com/) 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 más largo sobre el uso de SQLModel con **FastAPI**</a>. 🚀
+Puedes aprender mucho más en la documentación de **SQLModel**, hay un mini [tutorial más largo sobre el uso de SQLModel con **FastAPI**](https://sqlmodel.tiangolo.com/tutorial/fastapi/). 🚀
index 84d2e94a97aac0380aadb349ae531b7bcf62e1df..b99ed5f9c4218e482a7c3a7e06bb70c4e41029c4 100644 (file)
@@ -23,7 +23,7 @@ También podrías usar `from starlette.staticfiles import StaticFiles`.
 
 Esto es diferente a usar un `APIRouter`, ya que una aplicación montada es completamente independiente. El OpenAPI y la documentación de tu aplicación principal no incluirán nada de la aplicación montada, etc.
 
-Puedes leer más sobre esto en la [Guía de Usuario Avanzada](../advanced/index.md){.internal-link target=_blank}.
+Puedes leer más sobre esto en la [Guía de Usuario Avanzada](../advanced/index.md).
 
 ## Detalles { #details }
 
@@ -37,4 +37,4 @@ Todos estos parámetros pueden ser diferentes a "`static`", ajústalos según la
 
 ## Más info { #more-info }
 
-Para más detalles y opciones revisa <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">la documentación de Starlette sobre Archivos Estáticos</a>.
+Para más detalles y opciones revisa [la documentación de Starlette sobre Archivos Estáticos](https://www.starlette.dev/staticfiles/).
index c477129035fef6f902a4f32f2f5662a5ae5ea9b1..a40d90c5ee8bb5ddd9b74222c09800848a3f53da 100644 (file)
@@ -1,18 +1,18 @@
 # Testing { #testing }
 
-Gracias a <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>, escribir pruebas para aplicaciones de **FastAPI** es fácil y agradable.
+Gracias a [Starlette](https://www.starlette.dev/testclient/), escribir pruebas para aplicaciones de **FastAPI** es fácil y agradable.
 
-Está basado en <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>, que a su vez está diseñado basado en Requests, por lo que es muy familiar e intuitivo.
+Está basado en [HTTPX](https://www.python-httpx.org), que a su vez está diseñado basado en Requests, por lo que es muy familiar e intuitivo.
 
-Con él, puedes usar <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a> directamente con **FastAPI**.
+Con él, puedes usar [pytest](https://docs.pytest.org/) directamente con **FastAPI**.
 
 ## Usando `TestClient` { #using-testclient }
 
 /// info | Información
 
-Para usar `TestClient`, primero instala <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>.
+Para usar `TestClient`, primero instala [`httpx`](https://www.python-httpx.org).
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo y luego instalarlo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo y luego instalarlo, por ejemplo:
 
 ```console
 $ pip install httpx
@@ -42,7 +42,7 @@ Esto te permite usar `pytest` directamente sin complicaciones.
 
 ///
 
-/// note | Nota Técnica
+/// note | Detalles técnicos
 
 También podrías usar `from starlette.testclient import TestClient`.
 
@@ -52,7 +52,7 @@ También podrías usar `from starlette.testclient import TestClient`.
 
 /// tip | Consejo
 
-Si quieres llamar a funciones `async` en tus pruebas además de enviar requests a tu aplicación FastAPI (por ejemplo, funciones asincrónicas de bases de datos), echa un vistazo a las [Pruebas Asincrónicas](../advanced/async-tests.md){.internal-link target=_blank} en el tutorial avanzado.
+Si quieres llamar a funciones `async` en tus pruebas además de enviar requests a tu aplicación FastAPI (por ejemplo, funciones asincrónicas de bases de datos), echa un vistazo a las [Pruebas Asincrónicas](../advanced/async-tests.md) en el tutorial avanzado.
 
 ///
 
@@ -64,7 +64,7 @@ Y tu aplicación de **FastAPI** también podría estar compuesta de varios archi
 
 ### Archivo de aplicación **FastAPI** { #fastapi-app-file }
 
-Digamos que tienes una estructura de archivos como se describe en [Aplicaciones Más Grandes](bigger-applications.md){.internal-link target=_blank}:
+Digamos que tienes una estructura de archivos como se describe en [Aplicaciones Más Grandes](bigger-applications.md):
 
 ```
 .
@@ -75,6 +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_py310/main.py *}
 
 ### Archivo de prueba { #testing-file }
@@ -139,13 +140,13 @@ Por ejemplo:
 * Para pasar *headers*, usa un `dict` en el parámetro `headers`.
 * Para *cookies*, un `dict` en el parámetro `cookies`.
 
-Para más información sobre cómo pasar datos al backend (usando `httpx` o el `TestClient`) revisa la <a href="https://www.python-httpx.org" class="external-link" target="_blank">documentación de HTTPX</a>.
+Para más información sobre cómo pasar datos al backend (usando `httpx` o el `TestClient`) revisa la [documentación de HTTPX](https://www.python-httpx.org).
 
 /// info | Información
 
 Ten en cuenta que el `TestClient` recibe datos que pueden ser convertidos a JSON, no modelos de Pydantic.
 
-Si tienes un modelo de Pydantic en tu prueba y quieres enviar sus datos a la aplicación durante las pruebas, puedes usar el `jsonable_encoder` descrito en [Codificador Compatible con JSON](encoder.md){.internal-link target=_blank}.
+Si tienes un modelo de Pydantic en tu prueba y quieres enviar sus datos a la aplicación durante las pruebas, puedes usar el `jsonable_encoder` descrito en [Codificador Compatible con JSON](encoder.md).
 
 ///
 
@@ -153,7 +154,7 @@ Si tienes un modelo de Pydantic en tu prueba y quieres enviar sus datos a la apl
 
 Después de eso, solo necesitas instalar `pytest`.
 
-Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, activarlo y luego instalarlo, por ejemplo:
+Asegúrate de crear un [entorno virtual](../virtual-environments.md), activarlo y luego instalarlo, por ejemplo:
 
 <div class="termy">
 
index f8839ac6c31b6cc2bb9b24cdc20478a162641377..682f9e947c96bbe073e5d0469c33a8196218f94f 100644 (file)
@@ -22,7 +22,7 @@ Un **entorno virtual** es un directorio con algunos archivos en él.
 
 Esta página te enseñará cómo usar **entornos virtuales** y cómo funcionan.
 
-Si estás listo para adoptar una **herramienta que gestiona todo** por ti (incluyendo la instalación de Python), prueba <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Si estás listo para adoptar una **herramienta que gestiona todo** por ti (incluyendo la instalación de Python), prueba [uv](https://github.com/astral-sh/uv).
 
 ///
 
@@ -86,7 +86,7 @@ $ python -m venv .venv
 
 //// tab | `uv`
 
-Si tienes instalado <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>, puedes usarlo para crear un entorno virtual.
+Si tienes instalado [`uv`](https://github.com/astral-sh/uv), puedes usarlo para crear un entorno virtual.
 
 <div class="termy">
 
@@ -150,7 +150,7 @@ $ .venv\Scripts\Activate.ps1
 
 //// tab | Windows Bash
 
-O si usas Bash para Windows (por ejemplo, <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
+O si usas Bash para Windows (por ejemplo, [Git Bash](https://gitforwindows.org/)):
 
 <div class="termy">
 
@@ -216,7 +216,7 @@ Si muestra el binario de `python` en `.venv\Scripts\python`, dentro de tu proyec
 
 /// tip | Consejo
 
-Si usas <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> usarías eso para instalar cosas en lugar de `pip`, por lo que no necesitas actualizar `pip`. 😎
+Si usas [`uv`](https://github.com/astral-sh/uv) usarías eso para instalar cosas en lugar de `pip`, por lo que no necesitas actualizar `pip`. 😎
 
 ///
 
@@ -268,7 +268,7 @@ Si estás usando **Git** (deberías), añade un archivo `.gitignore` para exclui
 
 /// tip | Consejo
 
-Si usaste <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> para crear el entorno virtual, ya lo hizo por ti, puedes saltarte este paso. 😎
+Si usaste [`uv`](https://github.com/astral-sh/uv) para crear el entorno virtual, ya lo hizo por ti, puedes saltarte este paso. 😎
 
 ///
 
@@ -340,7 +340,7 @@ $ pip install "fastapi[standard]"
 
 //// tab | `uv`
 
-Si tienes <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
+Si tienes [`uv`](https://github.com/astral-sh/uv):
 
 <div class="termy">
 
@@ -372,7 +372,7 @@ $ pip install -r requirements.txt
 
 //// tab | `uv`
 
-Si tienes <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
+Si tienes [`uv`](https://github.com/astral-sh/uv):
 
 <div class="termy">
 
@@ -416,8 +416,8 @@ Probablemente usarías un editor, asegúrate de configurarlo para que use el mis
 
 Por ejemplo:
 
-* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a>
-* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a>
+* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
+* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
 
 /// tip | Consejo
 
@@ -453,7 +453,7 @@ Continúa leyendo. 👇🤓
 
 ## Por qué Entornos Virtuales { #why-virtual-environments }
 
-Para trabajar con FastAPI necesitas instalar <a href="https://www.python.org/" class="external-link" target="_blank">Python</a>.
+Para trabajar con FastAPI necesitas instalar [Python](https://www.python.org/).
 
 Después de eso, necesitarías **instalar** FastAPI y cualquier otro **paquete** que desees usar.
 
@@ -562,7 +562,7 @@ $ pip install "fastapi[standard]"
 
 </div>
 
-Eso descargará un archivo comprimido con el código de FastAPI, normalmente desde <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a>.
+Eso descargará un archivo comprimido con el código de FastAPI, normalmente desde [PyPI](https://pypi.org/project/fastapi/).
 
 También **descargará** archivos para otros paquetes de los que depende FastAPI.
 
@@ -625,7 +625,7 @@ $ .venv\Scripts\Activate.ps1
 
 //// tab | Windows Bash
 
-O si usas Bash para Windows (por ejemplo, <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
+O si usas Bash para Windows (por ejemplo, [Git Bash](https://gitforwindows.org/)):
 
 <div class="termy">
 
@@ -637,13 +637,13 @@ $ source .venv/Scripts/activate
 
 ////
 
-Ese comando creará o modificará algunas [variables de entorno](environment-variables.md){.internal-link target=_blank} que estarán disponibles para los siguientes comandos.
+Ese comando creará o modificará algunas [variables de entorno](environment-variables.md) que estarán disponibles para los siguientes comandos.
 
 Una de esas variables es la variable `PATH`.
 
 /// tip | Consejo
 
-Puedes aprender más sobre la variable de entorno `PATH` en la sección [Variables de Entorno](environment-variables.md#path-environment-variable){.internal-link target=_blank}.
+Puedes aprender más sobre la variable de entorno `PATH` en la sección [Variables de Entorno](environment-variables.md#path-environment-variable).
 
 ///
 
@@ -844,7 +844,7 @@ Esta es una guía simple para comenzar y enseñarte cómo funciona todo **por de
 
 Hay muchas **alternativas** para gestionar entornos virtuales, dependencias de paquetes (requisitos), proyectos.
 
-Una vez que estés listo y quieras usar una herramienta para **gestionar todo el proyecto**, dependencias de paquetes, entornos virtuales, etc. Te sugeriría probar <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Una vez que estés listo y quieras usar una herramienta para **gestionar todo el proyecto**, dependencias de paquetes, entornos virtuales, etc. Te sugeriría probar [uv](https://github.com/astral-sh/uv).
 
 `uv` puede hacer muchas cosas, puede: