From 495460d3edfe195602f9bd179642c1bf6046f071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 30 Dec 2024 17:46:44 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Update=20existing=20Spanish=20tr?= =?UTF-8?q?anslations=20using=20the=20new=20LLM-assisted=20system=20using?= =?UTF-8?q?=20PydanticAI=20(#13118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> --- .../docs/advanced/additional-status-codes.md | 30 +- docs/es/docs/advanced/index.md | 31 +- .../path-operation-advanced-configuration.md | 185 ++++++- .../advanced/response-change-status-code.md | 28 +- docs/es/docs/advanced/response-directly.md | 50 +- docs/es/docs/advanced/response-headers.md | 36 +- docs/es/docs/advanced/security/index.md | 14 +- docs/es/docs/async.md | 315 +++++------ docs/es/docs/benchmarks.md | 35 +- docs/es/docs/deployment/index.md | 22 +- docs/es/docs/deployment/versions.md | 68 +-- docs/es/docs/features.md | 166 +++--- docs/es/docs/how-to/graphql.md | 38 +- docs/es/docs/index.md | 323 ++++++----- docs/es/docs/learn/index.md | 4 +- docs/es/docs/project-generation.md | 28 +- docs/es/docs/python-types.md | 500 ++++++++++++++---- docs/es/docs/tutorial/cookie-params.md | 12 +- docs/es/docs/tutorial/first-steps.md | 248 +++++---- docs/es/docs/tutorial/index.md | 99 ++-- docs/es/docs/tutorial/path-params.md | 170 +++--- docs/es/docs/tutorial/query-params.md | 106 ++-- 22 files changed, 1513 insertions(+), 995 deletions(-) diff --git a/docs/es/docs/advanced/additional-status-codes.md b/docs/es/docs/advanced/additional-status-codes.md index b72798c2b..df7737aac 100644 --- a/docs/es/docs/advanced/additional-status-codes.md +++ b/docs/es/docs/advanced/additional-status-codes.md @@ -1,41 +1,41 @@ -# Códigos de estado adicionales +# Códigos de Estado Adicionales -Por defecto, **FastAPI** devolverá las respuestas utilizando una `JSONResponse`, poniendo el contenido que devuelves en tu *operación de path* dentro de esa `JSONResponse`. +Por defecto, **FastAPI** devolverá los responses usando un `JSONResponse`, colocando el contenido que devuelves desde tu *path operation* dentro de ese `JSONResponse`. -Utilizará el código de estado por defecto, o el que hayas asignado en tu *operación de path*. +Usará el código de estado por defecto o el que configures en tu *path operation*. ## Códigos de estado adicionales -Si quieres devolver códigos de estado adicionales además del principal, puedes hacerlo devolviendo directamente una `Response`, como una `JSONResponse`, y asignar directamente el código de estado adicional. +Si quieres devolver códigos de estado adicionales aparte del principal, puedes hacerlo devolviendo un `Response` directamente, como un `JSONResponse`, y configurando el código de estado adicional directamente. -Por ejemplo, digamos que quieres tener una *operación de path* que permita actualizar ítems y devolver códigos de estado HTTP 200 "OK" cuando sea exitosa. +Por ejemplo, supongamos que quieres tener una *path operation* que permita actualizar elementos, y devuelva códigos de estado HTTP de 200 "OK" cuando sea exitoso. -Pero también quieres que acepte nuevos ítems. Cuando los ítems no existan anteriormente, serán creados y devolverá un código de estado HTTP 201 "Created". +Pero también quieres que acepte nuevos elementos. Y cuando los elementos no existían antes, los crea y devuelve un código de estado HTTP de 201 "Created". -Para conseguir esto importa `JSONResponse` y devuelve ahí directamente tu contenido, asignando el `status_code` que quieras: +Para lograr eso, importa `JSONResponse`, y devuelve tu contenido allí directamente, configurando el `status_code` que deseas: -{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *} +{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *} /// warning | Advertencia -Cuando devuelves directamente una `Response`, como en los ejemplos anteriores, será devuelta directamente. +Cuando devuelves un `Response` directamente, como en el ejemplo anterior, se devuelve directamente. -No será serializado con el modelo, etc. +No se serializará con un modelo, etc. -Asegúrate de que la respuesta tenga los datos que quieras, y que los valores sean JSON válidos (si estás usando `JSONResponse`). +Asegúrate de que tenga los datos que deseas que tenga y que los valores sean JSON válidos (si estás usando `JSONResponse`). /// /// note | Detalles Técnicos -También podrías utilizar `from starlette.responses import JSONResponse`. +También podrías usar `from starlette.responses import JSONResponse`. -**FastAPI** provee las mismas `starlette.responses` que `fastapi.responses` simplemente como una convención para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette. Lo mismo con `status`. +**FastAPI** proporciona los mismos `starlette.responses` que `fastapi.responses` solo como una conveniencia para ti, el desarrollador. Pero la mayoría de los responses disponibles provienen directamente de Starlette. Lo mismo con `status`. /// ## OpenAPI y documentación de API -Si quieres devolver códigos de estado y respuestas adicionales directamente, estas no estarán incluidas en el schema de OpenAPI (documentación de API), porque FastAPI no tiene una manera de conocer de antemano lo que vas a devolver. +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 documentar eso en tu código usando [Respuestas Adicionales](additional-responses.md){.internal-link target=_blank}. +Pero puedes documentarlo en tu código, usando: [Responses Adicionales](additional-responses.md){.internal-link target=_blank}. diff --git a/docs/es/docs/advanced/index.md b/docs/es/docs/advanced/index.md index 10a1ff0d5..0626a1563 100644 --- a/docs/es/docs/advanced/index.md +++ b/docs/es/docs/advanced/index.md @@ -1,21 +1,36 @@ -# Guía de Usuario Avanzada +# Guía avanzada del usuario -## Características Adicionales +## Funcionalidades adicionales -El [Tutorial - Guía de Usuario](../tutorial/index.md){.internal-link target=_blank} principal debe ser suficiente para darte un paseo por todas las características principales de **FastAPI** +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**. -En las secciones siguientes verás otras opciones, configuraciones, y características adicionales. +En las siguientes secciones verás otras opciones, configuraciones y funcionalidades adicionales. /// tip | Consejo -Las próximas secciones **no son necesariamente "avanzadas"**. +Las siguientes secciones **no son necesariamente "avanzadas"**. -Y es posible que para tu caso, la solución se encuentre en una de estas. +Y es posible que para tu caso de uso, la solución esté en una de ellas. /// ## Lee primero el Tutorial -Puedes continuar usando la mayoría de las características de **FastAPI** con el conocimiento del [Tutorial - Guía de 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){.internal-link target=_blank} principal. -En las siguientes secciones se asume que lo has leído y conoces esas ideas principales. +Y las siguientes secciones asumen que ya lo leíste y que conoces esas ideas principales. + +## Cursos externos + +Aunque el [Tutorial - Guía del usuario](../tutorial/index.md){.internal-link target=_blank} y esta **Guía avanzada del usuario** están escritos como un tutorial guiado (como un libro) y deberían ser suficientes para que **aprendas FastAPI**, podrías querer complementarlo con cursos adicionales. + +O podría ser que simplemente prefieras tomar otros cursos porque se adaptan mejor a tu estilo de aprendizaje. + +Algunos proveedores de cursos ✨ [**sponsorean FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, esto asegura el desarrollo continuo y saludable de FastAPI y su **ecosistema**. + +Y muestra su verdadero compromiso con FastAPI y su **comunidad** (tú), ya que no solo quieren brindarte una **buena experiencia de aprendizaje** sino que también quieren asegurarse de que tengas un **buen y saludable framework**, FastAPI. 🙇 + +Podrías querer probar sus cursos: + +* Talk Python Training +* Desarrollo guiado por pruebas diff --git a/docs/es/docs/advanced/path-operation-advanced-configuration.md b/docs/es/docs/advanced/path-operation-advanced-configuration.md index 600e2e074..2b20819aa 100644 --- a/docs/es/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/es/docs/advanced/path-operation-advanced-configuration.md @@ -1,53 +1,204 @@ -# Configuración avanzada de las operaciones de path +# Configuración Avanzada de Path Operation -## OpenAPI operationId +## operationId de OpenAPI /// warning | Advertencia -Si no eres una persona "experta" en OpenAPI, probablemente no necesitas leer esto. +Si no eres un "experto" en OpenAPI, probablemente no necesites esto. /// -Puedes asignar el `operationId` de OpenAPI para ser usado en tu *operación de path* con el parámetro `operation_id`. +Puedes establecer el `operationId` de OpenAPI para ser usado en tu *path operation* con el parámetro `operation_id`. -En este caso tendrías que asegurarte de que sea único para cada operación. +Tienes que asegurarte de que sea único para cada operación. {* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *} -### Usando el nombre de la *función de la operación de path* en el operationId +### Usar el nombre de la *función de path operation* como el operationId -Si quieres usar tus nombres de funciones de API como `operationId`s, puedes iterar sobre todos ellos y sobrescribir `operation_id` de cada *operación de path* usando su `APIRoute.name`. +Si quieres usar los nombres de las funciones de tus APIs como `operationId`s, puedes iterar sobre todas ellas y sobrescribir el `operation_id` de cada *path operation* usando su `APIRoute.name`. -Deberías hacerlo después de adicionar todas tus *operaciones de path*. +Deberías hacerlo después de agregar todas tus *path operations*. -{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12,13,14,15,16,17,18,19,20,21,24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *} /// tip | Consejo -Si llamas manualmente a `app.openapi()`, debes actualizar el `operationId`s antes de hacerlo. +Si llamas manualmente a `app.openapi()`, deberías actualizar los `operationId`s antes de eso. /// /// warning | Advertencia -Si haces esto, debes asegurarte de que cada una de tus *funciones de las operaciones de path* tenga un nombre único. +Si haces esto, tienes que asegurarte de que cada una de tus *funciones de path operation* tenga un nombre único. -Incluso si están en diferentes módulos (archivos Python). +Incluso si están en diferentes módulos (archivos de Python). /// ## Excluir de OpenAPI -Para excluir una *operación de path* del esquema OpenAPI generado (y por tanto del la documentación generada automáticamente), usa el parámetro `include_in_schema` y asigna el valor como `False`; +Para excluir una *path operation* del esquema OpenAPI generado (y por lo tanto, de los sistemas de documentación automática), utiliza el parámetro `include_in_schema` y configúralo en `False`: {* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *} ## Descripción avanzada desde el docstring -Puedes limitar las líneas usadas desde el docstring de una *operación de path* para OpenAPI. +Puedes limitar las líneas usadas del docstring de una *función de path operation* para OpenAPI. -Agregar un `\f` (un carácter de "form feed" escapado) hace que **FastAPI** trunque el output utilizada para OpenAPI en ese punto. +Añadir un `\f` (un carácter de separación de página escapado) hace que **FastAPI** trunque la salida usada para OpenAPI en este punto. -No será mostrado en la documentación, pero otras herramientas (como Sphinx) serán capaces de usar el resto. +No aparecerá en la documentación, pero otras herramientas (como Sphinx) podrán usar el resto. -{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19,20,21,22,23,24,25,26,27,28,29] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *} + +## Responses Adicionales + +Probablemente has visto cómo declarar el `response_model` y el `status_code` para una *path operation*. + +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}. + +## OpenAPI Extra + +Cuando declaras una *path operation* en tu aplicación, **FastAPI** genera automáticamente los metadatos relevantes sobre esa *path operation* para incluirlos en el esquema de OpenAPI. + +/// note | Nota + +En la especificación de OpenAPI se llama el Objeto de Operación. + +/// + +Tiene toda la información sobre la *path operation* y se usa para generar la documentación automática. + +Incluye los `tags`, `parameters`, `requestBody`, `responses`, etc. + +Este esquema de OpenAPI específico de *path operation* normalmente se genera automáticamente por **FastAPI**, pero también puedes extenderlo. + +/// tip | Consejo + +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}. + +/// + +Puedes extender el esquema de OpenAPI para una *path operation* usando el parámetro `openapi_extra`. + +### Extensiones de OpenAPI + +Este `openapi_extra` puede ser útil, por ejemplo, para declarar [Extensiones de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions): + +{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *} + +Si abres la documentación automática de la API, tu extensión aparecerá en la parte inferior de la *path operation* específica. + + + +Y si ves el OpenAPI resultante (en `/openapi.json` en tu API), verás tu extensión como parte de la *path operation* específica también: + +```JSON hl_lines="22" +{ + "openapi": "3.1.0", + "info": { + "title": "FastAPI", + "version": "0.1.0" + }, + "paths": { + "/items/": { + "get": { + "summary": "Read Items", + "operationId": "read_items_items__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "x-aperture-labs-portal": "blue" + } + } + } +} +``` + +### Esquema de *path operation* personalizada de OpenAPI + +El diccionario en `openapi_extra` se combinará profundamente con el esquema de OpenAPI generado automáticamente para la *path operation*. + +Por lo tanto, podrías añadir datos adicionales al esquema generado automáticamente. + +Por ejemplo, podrías decidir leer y validar el request con tu propio código, sin usar las funcionalidades automáticas de FastAPI con Pydantic, pero aún podrías querer definir el request en el esquema de OpenAPI. + +Podrías hacer eso con `openapi_extra`: + +{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *} + +En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el cuerpo del request ni siquiera se parse como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera. + +Sin embargo, podemos declarar el esquema esperado para el cuerpo del request. + +### Tipo de contenido personalizado de OpenAPI + +Usando este mismo truco, podrías usar un modelo Pydantic para definir el esquema JSON que luego se incluye en la sección personalizada del esquema OpenAPI para la *path operation*. + +Y podrías hacer esto incluso si el tipo de datos en el request no es JSON. + +Por ejemplo, en esta aplicación no usamos la funcionalidad integrada de FastAPI para extraer el esquema JSON de los modelos Pydantic ni la validación automática para JSON. De hecho, estamos declarando el tipo de contenido del request como YAML, no JSON: + +//// tab | Pydantic v2 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *} + +//// + +//// tab | Pydantic v1 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *} + +//// + +/// info | Información + +En la versión 1 de Pydantic el método para obtener el esquema JSON para un modelo se llamaba `Item.schema()`, en la versión 2 de Pydantic, el método se llama `Item.model_json_schema()`. + +/// + +Sin embargo, aunque no estamos usando la funcionalidad integrada por defecto, aún estamos usando un modelo Pydantic para generar manualmente el esquema JSON 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. + +Y luego en nuestro código, parseamos ese contenido YAML directamente, y nuevamente estamos usando el mismo modelo Pydantic para validar el contenido YAML: + +//// tab | Pydantic v2 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *} + +//// + +//// tab | Pydantic v1 + +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *} + +//// + +/// info | Información + +En la versión 1 de Pydantic el método para parsear y validar un objeto era `Item.parse_obj()`, en la versión 2 de Pydantic, el método se llama `Item.model_validate()`. + +/// + +/// tip | Consejo + +Aquí reutilizamos el mismo modelo Pydantic. + +Pero de la misma manera, podríamos haberlo validado de alguna otra forma. + +/// diff --git a/docs/es/docs/advanced/response-change-status-code.md b/docs/es/docs/advanced/response-change-status-code.md index 6a44ea94e..e0889c474 100644 --- a/docs/es/docs/advanced/response-change-status-code.md +++ b/docs/es/docs/advanced/response-change-status-code.md @@ -1,31 +1,31 @@ -# Response - Cambiar el Status Code +# Response - Cambiar Código de Estado -Probablemente ya has leído con anterioridad que puedes establecer un [Response Status Code](../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){.internal-link target=_blank} por defecto. -Pero en algunos casos necesitas retornar un status code diferente al predeterminado. +Pero en algunos casos necesitas devolver un código de estado diferente al predeterminado. -## Casos de uso +## Caso de uso -Por ejemplo, imagina que quieres retornar un HTTP status code de "OK" `200` por defecto. +Por ejemplo, imagina que quieres devolver un código de estado HTTP de "OK" `200` por defecto. -Pero si los datos no existen, quieres crearlos y retornar un HTTP status code de "CREATED" `201`. +Pero si los datos no existieran, quieres crearlos y devolver un código de estado HTTP de "CREATED" `201`. -Pero aún quieres poder filtrar y convertir los datos que retornas con un `response_model`. +Pero todavía quieres poder filtrar y convertir los datos que devuelves con un `response_model`. Para esos casos, puedes usar un parámetro `Response`. -## Usar un parámetro `Response` +## Usa un parámetro `Response` -Puedes declarar un parámetro de tipo `Response` en tu *función de la operación de path* (como puedes hacer para cookies y headers). +Puedes declarar un parámetro de tipo `Response` en tu *función de path operation* (como puedes hacer para cookies y headers). -Y luego puedes establecer el `status_code` en ese objeto de respuesta *temporal*. +Y luego puedes establecer el `status_code` en ese objeto de response *temporal*. {* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *} -Y luego puedes retornar cualquier objeto que necesites, como normalmente lo harías (un `dict`, un modelo de base de datos, etc). +Y luego puedes devolver cualquier objeto que necesites, como lo harías normalmente (un `dict`, un modelo de base de datos, etc.). -Y si declaraste un `response_model`, aún se usará para filtrar y convertir el objeto que retornaste. +Y si declaraste un `response_model`, todavía se utilizará para filtrar y convertir el objeto que devolviste. -**FastAPI** usará esa respuesta *temporal* para extraer el código de estado (también cookies y headers), y los pondrá en la respuesta final que contiene el valor que retornaste, filtrado por cualquier `response_model`. +**FastAPI** usará ese response *temporal* para extraer el código de estado (también cookies y headers), y los pondrá en el response final que contiene el valor que devolviste, filtrado por cualquier `response_model`. -También puedes declarar la dependencia del parámetro `Response`, y establecer el código de estado en ellos. Pero ten en cuenta que el último en establecerse será el que gane. +También puedes declarar el parámetro `Response` en dependencias y establecer el código de estado en ellas. Pero ten en cuenta que el último establecido prevalecerá. diff --git a/docs/es/docs/advanced/response-directly.md b/docs/es/docs/advanced/response-directly.md index 3cab11d99..8594011d6 100644 --- a/docs/es/docs/advanced/response-directly.md +++ b/docs/es/docs/advanced/response-directly.md @@ -1,18 +1,18 @@ -# Devolver una respuesta directamente +# Devolver una Response Directamente -Cuando creas una *operación de path* normalmente puedes devolver cualquier dato: un `dict`, una `list`, un modelo Pydantic, un modelo de base de datos, etc. +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 devuelto a JSON usando el `jsonable_encoder` explicado en [Codificador Compatible JSON](../tutorial/encoder.md){.internal-link target=_blank}. +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}. -Luego, tras bastidores, pondría esos datos compatibles con JSON (por ejemplo, un `dict`) dentro de una `JSONResponse` que se usaría para enviar la respuesta al cliente. +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. -Pero puedes devolver una `JSONResponse` directamente de tu *operación de path*. +Pero puedes devolver un `JSONResponse` directamente desde tus *path operations*. -Esto puede ser útil, por ejemplo, para devolver cookies o headers personalizados. +Esto podría ser útil, por ejemplo, para devolver headers o cookies personalizados. ## Devolver una `Response` -De hecho, puedes devolver cualquier `Response` o cualquier subclase de la misma. +De hecho, puedes devolver cualquier `Response` o cualquier subclase de ella. /// tip | Consejo @@ -22,44 +22,44 @@ De hecho, puedes devolver cualquier `Response` o cualquier subclase de la misma. Y cuando devuelves una `Response`, **FastAPI** la pasará directamente. -No hará ninguna conversión de datos con modelos Pydantic, no convertirá el contenido a ningún tipo, etc. +No hará ninguna conversión de datos con los modelos de Pydantic, no convertirá los contenidos a ningún tipo, etc. -Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de dato, sobrescribir cualquier declaración de datos o validación, etc. +Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de datos, sobrescribir cualquier declaración o validación de datos, etc. -## Usando el `jsonable_encoder` en una `Response` +## Usar el `jsonable_encoder` en una `Response` -Como **FastAPI** no realiza ningún cambio en la `Response` que devuelves, debes asegurarte de que el contenido está listo. +Como **FastAPI** no realiza cambios en una `Response` que devuelves, tienes que asegurarte de que sus contenidos estén listos para ello. -Por ejemplo, no puedes poner un modelo Pydantic en una `JSONResponse` sin primero convertirlo a un `dict` con todos los tipos de datos (como `datetime`, `UUID`, etc) convertidos a tipos compatibles con JSON. +Por ejemplo, no puedes poner un modelo de Pydantic en un `JSONResponse` sin primero convertirlo a un `dict` con todos los tipos de datos (como `datetime`, `UUID`, etc.) convertidos a tipos compatibles con JSON. -Para esos casos, puedes usar el `jsonable_encoder` para convertir tus datos antes de pasarlos a la respuesta: +Para esos casos, puedes usar el `jsonable_encoder` para convertir tus datos antes de pasarlos a un response: -{* ../../docs_src/response_directly/tutorial001.py hl[4,6,20,21] *} +{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *} -/// note | Detalles Técnicos +/// note | Nota -También puedes usar `from starlette.responses import JSONResponse`. +También podrías usar `from starlette.responses import JSONResponse`. -**FastAPI** provee `starlette.responses` como `fastapi.responses`, simplemente como una conveniencia para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette. +**FastAPI** proporciona los mismos `starlette.responses` como `fastapi.responses` solo como una conveniencia para ti, el desarrollador. Pero la mayoría de los responses disponibles vienen directamente de Starlette. /// -## Devolviendo una `Response` personalizada +## Devolver una `Response` personalizada -El ejemplo anterior muestra las partes que necesitas, pero no es muy útil todavía, dado que podrías simplemente devolver el `item` directamente, y **FastAPI** lo pondría en una `JSONResponse` por ti, convirtiéndolo en un `dict`, etc. Todo esto por defecto. +El ejemplo anterior muestra todas las partes que necesitas, pero aún no es muy útil, ya que podrías haber devuelto el `item` directamente, y **FastAPI** lo colocaría en un `JSONResponse` por ti, convirtiéndolo a un `dict`, etc. Todo eso por defecto. -Ahora, veamos cómo puedes usarlo para devolver una respuesta personalizada. +Ahora, veamos cómo podrías usar eso para devolver un response personalizado. -Digamos que quieres devolver una respuesta XML. +Digamos que quieres devolver un response en XML. -Podrías poner tu contenido XML en un string, ponerlo en una `Response` y devolverlo: +Podrías poner tu contenido XML en un string, poner eso en un `Response`, y devolverlo: {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} ## Notas -Cuando devuelves una `Response` directamente, los datos no son validados, convertidos (serializados), ni documentados automáticamente. +Cuando devuelves una `Response` directamente, sus datos no son validados, convertidos (serializados), ni documentados automáticamente. -Pero todavía es posible documentarlo como es descrito en [Respuestas adicionales en OpenAPI](additional-responses.md){.internal-link target=_blank}. +Pero aún puedes documentarlo como se describe en [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}. -Puedes ver en secciones posteriores como usar/declarar esas `Response`s personalizadas aún teniendo conversión automática de datos, documentación, etc. +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. diff --git a/docs/es/docs/advanced/response-headers.md b/docs/es/docs/advanced/response-headers.md index a7a506142..49eaa53c1 100644 --- a/docs/es/docs/advanced/response-headers.md +++ b/docs/es/docs/advanced/response-headers.md @@ -1,43 +1,41 @@ -# Headers de Respuesta +# Response Headers -## Usar un parámetro `Response` +## Usa un parámetro `Response` -Puedes declarar un parámetro de tipo `Response` en tu *función de operación de path* (de manera similar como se hace con las cookies). +Puedes declarar un parámetro de tipo `Response` en tu *función de path operation* (como puedes hacer para cookies). -Y entonces, podrás configurar las cookies en ese objeto de response *temporal*. +Y luego puedes establecer headers en ese objeto de response *temporal*. -{* ../../docs_src/response_headers/tutorial002.py hl[1,7:8] *} +{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *} -Posteriormente, puedes devolver cualquier objeto que necesites, como normalmente harías (un `dict`, un modelo de base de datos, etc). +Y luego puedes devolver cualquier objeto que necesites, como harías normalmente (un `dict`, un modelo de base de datos, etc). -Si declaraste un `response_model`, este se continuará usando para filtrar y convertir el objeto que devolviste. +Y si declaraste un `response_model`, aún se usará para filtrar y convertir el objeto que devolviste. -**FastAPI** usará ese response *temporal* para extraer los headers (al igual que las cookies y el status code), además las pondrá en el response final que contendrá el valor retornado y filtrado por algún `response_model`. +**FastAPI** usará ese response *temporal* para extraer los headers (también cookies y el código de estado), y los pondrá en el response final que contiene el valor que devolviste, filtrado por cualquier `response_model`. -También puedes declarar el parámetro `Response` en dependencias, así como configurar los headers (y las cookies) en ellas. +También puedes declarar el parámetro `Response` en dependencias y establecer headers (y cookies) en ellas. +## Retorna una `Response` directamente -## Retornar una `Response` directamente +También puedes agregar headers cuando devuelves un `Response` directamente. -Adicionalmente, puedes añadir headers cuando se retorne una `Response` directamente. - -Crea un response tal como se describe en [Retornar una respuesta 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){.internal-link target=_blank} y pasa los headers como un parámetro adicional: {* ../../docs_src/response_headers/tutorial001.py hl[10:12] *} /// note | Detalles Técnicos -También podrías utilizar `from starlette.responses import Response` o `from starlette.responses import JSONResponse`. - -**FastAPI** proporciona las mismas `starlette.responses` en `fastapi.responses` sólo que de una manera más conveniente para ti, el desarrollador. En otras palabras, muchas de las responses disponibles provienen directamente de Starlette. +También podrías usar `from starlette.responses import Response` o `from starlette.responses import JSONResponse`. +**FastAPI** proporciona las mismas `starlette.responses` como `fastapi.responses` solo por conveniencia para ti, el desarrollador. Pero la mayoría de los responses disponibles provienen directamente de Starlette. -Y como la `Response` puede ser usada frecuentemente para configurar headers y cookies, **FastAPI** también la provee en `fastapi.Response`. +Y como el `Response` se puede usar frecuentemente para establecer headers y cookies, **FastAPI** también lo proporciona en `fastapi.Response`. /// ## Headers Personalizados -Ten en cuenta que se pueden añadir headers propietarios personalizados usando el prefijo 'X-'. +Ten en cuenta que los headers propietarios personalizados se pueden agregar usando el prefijo 'X-'. -Si tienes headers personalizados y deseas que un cliente pueda verlos en el navegador, es necesario que los añadas a tus configuraciones de CORS (puedes leer más en [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), usando el parámetro `expose_headers` documentado en Starlette's CORS docs. +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 la documentación CORS de Starlette. diff --git a/docs/es/docs/advanced/security/index.md b/docs/es/docs/advanced/security/index.md index 92de67d6a..e4ccb5978 100644 --- a/docs/es/docs/advanced/security/index.md +++ b/docs/es/docs/advanced/security/index.md @@ -1,19 +1,19 @@ # Seguridad Avanzada -## Características Adicionales +## Funcionalidades Adicionales -Hay algunas características adicionales para manejar la seguridad además de las que se tratan en el [Tutorial - Guía de 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){.internal-link target=_blank}. /// tip | Consejo -Las siguientes secciones **no necesariamente son "avanzadas"**. +Las siguientes secciones **no son necesariamente "avanzadas"**. -Y es posible que para tu caso de uso, la solución esté en alguna de ellas. +Y es posible que para tu caso de uso, la solución esté en una de ellas. /// -## Leer primero el Tutorial +## Lee primero el Tutorial -En las siguientes secciones asumimos que ya has leído el principal [Tutorial - Guía de Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank}. +Las siguientes secciones asumen que ya leíste el [Tutorial - Guía del Usuario: Seguridad](../../tutorial/security/index.md){.internal-link target=_blank}. -Están basadas en los mismos conceptos, pero permiten algunas funcionalidades adicionales. +Todas están basadas en los mismos conceptos, pero permiten algunas funcionalidades adicionales. diff --git a/docs/es/docs/async.md b/docs/es/docs/async.md index 5ab2ff9a4..a5c272fb3 100644 --- a/docs/es/docs/async.md +++ b/docs/es/docs/async.md @@ -1,18 +1,18 @@ # Concurrencia y async / await -Detalles sobre la sintaxis `async def` para *path operation functions* y un poco de información sobre código asíncrono, concurrencia y paralelismo. +Detalles sobre la sintaxis `async def` para *path operation functions* y algunos antecedentes sobre el código asíncrono, la concurrencia y el paralelismo. -## ¿Tienes prisa? +## ¿Con prisa? TL;DR: -Si estás utilizando libraries de terceros que te dicen que las llames con `await`, del tipo: +Si estás usando paquetes de terceros que te dicen que los llames con `await`, como: ```Python results = await some_library() ``` -Entonces declara tus *path operation functions* con `async def` de la siguiente manera: +Entonces, declara tus *path operation functions* con `async def` así: ```Python hl_lines="2" @app.get('/') @@ -29,7 +29,7 @@ Solo puedes usar `await` dentro de funciones creadas con `async def`. --- -Si estás utilizando libraries de terceros que se comunican con algo (una base de datos, una API, el sistema de archivos, etc.) y no tienes soporte para `await` (este es el caso para la mayoría de las libraries de bases de datos), declara tus *path operation functions* de forma habitual, con solo `def`, de la siguiente manera: +Si estás usando un paquete de terceros que se comunica con algo (una base de datos, una API, el sistema de archivos, etc.) y no tiene soporte para usar `await` (este es actualmente el caso para la mayoría de los paquetes de base de datos), entonces declara tus *path operation functions* como normalmente, usando simplemente `def`, así: ```Python hl_lines="2" @app.get('/') @@ -40,7 +40,7 @@ def results(): --- -Si tu aplicación (de alguna manera) no tiene que comunicarse con nada más y en consecuencia esperar a que responda, usa `async def`. +Si tu aplicación (de alguna manera) no tiene que comunicarse con nada más y esperar a que responda, usa `async def`. --- @@ -48,17 +48,17 @@ Si simplemente no lo sabes, usa `def` normal. --- -**Nota**: puedes mezclar `def` y `async def` en tus *path operation functions* tanto como lo necesites y definir cada una utilizando la mejor opción para ti. FastAPI hará lo correcto con ellos. +**Nota**: Puedes mezclar `def` y `async def` en tus *path operation functions* tanto como necesites y definir cada una utilizando la mejor opción para ti. FastAPI hará lo correcto con ellas. De todos modos, en cualquiera de los casos anteriores, FastAPI seguirá funcionando de forma asíncrona y será extremadamente rápido. -Pero siguiendo los pasos anteriores, FastAPI podrá hacer algunas optimizaciones de rendimiento. +Pero al seguir los pasos anteriores, podrá hacer algunas optimizaciones de rendimiento. ## Detalles Técnicos -Las versiones modernas de Python tienen soporte para **"código asíncrono"** usando algo llamado **"coroutines"**, usando la sintaxis **`async` y `await`**. +Las versiones modernas de Python tienen soporte para **"código asíncrono"** utilizando algo llamado **"coroutines"**, con la sintaxis **`async` y `await`**. -Veamos esa frase por partes en las secciones siguientes: +Veamos esa frase por partes en las secciones a continuación: * **Código Asíncrono** * **`async` y `await`** @@ -66,203 +66,200 @@ Veamos esa frase por partes en las secciones siguientes: ## Código Asíncrono -El código asíncrono sólo significa que el lenguaje 💬 tiene una manera de decirle al sistema / programa 🤖 que, en algún momento del código, 🤖 tendrá que esperar a que *algo más* termine en otro sitio. Digamos que ese *algo más* se llama, por ejemplo, "archivo lento" 📝. +El código asíncrono simplemente significa que el lenguaje 💬 tiene una forma de decirle a la computadora / programa 🤖 que en algún momento del código, tendrá que esperar que *otra cosa* termine en otro lugar. Digamos que esa *otra cosa* se llama "archivo-lento" 📝. -Durante ese tiempo, el sistema puede hacer otras cosas, mientras "archivo lento" 📝 termina. +Entonces, durante ese tiempo, la computadora puede ir y hacer algún otro trabajo, mientras "archivo-lento" 📝 termina. -Entonces el sistema / programa 🤖 volverá cada vez que pueda, sea porque está esperando otra vez, porque 🤖 ha terminado todo el trabajo que tenía en ese momento. Y 🤖 verá si alguna de las tareas por las que estaba esperando ha terminado, haciendo lo que tenía que hacer. +Luego la computadora / programa 🤖 volverá cada vez que tenga una oportunidad porque está esperando nuevamente, o siempre que 🤖 haya terminado todo el trabajo que tenía en ese punto. Y 🤖 comprobará si alguna de las tareas que estaba esperando ya se han completado, haciendo lo que tenía que hacer. -Luego, 🤖 cogerá la primera tarea finalizada (digamos, nuestro "archivo lento" 📝) y continuará con lo que tenía que hacer con esa tarea. +Después, 🤖 toma la primera tarea que termine (digamos, nuestro "archivo-lento" 📝) y continúa con lo que tenía que hacer con ella. -Esa "espera de otra cosa" normalmente se refiere a operaciones I/O que son relativamente "lentas" (en relación a la velocidad del procesador y memoria RAM), como por ejemplo esperar por: +Ese "esperar otra cosa" normalmente se refiere a las operaciones de I/O que son relativamente "lentas" (comparadas con la velocidad del procesador y la memoria RAM), como esperar: -* los datos de cliente que se envían a través de la red -* los datos enviados por tu programa para ser recibidos por el cliente a través de la red -* el contenido de un archivo en disco para ser leído por el sistema y entregado al programa -* los contenidos que tu programa da al sistema para ser escritos en disco -* una operación relacionada con una API remota -* una operación de base de datos -* el retorno de resultados de una consulta de base de datos +* que los datos del cliente se envíen a través de la red +* que los datos enviados por tu programa sean recibidos por el cliente a través de la red +* que el contenido de un archivo en el disco sea leído por el sistema y entregado a tu programa +* que el contenido que tu programa entregó al sistema sea escrito en el disco +* una operación de API remota +* que una operación de base de datos termine +* que una query de base de datos devuelva los resultados * etc. -Como el tiempo de ejecución se consume principalmente al esperar a operaciones de I/O, las llaman operaciones "I/O bound". +Como el tiempo de ejecución se consume principalmente esperando operaciones de I/O, las llaman operaciones "I/O bound". -Se llama "asíncrono" porque el sistema / programa no tiene que estar "sincronizado" con la tarea lenta, esperando el momento exacto en que finaliza la tarea, sin hacer nada, para poder recoger el resultado de la tarea y continuar el trabajo. +Se llama "asíncrono" porque la computadora / programa no tiene que estar "sincronizado" con la tarea lenta, esperando el momento exacto en que la tarea termine, sin hacer nada, para poder tomar el resultado de la tarea y continuar el trabajo. -En lugar de eso, al ser un sistema "asíncrono", una vez finalizada, la tarea puede esperar un poco en la cola (algunos microsegundos) para que la computadora / programa termine lo que estaba haciendo, y luego vuelva para recoger los resultados y seguir trabajando con ellos. +En lugar de eso, al ser un sistema "asíncrono", una vez terminado, la tarea puede esperar un poco en la cola (algunos microsegundos) para que la computadora / programa termine lo que salió a hacer, y luego regrese para tomar los resultados y continuar trabajando con ellos. -Por "síncrono" (contrario a "asíncrono") también se usa habitualmente el término "secuencial", porque el sistema / programa sigue todos los pasos secuencialmente antes de cambiar a una tarea diferente, incluso si esos pasos implican esperas. +Para el "sincrónico" (contrario al "asíncrono") comúnmente también usan el término "secuencial", porque la computadora / programa sigue todos los pasos en secuencia antes de cambiar a una tarea diferente, incluso si esos pasos implican esperar. ### Concurrencia y Hamburguesas -El concepto de código **asíncrono** descrito anteriormente a veces también se llama **"concurrencia"**. Es diferente del **"paralelismo"**. +Esta idea de código **asíncrono** descrita anteriormente a veces también se llama **"concurrencia"**. Es diferente del **"paralelismo"**. -**Concurrencia** y **paralelismo** ambos se relacionan con "cosas diferentes que suceden más o menos al mismo tiempo". +**Concurrencia** y **paralelismo** ambos se relacionan con "diferentes cosas sucediendo más o menos al mismo tiempo". Pero los detalles entre *concurrencia* y *paralelismo* son bastante diferentes. -Para entender las diferencias, imagina la siguiente historia sobre hamburguesas: +Para ver la diferencia, imagina la siguiente historia sobre hamburguesas: ### Hamburguesas Concurrentes -Vas con la persona que te gusta 😍 a pedir comida rápida 🍔, haces cola mientras el cajero 💁 recoge los pedidos de las personas de delante tuyo. +Vas con tu crush a conseguir comida rápida, te pones en fila mientras el cajero toma los pedidos de las personas frente a ti. 😍 -illustration + -Llega tu turno, haces tu pedido de 2 hamburguesas impresionantes para esa persona 😍 y para ti. +Luego es tu turno, haces tu pedido de 2 hamburguesas muy sofisticadas para tu crush y para ti. 🍔🍔 -illustration + -El cajero 💁 le dice algo al chico de la cocina 👨‍🍳 para que sepa que tiene que preparar tus hamburguesas 🍔 (a pesar de que actualmente está preparando las de los clientes anteriores). +El cajero dice algo al cocinero en la cocina para que sepan que tienen que preparar tus hamburguesas (aunque actualmente están preparando las de los clientes anteriores). -illustration + -Pagas 💸. -El cajero 💁 te da el número de tu turno. +Pagas. 💸 + +El cajero te da el número de tu turno. -illustration + -Mientras esperas, vas con esa persona 😍 y eliges una mesa, se sientan y hablan durante un rato largo (ya que las hamburguesas son muy impresionantes y necesitan un rato para prepararse ✨🍔✨). +Mientras esperas, vas con tu crush y eliges una mesa, te sientas y hablas con tu crush por un largo rato (ya que tus hamburguesas son muy sofisticadas y toman un tiempo en prepararse). -Mientras te sientas en la mesa con esa persona 😍, esperando las hamburguesas 🍔, puedes disfrutar ese tiempo admirando lo increíble, inteligente, y bien que se ve ✨😍✨. +Mientras estás sentado en la mesa con tu crush, mientras esperas las hamburguesas, puedes pasar ese tiempo admirando lo increíble, lindo e inteligente que es tu crush ✨😍✨. -illustration + -Mientras esperas y hablas con esa persona 😍, de vez en cuando, verificas el número del mostrador para ver si ya es tu turno. +Mientras esperas y hablas con tu crush, de vez en cuando revisas el número mostrado en el mostrador para ver si ya es tu turno. -Al final, en algún momento, llega tu turno. Vas al mostrador, coges tus hamburguesas 🍔 y vuelves a la mesa. +Luego, en algún momento, finalmente es tu turno. Vas al mostrador, obtienes tus hamburguesas y vuelves a la mesa. -illustration + -Tú y esa persona 😍 se comen las hamburguesas 🍔 y la pasan genial ✨. +Tú y tu crush comen las hamburguesas y pasan un buen rato. ✨ -illustration + /// info | Información -Las ilustraciones fueron creados por Ketrina Thompson. 🎨 +Hermosas ilustraciones de Ketrina Thompson. 🎨 /// --- -Imagina que eres el sistema / programa 🤖 en esa historia. +Imagina que eres la computadora / programa 🤖 en esa historia. -Mientras estás en la cola, estás quieto 😴, esperando tu turno, sin hacer nada muy "productivo". Pero la línea va rápida porque el cajero 💁 solo recibe los pedidos (no los prepara), así que está bien. +Mientras estás en la fila, estás inactivo 😴, esperando tu turno, sin hacer nada muy "productivo". Pero la fila es rápida porque el cajero solo está tomando los pedidos (no preparándolos), así que está bien. -Luego, cuando llega tu turno, haces un trabajo "productivo" real 🤓, procesas el menú, decides lo que quieres, lo que quiere esa persona 😍, pagas 💸, verificas que das el billete o tarjeta correctos, verificas que te cobren correctamente, que el pedido tiene los artículos correctos, etc. +Luego, cuando es tu turno, haces un trabajo realmente "productivo", procesas el menú, decides lo que quieres, obtienes la elección de tu crush, pagas, verificas que das el billete o tarjeta correctos, verificas que te cobren correctamente, verificas que el pedido tenga los artículos correctos, etc. -Pero entonces, aunque aún no tienes tus hamburguesas 🍔, el trabajo hecho con el cajero 💁 está "en pausa" ⏸, porque debes esperar 🕙 a que tus hamburguesas estén listas. +Pero luego, aunque todavía no tienes tus hamburguesas, tu trabajo con el cajero está "en pausa" ⏸, porque tienes que esperar 🕙 a que tus hamburguesas estén listas. -Pero como te alejas del mostrador y te sientas en la mesa con un número para tu turno, puedes cambiar tu atención 🔀 a esa persona 😍 y "trabajar" ⏯ 🤓 en eso. Entonces nuevamente estás haciendo algo muy "productivo" 🤓, como coquetear con esa persona 😍. +Pero como te alejas del mostrador y te sientas en la mesa con un número para tu turno, puedes cambiar 🔀 tu atención a tu crush, y "trabajar" ⏯ 🤓 en eso. Luego, nuevamente estás haciendo algo muy "productivo" como es coquetear con tu crush 😍. -Después, el 💁 cajero dice "he terminado de hacer las hamburguesas" 🍔 poniendo tu número en la pantalla del mostrador, pero no saltas al momento que el número que se muestra es el tuyo. Sabes que nadie robará tus hamburguesas 🍔 porque tienes el número de tu turno y ellos tienen el suyo. +Luego el cajero 💁 dice "he terminado de hacer las hamburguesas" al poner tu número en el mostrador, pero no saltas como loco inmediatamente cuando el número mostrado cambia a tu número de turno. Sabes que nadie robará tus hamburguesas porque tienes el número de tu turno, y ellos tienen el suyo. -Así que esperas a que esa persona 😍 termine la historia (terminas el trabajo actual ⏯ / tarea actual que se está procesando 🤓), sonríes gentilmente y le dices que vas por las hamburguesas ⏸. +Así que esperas a que tu crush termine la historia (termine el trabajo ⏯ / tarea actual que se está procesando 🤓), sonríes amablemente y dices que vas por las hamburguesas ⏸. -Luego vas al mostrador 🔀, a la tarea inicial que ya está terminada ⏯, recoges las hamburguesas 🍔, les dices gracias y las llevas a la mesa. Eso termina esa fase / tarea de interacción con el mostrador ⏹. Eso a su vez, crea una nueva tarea, "comer hamburguesas" 🔀 ⏯, pero la anterior de "conseguir hamburguesas" está terminada ⏹. +Luego vas al mostrador 🔀, a la tarea inicial que ahora está terminada ⏯, recoges las hamburguesas, das las gracias y las llevas a la mesa. Eso termina ese paso / tarea de interacción con el mostrador ⏹. Eso a su vez, crea una nueva tarea, de "comer hamburguesas" 🔀 ⏯, pero la anterior de "obtener hamburguesas" ha terminado ⏹. ### Hamburguesas Paralelas -Ahora imagina que estas no son "Hamburguesas Concurrentes" sino "Hamburguesas Paralelas". +Ahora imaginemos que estas no son "Hamburguesas Concurrentes", sino "Hamburguesas Paralelas". -Vas con la persona que te gusta 😍 por comida rápida paralela 🍔. +Vas con tu crush a obtener comida rápida paralela. -Haces la cola mientras varios cajeros (digamos 8) que a la vez son cocineros 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳 toman los pedidos de las personas que están delante de ti. +Te pones en fila mientras varios (digamos 8) cajeros que al mismo tiempo son cocineros toman los pedidos de las personas frente a ti. -Todos los que están antes de ti están esperando 🕙 que sus hamburguesas 🍔 estén listas antes de dejar el mostrador porque cada uno de los 8 cajeros prepara la hamburguesa de inmediato antes de recibir el siguiente pedido. +Todos antes que tú están esperando a que sus hamburguesas estén listas antes de dejar el mostrador porque cada uno de los 8 cajeros va y prepara la hamburguesa de inmediato antes de obtener el siguiente pedido. -illustration + -Entonces finalmente es tu turno, haces tu pedido de 2 hamburguesas 🍔 impresionantes para esa persona 😍 y para ti. +Luego, finalmente es tu turno, haces tu pedido de 2 hamburguesas muy sofisticadas para tu crush y para ti. Pagas 💸. -illustration + -El cajero va a la cocina 👨‍🍳. +El cajero va a la cocina. -Esperas, de pie frente al mostrador 🕙, para que nadie más recoja tus hamburguesas 🍔, ya que no hay números para los turnos. +Esperas, de pie frente al mostrador 🕙, para que nadie más tome tus hamburguesas antes que tú, ya que no hay números para los turnos. -illustration + -Como tu y esa persona 😍 están ocupados en impedir que alguien se ponga delante y recoja tus hamburguesas apenas llegan 🕙, tampoco puedes prestarle atención a esa persona 😞. +Como tú y tu crush están ocupados no dejando que nadie se interponga y tome tus hamburguesas cuando lleguen, no puedes prestar atención a tu crush. 😞 -Este es un trabajo "síncrono", estás "sincronizado" con el cajero / cocinero 👨‍🍳. Tienes que esperar y estar allí en el momento exacto en que el cajero / cocinero 👨‍🍳 termina las hamburguesas 🍔 y te las da, o de lo contrario, alguien más podría cogerlas. +Este es un trabajo "sincrónico", estás "sincronizado" con el cajero/cocinero 👨‍🍳. Tienes que esperar 🕙 y estar allí en el momento exacto en que el cajero/cocinero 👨‍🍳 termine las hamburguesas y te las entregue, o de lo contrario, alguien más podría tomarlas. -illustration + -Luego, el cajero / cocinero 👨‍🍳 finalmente regresa con tus hamburguesas 🍔, después de mucho tiempo esperando 🕙 frente al mostrador. +Luego tu cajero/cocinero 👨‍🍳 finalmente regresa con tus hamburguesas, después de mucho tiempo esperando 🕙 allí frente al mostrador. -illustration + -Coges tus hamburguesas 🍔 y vas a la mesa con esa persona 😍. +Tomas tus hamburguesas y vas a la mesa con tu crush. -Sólo las comes y listo 🍔 ⏹. +Simplemente las comes, y has terminado. ⏹ -illustration + -No has hablado ni coqueteado mucho, ya que has pasado la mayor parte del tiempo esperando 🕙 frente al mostrador 😞. +No hubo mucho hablar o coquetear ya que la mayor parte del tiempo se dedicó a esperar 🕙 frente al mostrador. 😞 /// info | Información -Las ilustraciones fueron creados por Ketrina Thompson. 🎨 +Hermosas ilustraciones de Ketrina Thompson. 🎨 /// --- -En este escenario de las hamburguesas paralelas, tú eres un sistema / programa 🤖 con dos procesadores (tú y la persona que te gusta 😍), ambos esperando 🕙 y dedicando su atención ⏯ a estar "esperando en el mostrador" 🕙 durante mucho tiempo. +En este escenario de las hamburguesas paralelas, eres una computadora / programa 🤖 con dos procesadores (tú y tu crush), ambos esperando 🕙 y dedicando su atención ⏯ a estar "esperando en el mostrador" 🕙 por mucho tiempo. -La tienda de comida rápida tiene 8 procesadores (cajeros / cocineros) 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳. Mientras que la tienda de hamburguesas concurrentes podría haber tenido solo 2 (un cajero y un cocinero) 💁 👨‍🍳. +La tienda de comida rápida tiene 8 procesadores (cajeros/cocineros). Mientras que la tienda de hamburguesas concurrentes podría haber tenido solo 2 (un cajero y un cocinero). -Pero aún así, la experiencia final no es la mejor 😞. +Pero aún así, la experiencia final no es la mejor. 😞 --- -Esta sería la historia paralela equivalente de las hamburguesas 🍔. +Esta sería la historia equivalente de las hamburguesas paralelas. 🍔 -Para un ejemplo más "real" de ésto, imagina un banco. +Para un ejemplo más "de la vida real" de esto, imagina un banco. -Hasta hace poco, la mayoría de los bancos tenían varios cajeros 👨‍💼👨‍💼👨‍💼👨‍💼 y una gran línea 🕙🕙🕙🕙🕙🕙🕙🕙. +Hasta hace poco, la mayoría de los bancos tenían múltiples cajeros 👨‍💼👨‍💼👨‍💼👨‍💼 y una gran fila 🕙🕙🕙🕙🕙🕙🕙🕙. Todos los cajeros haciendo todo el trabajo con un cliente tras otro 👨‍💼⏯. -Y tienes que esperar 🕙 en la fila durante mucho tiempo o perderás tu turno. - -Probablemente no querrás llevar contigo a la persona que te gusta 😍 a hacer encargos al banco 🏦. +Y tienes que esperar 🕙 en la fila por mucho tiempo o pierdes tu turno. -### Conclusión de las Hamburguesa +Probablemente no querrías llevar a tu crush 😍 contigo a hacer trámites en el banco 🏦. -En este escenario de "hamburguesas de comida rápida con tu pareja", debido a que hay mucha espera 🕙, tiene mucho más sentido tener un sistema con concurrencia ⏸🔀⏯. +### Conclusión de las Hamburguesas -Este es el caso de la mayoría de las aplicaciones web. +En este escenario de "hamburguesas de comida rápida con tu crush", como hay mucha espera 🕙, tiene mucho más sentido tener un sistema concurrente ⏸🔀⏯. -Muchos, muchos usuarios, pero el servidor está esperando 🕙 el envío de las peticiones ya que su conexión no es buena. +Este es el caso para la mayoría de las aplicaciones web. -Y luego esperando 🕙 nuevamente a que las respuestas retornen. +Muchos, muchos usuarios, pero tu servidor está esperando 🕙 su conexión no tan buena para enviar sus requests. -Esta "espera" 🕙 se mide en microsegundos, pero aun así, sumando todo, al final es mucha espera. +Y luego esperar 🕙 nuevamente a que los responses regresen. -Es por eso que tiene mucho sentido usar código asíncrono ⏸🔀⏯ para las API web. +Esta "espera" 🕙 se mide en microsegundos, pero aún así, sumándolo todo, es mucha espera al final. -La mayoría de los framework populares de Python existentes (incluidos Flask y Django) se crearon antes de que existieran las nuevas funciones asíncronas en Python. Por lo tanto, las formas en que pueden implementarse admiten la ejecución paralela y una forma más antigua de ejecución asíncrona que no es tan potente como la actual. +Por eso tiene mucho sentido usar código asíncrono ⏸🔀⏯ para las APIs web. -A pesar de que la especificación principal para Python web asíncrono (ASGI) se desarrolló en Django, para agregar soporte para WebSockets. - -Ese tipo de asincronía es lo que hizo popular a NodeJS (aunque NodeJS no es paralelo) y esa es la fortaleza de Go como lenguaje de programación. +Este tipo de asincronía es lo que hizo popular a NodeJS (aunque NodeJS no es paralelo) y esa es la fortaleza de Go como lenguaje de programación. Y ese es el mismo nivel de rendimiento que obtienes con **FastAPI**. -Y como puede 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 Starlette). +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). ### ¿Es la concurrencia mejor que el paralelismo? ¡No! Esa no es la moraleja de la historia. -La concurrencia es diferente al paralelismo. Y es mejor en escenarios **específicos** que implican mucha espera. Debido a eso, generalmente es mucho mejor que el paralelismo para el desarrollo de aplicaciones web. Pero no para todo. +La concurrencia es diferente del paralelismo. Y es mejor en escenarios **específicos** que implican mucha espera. Debido a eso, generalmente es mucho mejor que el paralelismo para el desarrollo de aplicaciones web. Pero no para todo. -Entonces, para explicar eso, imagina la siguiente historia corta: +Así que, para equilibrar eso, imagina la siguiente historia corta: > Tienes que limpiar una casa grande y sucia. @@ -270,80 +267,80 @@ Entonces, para explicar eso, imagina la siguiente historia corta: --- -No hay esperas 🕙, solo hay mucho trabajo por hacer, en varios lugares de la casa. +No hay esperas 🕙 en ninguna parte, solo mucho trabajo por hacer, en múltiples lugares de la casa. -Podrías tener turnos como en el ejemplo de las hamburguesas, primero la sala de estar, luego la cocina, pero como no estás esperando nada, solo limpiando y limpiando, los turnos no afectarían nada. +Podrías tener turnos como en el ejemplo de las hamburguesas, primero la sala de estar, luego la cocina, pero como no estás esperando 🕙 nada, solo limpiando y limpiando, los turnos no afectarían nada. Tomaría la misma cantidad de tiempo terminar con o sin turnos (concurrencia) y habrías hecho la misma cantidad de trabajo. -Pero en este caso, si pudieras traer a los 8 ex cajeros / cocineros / ahora limpiadores 👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳👨‍🍳, y cada uno de ellos (y tú) podría tomar una zona de la casa para limpiarla, podría hacer todo el trabajo en **paralelo**, con la ayuda adicional y terminar mucho antes. +Pero en este caso, si pudieras traer a los 8 ex-cajeros/cocineros/ahora-limpiadores, y cada uno de ellos (más tú) pudiera tomar una zona de la casa para limpiarla, podrías hacer todo el trabajo en **paralelo**, con la ayuda extra, y terminar mucho antes. -En este escenario, cada uno de los limpiadores (incluido tú) sería un procesador, haciendo su parte del trabajo. +En este escenario, cada uno de los limpiadores (incluyéndote) sería un procesador, haciendo su parte del trabajo. -Y como la mayor parte del tiempo de ejecución lo coge el trabajo real (en lugar de esperar), y el trabajo en un sistema lo realiza una CPU , a estos problemas se les llama "CPU bound". +Y como la mayor parte del tiempo de ejecución se dedica al trabajo real (en lugar de esperar), y el trabajo en una computadora lo realiza una CPU, llaman a estos problemas "CPU bound". --- -Ejemplos típicos de operaciones dependientes de CPU son cosas que requieren un procesamiento matemático complejo. +Ejemplos comunes de operaciones limitadas por la CPU son cosas que requieren procesamiento matemático complejo. Por ejemplo: -* **Audio** o **procesamiento de imágenes**. -* **Visión por computadora**: una imagen está compuesta de millones de píxeles, cada píxel tiene 3 valores / colores, procesamiento que normalmente requiere calcular algo en esos píxeles, todo al mismo tiempo. -* **Machine Learning**: normalmente requiere muchas multiplicaciones de "matrices" y "vectores". Imagina en una enorme hoja de cálculo con números y tener que multiplicarlos todos al mismo tiempo. -* **Deep Learning**: este es un subcampo de Machine Learning, por lo tanto, aplica lo mismo. Es solo que no hay una sola hoja de cálculo de números para multiplicar, sino un gran conjunto de ellas, y en muchos casos, usa un procesador especial para construir y / o usar esos modelos. +* **Procesamiento de audio** o **imágenes**. +* **Visión por computadora**: una imagen está compuesta de millones de píxeles, cada píxel tiene 3 valores / colores, procesar eso normalmente requiere calcular algo en esos píxeles, todos al mismo tiempo. +* **Machine Learning**: normalmente requiere muchas multiplicaciones de "matrices" y "vectores". Piensa en una enorme hoja de cálculo con números y multiplicando todos juntos al mismo tiempo. +* **Deep Learning**: este es un subcampo de Machine Learning, por lo tanto, se aplica lo mismo. Es solo que no hay una sola hoja de cálculo de números para multiplicar, sino un enorme conjunto de ellas, y en muchos casos, usas un procesador especial para construir y / o usar esos modelos. ### Concurrencia + Paralelismo: Web + Machine Learning -Con **FastAPI** puedes aprovechar la concurrencia que es muy común para el desarrollo web (atractivo principal de NodeJS). +Con **FastAPI** puedes aprovechar la concurrencia que es muy común para el desarrollo web (la misma atracción principal de NodeJS). -Pero también puedes aprovechar los beneficios del paralelismo y el multiprocesamiento (tener múltiples procesos ejecutándose en paralelo) para cargas de trabajo **CPU bound** como las de los sistemas de Machine Learning. +Pero también puedes explotar los beneficios del paralelismo y la multiprocesamiento (tener múltiples procesos ejecutándose en paralelo) para cargas de trabajo **CPU bound** como las de los sistemas de Machine Learning. -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 combinación para las API y aplicaciones web de Data Science / Machine Learning (entre muchas otras). +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 [Despliegue](deployment/index.md){.internal-link target=_blank}. +Para ver cómo lograr este paralelismo en producción, consulta la sección sobre [Deployment](deployment/index.md){.internal-link target=_blank}. ## `async` y `await` -Las versiones modernas de Python tienen una forma muy intuitiva de definir código asíncrono. Esto hace que se vea como un código "secuencial" normal y que haga la "espera" por ti en los momentos correctos. +Las versiones modernas de Python tienen una forma muy intuitiva de definir código asíncrono. Esto hace que se vea igual que el código "secuencial" normal y hace el "wait" por ti en los momentos adecuados. -Cuando hay una operación que requerirá esperar antes de dar los resultados y tiene soporte para estas nuevas características de Python, puedes programarlo como: +Cuando hay una operación que requerirá esperar antes de dar los resultados y tiene soporte para estas nuevas funcionalidades de Python, puedes programarlo así: ```Python burgers = await get_burgers(2) ``` -La clave aquí es `await`. Eso le dice a Python que tiene que esperar ⏸ a que `get_burgers (2)` termine de hacer lo suyo 🕙 antes de almacenar los resultados en `hamburguesas`. Con eso, Python sabrá que puede ir y hacer otra cosa 🔀 ⏯ mientras tanto (como recibir otra solicitud). +La clave aquí es el `await`. Dice a Python que tiene que esperar ⏸ a que `get_burgers(2)` termine de hacer su cosa 🕙 antes de almacenar los resultados en `burgers`. Con eso, Python sabrá que puede ir y hacer algo más 🔀 ⏯ mientras tanto (como recibir otro request). -Para que `await` funcione, tiene que estar dentro de una función que admita esta asincronía. Para hacer eso, simplemente lo declaras con `async def`: +Para que `await` funcione, tiene que estar dentro de una función que soporte esta asincronía. Para hacer eso, solo declara la función con `async def`: ```Python hl_lines="1" async def get_burgers(number: int): - # Do some asynchronous stuff to create the burgers + # Hacer algunas cosas asíncronas para crear las hamburguesas return burgers ``` -...en vez de `def`: +...en lugar de `def`: ```Python hl_lines="2" -# This is not asynchronous +# Esto no es asíncrono def get_sequential_burgers(number: int): - # Do some sequential stuff to create the burgers + # Hacer algunas cosas secuenciales para crear las hamburguesas return burgers ``` -Con `async def`, Python sabe que, dentro de esa función, debe tener en cuenta las expresiones `wait` y que puede "pausar" ⏸ la ejecución de esa función e ir a hacer otra cosa 🔀 antes de regresar. +Con `async def`, Python sabe que, dentro de esa función, tiene que estar atento a las expresiones `await`, y que puede "pausar" ⏸ la ejecución de esa función e ir a hacer algo más 🔀 antes de regresar. -Cuando desees llamar a una función `async def`, debes "esperarla". Entonces, esto no funcionará: +Cuando deseas llamar a una función `async def`, tienes que "await" dicha función. Así que, esto no funcionará: ```Python -# Esto no funcionará, porque get_burgers se definió con: async def -hamburguesas = get_burgers (2) +# Esto no funcionará, porque get_burgers fue definido con: async def +burgers = get_burgers(2) ``` --- -Por lo tanto, si estás utilizando una library que te dice que puedes llamarla con `await`, debes crear las *path operation functions* que la usan con `async def`, como en: +Así que, si estás usando un paquete que te dice que puedes llamarlo con `await`, necesitas crear las *path operation functions* que lo usen con `async def`, como en: ```Python hl_lines="2-3" @app.get('/burgers') @@ -354,15 +351,25 @@ async def read_burgers(): ### Más detalles técnicos -Es posible que hayas notado que `await` solo se puede usar dentro de las funciones definidas con `async def`. +Podrías haber notado que `await` solo se puede usar dentro de funciones definidas con `async def`. + +Pero al mismo tiempo, las funciones definidas con `async def` deben ser "awaited". Por lo tanto, las funciones con `async def` solo se pueden llamar dentro de funciones definidas con `async def` también. + +Entonces, sobre el huevo y la gallina, ¿cómo llamas a la primera función `async`? + +Si estás trabajando con **FastAPI** no tienes que preocuparte por eso, porque esa "primera" función será tu *path operation function*, y FastAPI sabrá cómo hacer lo correcto. + +Pero si deseas usar `async` / `await` sin FastAPI, también puedes hacerlo. + +### Escribe tu propio código async -Pero al mismo tiempo, las funciones definidas con `async def` deben ser "esperadas". Por lo tanto, las funciones con `async def` solo se pueden invocar dentro de las funciones definidas con `async def` también. +Starlette (y **FastAPI**) están basados en AnyIO, lo que lo hace compatible tanto con la librería estándar de Python asyncio como con Trio. -Entonces, relacionado con la paradoja del huevo y la gallina, ¿cómo se llama a la primera función `async`? +En particular, puedes usar directamente AnyIO para tus casos de uso avanzados de concurrencia que requieran patrones más avanzados en tu propio código. -Si estás trabajando con **FastAPI** no tienes que preocuparte por eso, porque esa "primera" función será tu *path operation function*, y FastAPI sabrá cómo hacer lo pertinente. +E incluso si no estuvieras usando FastAPI, también podrías escribir tus propias aplicaciones asíncronas con AnyIO para ser altamente compatibles y obtener sus beneficios (p.ej. *concurrencia estructurada*). -En el caso de que desees usar `async` / `await` sin FastAPI, revisa la documentación oficial de Python. +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. Sería particularmente útil si necesitas **combinar código async con regular** (bloqueante/sincrónico). ### Otras formas de código asíncrono @@ -370,68 +377,68 @@ Este estilo de usar `async` y `await` es relativamente nuevo en el lenguaje. Pero hace que trabajar con código asíncrono sea mucho más fácil. -Esta misma sintaxis (o casi idéntica) también se incluyó recientemente en las versiones modernas de JavaScript (en Browser y NodeJS). +Esta misma sintaxis (o casi idéntica) también se incluyó recientemente en las versiones modernas de JavaScript (en el Navegador y NodeJS). -Pero antes de eso, manejar código asíncrono era bastante más complejo y difícil. +Pero antes de eso, manejar el código asíncrono era mucho más complejo y difícil. -En versiones anteriores de Python, podrías haber utilizado threads o Gevent. Pero el código es mucho más complejo de entender, depurar y desarrollar. +En versiones previas de Python, podrías haber usado hilos o Gevent. Pero el código es mucho más complejo de entender, depurar y razonar. -En versiones anteriores de NodeJS / Browser JavaScript, habrías utilizado "callbacks". Lo que conduce a callback hell. +En versiones previas de NodeJS / JavaScript en el Navegador, habrías usado "callbacks". Lo que lleva al callback hell. ## Coroutines -**Coroutine** es un término sofisticado para referirse a la cosa devuelta por una función `async def`. Python sabe que es algo así como una función que puede iniciar y que terminará en algún momento, pero que también podría pausarse ⏸ internamente, siempre que haya un `await` dentro de ella. +**Coroutines** es simplemente el término muy elegante para la cosa que devuelve una función `async def`. Python sabe que es algo parecido a una función, que puede comenzar y que terminará en algún momento, pero que podría pausar ⏸ internamente también, siempre que haya un `await` dentro de él. -Pero toda esta funcionalidad de usar código asincrónico con `async` y `await` se resume muchas veces como usar "coroutines". Es comparable a la característica principal de Go, las "Goroutines". +Pero toda esta funcionalidad de usar código asíncrono con `async` y `await` a menudo se resume como utilizar "coroutines". Es comparable a la funcionalidad clave principal de Go, las "Goroutines". ## Conclusión Veamos la misma frase de arriba: -> Las versiones modernas de Python tienen soporte para **"código asíncrono"** usando algo llamado **"coroutines"**, con la sintaxis **`async` y `await`**. +> Las versiones modernas de Python tienen soporte para **"código asíncrono"** utilizando algo llamado **"coroutines"**, con la sintaxis **`async` y `await`**. -Eso ya debería tener más sentido ahora. ✨ +Eso debería tener más sentido ahora. ✨ Todo eso es lo que impulsa FastAPI (a través de Starlette) y lo que hace que tenga un rendimiento tan impresionante. -## Detalles muy técnicos +## Detalles Muy Técnicos /// warning | Advertencia Probablemente puedas saltarte esto. -Estos son detalles muy técnicos de cómo **FastAPI** funciona a muy bajo nivel. +Estos son detalles muy técnicos de cómo funciona **FastAPI** en su interior. -Si tienes bastante conocimiento técnico (coroutines, threads, bloqueos, etc.) y tienes curiosidad acerca de cómo FastAPI gestiona `async def` vs `def` normal, continúa. +Si tienes bastante conocimiento técnico (coroutines, hilos, bloqueo, etc.) y tienes curiosidad sobre cómo FastAPI maneja `async def` vs `def` normal, adelante. /// -### Path operation functions +### Funciones de *path operation* -Cuando declaras una *path operation function* con `def` normal en lugar de `async def`, se ejecuta en un threadpool externo que luego es "awaited", en lugar de ser llamado directamente (ya que bloquearía el servidor). +Cuando declaras una *path operation function* con `def` normal en lugar de `async def`, se ejecuta en un threadpool externo que luego es esperado, en lugar de ser llamado directamente (ya que bloquearía el servidor). -Si vienes de otro framework asíncrono que no funciona de la manera descrita anteriormente y estás acostumbrado a definir *path operation functions* del tipo sólo cálculo con `def` simple para una pequeña ganancia de rendimiento (aproximadamente 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 un código que realice el bloqueo I/O. +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 I/O de bloqueo. -Aún así, en ambas situaciones, es probable que **FastAPI** sea [aún más rápido](index.md#rendimiento){.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){.internal-link target=_blank} que (o al menos comparable a) tu framework anterior. ### Dependencias -Lo mismo se aplica para las dependencias. 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){.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. -### Subdependencias +### Sub-dependencias -Puedes tener múltiples dependencias y subdependencias que se requieren unas a otras (como parámetros de las definiciones de cada función), algunas de ellas pueden crearse con `async def` y otras con `def` normal. Igual todo seguiría funcionando correctamente, y las creadas con `def` normal se llamarían en un thread externo (del threadpool) en lugar de ser "awaited". +Puedes tener múltiples dependencias y [sub-dependencias](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} requiriéndose mutuamente (como parámetros de las definiciones de funciones), algunas de ellas podrían ser creadas con `async def` y algunas con `def` normal. Aun funcionará, y las que fueron creadas con `def` normal serían llamadas en un hilo externo (del threadpool) en lugar de ser "awaited". -### Otras funciones de utilidades +### Otras funciones de utilidad -Cualquier otra función de utilidad que llames directamente se puede crear con `def` o `async def` normales y FastAPI no afectará la manera en que la llames. +Cualquier otra función de utilidad que llames directamente puede ser creada con `def` normal o `async def` y FastAPI no afectará la forma en que la llames. -Esto contrasta con las funciones que FastAPI llama por ti: las *path operation functions* y dependencias. +Esto contrasta con las funciones que FastAPI llama por ti: *path operation functions* y dependencias. -Si tu función de utilidad es creada con `def` normal, se llamará directamente (tal cual la escribes en tu código), no en un threadpool, si la función se crea con `async def`, entonces debes usar `await` con esa función cuando la llamas en tu código. +Si tu función de utilidad es una función normal con `def`, será llamada directamente (como la escribas en tu código), no en un threadpool; si la función es creada con `async def` entonces deberías "await" por esa función cuando la llames en tu código. --- -Nuevamente, estos son detalles muy técnicos que probablemente sólo son útiles si los viniste a buscar expresamente. +Nuevamente, estos son detalles muy técnicos que probablemente serían útiles si los buscaste. -De lo contrario, la guía de la sección anterior debería ser suficiente: ¿Tienes prisa?. +De lo contrario, deberías estar bien con las pautas de la sección anterior: ¿Con prisa?. diff --git a/docs/es/docs/benchmarks.md b/docs/es/docs/benchmarks.md index 3e02d4e9f..49d65b6ba 100644 --- a/docs/es/docs/benchmarks.md +++ b/docs/es/docs/benchmarks.md @@ -1,33 +1,34 @@ # Benchmarks -Los benchmarks independientes de TechEmpower muestran aplicaciones de **FastAPI** que se ejecutan en Uvicorn como uno de los frameworks de Python más rápidos disponibles, solo por debajo de Starlette y Uvicorn (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, solo por debajo de Starlette y Uvicorn en sí mismos (utilizados internamente por FastAPI). -Pero al comprobar benchmarks y comparaciones debes tener en cuenta lo siguiente. +Pero al revisar benchmarks y comparaciones, debes tener en cuenta lo siguiente. ## Benchmarks y velocidad -Cuando revisas los benchmarks, es común ver varias herramientas de diferentes tipos comparadas como equivalentes. +Cuando ves los benchmarks, es común ver varias herramientas de diferentes tipos comparadas como equivalentes. -Específicamente, para ver Uvicorn, Starlette y FastAPI comparadas entre sí (entre muchas otras herramientas). +Específicamente, ver Uvicorn, Starlette y FastAPI comparados juntos (entre muchas otras herramientas). -Cuanto más sencillo sea el problema resuelto por la herramienta, mejor rendimiento obtendrá. Y la mayoría de los benchmarks no prueban las funciones adicionales proporcionadas por la herramienta. +Cuanto más simple sea el problema resuelto por la herramienta, mejor rendimiento tendrá. Y la mayoría de los benchmarks no prueban las funcionalidades adicionales proporcionadas por la herramienta. -La jerarquía sería: +La jerarquía es como: -* **Uvicorn**: como servidor ASGI +* **Uvicorn**: un servidor ASGI * **Starlette**: (usa Uvicorn) un microframework web - * **FastAPI**: (usa Starlette) un microframework API con varias características adicionales para construir APIs, con validación de datos, etc. + * **FastAPI**: (usa Starlette) un microframework para APIs con varias funcionalidades adicionales para construir APIs, con validación de datos, etc. + * **Uvicorn**: * Tendrá el mejor rendimiento, ya que no tiene mucho código extra aparte del propio servidor. - * No escribirías una aplicación directamente en Uvicorn. Eso significaría que tu código tendría que incluir más o menos, al menos, todo el código proporcionado por Starlette (o **FastAPI**). Y si hicieras eso, tu aplicación final tendría la misma sobrecarga que si hubieras usado un framework y minimizado el código de tu aplicación y los errores. - * Si estás comparando Uvicorn, compáralo con los servidores de aplicaciones Daphne, Hypercorn, uWSGI, etc. + * No escribirías una aplicación directamente en Uvicorn. Eso significaría que tu código tendría que incluir, más o menos, al menos, todo el código proporcionado por Starlette (o **FastAPI**). Y si hicieras eso, tu aplicación final tendría la misma carga que si hubieras usado un framework, minimizando el código de tu aplicación y los bugs. + * Si estás comparando Uvicorn, compáralo con Daphne, Hypercorn, uWSGI, etc. Servidores de aplicaciones. * **Starlette**: - * Tendrá el siguiente mejor desempeño, después de Uvicorn. De hecho, Starlette usa Uvicorn para correr. Por lo tanto, probablemente sólo pueda volverse "más lento" que Uvicorn al tener que ejecutar más código. - * Pero te proporciona las herramientas para crear aplicaciones web simples, con routing basado en paths, etc. + * Tendrá el siguiente mejor rendimiento, después de Uvicorn. De hecho, Starlette usa Uvicorn para ejecutarse. Así que probablemente solo pueda ser "más lento" que Uvicorn por tener que ejecutar más código. + * Pero te proporciona las herramientas para construir aplicaciones web sencillas, con enrutamiento basado en paths, etc. * Si estás comparando Starlette, compáralo con Sanic, Flask, Django, etc. Frameworks web (o microframeworks). * **FastAPI**: - * De la misma manera que Starlette usa Uvicorn y no puede ser más rápido que él, **FastAPI** usa Starlette, por lo que no puede ser más rápido que él. - * * FastAPI ofrece más características además de las de Starlette. Funciones que casi siempre necesitas al crear una API, como validación y serialización de datos. Y al usarlo, obtienes documentación automática de forma gratuita (la documentación automática ni siquiera agrega gastos generales a las aplicaciones en ejecución, se genera al iniciar). - * Si no usaras FastAPI y usaras Starlette directamente (u otra herramienta, como Sanic, Flask, Responder, etc.), tendrías que implementar toda la validación y serialización de datos tu mismo. Por lo tanto, tu aplicación final seguirá teniendo la misma sobrecarga que si se hubiera creado con FastAPI. Y en muchos casos, esta validación y serialización de datos constituye la mayor cantidad de código escrito en las aplicaciones. - * Entonces, al usar FastAPI estás ahorrando tiempo de desarrollo, errores, líneas de código y probablemente obtendrías el mismo rendimiento (o mejor) que obtendrías si no lo usaras (ya que tendrías que implementarlo todo en tu código). - * Si estás comparando FastAPI, compáralo con un framework de aplicaciones web (o conjunto de herramientas) que proporciona validación, serialización y documentación de datos, como Flask-apispec, NestJS, Molten, etc. Frameworks con validación, serialización y documentación automáticas integradas. + * De la misma forma en que Starlette usa Uvicorn y no puede ser más rápido que él, **FastAPI** usa Starlette, por lo que no puede ser más rápido que él. + * FastAPI ofrece más funcionalidades además de las de Starlette. Funcionalidades que casi siempre necesitas al construir APIs, como la validación y serialización de datos. Y al utilizarlo, obtienes documentación automática gratis (la documentación automática ni siquiera añade carga a las aplicaciones en ejecución, se genera al inicio). + * Si no usabas FastAPI y utilizabas Starlette directamente (u otra herramienta, como Sanic, Flask, Responder, etc.) tendrías que implementar toda la validación y serialización de datos por ti mismo. Entonces, tu aplicación final aún tendría la misma carga que si hubiera sido construida usando FastAPI. Y en muchos casos, esta validación y serialización de datos es la mayor cantidad de código escrito en las aplicaciones. + * Entonces, al usar FastAPI estás ahorrando tiempo de desarrollo, bugs, líneas de código, y probablemente obtendrías el mismo rendimiento (o mejor) que si no lo usaras (ya que tendrías que implementarlo todo en tu código). + * Si estás comparando FastAPI, compáralo con un framework de aplicación web (o conjunto de herramientas) que proporcione validación de datos, serialización y documentación, como Flask-apispec, NestJS, Molten, etc. Frameworks con validación de datos, serialización y documentación automáticas integradas. diff --git a/docs/es/docs/deployment/index.md b/docs/es/docs/deployment/index.md index 74b0e22f0..3b6dcc05d 100644 --- a/docs/es/docs/deployment/index.md +++ b/docs/es/docs/deployment/index.md @@ -1,21 +1,21 @@ -# Despliegue - Introducción +# Despliegue -Desplegar una aplicación hecha con **FastAPI** es relativamente fácil. +Desplegar una aplicación **FastAPI** es relativamente fácil. -## ¿Qué significa desplegar una aplicación? +## Qué Significa Despliegue -**Desplegar** una aplicación significa realizar una serie de pasos para hacerla **disponible para los usuarios**. +**Desplegar** una aplicación significa realizar los pasos necesarios para hacerla **disponible para los usuarios**. -Para una **API web**, normalmente implica ponerla en una **máquina remota**, con un **programa de servidor** que proporcione un buen rendimiento, estabilidad, etc, para que sus **usuarios** puedan **acceder** a la aplicación de manera eficiente y sin interrupciones o problemas. +Para una **API web**, normalmente implica ponerla en una **máquina remota**, con un **programa de servidor** que proporcione buen rendimiento, estabilidad, etc., para que tus **usuarios** puedan **acceder** a la aplicación de manera eficiente y sin interrupciones o problemas. -Esto difiere en las fases de **desarrollo**, donde estás constantemente cambiando el código, rompiéndolo y arreglándolo, deteniendo y reiniciando el servidor de desarrollo, etc. +Esto contrasta con las etapas de **desarrollo**, donde estás constantemente cambiando el código, rompiéndolo y arreglándolo, deteniendo y reiniciando el servidor de desarrollo, etc. -## Estrategias de despliegue +## Estrategias de Despliegue -Existen varias formas de hacerlo dependiendo de tu caso de uso específico y las herramientas que uses. +Hay varias maneras de hacerlo dependiendo de tu caso de uso específico y las herramientas que utilices. -Puedes **desplegar un servidor** tú mismo usando un conjunto de herramientas, puedes usar **servicios en la nube** que haga parte del trabajo por ti, o usar otras posibles opciones. +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. -Te enseñaré algunos de los conceptos principales que debes tener en cuenta al desplegar aplicaciones hechas con **FastAPI** (aunque la mayoría de estos conceptos aplican para cualquier otro tipo de aplicación web). +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). -Podrás ver más detalles para tener en cuenta y algunas de las técnicas para hacerlo en las próximas secciones.✨ +Verás más detalles a tener en cuenta y algunas de las técnicas para hacerlo en las siguientes secciones. ✨ diff --git a/docs/es/docs/deployment/versions.md b/docs/es/docs/deployment/versions.md index 74243da89..d16ecf0a5 100644 --- a/docs/es/docs/deployment/versions.md +++ b/docs/es/docs/deployment/versions.md @@ -1,93 +1,93 @@ -# Acerca de las versiones de FastAPI +# Sobre las versiones de FastAPI -**FastAPI** está siendo utilizado en producción en muchas aplicaciones y sistemas. La cobertura de los tests se mantiene al 100%. Sin embargo, su desarrollo sigue siendo rápido. +**FastAPI** ya se está utilizando en producción en muchas aplicaciones y sistemas. Y la cobertura de tests se mantiene al 100%. Pero su desarrollo sigue avanzando rápidamente. -Se agregan nuevas características frecuentemente, se corrigen errores continuamente y el código está constantemente mejorando. +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 significa que cada versión puede potencialmente tener *breaking changes*. Las versiones siguen las convenciones de *Semantic Versioning*. +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. -Puedes crear aplicaciones listas para producción con **FastAPI** ahora mismo (y probablemente lo has estado haciendo por algún tiempo), solo tienes que asegurarte de usar la versión que funciona correctamente con el resto de tu código. +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. -## Fijar la versión de `fastapi` +## Fijar tu versión de `fastapi` -Lo primero que debes hacer en tu proyecto es "fijar" la última versión específica de **FastAPI** que sabes que funciona bien con tu aplicación. +Lo primero que debes hacer es "fijar" la versión de **FastAPI** que estás usando a la versión específica más reciente que sabes que funciona correctamente para tu aplicación. -Por ejemplo, digamos que estás usando la versión `0.45.0` en tu aplicación. +Por ejemplo, digamos que estás utilizando la versión `0.112.0` en tu aplicación. -Si usas el archivo `requirements.txt` puedes especificar la versión con: +Si usas un archivo `requirements.txt` podrías especificar la versión con: ```txt -fastapi==0.45.0 +fastapi[standard]==0.112.0 ``` -esto significa que usarás específicamente la versión `0.45.0`. +eso significaría que usarías exactamente la versión `0.112.0`. -También puedes fijar las versiones de esta forma: +O también podrías fijarla con: ```txt -fastapi>=0.45.0,<0.46.0 +fastapi[standard]>=0.112.0,<0.113.0 ``` -esto significa que usarás la versión `0.45.0` o superiores, pero menores a la versión `0.46.0`, por ejemplo, la versión `0.45.2` sería aceptada. +eso significaría que usarías las versiones `0.112.0` o superiores, pero menores que `0.113.0`, por ejemplo, una versión `0.112.2` todavía sería aceptada. -Si usas cualquier otra herramienta para manejar tus instalaciones, como Poetry, Pipenv, u otras, todas tienen una forma que puedes usar para definir versiones específicas para tus paquetes. +Si utilizas cualquier otra herramienta para gestionar tus instalaciones, como `uv`, Poetry, Pipenv, u otras, todas tienen una forma que puedes usar para definir versiones específicas para tus paquetes. ## Versiones disponibles -Puedes ver las versiones disponibles (por ejemplo, para revisar cuál es la actual) 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){.internal-link target=_blank}. -## Acerca de las versiones +## Sobre las versiones -Siguiendo las convenciones de *Semantic Versioning*, cualquier versión por debajo de `1.0.0` puede potencialmente tener *breaking changes*. +Siguiendo las convenciones del Semantic Versioning, cualquier versión por debajo de `1.0.0` podría potencialmente añadir cambios incompatibles. -FastAPI también sigue la convención de que cualquier cambio hecho en una "PATCH" version es para solucionar errores y *non-breaking changes*. +FastAPI también sigue la convención de que cualquier cambio de versión "PATCH" es para corrección de bugs y cambios no incompatibles. /// tip | Consejo -El "PATCH" es el último número, por ejemplo, en `0.2.3`, la PATCH version es `3`. +El "PATCH" es el último número, por ejemplo, en `0.2.3`, la versión PATCH es `3`. /// -Entonces, deberías fijar la versión así: +Así que deberías poder fijar a una versión como: ```txt fastapi>=0.45.0,<0.46.0 ``` -En versiones "MINOR" son añadidas nuevas características y posibles breaking changes. +Los cambios incompatibles y nuevas funcionalidades se añaden en versiones "MINOR". /// tip | Consejo -La versión "MINOR" es el número en el medio, por ejemplo, en `0.2.3`, la "MINOR" version es `2`. +El "MINOR" es el número en el medio, por ejemplo, en `0.2.3`, la versión MINOR es `2`. /// ## Actualizando las versiones de FastAPI -Para esto es recomendable primero añadir tests a tu aplicación. +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: [Testing](../tutorial/testing.md){.internal-link target=_blank} -Luego de tener los tests, puedes actualizar la versión de **FastAPI** a una más reciente y asegurarte de que tu código funciona correctamente ejecutando los tests. +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. -Si todo funciona correctamente, o haces los cambios necesarios para que esto suceda, y todos tus tests pasan, entonces puedes fijar tu versión de `fastapi` a la más reciente. +Si todo está funcionando, o después de hacer los cambios necesarios, y todos tus tests pasan, entonces puedes fijar tu `fastapi` a esa nueva versión más reciente. -## Acerca de Starlette +## Sobre Starlette No deberías fijar la versión de `starlette`. -Diferentes versiones de **FastAPI** pueden usar una versión específica de Starlette. +Diferentes versiones de **FastAPI** utilizarán una versión más reciente específica de Starlette. -Entonces, puedes dejar que **FastAPI** se asegure por sí mismo de qué versión de Starlette usar. +Así que, puedes simplemente dejar que **FastAPI** use la versión correcta de Starlette. -## Acerca de Pydantic +## Sobre Pydantic -Pydantic incluye los tests para **FastAPI** dentro de sus propios tests, esto significa que las versiones de Pydantic (superiores a `1.0.0`) son compatibles con FastAPI. +Pydantic incluye los tests para **FastAPI** con sus propios tests, así que nuevas versiones de Pydantic (por encima de `1.0.0`) siempre son compatibles con FastAPI. -Puedes fijar Pydantic a cualquier versión superior a `1.0.0` e inferior a `2.0.0` que funcione para ti. +Puedes fijar Pydantic a cualquier versión por encima de `1.0.0` que funcione para ti. Por ejemplo: ```txt -pydantic>=1.2.0,<2.0.0 +pydantic>=2.7.0,<3.0.0 ``` diff --git a/docs/es/docs/features.md b/docs/es/docs/features.md index b75918dff..472fdd736 100644 --- a/docs/es/docs/features.md +++ b/docs/es/docs/features.md @@ -1,43 +1,43 @@ -# Características +# Funcionalidades -## Características de FastAPI +## Funcionalidades de FastAPI -**FastAPI** te provee lo siguiente: +**FastAPI** te ofrece lo siguiente: ### Basado en estándares abiertos -* OpenAPI para la creación de APIs, incluyendo declaraciones de path operations, parámetros, body requests, seguridad, etc. -* Documentación automática del modelo de datos con JSON Schema (dado que OpenAPI mismo está basado en JSON Schema). -* Diseñado alrededor de estos estándares después de un estudio meticuloso. En vez de ser una capa añadida a último momento. -* Esto también permite la **generación automática de código de cliente** para muchos lenguajes. +* OpenAPI para la creación de APIs, incluyendo declaraciones de path operations, parámetros, request bodies, seguridad, etc. +* Documentación automática de modelos de datos con JSON Schema (ya que OpenAPI en sí mismo está basado en JSON Schema). +* Diseñado alrededor de estos estándares, tras un estudio meticuloso. En lugar de ser una capa adicional. +* Esto también permite el uso de **generación de código cliente automática** en muchos idiomas. ### Documentación automática -Documentación interactiva de la API e interfaces web de exploración. Hay múltiples opciones, dos incluidas por defecto, porque el framework está basado en OpenAPI. +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. -* Swagger UI, con exploración interactiva, llama y prueba tu API directamente desde tu navegador. +* Swagger UI, con exploración interactiva, llama y prueba tu API directamente desde el navegador. -![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) +![Interacción Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) -* Documentación alternativa de la API con ReDoc. +* Documentación alternativa de API con ReDoc. ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### Simplemente Python moderno +### Solo Python moderno -Todo está basado en las declaraciones de tipo de **Python 3.8** estándar (gracias a Pydantic). No necesitas aprender una sintaxis nueva, solo Python moderno. +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 de cómo usar los tipos de Python (así no uses FastAPI) prueba el tutorial corto: [Python Types](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){.internal-link target=_blank}. -Escribes Python estándar con tipos así: +Escribes Python estándar con tipos: ```Python from datetime import date from pydantic import BaseModel -# Declaras la variable como un str -# y obtienes soporte del editor dentro de la función +# Declara una variable como un str +# y obtiene soporte del editor dentro de la función def main(user_id: str): return user_id @@ -49,7 +49,7 @@ class User(BaseModel): joined: date ``` -Este puede ser usado como: +Que luego puede ser usado como: ```Python my_user: User = User(id=3, name="John Doe", joined="2018-07-19") @@ -67,135 +67,135 @@ my_second_user: User = User(**second_user_data) `**second_user_data` significa: -Pasa las keys y los valores del dict `second_user_data` directamente como argumentos de key-value, equivalente a: `User(id=4, name="Mary", joined="2018-11-30")` +Pasa las claves y valores del dict `second_user_data` directamente como argumentos de clave-valor, equivalente a: `User(id=4, name="Mary", joined="2018-11-30")` /// ### Soporte del editor -El framework fue diseñado en su totalidad para ser fácil e intuitivo de usar. Todas las decisiones fueron probadas en múltiples editores antes de comenzar el desarrollo para asegurar la mejor experiencia de desarrollo. +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 la última encuesta a desarrolladores de Python fue claro que la característica más usada es el "auto-completado". +En las encuestas a desarrolladores de Python, es claro que una de las funcionalidades más usadas es el "autocompletado". -El framework **FastAPI** está creado para satisfacer eso. El auto-completado funciona en todas partes. +Todo el framework **FastAPI** está basado para satisfacer eso. El autocompletado funciona en todas partes. -No vas a tener que volver a la documentación seguido. +Rara vez necesitarás regresar a la documentación. -Así es como tu editor te puede ayudar: +Aquí está cómo tu editor podría ayudarte: * en Visual Studio Code: -![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) +![soporte del editor](https://fastapi.tiangolo.com/img/vscode-completion.png) * en PyCharm: -![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png) +![soporte del editor](https://fastapi.tiangolo.com/img/pycharm-completion.png) -Obtendrás completado para tu código que podrías haber considerado imposible antes. Por ejemplo, el key `price` dentro del JSON body (que podría haber estado anidado) que viene de un request. +Obtendrás autocompletado en código que podrías considerar imposible antes. Por ejemplo, la clave `price` dentro de un cuerpo JSON (que podría haber estado anidado) que proviene de un request. -Ya no pasará que escribas los nombres de key equivocados, o que tengas que revisar constantemente la documentación o desplazarte arriba y abajo para saber si usaste `username` o `user_name`. +No más escribir nombres de claves incorrectos, yendo de un lado a otro entre la documentación, o desplazándote hacia arriba y abajo para encontrar si finalmente usaste `username` o `user_name`. -### Corto +### Breve -Tiene **configuraciones por defecto** razonables para todo, con configuraciones opcionales en todas partes. Todos los parámetros pueden ser ajustados para tus necesidades y las de tu API. +Tiene **valores predeterminados** sensatos para todo, con configuraciones opcionales en todas partes. Todos los parámetros se pueden ajustar finamente para hacer lo que necesitas y para definir el API que necesitas. -Pero, todo **simplemente funciona** por defecto. +Pero por defecto, todo **"simplemente funciona"**. ### Validación -* Validación para la mayoría (¿o todos?) los **tipos de datos** de Python incluyendo: +* Validación para la mayoría (¿o todas?) de los **tipos de datos** de Python, incluyendo: * Objetos JSON (`dict`). - * JSON array (`list`) definiendo tipos de ítem. - * Campos de texto (`str`) definiendo longitudes mínimas y máximas. + * Array JSON (`list`) definiendo tipos de elementos. + * Campos de cadena de caracteres (`str`), definiendo longitudes mínimas y máximas. * Números (`int`, `float`) con valores mínimos y máximos, etc. -* Validación para tipos más exóticos como: +* Validación para tipos más exóticos, como: * URL. * Email. * UUID. * ...y otros. -Toda la validación es manejada por **Pydantic**, que es robusto y sólidamente establecido. +Toda la validación es manejada por **Pydantic**, una herramienta bien establecida y robusta. ### Seguridad y autenticación -La seguridad y la autenticación están integradas. Sin ningún compromiso con bases de datos ni modelos de datos. +Seguridad y autenticación integradas. Sin ningún compromiso con bases de datos o modelos de datos. -Todos los schemes de seguridad están definidos en OpenAPI incluyendo: +Todos los esquemas de seguridad definidos en OpenAPI, incluyendo: -* HTTP Basic. -* **OAuth2** (también con **JWT tokens**). Prueba el tutorial en [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. +* 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}. * API keys en: * Headers. - * Parámetros de Query. + * Parámetros de query. * Cookies, etc. -Más todas las características de seguridad de Starlette (incluyendo **session cookies**). +Además de todas las características de seguridad de Starlette (incluyendo **cookies de sesión**). -Todo ha sido construido como herramientas y componentes reutilizables que son fácilmente integrados con tus sistemas, almacenamiento de datos, bases de datos relacionales y no relacionales, etc. +Todo construido como herramientas y componentes reutilizables que son fáciles de integrar con tus sistemas, almacenes de datos, bases de datos relacionales y NoSQL, etc. -### Dependency Injection +### Inyección de dependencias -FastAPI incluye un sistema de Dependency Injection extremadamente poderoso y fácil de usar. +FastAPI incluye un sistema de Inyección de Dependencias extremadamente fácil de usar, pero extremadamente potente. -* Inclusive las dependencias pueden tener dependencias creando una jerarquía o un **"grafo" de dependencias**. -* Todas son **manejadas automáticamente** por el framework. -* Todas las dependencias pueden requerir datos de los requests y aumentar las restricciones del *path operation* y la documentación automática. -* **Validación automática** inclusive para parámetros del *path operation* definidos en las dependencias. -* Soporte para sistemas complejos de autenticación de usuarios, **conexiones con bases de datos**, etc. -* **Sin comprometerse** con bases de datos, frontend, etc. Pero permitiendo integración fácil con todos ellos. +* Incluso las dependencias pueden tener dependencias, creando una jerarquía o **"gráfico de dependencias"**. +* Todo **manejado automáticamente** por el framework. +* Todas las dependencias pueden requerir datos de los requests y **aumentar las restricciones de la path operation** y la documentación automática. +* **Validación automática** incluso para los parámetros de *path operation* definidos en las dependencias. +* Soporte para sistemas de autenticación de usuario complejos, **conexiones a bases de datos**, etc. +* **Sin compromisos** con bases de datos, frontends, etc. Pero fácil integración con todos ellos. ### "Plug-ins" ilimitados -O dicho de otra manera, no hay necesidad para "plug-ins". Importa y usa el código que necesites. +O de otra manera, no hay necesidad de ellos, importa y usa el código que necesitas. -Cualquier integración está diseñada para que sea tan sencilla de usar (con dependencias) que puedas crear un "plug-in" para tu aplicación en dos líneas de código usando la misma estructura y sintaxis que usaste para tus *path operations*. +Cualquier integración está diseñada para ser tan simple de usar (con dependencias) que puedes crear un "plug-in" para tu aplicación en 2 líneas de código usando la misma estructura y sintaxis utilizada para tus *path operations*. ### Probado -* Cobertura de pruebas al 100%. -* Base de código 100% anotada con tipos. +* 100% de cobertura de tests. +* Código completamente anotado con tipos. * Usado en aplicaciones en producción. -## Características de Starlette +## Funcionalidades de Starlette -**FastAPI** está basado y es completamente compatible con Starlette. Tanto así, que cualquier código de Starlette que tengas también funcionará. +**FastAPI** es totalmente compatible con (y está basado en) Starlette. Así que, cualquier código adicional de Starlette que tengas, también funcionará. -`FastAPI` es realmente una sub-clase de `Starlette`. Así que, si ya conoces o usas Starlette, muchas de las características funcionarán de la misma manera. +`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 características de **Starlette** (porque FastAPI es simplemente Starlette en esteroides): +Con **FastAPI** obtienes todas las funcionalidades de **Starlette** (ya que FastAPI es simplemente Starlette potenciado): -* Desempeño realmente impresionante. Es uno de los frameworks de Python más rápidos, a la par con **NodeJS** y **Go**. +* Rendimiento seriamente impresionante. Es uno de los frameworks de Python más rápidos disponibles, a la par de **NodeJS** y **Go**. * Soporte para **WebSocket**. -* Tareas en background. -* Eventos de startup y shutdown. -* Cliente de pruebas construido con HTTPX. -* **CORS**, GZip, Static Files, Streaming responses. -* Soporte para **Session and Cookie**. -* Cobertura de pruebas al 100%. -* Base de código 100% anotada con tipos. +* Tareas en segundo plano en el mismo proceso. +* Eventos de inicio y apagado. +* Cliente de prueba basado en HTTPX. +* **CORS**, GZip, archivos estáticos, responses en streaming. +* Soporte para **Session y Cookie**. +* Cobertura de tests del 100%. +* Código completamente anotado con tipos. -## Características de Pydantic +## Funcionalidades de Pydantic -**FastAPI** está basado y es completamente compatible con Pydantic. Tanto así, que cualquier código de Pydantic que tengas también funcionará. +**FastAPI** es totalmente compatible con (y está basado en) Pydantic. Por lo tanto, cualquier código adicional de Pydantic que tengas, también funcionará. -Esto incluye a librerías externas basadas en Pydantic como ORMs y ODMs para bases de datos. +Incluyendo paquetes externos también basados en Pydantic, como ORMs, ODMs para bases de datos. -Esto también significa que en muchos casos puedes pasar el mismo objeto que obtuviste de un request **directamente a la base de datos**, dado que todo es validado automáticamente. +Esto también significa que, en muchos casos, puedes pasar el mismo objeto que obtienes de un request **directamente a la base de datos**, ya que todo se valida automáticamente. -Lo mismo aplica para el sentido contrario. En muchos casos puedes pasar el objeto que obtienes de la base de datos **directamente al cliente**. +Lo mismo aplica al revés, en muchos casos puedes simplemente pasar el objeto que obtienes de la base de datos **directamente al cliente**. -Con **FastAPI** obtienes todas las características de **Pydantic** (dado que FastAPI está basado en Pydantic para todo el manejo de datos): +Con **FastAPI** obtienes todas las funcionalidades de **Pydantic** (ya que FastAPI está basado en Pydantic para todo el manejo de datos): -* **Sin dificultades para entender**: - * No necesitas aprender un nuevo micro-lenguaje de definición de schemas. - * Si sabes tipos de Python, sabes cómo usar Pydantic. -* Interactúa bien con tu **IDE/linter/cerebro**: - * Porque las estructuras de datos de Pydantic son solo instances de clases que tu defines, el auto-completado, el linting, mypy y tu intuición deberían funcionar bien con tus datos validados. +* **Sin complicaciones**: + * Sin micro-lenguaje de definición de esquemas nuevo que aprender. + * Si conoces los tipos en Python sabes cómo usar Pydantic. +* Se lleva bien con tu **IDE/linter/cerebro**: + * Porque las estructuras de datos de pydantic son solo instances de clases que defines; autocompletado, linting, mypy y tu intuición deberían funcionar correctamente con tus datos validados. * Valida **estructuras complejas**: - * Usa modelos jerárquicos de modelos de Pydantic, `typing` de Python, `List` y `Dict`, etc. - * Los validadores también permiten que se definan fácil y claramente schemas complejos de datos. Estos son chequeados y documentados como JSON Schema. - * Puedes tener objetos de **JSON profundamente anidados** y que todos sean validados y anotados. + * Uso de modelos jerárquicos de Pydantic, `List` y `Dict` de `typing` de Python, etc. + * Y los validadores permiten definir, verificar y documentar de manera clara y fácil esquemas de datos complejos como JSON Schema. + * Puedes tener objetos JSON profundamente **anidados** y validarlos todos y anotarlos. * **Extensible**: - * Pydantic permite que se definan tipos de datos a la medida o puedes extender la validación con métodos en un modelo decorado con el decorador de validación. -* Cobertura de pruebas al 100%. + * Pydantic permite definir tipos de datos personalizados o puedes extender la validación con métodos en un modelo decorados con el decorador validator. +* Cobertura de tests del 100%. diff --git a/docs/es/docs/how-to/graphql.md b/docs/es/docs/how-to/graphql.md index 2c0e80d77..52f163809 100644 --- a/docs/es/docs/how-to/graphql.md +++ b/docs/es/docs/how-to/graphql.md @@ -1,60 +1,60 @@ # GraphQL -Como **FastAPI** está basado en el estándar **ASGI**, es muy fácil integrar cualquier library **GraphQL** que sea compatible con ASGI. +Como **FastAPI** se basa en el estándar **ASGI**, es muy fácil integrar cualquier paquete de **GraphQL** que también sea compatible con ASGI. -Puedes combinar *operaciones de path* regulares de la library de FastAPI con GraphQL en la misma aplicación. +Puedes combinar las *path operations* normales de FastAPI con GraphQL en la misma aplicación. /// tip | Consejo -**GraphQL** resuelve algunos casos de uso específicos. +**GraphQL** resuelve algunos casos de uso muy específicos. -Tiene **ventajas** y **desventajas** cuando lo comparas con **APIs web** comunes. +Tiene **ventajas** y **desventajas** en comparación con las **APIs web** comunes. -Asegúrate de evaluar si los **beneficios** para tu caso de uso compensan las **desventajas.** 🤓 +Asegúrate de evaluar si los **beneficios** para tu caso de uso compensan los **inconvenientes**. 🤓 /// -## Librerías GraphQL +## Paquetes de GraphQL -Aquí hay algunas de las libraries de **GraphQL** que tienen soporte con **ASGI** las cuales podrías usar con **FastAPI**: +Aquí algunos de los paquetes de **GraphQL** que tienen soporte **ASGI**. Podrías usarlos con **FastAPI**: * Strawberry 🍓 * Con documentación para FastAPI * Ariadne * Con documentación para FastAPI * Tartiflette - * Con Tartiflette ASGI para proveer integración con ASGI + * Con Tartiflette ASGI para proporcionar integración con ASGI * Graphene * Con starlette-graphene3 ## GraphQL con Strawberry -Si necesitas o quieres trabajar con **GraphQL**, **Strawberry** es la library **recomendada** por el diseño más cercano a **FastAPI**, el cual es completamente basado en **anotaciones de tipo**. +Si necesitas o quieres trabajar con **GraphQL**, **Strawberry** 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 tus casos de uso, podrías preferir usar una library diferente, pero si me preguntas, probablemente te recomendaría **Strawberry**. +Dependiendo de tu caso de uso, podrías preferir usar un paquete diferente, pero si me preguntas, probablemente te sugeriría probar **Strawberry**. -Aquí hay una pequeña muestra de cómo podrías integrar Strawberry con FastAPI: +Aquí tienes una pequeña vista previa de cómo podrías integrar Strawberry con FastAPI: {* ../../docs_src/graphql/tutorial001.py hl[3,22,25:26] *} Puedes aprender más sobre Strawberry en la documentación de Strawberry. -Y también en la documentación sobre Strawberry con FastAPI. +Y también la documentación sobre Strawberry con FastAPI. -## Clase obsoleta `GraphQLApp` en Starlette +## `GraphQLApp` viejo de Starlette -Versiones anteriores de Starlette incluyen la clase `GraphQLApp` para integrarlo con Graphene. +Las versiones anteriores de Starlette incluían una clase `GraphQLApp` para integrar con Graphene. -Esto fue marcado como obsoleto en Starlette, pero si aún tienes código que lo usa, puedes fácilmente **migrar** a starlette-graphene3, la cual 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, que cubre el mismo caso de uso y tiene una **interfaz casi idéntica**. /// tip | Consejo -Si necesitas GraphQL, te recomendaría revisar Strawberry, que es basada en anotaciones de tipo en vez de clases y tipos personalizados. +Si necesitas GraphQL, aún te recomendaría revisar Strawberry, ya que se basa en anotaciones de tipos en lugar de clases y tipos personalizados. /// -## Aprende más +## Aprende Más -Puedes aprender más acerca de **GraphQL** en la documentación oficial de GraphQL. +Puedes aprender más sobre **GraphQL** en la documentación oficial de GraphQL. -También puedes leer más acerca de cada library descrita anteriormente en sus enlaces. +También puedes leer más sobre cada uno de esos paquetes descritos arriba en sus enlaces. diff --git a/docs/es/docs/index.md b/docs/es/docs/index.md index 73d9b679e..db8da6933 100644 --- a/docs/es/docs/index.md +++ b/docs/es/docs/index.md @@ -8,18 +8,21 @@ FastAPI

- FastAPI framework, alto desempeño, fácil de aprender, rápido de programar, listo para producción + FastAPI framework, alto rendimiento, fácil de aprender, rápido de programar, listo para producción

- - Test + + Test - - Coverage + + Coverage Package version + + Supported Python versions +

--- @@ -29,21 +32,21 @@ **Código Fuente**: https://github.com/fastapi/fastapi --- -FastAPI es un web framework moderno y rápido (de alto rendimiento) para construir APIs con Python basado en las anotaciones de tipos estándar de Python. -Sus características principales son: +FastAPI es un framework web moderno, rápido (de alto rendimiento), para construir APIs con Python basado en las anotaciones de tipos estándar de Python. -* **Rapidez**: Alto rendimiento, a la par con **NodeJS** y **Go** (gracias a Starlette y Pydantic). [Uno de los frameworks de Python más rápidos](#rendimiento). +Las características clave son: -* **Rápido de programar**: Incrementa la velocidad de desarrollo entre 200% y 300%. * -* **Menos errores**: Reduce los errores humanos (de programador) aproximadamente un 40%. * -* **Intuitivo**: Gran soporte en los editores con auto completado en todas partes. Gasta menos tiempo debugging. -* **Fácil**: Está diseñado para ser fácil de usar y aprender. Gastando menos tiempo leyendo documentación. -* **Corto**: Minimiza la duplicación de código. Múltiples funcionalidades con cada declaración de parámetros. Menos errores. -* **Robusto**: Crea código listo para producción con documentación automática interactiva. -* **Basado en estándares**: Basado y totalmente compatible con los estándares abiertos para APIs: OpenAPI (conocido previamente como Swagger) y JSON Schema. +* **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. Autocompletado 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: OpenAPI (anteriormente conocido como Swagger) y JSON Schema. -* Esta estimación está basada en pruebas con un equipo de desarrollo interno construyendo aplicaciones listas para producción. +* estimación basada en pruebas con un equipo de desarrollo interno, construyendo aplicaciones de producción. ## Sponsors @@ -64,41 +67,47 @@ Sus características principales son: ## Opiniones -"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" +"_[...] 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**._"
Kabir Khan - Microsoft (ref)
--- -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" +"_Adoptamos el paquete **FastAPI** para crear un servidor **REST** que pueda ser consultado para obtener **predicciones**. [para Ludwig]_" -
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
+
Piero Molino, Yaroslav Dudin, y Sai Sumanth Miryala - Uber (ref)
--- -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" +"_**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**]_"
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
--- -"_I’m over the moon excited about **FastAPI**. It’s so fun!_" +"_Estoy súper emocionado con **FastAPI**. ¡Es tan divertido!_" -
Brian Okken - Python Bytes podcast host (ref)
+
Brian Okken - host del podcast Python Bytes (ref)
--- -"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._" +"_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._" -
Timothy Crosley - Hug creator (ref)
+
Timothy Crosley - creador de Hug (ref)
--- -"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_" +"_Si estás buscando aprender un **framework moderno** para construir APIs REST, échale un vistazo a **FastAPI** [...] Es rápido, fácil de usar y fácil de aprender [...]_" + +"_Nos hemos cambiado a **FastAPI** para nuestras **APIs** [...] Creo que te gustará [...]_" + +
Ines Montani - Matthew Honnibal - fundadores de Explosion AI - creadores de spaCy (ref) - (ref)
+ +--- -"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_" +"_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._" -
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
+
Deon Pillsbury - Cisco (ref)
--- @@ -106,41 +115,33 @@ Sus características principales son: -Si estás construyendo un app de CLI para ser usada en la terminal en vez de una API web, fíjate en **Typer**. +Si estás construyendo una aplicación de CLI para ser usada en el terminal en lugar de una API web, revisa **Typer**. -**Typer** es el hermano menor de FastAPI. La intención es que sea el **FastAPI de las CLIs**. ⌨️ 🚀 +**Typer** es el hermano pequeño de FastAPI. Y está destinado a ser el **FastAPI de las CLIs**. ⌨️ 🚀 ## Requisitos -FastAPI está sobre los hombros de gigantes: +FastAPI se apoya en hombros de gigantes: * Starlette para las partes web. * Pydantic para las partes de datos. ## Instalación -
- -```console -$ pip install fastapi - ----> 100% -``` - -
- -También vas a necesitar un servidor ASGI para producción cómo Uvicorn o Hypercorn. +Crea y activa un entorno virtual y luego instala FastAPI:
```console -$ pip install "uvicorn[standard]" +$ pip install "fastapi[standard]" ---> 100% ```
+**Nota**: Asegúrate de poner `"fastapi[standard]"` entre comillas para asegurar que funcione en todas las terminales. + ## Ejemplo ### Créalo @@ -148,9 +149,10 @@ $ pip install "uvicorn[standard]" * Crea un archivo `main.py` con: ```Python -from fastapi import FastAPI from typing import Union +from fastapi import FastAPI + app = FastAPI() @@ -169,10 +171,11 @@ def read_item(item_id: int, q: Union[str, None] = None): Si tu código usa `async` / `await`, usa `async def`: -```Python hl_lines="7 12" -from fastapi import FastAPI +```Python hl_lines="9 14" from typing import Union +from fastapi import FastAPI + app = FastAPI() @@ -188,7 +191,7 @@ async def read_item(item_id: int, q: Union[str, None] = None): **Nota**: -Si no lo sabes, revisa la sección _"¿Con prisa?"_ sobre `async` y `await` en la documentación. +Si no lo sabes, revisa la sección _"¿Con prisa?"_ sobre `async` y `await` en la documentación. @@ -199,11 +202,24 @@ Corre el servidor con:
```console -$ uvicorn main:app --reload - +$ fastapi dev main.py + + ╭────────── FastAPI CLI - Development mode ───────────╮ + │ │ + │ Serving at: http://127.0.0.1:8000 │ + │ │ + │ API docs: http://127.0.0.1:8000/docs │ + │ │ + │ Running in development mode, for production use: │ + │ │ + │ fastapi run │ + │ │ + ╰─────────────────────────────────────────────────────╯ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [28720] -INFO: Started server process [28722] +INFO: Started reloader process [2248755] using WatchFiles +INFO: Started server process [2248757] INFO: Waiting for application startup. INFO: Application startup complete. ``` @@ -211,13 +227,13 @@ INFO: Application startup complete.
-Sobre el comando uvicorn main:app --reload... +Acerca del comando fastapi dev main.py... + +El comando `fastapi dev` lee tu archivo `main.py`, detecta la app **FastAPI** en él y arranca un servidor usando Uvicorn. -El comando `uvicorn main:app` se refiere a: +Por defecto, `fastapi dev` comenzará con auto-recarga habilitada para el desarrollo local. -* `main`: el archivo `main.py` (el"modulo" de Python). -* `app`: el objeto creado dentro de `main.py` con la línea `app = FastAPI()`. -* `--reload`: hace que el servidor se reinicie después de cambios en el código. Esta opción solo debe ser usada en desarrollo. +Puedes leer más sobre esto en la documentación del CLI de FastAPI.
@@ -225,7 +241,7 @@ El comando `uvicorn main:app` se refiere a: Abre tu navegador en http://127.0.0.1:8000/items/5?q=somequery. -Verás la respuesta de JSON cómo: +Verás el response JSON como: ```JSON {"item_id": 5, "q": "somequery"} @@ -233,37 +249,38 @@ Verás la respuesta de JSON cómo: Ya creaste una API que: -* Recibe HTTP requests en los _paths_ `/` y `/items/{item_id}`. -* Ambos _paths_ toman operaciones `GET` (también conocido como HTTP _methods_). -* El _path_ `/items/{item_id}` tiene un _path parameter_ `item_id` que debería ser un `int`. -* El _path_ `/items/{item_id}` tiene un `str` _query parameter_ `q` opcional. +* Recibe requests HTTP en los _paths_ `/` y `/items/{item_id}`. +* Ambos _paths_ toman _operaciones_ `GET` (también conocidas como métodos HTTP). +* El _path_ `/items/{item_id}` tiene un _parámetro de path_ `item_id` que debe ser un `int`. +* El _path_ `/items/{item_id}` tiene un _parámetro de query_ `q` opcional que es un `str`. -### Documentación interactiva de APIs +### Documentación interactiva de la API Ahora ve a http://127.0.0.1:8000/docs. -Verás la documentación automática e interactiva de la API (proveída por Swagger UI): +Verás la documentación interactiva automática de la API (proporcionada por Swagger UI): ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) -### Documentación alternativa de la API +### Documentación de API Alternativa -Ahora, ve a http://127.0.0.1:8000/redoc. +Y ahora, ve a http://127.0.0.1:8000/redoc. -Ahora verás la documentación automática alternativa (proveída por ReDoc): +Verás la documentación alternativa automática (proporcionada por ReDoc): ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) -## Mejora al ejemplo +## Actualización del Ejemplo -Ahora modifica el archivo `main.py` para recibir un body del `PUT` request. +Ahora modifica el archivo `main.py` para recibir un body desde un request `PUT`. -Declara el body usando las declaraciones de tipo estándares de Python gracias a Pydantic. +Declara el body usando tipos estándar de Python, gracias a Pydantic. + +```Python hl_lines="4 9-12 25-27" +from typing import Union -```Python hl_lines="2 7-10 23-25" from fastapi import FastAPI from pydantic import BaseModel -from typing import Union app = FastAPI() @@ -289,9 +306,9 @@ def update_item(item_id: int, item: Item): return {"item_name": item.name, "item_id": item_id} ``` -El servidor debería recargar automáticamente (porque añadiste `--reload` al comando `uvicorn` que está más arriba). +El servidor `fastapi dev` debería recargarse automáticamente. -### Mejora a la documentación interactiva de APIs +### Actualización de la Documentación Interactiva de la API Ahora ve a http://127.0.0.1:8000/docs. @@ -299,29 +316,29 @@ Ahora ve a http://127.0.0.1:8000/redoc. +Y ahora, ve a http://127.0.0.1:8000/redoc. -* La documentación alternativa también reflejará el nuevo parámetro de query y el body: +* La documentación alternativa también reflejará el nuevo parámetro de query y body: ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) ### Resumen -En resumen, declaras los tipos de parámetros, body, etc. **una vez** como parámetros de la función. +En resumen, declaras **una vez** los tipos de parámetros, body, etc. como parámetros de función. -Lo haces con tipos modernos estándar de Python. +Lo haces con tipos estándar modernos de Python. -No tienes que aprender una sintaxis nueva, los métodos o clases de una library específica, etc. +No tienes que aprender una nueva sintaxis, los métodos o clases de un paquete específico, etc. Solo **Python** estándar. @@ -331,7 +348,7 @@ Por ejemplo, para un `int`: item_id: int ``` -o para un modelo más complejo de `Item`: +o para un modelo `Item` más complejo: ```Python item: Item @@ -339,62 +356,62 @@ item: Item ...y con esa única declaración obtienes: -* Soporte del editor incluyendo: - * Auto completado. - * Anotaciones de tipos. +* Soporte para editores, incluyendo: + * Autocompletado. + * Chequeo de tipos. * Validación de datos: - * Errores automáticos y claros cuándo los datos son inválidos. - * Validación, incluso para objetos JSON profundamente anidados. -* Conversión de datos de input: viniendo de la red a datos y tipos de Python. Leyendo desde: + * Errores automáticos y claros cuando los datos son inválidos. + * Validación incluso para objetos JSON profundamente anidados. +* Conversión de datos de entrada: de la red a los datos y tipos de Python. Leyendo desde: * JSON. - * Path parameters. - * Query parameters. + * Parámetros de path. + * Parámetros de query. * Cookies. * Headers. - * Formularios. + * Forms. * Archivos. -* Conversión de datos de output: convirtiendo de datos y tipos de Python a datos para la red (como JSON): +* Conversión de datos de salida: convirtiendo de datos y tipos de Python a datos de red (como JSON): * Convertir tipos de Python (`str`, `int`, `float`, `bool`, `list`, etc). * Objetos `datetime`. * Objetos `UUID`. - * Modelos de bases de datos. + * Modelos de base de datos. * ...y muchos más. -* Documentación automática e interactiva incluyendo 2 interfaces de usuario alternativas: +* Documentación interactiva automática de la API, incluyendo 2 interfaces de usuario alternativas: * Swagger UI. * ReDoc. --- -Volviendo al ejemplo de código anterior, **FastAPI** va a: - -* Validar que existe un `item_id` en el path para requests usando `GET` y `PUT`. -* Validar que el `item_id` es del tipo `int` para requests de tipo `GET` y `PUT`. - * Si no lo es, el cliente verá un mensaje de error útil y claro. -* Revisar si existe un query parameter opcional llamado `q` (cómo en `http://127.0.0.1:8000/items/foo?q=somequery`) para requests de tipo `GET`. - * Como el parámetro `q` fue declarado con `= None` es opcional. - * Sin el `None` sería obligatorio (cómo lo es el body en el caso con `PUT`). -* Para requests de tipo `PUT` a `/items/{item_id}` leer el body como JSON: - * Revisar si tiene un atributo requerido `name` que debe ser un `str`. - * Revisar si tiene un atributo requerido `price` que debe ser un `float`. - * Revisar si tiene un atributo opcional `is_offer`, que debe ser un `bool`si está presente. - * Todo esto funcionaría para objetos JSON profundamente anidados. -* Convertir de y a JSON automáticamente. -* Documentar todo con OpenAPI que puede ser usado por: +Volviendo al ejemplo de código anterior, **FastAPI**: + +* Validará que haya un `item_id` en el path para requests `GET` y `PUT`. +* Validará que el `item_id` sea del tipo `int` para requests `GET` y `PUT`. + * Si no lo es, el cliente verá un error útil y claro. +* Comprobará si hay un parámetro de query opcional llamado `q` (como en `http://127.0.0.1:8000/items/foo?q=somequery`) para requests `GET`. + * Como el parámetro `q` está declarado con `= None`, es opcional. + * Sin el `None` sería requerido (como lo es el body en el caso con `PUT`). +* Para requests `PUT` a `/items/{item_id}`, leerá el body como JSON: + * Comprobará que tiene un atributo requerido `name` que debe ser un `str`. + * Comprobará que tiene un atributo requerido `price` que debe ser un `float`. + * Comprobará que tiene un atributo opcional `is_offer`, que debe ser un `bool`, si está presente. + * Todo esto también funcionaría para objetos JSON profundamente anidados. +* Convertirá de y a JSON automáticamente. +* Documentará todo con OpenAPI, que puede ser usado por: * Sistemas de documentación interactiva. - * Sistemas de generación automática de código de cliente para muchos lenguajes. -* Proveer directamente 2 interfaces de documentación web interactivas. + * Sistemas de generación automática de código cliente, para muchos lenguajes. +* Proporcionará 2 interfaces web de documentación interactiva directamente. --- -Hasta ahora, escasamente vimos lo básico pero ya tienes una idea de cómo funciona. +Solo tocamos los conceptos básicos, pero ya te haces una idea de cómo funciona todo. -Intenta cambiando la línea a: +Intenta cambiar la línea con: ```Python return {"item_name": item.name, "item_id": item_id} ``` -...de: +...desde: ```Python ... "item_name": item.name ... @@ -406,56 +423,74 @@ Intenta cambiando la línea a: ... "item_price": item.price ... ``` -... y mira como el editor va a auto-completar los atributos y sabrá sus tipos: +...y observa cómo tu editor autocompleta los atributos y conoce sus tipos: -![soporte de editor](https://fastapi.tiangolo.com/img/vscode-completion.png) +![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) -Para un ejemplo más completo que incluye más características ve el Tutorial - Guía de Usuario. +Para un ejemplo más completo incluyendo más funcionalidades, ve al Tutorial - Guía del Usuario. -**Spoiler alert**: el Tutorial - Guía de Usuario incluye: +**Alerta de spoilers**: el tutorial - guía del usuario incluye: -* Declaración de **parámetros** en otros lugares diferentes cómo los: **headers**, **cookies**, **formularios** y **archivos**. -* Cómo agregar **requisitos de validación** cómo `maximum_length` o `regex`. -* Un sistema de **Dependency Injection** poderoso y fácil de usar. -* Seguridad y autenticación incluyendo soporte para **OAuth2** con **JWT tokens** y **HTTP Basic** auth. -* Técnicas más avanzadas, pero igual de fáciles, para declarar **modelos de JSON profundamente anidados** (gracias a Pydantic). -* Muchas características extra (gracias a Starlette) como: +* Declaración de **parámetros** desde otros lugares diferentes como: **headers**, **cookies**, **campos de formulario** y **archivos**. +* Cómo establecer **restricciones de validación** como `maximum_length` o `regex`. +* Un sistema de **Inyección de Dependencias** 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 Strawberry y otros paquetes. +* Muchas funcionalidades extra (gracias a Starlette) como: * **WebSockets** - * **GraphQL** - * pruebas extremadamente fáciles con HTTPX y `pytest` + * pruebas extremadamente fáciles basadas en HTTPX y `pytest` * **CORS** - * **Cookie Sessions** - * ...y mucho más. + * **Sesiones de Cookies** + * ...y más. ## Rendimiento -Benchmarks independientes de TechEmpower muestran que aplicaciones de **FastAPI** corriendo con Uvicorn cómo uno de los frameworks de Python más rápidos, únicamente 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, solo por debajo de Starlette y Uvicorn (usados internamente por FastAPI). (*) + +Para entender más sobre esto, ve la sección Benchmarks. -Para entender más al respecto revisa la sección Benchmarks. +## Dependencias -## Dependencias Opcionales +FastAPI depende de Pydantic y Starlette. + +### Dependencias `standard` + +Cuando instalas FastAPI con `pip install "fastapi[standard]"` viene con el grupo `standard` de dependencias opcionales: Usadas por Pydantic: -* email-validator - para validación de emails. +* email-validator - para validación de correos electrónicos. + +Usadas por Starlette: + +* httpx - Requerido si deseas usar el `TestClient`. +* jinja2 - Requerido si deseas usar la configuración de plantilla predeterminada. +* python-multipart - Requerido si deseas soportar "parsing" de forms, con `request.form()`. + +Usadas por FastAPI / Starlette: + +* uvicorn - 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` - para proporcionar el comando `fastapi`. + +### Sin Dependencias `standard` + +Si no deseas incluir las dependencias opcionales `standard`, puedes instalar con `pip install fastapi` en lugar de `pip install "fastapi[standard]"`. + +### Dependencias Opcionales Adicionales -Usados por Starlette: +Existen algunas dependencias adicionales que podrías querer instalar. -* httpx - Requerido si quieres usar el `TestClient`. -* jinja2 - Requerido si quieres usar la configuración por defecto de templates. -* python-multipart - Requerido si quieres dar soporte a "parsing" de formularios, con `request.form()`. -* itsdangerous - Requerido para dar soporte a `SessionMiddleware`. -* pyyaml - Requerido para dar soporte al `SchemaGenerator` de Starlette (probablemente no lo necesites con FastAPI). -* graphene - Requerido para dar soporte a `GraphQLApp`. +Dependencias opcionales adicionales de Pydantic: -Usado por FastAPI / Starlette: +* pydantic-settings - para la gestión de configuraciones. +* pydantic-extra-types - para tipos extra para ser usados con Pydantic. -* uvicorn - para el servidor que carga y sirve tu aplicación. -* orjson - Requerido si quieres usar `ORJSONResponse`. -* ujson - Requerido si quieres usar `UJSONResponse`. +Dependencias opcionales adicionales de FastAPI: -Puedes instalarlos con `pip install fastapi[all]`. +* orjson - Requerido si deseas usar `ORJSONResponse`. +* ujson - Requerido si deseas usar `UJSONResponse`. ## Licencia -Este proyecto está licenciado bajo los términos de la licencia del MIT. +Este proyecto tiene licencia bajo los términos de la licencia MIT. diff --git a/docs/es/docs/learn/index.md b/docs/es/docs/learn/index.md index b8d26cf34..cc6c7cc3f 100644 --- a/docs/es/docs/learn/index.md +++ b/docs/es/docs/learn/index.md @@ -1,5 +1,5 @@ -# Aprender +# Aprende Aquí están las secciones introductorias y los tutoriales para aprender **FastAPI**. -Podrías considerar esto como un **libro**, un **curso**, la forma **oficial** y recomendada de aprender FastAPI. 😎 +Podrías considerar esto un **libro**, un **curso**, la forma **oficial** y recomendada de aprender FastAPI. 😎 diff --git a/docs/es/docs/project-generation.md b/docs/es/docs/project-generation.md index 6aa570397..559995151 100644 --- a/docs/es/docs/project-generation.md +++ b/docs/es/docs/project-generation.md @@ -1,28 +1,28 @@ -# Plantilla de FastAPI Full Stack +# Plantilla Full Stack FastAPI -Las plantillas, aunque típicamente vienen con una configuración específica, están diseñadas para ser flexibles y personalizables. Esto te permite modificarlas y adaptarlas a los requisitos de tu proyecto, lo que las convierte en un excelente punto de partida. 🏁 +Las plantillas, aunque normalmente vienen con una configuración específica, están diseñadas para ser flexibles y personalizables. Esto te permite modificarlas y adaptarlas a los requisitos de tu proyecto, haciéndolas un excelente punto de partida. 🏁 -Puedes utilizar esta plantilla para comenzar, ya que incluye gran parte de la configuración inicial, seguridad, base de datos y algunos endpoints de API ya realizados. +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 en GitHub: [Full Stack FastAPI Template](https://github.com/tiangolo/full-stack-fastapi-template) +Repositorio de GitHub: Plantilla Full Stack FastAPI -## Plantilla de FastAPI Full Stack - Tecnología y Características +## Plantilla Full Stack FastAPI - Tecnología y Funcionalidades -- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) para el backend API en Python. - - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) para las interacciones con la base de datos SQL en Python (ORM). - - 🔍 [Pydantic](https://docs.pydantic.dev), utilizado por FastAPI, para la validación de datos y la gestión de configuraciones. - - 💾 [PostgreSQL](https://www.postgresql.org) como la base de datos SQL. +- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) para la API del backend en Python. + - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) para las interacciones con bases de datos SQL en Python (ORM). + - 🔍 [Pydantic](https://docs.pydantic.dev), utilizado por FastAPI, para la validación de datos y gestión de configuraciones. + - 💾 [PostgreSQL](https://www.postgresql.org) como base de datos SQL. - 🚀 [React](https://react.dev) para el frontend. - - 💃 Usando TypeScript, hooks, [Vite](https://vitejs.dev) y otras partes de un stack de frontend moderno. + - 💃 Usando TypeScript, hooks, [Vite](https://vitejs.dev), y otras partes de una stack moderna de frontend. - 🎨 [Chakra UI](https://chakra-ui.com) para los componentes del frontend. - - 🤖 Un cliente frontend generado automáticamente. + - 🤖 Un cliente de frontend generado automáticamente. - 🧪 [Playwright](https://playwright.dev) para pruebas End-to-End. - 🦇 Soporte para modo oscuro. - 🐋 [Docker Compose](https://www.docker.com) para desarrollo y producción. - 🔒 Hashing seguro de contraseñas por defecto. -- 🔑 Autenticación con token JWT. +- 🔑 Autenticación con tokens JWT. - 📫 Recuperación de contraseñas basada en email. -- ✅ Tests con [Pytest](https://pytest.org). +- ✅ Pruebas con [Pytest](https://pytest.org). - 📞 [Traefik](https://traefik.io) como proxy inverso / balanceador de carga. -- 🚢 Instrucciones de despliegue utilizando Docker Compose, incluyendo cómo configurar un proxy frontend Traefik para manejar certificados HTTPS automáticos. +- 🚢 Instrucciones de despliegue usando Docker Compose, incluyendo cómo configurar un proxy Traefik frontend para manejar certificados HTTPS automáticos. - 🏭 CI (integración continua) y CD (despliegue continuo) basados en GitHub Actions. diff --git a/docs/es/docs/python-types.md b/docs/es/docs/python-types.md index de502314e..769204f8f 100644 --- a/docs/es/docs/python-types.md +++ b/docs/es/docs/python-types.md @@ -1,20 +1,20 @@ -# Introducción a los Tipos de Python +# Introducción a Tipos en Python -**Python 3.6+** tiene soporte para "type hints" opcionales. +Python tiene soporte para "anotaciones de tipos" opcionales (también llamadas "type hints"). -Estos **type hints** son una nueva sintaxis, desde Python 3.6+, que permite declarar el tipo de una variable. +Estas **"anotaciones de tipos"** o type hints son una sintaxis especial que permite declarar el tipo de una variable. -Usando las declaraciones de tipos para tus variables, los editores y otras herramientas pueden proveerte un soporte mejor. +Al declarar tipos para tus variables, los editores y herramientas te pueden proporcionar un mejor soporte. -Este es solo un **tutorial corto** sobre los Python type hints. Solo cubre lo mínimo necesario para usarlos con **FastAPI**... realmente es muy poco lo que necesitas. +Este es solo un **tutorial rápido / recordatorio** sobre las anotaciones de tipos en Python. Cubre solo lo mínimo necesario para usarlas con **FastAPI**... que en realidad es muy poco. -Todo **FastAPI** está basado en estos type hints, lo que le da muchas ventajas y beneficios. +**FastAPI** se basa completamente en estas anotaciones de tipos, dándole muchas ventajas y beneficios. -Pero, así nunca uses **FastAPI** te beneficiarás de aprender un poco sobre los type hints. +Pero incluso si nunca usas **FastAPI**, te beneficiaría aprender un poco sobre ellas. /// note | Nota -Si eres un experto en Python y ya lo sabes todo sobre los type hints, salta al siguiente capítulo. +Si eres un experto en Python, y ya sabes todo sobre las anotaciones de tipos, salta al siguiente capítulo. /// @@ -24,8 +24,7 @@ Comencemos con un ejemplo simple: {* ../../docs_src/python_types/tutorial001.py *} - -Llamar este programa nos muestra el siguiente output: +Llamar a este programa genera: ``` John Doe @@ -33,38 +32,37 @@ John Doe La función hace lo siguiente: -* Toma un `first_name` y un `last_name`. -* Convierte la primera letra de cada uno en una letra mayúscula con `title()`. -* Las concatena con un espacio en la mitad. +* Toma un `first_name` y `last_name`. +* Convierte la primera letra de cada uno a mayúsculas con `title()`. +* Concatena ambos con un espacio en el medio. {* ../../docs_src/python_types/tutorial001.py hl[2] *} - ### Edítalo Es un programa muy simple. -Ahora, imagina que lo estás escribiendo desde cero. +Pero ahora imagina que lo escribieras desde cero. -En algún punto habrías comenzado con la definición de la función, tenías los parámetros listos... +En algún momento habrías empezado la definición de la función, tenías los parámetros listos... -Pero, luego tienes que llamar "ese método que convierte la primera letra en una mayúscula". +Pero luego tienes que llamar "ese método que convierte la primera letra a mayúscula". -Era `upper`? O era `uppercase`? `first_uppercase`? `capitalize`? +¿Era `upper`? ¿Era `uppercase`? `first_uppercase`? `capitalize`? -Luego lo intentas con el viejo amigo de los programadores, el auto-completado del editor. +Entonces, pruebas con el amigo del viejo programador, el autocompletado del editor. -Escribes el primer parámetro de la función `first_name`, luego un punto (`.`) y luego presionas `Ctrl+Space` para iniciar el auto-completado. +Escribes el primer parámetro de la función, `first_name`, luego un punto (`.`) y luego presionas `Ctrl+Espacio` para activar el autocompletado. -Tristemente, no obtienes nada útil: +Pero, tristemente, no obtienes nada útil: - + -### Añade tipos +### Añadir tipos -Vamos a modificar una única línea de la versión previa. +Modifiquemos una sola línea de la versión anterior. -Vamos a cambiar exactamente este fragmento, los parámetros de la función, de: +Cambiaremos exactamente este fragmento, los parámetros de la función, de: ```Python first_name, last_name @@ -78,60 +76,57 @@ a: Eso es todo. -Esos son los "type hints": +Esas son las "anotaciones de tipos": {* ../../docs_src/python_types/tutorial002.py hl[1] *} - -No es lo mismo a declarar valores por defecto, como sería con: +Eso no es lo mismo que declarar valores predeterminados como sería con: ```Python first_name="john", last_name="doe" ``` -Es algo diferente. +Es una cosa diferente. -Estamos usando los dos puntos (`:`), no un símbolo de igual (`=`). +Estamos usando dos puntos (`:`), no igualdades (`=`). -Añadir los type hints normalmente no cambia lo que sucedería si ellos no estuviesen presentes. +Y agregar anotaciones de tipos normalmente no cambia lo que sucede de lo que ocurriría sin ellas. -Pero ahora imagina que nuevamente estás creando la función, pero con los type hints. +Pero ahora, imagina que nuevamente estás en medio de la creación de esa función, pero con anotaciones de tipos. -En el mismo punto intentas iniciar el auto-completado con `Ctrl+Space` y ves: +En el mismo punto, intentas activar el autocompletado con `Ctrl+Espacio` y ves: - + -Con esto puedes moverte hacia abajo viendo las opciones hasta que encuentras una que te suene: +Con eso, puedes desplazarte, viendo las opciones, hasta que encuentres la que "te suene": - + ## Más motivación -Mira esta función que ya tiene type hints: +Revisa esta función, ya tiene anotaciones de tipos: {* ../../docs_src/python_types/tutorial003.py hl[1] *} +Porque el editor conoce los tipos de las variables, no solo obtienes autocompletado, también obtienes chequeo de errores: -Como el editor conoce el tipo de las variables no solo obtienes auto-completado, si no que también obtienes chequeo de errores: + - - -Ahora que sabes que tienes que arreglarlo convierte `age` a un string con `str(age)`: +Ahora sabes que debes corregirlo, convertir `age` a un string con `str(age)`: {* ../../docs_src/python_types/tutorial004.py hl[2] *} +## Declaración de tipos -## Declarando tipos - -Acabas de ver el lugar principal para declarar los type hints. Como parámetros de las funciones. +Acabas de ver el lugar principal para declarar anotaciones de tipos. Como parámetros de función. -Este es también el lugar principal en que los usarías con **FastAPI**. +Este también es el lugar principal donde los utilizarías con **FastAPI**. ### Tipos simples -Puedes declarar todos los tipos estándar de Python, no solamente `str`. +Puedes declarar todos los tipos estándar de Python, no solo `str`. -Por ejemplo, puedes usar: +Puedes usar, por ejemplo: * `int` * `float` @@ -140,143 +135,442 @@ Por ejemplo, puedes usar: {* ../../docs_src/python_types/tutorial005.py hl[1] *} +### Tipos genéricos con parámetros de tipo + +Hay algunas estructuras de datos que pueden contener otros valores, como `dict`, `list`, `set` y `tuple`. Y los valores internos también pueden tener su propio tipo. + +Estos tipos que tienen tipos internos se denominan tipos "**genéricos**". Y es posible declararlos, incluso con sus tipos internos. + +Para declarar esos tipos y los tipos internos, puedes usar el módulo estándar de Python `typing`. Existe específicamente para soportar estas anotaciones de tipos. + +#### Versiones más recientes de Python + +La sintaxis que utiliza `typing` es **compatible** con todas las versiones, desde Python 3.6 hasta las versiones más recientes, incluyendo Python 3.9, Python 3.10, etc. -### Tipos con sub-tipos +A medida que avanza Python, las **versiones más recientes** vienen con soporte mejorado para estas anotaciones de tipos y en muchos casos ni siquiera necesitarás importar y usar el módulo `typing` para declarar las anotaciones de tipos. -Existen algunas estructuras de datos que pueden contener otros valores, como `dict`, `list`, `set` y `tuple`. Los valores internos pueden tener su propio tipo también. +Si puedes elegir una versión más reciente de Python para tu proyecto, podrás aprovechar esa simplicidad adicional. -Para declarar esos tipos y sub-tipos puedes usar el módulo estándar de Python `typing`. +En toda la documentación hay ejemplos compatibles con cada versión de Python (cuando hay una diferencia). -Él existe específicamente para dar soporte a este tipo de type hints. +Por ejemplo, "**Python 3.6+**" significa que es compatible con Python 3.6 o superior (incluyendo 3.7, 3.8, 3.9, 3.10, etc). Y "**Python 3.9+**" significa que es compatible con Python 3.9 o superior (incluyendo 3.10, etc). + +Si puedes usar las **últimas versiones de Python**, utiliza los ejemplos para la última versión, esos tendrán la **mejor y más simple sintaxis**, por ejemplo, "**Python 3.10+**". + +#### Lista + +Por ejemplo, vamos a definir una variable para ser una `list` de `str`. + +//// tab | Python 3.9+ + +Declara la variable, con la misma sintaxis de dos puntos (`:`). + +Como tipo, pon `list`. + +Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes: + +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial006_py39.py!} +``` -#### Listas +//// -Por ejemplo, vamos a definir una variable para que sea una `list` compuesta de `str`. +//// tab | Python 3.8+ De `typing`, importa `List` (con una `L` mayúscula): -{* ../../docs_src/python_types/tutorial006.py hl[1] *} +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial006.py!} +``` + +Declara la variable, con la misma sintaxis de dos puntos (`:`). + +Como tipo, pon el `List` que importaste de `typing`. + +Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes: + +```Python hl_lines="4" +{!> ../../docs_src/python_types/tutorial006.py!} +``` +//// -Declara la variable con la misma sintaxis de los dos puntos (`:`). +/// info | Información -Pon `List` como el tipo. +Esos tipos internos en los corchetes se denominan "parámetros de tipo". -Como la lista es un tipo que permite tener un "sub-tipo" pones el sub-tipo en corchetes `[]`: +En este caso, `str` es el parámetro de tipo pasado a `List` (o `list` en Python 3.9 y superior). -{* ../../docs_src/python_types/tutorial006.py hl[4] *} +/// +Eso significa: "la variable `items` es una `list`, y cada uno de los ítems en esta lista es un `str`". -Esto significa: la variable `items` es una `list` y cada uno de los ítems en esta lista es un `str`. +/// tip | Consejo -Con esta declaración tu editor puede proveerte soporte inclusive mientras está procesando ítems de la lista. +Si usas Python 3.9 o superior, no tienes que importar `List` de `typing`, puedes usar el mismo tipo `list` regular en su lugar. + +/// -Sin tipos el auto-completado en este tipo de estructura es casi imposible de lograr: +Al hacer eso, tu editor puede proporcionar soporte incluso mientras procesa elementos de la lista: - + -Observa que la variable `item` es unos de los elementos en la lista `items`. +Sin tipos, eso es casi imposible de lograr. -El editor aún sabe que es un `str` y provee soporte para ello. +Nota que la variable `item` es uno de los elementos en la lista `items`. -#### Tuples y Sets +Y aún así, el editor sabe que es un `str` y proporciona soporte para eso. + +#### Tuple y Set Harías lo mismo para declarar `tuple`s y `set`s: -{* ../../docs_src/python_types/tutorial007.py hl[1,4] *} +//// tab | Python 3.9+ + +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial007_py39.py!} +``` +//// + +//// tab | Python 3.8+ + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial007.py!} +``` + +//// Esto significa: * La variable `items_t` es un `tuple` con 3 ítems, un `int`, otro `int`, y un `str`. -* La variable `items_s` es un `set` y cada uno de sus ítems es de tipo `bytes`. +* La variable `items_s` es un `set`, y cada uno de sus ítems es del tipo `bytes`. + +#### Dict + +Para definir un `dict`, pasas 2 parámetros de tipo, separados por comas. -#### Diccionarios (Dicts) +El primer parámetro de tipo es para las claves del `dict`. -Para definir un `dict` le pasas 2 sub-tipos separados por comas. +El segundo parámetro de tipo es para los valores del `dict`: -El primer sub-tipo es para los keys del `dict`. +//// tab | Python 3.9+ -El segundo sub-tipo es para los valores del `dict`: +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial008_py39.py!} +``` + +//// -{* ../../docs_src/python_types/tutorial008.py hl[1,4] *} +//// tab | Python 3.8+ +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial008.py!} +``` + +//// Esto significa: * La variable `prices` es un `dict`: - * Los keys de este `dict` son de tipo `str` (Digamos que son el nombre de cada ítem). - * Los valores de este `dict` son de tipo `float` (Digamos que son el precio de cada ítem). + * Las claves de este `dict` son del tipo `str` (digamos, el nombre de cada ítem). + * Los valores de este `dict` son del tipo `float` (digamos, el precio de cada ítem). + +#### Union + +Puedes declarar que una variable puede ser cualquier de **varios tipos**, por ejemplo, un `int` o un `str`. + +En Python 3.6 y posterior (incluyendo Python 3.10) puedes usar el tipo `Union` de `typing` y poner dentro de los corchetes los posibles tipos a aceptar. + +En Python 3.10 también hay una **nueva sintaxis** donde puedes poner los posibles tipos separados por una barra vertical (`|`). + +//// tab | Python 3.10+ + +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial008b_py310.py!} +``` + +//// + +//// tab | Python 3.8+ + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial008b.py!} +``` + +//// + +En ambos casos, esto significa que `item` podría ser un `int` o un `str`. + +#### Posiblemente `None` + +Puedes declarar que un valor podría tener un tipo, como `str`, pero que también podría ser `None`. + +En Python 3.6 y posteriores (incluyendo Python 3.10) puedes declararlo importando y usando `Optional` del módulo `typing`. + +```Python hl_lines="1 4" +{!../../docs_src/python_types/tutorial009.py!} +``` + +Usar `Optional[str]` en lugar de solo `str` te permitirá al editor ayudarte a detectar errores donde podrías estar asumiendo que un valor siempre es un `str`, cuando en realidad también podría ser `None`. + +`Optional[Something]` es realmente un atajo para `Union[Something, None]`, son equivalentes. + +Esto también significa que en Python 3.10, puedes usar `Something | None`: + +//// tab | Python 3.10+ + +```Python hl_lines="1" +{!> ../../docs_src/python_types/tutorial009_py310.py!} +``` + +//// + +//// tab | Python 3.8+ + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial009.py!} +``` + +//// + +//// tab | Python 3.8+ alternative + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial009b.py!} +``` + +//// + +#### Uso de `Union` u `Optional` + +Si estás usando una versión de Python inferior a 3.10, aquí tienes un consejo desde mi punto de vista muy **subjetivo**: + +* 🚨 Evita usar `Optional[SomeType]` +* En su lugar ✨ **usa `Union[SomeType, None]`** ✨. + +Ambos son equivalentes y debajo son lo mismo, pero recomendaría `Union` en lugar de `Optional` porque la palabra "**opcional**" parecería implicar que el valor es opcional, y en realidad significa "puede ser `None`", incluso si no es opcional y aún es requerido. + +Creo que `Union[SomeType, None]` es más explícito sobre lo que significa. + +Se trata solo de las palabras y nombres. Pero esas palabras pueden afectar cómo tú y tus compañeros de equipo piensan sobre el código. + +Como ejemplo, tomemos esta función: + +{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *} + +El parámetro `name` está definido como `Optional[str]`, pero **no es opcional**, no puedes llamar a la función sin el parámetro: + +```Python +say_hi() # ¡Oh, no, esto lanza un error! 😱 +``` + +El parámetro `name` sigue siendo **requerido** (no *opcional*) porque no tiene un valor predeterminado. Aún así, `name` acepta `None` como valor: + +```Python +say_hi(name=None) # Esto funciona, None es válido 🎉 +``` + +La buena noticia es que, una vez que estés en Python 3.10, no tendrás que preocuparte por eso, ya que podrás simplemente usar `|` para definir uniones de tipos: + +{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *} + +Y entonces no tendrás que preocuparte por nombres como `Optional` y `Union`. 😎 + +#### Tipos genéricos + +Estos tipos que toman parámetros de tipo en corchetes se llaman **Tipos Genéricos** o **Genéricos**, por ejemplo: + +//// tab | Python 3.10+ + +Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos dentro): + +* `list` +* `tuple` +* `set` +* `dict` + +Y lo mismo que con Python 3.8, desde el módulo `typing`: + +* `Union` +* `Optional` (lo mismo que con Python 3.8) +* ...y otros. + +En Python 3.10, como alternativa a usar los genéricos `Union` y `Optional`, puedes usar la barra vertical (`|`) para declarar uniones de tipos, eso es mucho mejor y más simple. + +//// + +//// tab | Python 3.9+ + +Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos dentro): + +* `list` +* `tuple` +* `set` +* `dict` + +Y lo mismo que con Python 3.8, desde el módulo `typing`: + +* `Union` +* `Optional` +* ...y otros. + +//// + +//// tab | Python 3.8+ + +* `List` +* `Tuple` +* `Set` +* `Dict` +* `Union` +* `Optional` +* ...y otros. + +//// ### Clases como tipos También puedes declarar una clase como el tipo de una variable. -Digamos que tienes una clase `Person`con un nombre: +Digamos que tienes una clase `Person`, con un nombre: + +{* ../../docs_src/python_types/tutorial010.py hl[1:3] *} + +Luego puedes declarar una variable para que sea de tipo `Person`: -{* ../../docs_src/python_types/tutorial009.py hl[1:3] *} +{* ../../docs_src/python_types/tutorial010.py hl[6] *} +Y luego, nuevamente, obtienes todo el soporte del editor: -Entonces puedes declarar una variable que sea de tipo `Person`: + -{* ../../docs_src/python_types/tutorial009.py hl[6] *} +Nota que esto significa "`one_person` es una **instance** de la clase `Person`". +No significa "`one_person` es la **clase** llamada `Person`". -Una vez más tendrás todo el soporte del editor: +## Modelos Pydantic - +Pydantic es un paquete de Python para realizar la validación de datos. -## Modelos de Pydantic +Declaras la "forma" de los datos como clases con atributos. -Pydantic es una library de Python para llevar a cabo validación de datos. +Y cada atributo tiene un tipo. -Tú declaras la "forma" de los datos mediante clases con atributos. +Entonces creas un instance de esa clase con algunos valores y validará los valores, los convertirá al tipo adecuado (si es el caso) y te dará un objeto con todos los datos. -Cada atributo tiene un tipo. +Y obtienes todo el soporte del editor con ese objeto resultante. -Luego creas un instance de esa clase con algunos valores y Pydantic validará los valores, los convertirá al tipo apropiado (si ese es el caso) y te dará un objeto con todos los datos. +Un ejemplo de la documentación oficial de Pydantic: -Y obtienes todo el soporte del editor con el objeto resultante. +//// tab | Python 3.10+ -Tomado de la documentación oficial de Pydantic: +```Python +{!> ../../docs_src/python_types/tutorial011_py310.py!} +``` + +//// + +//// tab | Python 3.9+ + +```Python +{!> ../../docs_src/python_types/tutorial011_py39.py!} +``` + +//// -{* ../../docs_src/python_types/tutorial010.py *} +//// tab | Python 3.8+ +```Python +{!> ../../docs_src/python_types/tutorial011.py!} +``` + +//// /// info | Información -Para aprender más sobre Pydantic mira su documentación. +Para saber más sobre Pydantic, revisa su documentación. /// -**FastAPI** está todo basado en Pydantic. +**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}. + +/// tip | Consejo + +Pydantic tiene un comportamiento especial cuando utilizas `Optional` o `Union[Something, None]` sin un valor por defecto, puedes leer más sobre ello en la documentación de Pydantic sobre Required Optional fields. + +/// + +## Anotaciones de tipos con metadata + +Python también tiene una funcionalidad que permite poner **metadata adicional** en estas anotaciones de tipos usando `Annotated`. + +//// tab | Python 3.9+ -Vas a ver mucho más de esto en práctica en el [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}. +En Python 3.9, `Annotated` es parte de la librería estándar, así que puedes importarlo desde `typing`. + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial013_py39.py!} +``` + +//// + +//// tab | Python 3.8+ + +En versiones por debajo de Python 3.9, importas `Annotated` de `typing_extensions`. + +Ya estará instalado con **FastAPI**. + +```Python hl_lines="1 4" +{!> ../../docs_src/python_types/tutorial013.py!} +``` + +//// + +Python en sí no hace nada con este `Annotated`. Y para los editores y otras herramientas, el tipo sigue siendo `str`. + +Pero puedes usar este espacio en `Annotated` para proporcionar a **FastAPI** metadata adicional sobre cómo quieres que se comporte tu aplicación. + +Lo importante a recordar es que **el primer *parámetro de tipo*** que pasas a `Annotated` es el **tipo real**. El resto es solo metadata para otras herramientas. + +Por ahora, solo necesitas saber que `Annotated` existe, y que es Python estándar. 😎 + +Luego verás lo **poderoso** que puede ser. + +/// tip | Consejo + +El hecho de que esto sea **Python estándar** significa que seguirás obteniendo la **mejor experiencia de desarrollador posible** en tu editor, con las herramientas que usas para analizar y refactorizar tu código, etc. ✨ + +Y también que tu código será muy compatible con muchas otras herramientas y paquetes de Python. 🚀 + +/// -## Type hints en **FastAPI** +## Anotaciones de tipos en **FastAPI** -**FastAPI** aprovecha estos type hints para hacer varias cosas. +**FastAPI** aprovecha estas anotaciones de tipos para hacer varias cosas. -Con **FastAPI** declaras los parámetros con type hints y obtienes: +Con **FastAPI** declaras parámetros con anotaciones de tipos y obtienes: -* **Soporte en el editor**. -* **Type checks**. +* **Soporte del editor**. +* **Chequeo de tipos**. ...y **FastAPI** usa las mismas declaraciones para: -* **Definir requerimientos**: desde request path parameters, query parameters, headers, bodies, dependencies, etc. -* **Convertir datos**: desde el request al tipo requerido. -* **Validar datos**: viniendo de cada request: +* **Definir requerimientos**: de parámetros de path de la request, parámetros de query, headers, bodies, dependencias, etc. +* **Convertir datos**: de la request al tipo requerido. +* **Validar datos**: provenientes de cada request: * Generando **errores automáticos** devueltos al cliente cuando los datos son inválidos. * **Documentar** la API usando OpenAPI: - * que en su caso es usada por las interfaces de usuario de la documentación automática e interactiva. + * Que luego es usada por las interfaces de documentación interactiva automática. -Puede que todo esto suene abstracto. Pero no te preocupes que todo lo verás en acción en el [Tutorial - User Guide](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){.internal-link target=_blank}. -Lo importante es que usando los tipos de Python estándar en un único lugar (en vez de añadir más clases, decorator, etc.) **FastAPI** hará mucho del trabajo por ti. +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 pasaste por todo el tutorial y volviste a la sección de los tipos, una buena referencia es la "cheat sheet" de `mypy`. +Si ya revisaste todo el tutorial y volviste para ver más sobre tipos, un buen recurso es la "cheat sheet" de `mypy`. /// diff --git a/docs/es/docs/tutorial/cookie-params.md b/docs/es/docs/tutorial/cookie-params.md index 9a3b1a00b..45b113ff9 100644 --- a/docs/es/docs/tutorial/cookie-params.md +++ b/docs/es/docs/tutorial/cookie-params.md @@ -1,30 +1,30 @@ # Parámetros de Cookie -Puedes definir parámetros de Cookie de la misma manera que defines parámetros de `Query` y `Path`. +Puedes definir parámetros de Cookie de la misma manera que defines los parámetros `Query` y `Path`. ## Importar `Cookie` Primero importa `Cookie`: -{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3]*} +{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *} ## Declarar parámetros de `Cookie` Luego declara los parámetros de cookie usando la misma estructura que con `Path` y `Query`. -El primer valor es el valor por defecto, puedes pasar todos los parámetros adicionales de validación o anotación: +Puedes definir el valor por defecto así como toda la validación extra o los parámetros de anotación: -{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9]*} +{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *} /// note | Detalles Técnicos `Cookie` es una clase "hermana" de `Path` y `Query`. También hereda de la misma clase común `Param`. -Pero recuerda que cuando importas `Query`, `Path`, `Cookie` y otros de `fastapi`, en realidad son funciones que devuelven clases especiales. +Pero recuerda que cuando importas `Query`, `Path`, `Cookie` y otros desde `fastapi`, en realidad son funciones que devuelven clases especiales. /// -/// info +/// info | Información Para declarar cookies, necesitas usar `Cookie`, porque de lo contrario los parámetros serían interpretados como parámetros de query. diff --git a/docs/es/docs/tutorial/first-steps.md b/docs/es/docs/tutorial/first-steps.md index 4cc4cc11d..5d869c22f 100644 --- a/docs/es/docs/tutorial/first-steps.md +++ b/docs/es/docs/tutorial/first-steps.md @@ -1,50 +1,74 @@ -# Primeros pasos +# Primeros Pasos -Un archivo muy simple de FastAPI podría verse así: +El archivo FastAPI más simple podría verse así: {* ../../docs_src/first_steps/tutorial001.py *} -Copia eso a un archivo `main.py`. +Copia eso en un archivo `main.py`. -Corre el servidor en vivo: +Ejecuta el servidor en vivo:
```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [28720] -INFO: Started server process [28722] -INFO: Waiting for application startup. -INFO: Application startup complete. +$ fastapi dev main.py +INFO Using path main.py +INFO Resolved absolute path /home/user/code/awesomeapp/main.py +INFO Searching for package file structure from directories with __init__.py files +INFO Importing from /home/user/code/awesomeapp + + ╭─ Python module file ─╮ + │ │ + │ 🐍 main.py │ + │ │ + ╰──────────────────────╯ + +INFO Importing module main +INFO Found importable FastAPI app + + ╭─ Importable FastAPI app ─╮ + │ │ + │ from main import app │ + │ │ + ╰──────────────────────────╯ + +INFO Using import string main:app + + ╭────────── FastAPI CLI - Development mode ───────────╮ + │ │ + │ Serving at: http://127.0.0.1:8000 │ + │ │ + │ API docs: http://127.0.0.1:8000/docs │ + │ │ + │ Running in development mode, for production use: │ + │ │ + fastapi run + │ │ + ╰─────────────────────────────────────────────────────╯ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +INFO: Started reloader process [2265862] using WatchFiles +INFO: Started server process [2265873] +INFO: Waiting for application startup. +INFO: Application startup complete. ```
-/// note | Nota - -El comando `uvicorn main:app` se refiere a: - -* `main`: el archivo `main.py` (el "módulo" de Python). -* `app`: el objeto creado dentro de `main.py` con la línea `app = FastAPI()`. -* `--reload`: hace que el servidor se reinicie cada vez que cambia el código. Úsalo únicamente para desarrollo. - -/// - -En el output, hay una línea que dice más o menos: +En el resultado, hay una línea con algo como: ```hl_lines="4" INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) ``` -Esa línea muestra la URL dónde se está sirviendo tu app en tu maquina local. +Esa línea muestra la URL donde tu aplicación está siendo servida, en tu máquina local. -### Revísalo +### Compruébalo Abre tu navegador en http://127.0.0.1:8000. -Verás la respuesta en JSON: +Verás el response JSON como: ```JSON {"message": "Hello World"} @@ -52,55 +76,55 @@ Verás la respuesta en JSON: ### Documentación interactiva de la API -Ahora dirígete a http://127.0.0.1:8000/docs. +Ahora ve a http://127.0.0.1:8000/docs. -Ahí verás la documentación automática e interactiva de la API (proveída por Swagger UI): +Verás la documentación interactiva automática de la API (proporcionada por Swagger UI): ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) ### Documentación alternativa de la API -Ahora, dirígete a http://127.0.0.1:8000/redoc. +Y ahora, ve a http://127.0.0.1:8000/redoc. -Aquí verás la documentación automática alternativa (proveída por ReDoc): +Verás la documentación alternativa automática (proporcionada por ReDoc): ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) ### OpenAPI -**FastAPI** genera un "schema" con toda tu API usando el estándar para definir APIs, **OpenAPI**. +**FastAPI** genera un "esquema" con toda tu API utilizando el estándar **OpenAPI** para definir APIs. -#### "Schema" +#### "Esquema" -Un "schema" es una definición o descripción de algo. No es el código que la implementa, sino solo una descripción abstracta. +Un "esquema" es una definición o descripción de algo. No el código que lo implementa, sino solo una descripción abstracta. -#### "Schema" de la API +#### Esquema de la API -En este caso, OpenAPI es una especificación que dicta como se debe definir el schema de tu API. +En este caso, OpenAPI es una especificación que dicta cómo definir un esquema de tu API. -La definición del schema incluye los paths de tu API, los parámetros que podría recibir, etc. +Esta definición de esquema incluye los paths de tu API, los posibles parámetros que toman, etc. -#### "Schema" de datos +#### Esquema de Datos -El concepto "schema" también se puede referir a la forma de algunos datos, como un contenido en formato JSON. +El término "esquema" también podría referirse a la forma de algunos datos, como el contenido JSON. -En ese caso haría referencia a los atributos del JSON, los tipos de datos que tiene, etc. +En ese caso, significaría los atributos del JSON, los tipos de datos que tienen, etc. #### OpenAPI y JSON Schema -OpenAPI define un schema de API para tu API. Ese schema incluye definiciones (o "schemas") de los datos enviados y recibidos por tu API usando **JSON Schema**, el estándar para los schemas de datos en JSON. +OpenAPI define un esquema de API para tu API. Y ese esquema incluye definiciones (o "esquemas") de los datos enviados y recibidos por tu API utilizando **JSON Schema**, el estándar para esquemas de datos JSON. #### Revisa el `openapi.json` -Si sientes curiosidad por saber cómo se ve el schema de OpenAPI en bruto, FastAPI genera automáticamente un (schema) JSON con la descripción de todo tu API. +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. -Lo puedes ver directamente en: http://127.0.0.1:8000/openapi.json. +Puedes verlo directamente en: http://127.0.0.1:8000/openapi.json. -Esto te mostrará un JSON que comienza con algo como: +Mostrará un JSON que empieza con algo como: ```JSON { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": { "title": "FastAPI", "version": "0.1.0" @@ -119,73 +143,45 @@ Esto te mostrará un JSON que comienza con algo como: ... ``` -#### ¿Para qué se usa OpenAPI? +#### Para qué sirve OpenAPI -El schema de OpenAPI es lo que alimenta a los dos sistemas de documentación interactiva incluidos. +El esquema OpenAPI es lo que impulsa los dos sistemas de documentación interactiva incluidos. -También hay docenas de alternativas, todas basadas en OpenAPI. Podrías añadir fácilmente cualquiera de esas alternativas a tu aplicación construida con **FastAPI**. +Y hay docenas de alternativas, todas basadas en OpenAPI. Podrías añadir fácilmente cualquiera de esas alternativas a tu aplicación construida con **FastAPI**. -También podrías usarlo para generar código automáticamente, para los clientes que se comunican con tu API. Por ejemplo, frontend, móvil o aplicaciones de IoT. +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. -## Repaso, paso a paso +## Recapitulación, paso a paso ### Paso 1: importa `FastAPI` {* ../../docs_src/first_steps/tutorial001.py hl[1] *} -`FastAPI` es una clase de Python que provee toda la funcionalidad para tu API. +`FastAPI` es una clase de Python que proporciona toda la funcionalidad para tu API. /// note | Detalles Técnicos `FastAPI` es una clase que hereda directamente de `Starlette`. -También puedes usar toda la funcionalidad de Starlette. +Puedes usar toda la funcionalidad de Starlette con `FastAPI` también. /// -### Paso 2: crea un "instance" de `FastAPI` +### Paso 2: crea una "instance" de `FastAPI` {* ../../docs_src/first_steps/tutorial001.py hl[3] *} -Aquí la variable `app` será un instance de la clase `FastAPI`. +Aquí la variable `app` será una "instance" de la clase `FastAPI`. -Este será el punto de interacción principal para crear todo tu API. - -Esta `app` es la misma a la que nos referimos cuando usamos el comando de `uvicorn`: - -
- -```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
- -Si creas un app como: - -{* ../../docs_src/first_steps/tutorial002.py hl[3] *} - -y lo guardas en un archivo `main.py`, entonces ejecutarías `uvicorn` así: - -
- -```console -$ uvicorn main:my_awesome_api --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -``` - -
+Este será el punto principal de interacción para crear toda tu API. -### Paso 3: crea una *operación de path* +### Paso 3: crea una *path operation* #### Path -"Path" aquí se refiere a la última parte de una URL comenzando desde el primer `/`. +"Path" aquí se refiere a la última parte de la URL empezando desde la primera `/`. -Entonces, en una URL como: +Así que, en una URL como: ``` https://example.com/items/foo @@ -197,19 +193,19 @@ https://example.com/items/foo /items/foo ``` -/// info | Información +/// info -Un "path" también se conoce habitualmente como "endpoint", "route" o "ruta". +Un "path" también es comúnmente llamado "endpoint" o "ruta". /// -Cuando construyes una API, el "path" es la manera principal de separar los "intereses" y los "recursos". +Mientras construyes una API, el "path" es la forma principal de separar "concerns" y "resources". #### Operación -"Operación" aquí se refiere a uno de los "métodos" de HTTP. +"Operación" aquí se refiere a uno de los "métodos" HTTP. -Uno como: +Uno de: * `POST` * `GET` @@ -223,43 +219,43 @@ Uno como: * `PATCH` * `TRACE` -En el protocolo de HTTP, te puedes comunicar con cada path usando uno (o más) de estos "métodos". +En el protocolo HTTP, puedes comunicarte con cada path usando uno (o más) de estos "métodos". --- -Cuando construyes APIs, normalmente usas uno de estos métodos específicos de HTTP para realizar una acción específica. +Al construir APIs, normalmente usas estos métodos HTTP específicos para realizar una acción específica. Normalmente usas: * `POST`: para crear datos. * `GET`: para leer datos. * `PUT`: para actualizar datos. -* `DELETE`: para borrar datos. +* `DELETE`: para eliminar datos. -Así que en OpenAPI, cada uno de estos métodos de HTTP es referido como una "operación". +Así que, en OpenAPI, cada uno de los métodos HTTP se llama una "operation". -Nosotros también los llamaremos "**operación**". +Vamos a llamarlas "**operaciones**" también. -#### Define un *decorador de operaciones de path* +#### Define un *path operation decorator* {* ../../docs_src/first_steps/tutorial001.py hl[6] *} -El `@app.get("/")` le dice a **FastAPI** que la función que tiene justo debajo está a cargo de manejar los requests que van a: +El `@app.get("/")` le dice a **FastAPI** que la función justo debajo se encarga de manejar requests que vayan a: * el path `/` -* usando una operación get +* usando una get operation /// info | Información sobre `@decorator` -Esa sintaxis `@algo` se llama un "decorador" en Python. +Esa sintaxis `@algo` en Python se llama un "decorador". -Lo pones encima de una función. Es como un lindo sombrero decorado (creo que de ahí salió el concepto). +Lo pones encima de una función. Como un bonito sombrero decorativo (supongo que de ahí viene el término). -Un "decorador" toma la función que tiene debajo y hace algo con ella. +Un "decorador" toma la función de abajo y hace algo con ella. -En nuestro caso, este decorador le dice a **FastAPI** que la función que está debajo corresponde al **path** `/` con una **operación** `get`. +En nuestro caso, este decorador le dice a **FastAPI** que la función de abajo corresponde al **path** `/` con una **operation** `get`. -Es el "**decorador de operaciones de path**". +Es el "**path operation decorator**". /// @@ -269,67 +265,67 @@ También puedes usar las otras operaciones: * `@app.put()` * `@app.delete()` -y las más exóticas: +Y los más exóticos: * `@app.options()` * `@app.head()` * `@app.patch()` * `@app.trace()` -/// tip | Consejo +/// tip -Tienes la libertad de usar cada operación (método de HTTP) como quieras. +Eres libre de usar cada operación (método HTTP) como quieras. -**FastAPI** no impone ningún significado específico. +**FastAPI** no fuerza ningún significado específico. -La información que está presentada aquí es una guía, no un requerimiento. +La información aquí se presenta como una guía, no un requisito. -Por ejemplo, cuando usas GraphQL normalmente realizas todas las acciones usando únicamente operaciones `POST`. +Por ejemplo, cuando usas GraphQL normalmente realizas todas las acciones usando solo operaciones `POST`. /// -### Paso 4: define la **función de la operación de path** +### Paso 4: define la **path operation function** -Esta es nuestra "**función de la operación de path**": +Esta es nuestra "**path operation function**": * **path**: es `/`. -* **operación**: es `get`. -* **función**: es la función debajo del "decorador" (debajo de `@app.get("/")`). +* **operation**: es `get`. +* **function**: es la función debajo del "decorador" (debajo de `@app.get("/")`). {* ../../docs_src/first_steps/tutorial001.py hl[7] *} -Esto es una función de Python. +Esta es una función de Python. -Esta función será llamada por **FastAPI** cada vez que reciba un request en la URL "`/`" usando una operación `GET`. +Será llamada por **FastAPI** cuando reciba un request en la URL "`/`" usando una operación `GET`. -En este caso es una función `async`. +En este caso, es una función `async`. --- -También podrías definirla como una función estándar en lugar de `async def`: +También podrías definirla como una función normal en lugar de `async def`: {* ../../docs_src/first_steps/tutorial003.py hl[7] *} /// note | Nota -Si no sabes la diferencia, revisa el [Async: *"¿Tienes prisa?"*](../async.md#tienes-prisa){.internal-link target=_blank}. +Si no sabes la diferencia, revisa la sección [Async: *"¿Tienes prisa?"*](../async.md#in-a-hurry){.internal-link target=_blank}. /// -### Paso 5: devuelve el contenido +### Paso 5: retorna el contenido {* ../../docs_src/first_steps/tutorial001.py hl[8] *} -Puedes devolver `dict`, `list`, valores singulares como un `str`, `int`, etc. +Puedes retornar un `dict`, `list`, valores singulares como `str`, `int`, etc. -También puedes devolver modelos de Pydantic (ya verás más sobre esto más adelante). +También puedes retornar modelos de Pydantic (verás más sobre eso más adelante). -Hay muchos objetos y modelos que pueden ser convertidos automáticamente a JSON (incluyendo ORMs, etc.). Intenta usar tus favoritos, es muy probable que ya tengan soporte. +Hay muchos otros objetos y modelos que serán automáticamente convertidos a JSON (incluyendo ORMs, etc). Intenta usar tus favoritos, es altamente probable que ya sean compatibles. -## Repaso +## Recapitulación * Importa `FastAPI`. -* Crea un instance de `app`. -* Escribe un **decorador de operación de path** (como `@app.get("/")`). -* Escribe una **función de la operación de path** (como `def root(): ...` arriba). -* Corre el servidor de desarrollo (como `uvicorn main:app --reload`). +* Crea una instancia `app`. +* Escribe un **path operation decorator** usando decoradores como `@app.get("/")`. +* Define una **path operation function**; por ejemplo, `def root(): ...`. +* Ejecuta el servidor de desarrollo usando el comando `fastapi dev`. diff --git a/docs/es/docs/tutorial/index.md b/docs/es/docs/tutorial/index.md index fa13450f0..dcfc6cdfb 100644 --- a/docs/es/docs/tutorial/index.md +++ b/docs/es/docs/tutorial/index.md @@ -1,81 +1,102 @@ -# Tutorial - Guía de Usuario +# Tutorial - Guía del Usuario -Este tutorial te muestra cómo usar **FastAPI** con la mayoría de sus características paso a paso. +Este tutorial te muestra cómo usar **FastAPI** con la mayoría de sus funcionalidades, paso a paso. -Cada sección se basa gradualmente en las anteriores, pero está estructurada en temas separados, así puedes ir directamente a cualquier tema en concreto para resolver tus necesidades específicas sobre la API. +Cada sección se basa gradualmente en las anteriores, pero está estructurada para separar temas, de manera que puedas ir directamente a cualquier sección específica para resolver tus necesidades específicas de API. -Funciona también como una referencia futura, para que puedas volver y ver exactamente lo que necesitas. +También está diseñado para funcionar como una referencia futura para que puedas volver y ver exactamente lo que necesitas. ## Ejecuta el código -Todos los bloques de código se pueden copiar y usar directamente (en realidad son archivos Python probados). +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 en un archivo llamado `main.py`, y ejecuta `uvicorn` de la siguiente manera en tu terminal: +Para ejecutar cualquiera de los ejemplos, copia el código a un archivo `main.py`, y comienza `fastapi dev` con:
```console -$ uvicorn main:app --reload - -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [28720] -INFO: Started server process [28722] -INFO: Waiting for application startup. -INFO: Application startup complete. +$ fastapi dev main.py +INFO Using path main.py +INFO Resolved absolute path /home/user/code/awesomeapp/main.py +INFO Searching for package file structure from directories with __init__.py files +INFO Importing from /home/user/code/awesomeapp + + ╭─ Python module file ─╮ + │ │ + │ 🐍 main.py │ + │ │ + ╰──────────────────────╯ + +INFO Importing module main +INFO Found importable FastAPI app + + ╭─ Importable FastAPI app ─╮ + │ │ + │ from main import app │ + │ │ + ╰──────────────────────────╯ + +INFO Using import string main:app + + ╭────────── FastAPI CLI - Development mode ───────────╮ + │ │ + │ Serving at: http://127.0.0.1:8000 │ + │ │ + │ API docs: http://127.0.0.1:8000/docs │ + │ │ + │ Running in development mode, for production use: │ + │ │ + fastapi run + │ │ + ╰─────────────────────────────────────────────────────╯ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +INFO: Started reloader process [2265862] using WatchFiles +INFO: Started server process [2265873] +INFO: Waiting for application startup. +INFO: Application startup complete. + ```
-Se **RECOMIENDA** que escribas o copies el código, lo edites y lo ejecutes localmente. +Es **ALTAMENTE recomendable** que escribas o copies el código, lo edites y lo ejecutes localmente. -Usarlo en tu editor de código es lo que realmente te muestra los beneficios de FastAPI, al ver la poca cantidad de código que tienes que escribir, todas las verificaciones de tipo, auto-completado, etc. +Usarlo en tu editor es lo que realmente te muestra los beneficios de FastAPI, al ver cuán poco código tienes que escribir, todos los chequeos de tipos, autocompletado, etc. --- -## Instala FastAPI +## Instalar FastAPI El primer paso es instalar FastAPI. -Para el tutorial, es posible que quieras instalarlo con todas las dependencias y características opcionales: +Asegúrate de crear un [entorno virtual](../virtual-environments.md){.internal-link target=_blank}, actívalo, y luego **instala FastAPI**:
```console -$ pip install "fastapi[all]" +$ pip install "fastapi[standard]" ---> 100% ```
-...eso también incluye `uvicorn` que puedes usar como el servidor que ejecuta tu código. - /// note | Nota -También puedes instalarlo parte por parte. - -Esto es lo que probablemente harías una vez que desees implementar tu aplicación en producción: - -``` -pip install fastapi -``` - -También debes instalar `uvicorn` para que funcione como tu servidor: - -``` -pip install "uvicorn[standard]" -``` +Cuando instalas con `pip install "fastapi[standard]"` viene con algunas dependencias opcionales estándar por defecto. -Y lo mismo para cada una de las dependencias opcionales que quieras utilizar. +Si no quieres tener esas dependencias opcionales, en su lugar puedes instalar `pip install fastapi`. /// -## Guía Avanzada de Usuario +## Guía Avanzada del Usuario -También hay una **Guía Avanzada de Usuario** que puedes leer luego de este **Tutorial - Guía de Usuario**. +También hay una **Guía Avanzada del Usuario** que puedes leer después de esta **Tutorial - Guía del Usuario**. -La **Guía Avanzada de Usuario**, se basa en este tutorial, utiliza los mismos conceptos y enseña algunas características adicionales. +La **Guía Avanzada del Usuario** se basa en esta, utiliza los mismos conceptos y te enseña algunas funcionalidades adicionales. -Pero primero deberías leer el **Tutorial - Guía de Usuario** (lo que estas leyendo ahora mismo). +Pero primero deberías leer la **Tutorial - Guía del Usuario** (lo que estás leyendo ahora mismo). -La guía esa diseñada para que puedas crear una aplicación completa con solo el **Tutorial - Guía de Usuario**, y luego extenderlo de diferentes maneras, según tus necesidades, utilizando algunas de las ideas adicionales de la **Guía Avanzada de Usuario**. +Está diseñada para que puedas construir una aplicación completa solo con la **Tutorial - Guía del Usuario**, y luego extenderla de diferentes maneras, dependiendo de tus necesidades, utilizando algunas de las ideas adicionales de la **Guía Avanzada del Usuario**. diff --git a/docs/es/docs/tutorial/path-params.md b/docs/es/docs/tutorial/path-params.md index f36c4f493..12a1b647b 100644 --- a/docs/es/docs/tutorial/path-params.md +++ b/docs/es/docs/tutorial/path-params.md @@ -1,12 +1,12 @@ -# Parámetros de path +# Parámetros de Path -Puedes declarar los "parámetros" o "variables" con la misma sintaxis que usan los format strings de Python: +Puedes declarar "parámetros" o "variables" de path con la misma sintaxis que se usa en los format strings de Python: {* ../../docs_src/path_params/tutorial001.py hl[6:7] *} -El valor del parámetro de path `item_id` será pasado a tu función como el argumento `item_id`. +El valor del parámetro de path `item_id` se pasará a tu función como el argumento `item_id`. -Entonces, si corres este ejemplo y vas a http://127.0.0.1:8000/items/foo, verás una respuesta de: +Así que, si ejecutas este ejemplo y vas a http://127.0.0.1:8000/items/foo, verás un response de: ```JSON {"item_id":"foo"} @@ -14,21 +14,21 @@ Entonces, si corres este ejemplo y vas a Conversión de datos +## Conversión de datos -Si corres este ejemplo y abres tu navegador en http://127.0.0.1:8000/items/3 verás una respuesta de: +Si ejecutas este ejemplo y abres tu navegador en http://127.0.0.1:8000/items/3, verás un response de: ```JSON {"item_id":3} @@ -36,160 +36,168 @@ Si corres este ejemplo y abres tu navegador en "parsing" automático del request. +Entonces, con esa declaración de tipo, **FastAPI** te ofrece "parsing" automático de requests. /// ## Validación de datos -Pero si abres tu navegador en http://127.0.0.1:8000/items/foo verás este lindo error de HTTP: +Pero si vas al navegador en http://127.0.0.1:8000/items/foo, verás un bonito error HTTP de: ```JSON { - "detail": [ - { - "loc": [ - "path", - "item_id" - ], - "msg": "value is not a valid integer", - "type": "type_error.integer" - } - ] + "detail": [ + { + "type": "int_parsing", + "loc": [ + "path", + "item_id" + ], + "msg": "Input should be a valid integer, unable to parse string as an integer", + "input": "foo", + "url": "https://errors.pydantic.dev/2.1/v/int_parsing" + } + ] } ``` -debido a que el parámetro de path `item_id` tenía el valor `"foo"`, que no es un `int`. +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 pasaras un `float` en vez de un `int` como en: http://127.0.0.1:8000/items/4.2 +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 /// check | Revisa -Así, con la misma declaración de tipo de Python, **FastAPI** te da validación de datos. +Entonces, con la misma declaración de tipo de Python, **FastAPI** te ofrece validación de datos. -Observa que el error también muestra claramente el punto exacto en el que no pasó la validación. +Nota que el error también indica claramente el punto exacto donde la validación falló. -Esto es increíblemente útil cuando estás desarrollando y debugging código que interactúa con tu API. +Esto es increíblemente útil mientras desarrollas y depuras código que interactúa con tu API. /// ## Documentación -Cuando abras tu navegador en http://127.0.0.1:8000/docs verás la documentación automática e interactiva del API como: +Y cuando abras tu navegador en http://127.0.0.1:8000/docs, verás una documentación de API automática e interactiva como: /// check | Revisa -Nuevamente, con la misma declaración de tipo de Python, **FastAPI** te da documentación automática e interactiva (integrándose con Swagger UI) +Nuevamente, solo con esa misma declaración de tipo de Python, **FastAPI** te ofrece documentación automática e interactiva (integrando Swagger UI). -Observa que el parámetro de path está declarado como un integer. +Nota que el parámetro de path está declarado como un entero. /// ## Beneficios basados en estándares, documentación alternativa -Debido a que el schema generado es del estándar OpenAPI hay muchas herramientas compatibles. +Y porque el esquema generado es del estándar OpenAPI, hay muchas herramientas compatibles. -Es por esto que **FastAPI** mismo provee una documentación alternativa de la API (usando ReDoc), a la que puedes acceder en http://127.0.0.1:8000/redoc: +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: -De la misma manera hay muchas herramientas compatibles. Incluyendo herramientas de generación de código para muchos lenguajes. +De la misma manera, hay muchas herramientas compatibles. Incluyendo herramientas de generación de código para muchos lenguajes. ## Pydantic -Toda la validación de datos es realizada tras bastidores por Pydantic, así que obtienes todos sus beneficios. Así sabes que estás en buenas manos. +Toda la validación de datos se realiza internamente con Pydantic, así que obtienes todos los beneficios de esta. Y sabes que estás en buenas manos. -Puedes usar las mismas declaraciones de tipos con `str`, `float`, `bool` y otros tipos de datos más complejos. +Puedes usar las mismas declaraciones de tipo con `str`, `float`, `bool` y muchos otros tipos de datos complejos. -Exploraremos varios de estos tipos en los próximos capítulos del tutorial. +Varios de estos se exploran en los siguientes capítulos del tutorial. ## El orden importa -Cuando creas *operaciones de path* puedes encontrarte con situaciones en las que tengas un path fijo. +Al crear *path operations*, puedes encontrarte en situaciones donde tienes un path fijo. -Digamos algo como `/users/me` que sea para obtener datos del usuario actual. +Como `/users/me`, imaginemos que es para obtener datos sobre el usuario actual. -... y luego puedes tener el path `/users/{user_id}` para obtener los datos sobre un usuario específico asociados a un ID de usuario. +Y luego también puedes tener un path `/users/{user_id}` para obtener datos sobre un usuario específico por algún ID de usuario. -Porque las *operaciones de path* son evaluadas en orden, tienes que asegurarte de que el path para `/users/me` sea declarado antes que el path para `/users/{user_id}`: +Debido a que las *path operations* se evalúan en orden, necesitas asegurarte de que el path para `/users/me` se declara antes que el de `/users/{user_id}`: {* ../../docs_src/path_params/tutorial003.py hl[6,11] *} -De otra manera el path para `/users/{user_id}` coincidiría también con `/users/me` "pensando" que está recibiendo el parámetro `user_id` con el valor `"me"`. +De lo contrario, el path para `/users/{user_id}` también coincidiría para `/users/me`, "pensando" que está recibiendo un parámetro `user_id` con un valor de `"me"`. + +De manera similar, no puedes redefinir una path operation: + +{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *} + +La primera siempre será utilizada ya que el path coincide primero. ## Valores predefinidos -Si tienes una *operación de path* que recibe un *parámetro de path* pero quieres que los valores posibles del *parámetro de path* sean predefinidos puedes usar un `Enum` estándar de Python. +Si tienes una *path operation* que recibe un *path parameter*, pero quieres que los valores posibles válidos del *path parameter* estén predefinidos, puedes usar un `Enum` estándar de Python. -### Crea una clase `Enum` +### Crear una clase `Enum` -Importa `Enum` y crea una sub-clase que herede desde `str` y desde `Enum`. +Importa `Enum` y crea una subclase que herede de `str` y de `Enum`. -Al heredar desde `str` la documentación de la API podrá saber que los valores deben ser de tipo `string` y podrá mostrarlos correctamente. +Al heredar de `str`, la documentación de la API podrá saber que los valores deben ser de tipo `string` y podrá representarlos correctamente. -Luego crea atributos de clase con valores fijos, que serán los valores disponibles válidos: +Luego crea atributos de clase con valores fijos, que serán los valores válidos disponibles: {* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *} /// info | Información -Las Enumerations (o enums) están disponibles en Python desde la versión 3.4. +Las enumeraciones (o enums) están disponibles en Python desde la versión 3.4. /// /// tip | Consejo -Si lo estás dudando, "AlexNet", "ResNet", y "LeNet" son solo nombres de modelos de Machine Learning. +Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de modelos de Machine Learning. /// -### Declara un *parámetro de path* +### Declarar un *path parameter* -Luego, crea un *parámetro de path* con anotaciones de tipos usando la clase enum que creaste (`ModelName`): +Luego crea un *path parameter* con una anotación de tipo usando la clase enum que creaste (`ModelName`): {* ../../docs_src/path_params/tutorial005.py hl[16] *} ### Revisa la documentación -Debido a que los valores disponibles para el *parámetro de path* están predefinidos, la documentación interactiva los puede mostrar bien: +Como los valores disponibles para el *path parameter* están predefinidos, la documentación interactiva puede mostrarlos de manera ordenada: -### Trabajando con los *enumerations* de Python +### Trabajando con *enumeraciones* de Python -El valor del *parámetro de path* será un *enumeration member*. +El valor del *path parameter* será un *miembro* de enumeración. -#### Compara *enumeration members* +#### Comparar *miembros* de enumeraciones -Puedes compararlo con el *enumeration member* en el enum (`ModelName`) que creaste: +Puedes compararlo con el *miembro* de enumeración en tu enum creada `ModelName`: {* ../../docs_src/path_params/tutorial005.py hl[17] *} -#### Obtén el *enumeration value* +#### Obtener el valor de *enumeración* -Puedes obtener el valor exacto (un `str` en este caso) usando `model_name.value`, o en general, `your_enum_member.value`: +Puedes obtener el valor actual (un `str` en este caso) usando `model_name.value`, o en general, `your_enum_member.value`: {* ../../docs_src/path_params/tutorial005.py hl[20] *} /// tip | Consejo -También podrías obtener el valor `"lenet"` con `ModelName.lenet.value`. +También podrías acceder al valor `"lenet"` con `ModelName.lenet.value`. /// -#### Devuelve *enumeration members* +#### Devolver *miembros* de enumeración -Puedes devolver *enum members* desde tu *operación de path* inclusive en un body de JSON anidado (por ejemplo, un `dict`). +Puedes devolver *miembros de enum* desde tu *path operation*, incluso anidados en un cuerpo JSON (por ejemplo, un `dict`). -Ellos serán convertidos a sus valores correspondientes (strings en este caso) antes de devolverlos al cliente: +Serán convertidos a sus valores correspondientes (cadenas en este caso) antes de devolverlos al cliente: {* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *} -En tu cliente obtendrás una respuesta en JSON como: +En tu cliente recibirás un response JSON como: ```JSON { @@ -198,53 +206,53 @@ En tu cliente obtendrás una respuesta en JSON como: } ``` -## Parámetros de path parameters que contienen paths +## Parámetros de path conteniendo paths -Digamos que tienes una *operación de path* con un path `/files/{file_path}`. +Imaginemos que tienes una *path operation* con un path `/files/{file_path}`. -Pero necesitas que el mismo `file_path` contenga un path como `home/johndoe/myfile.txt`. +Pero necesitas que `file_path` en sí mismo contenga un *path*, como `home/johndoe/myfile.txt`. Entonces, la URL para ese archivo sería algo como: `/files/home/johndoe/myfile.txt`. ### Soporte de OpenAPI -OpenAPI no soporta una manera de declarar un *parámetro de path* que contenga un path, dado que esto podría llevar a escenarios que son difíciles de probar y definir. +OpenAPI no soporta una manera de declarar un *path parameter* para que contenga un *path* dentro, ya que eso podría llevar a escenarios que son difíciles de probar y definir. -Sin embargo, lo puedes hacer en **FastAPI** usando una de las herramientas internas de Starlette. +Sin embargo, todavía puedes hacerlo en **FastAPI**, usando una de las herramientas internas de Starlette. -La documentación seguirá funcionando, aunque no añadirá ninguna información diciendo que el parámetro debería contener un path. +Y la documentación seguiría funcionando, aunque no agregue ninguna documentación indicando que el parámetro debe contener un path. -### Convertidor de path +### Convertidor de Path -Usando una opción directamente desde Starlette puedes declarar un *parámetro de path* que contenga un path usando una URL como: +Usando una opción directamente de Starlette puedes declarar un *path parameter* conteniendo un *path* usando una URL como: ``` /files/{file_path:path} ``` -En este caso el nombre del parámetro es `file_path` y la última parte, `:path`, le dice que el parámetro debería coincidir con cualquier path. +En este caso, el nombre del parámetro es `file_path`, y la última parte, `:path`, indica que el parámetro debería coincidir con cualquier *path*. -Entonces lo puedes usar con: +Así que, puedes usarlo con: {* ../../docs_src/path_params/tutorial004.py hl[6] *} /// tip | Consejo -Podrías necesitar que el parámetro contenga `/home/johndoe/myfile.txt` con un slash inicial (`/`). +Podrías necesitar que el parámetro contenga `/home/johndoe/myfile.txt`, con una barra inclinada (`/`) inicial. -En este caso la URL sería `/files//home/johndoe/myfile.txt` con un slash doble (`//`) entre `files` y `home`. +En ese caso, la URL sería: `/files//home/johndoe/myfile.txt`, con una doble barra inclinada (`//`) entre `files` y `home`. /// -## Repaso +## Resumen -Con **FastAPI**, usando declaraciones de tipo de Python intuitivas y estándares, obtienes: +Con **FastAPI**, al usar declaraciones de tipo estándar de Python, cortas e intuitivas, obtienes: -* Soporte en el editor: chequeo de errores, auto-completado, etc. -* "Parsing" de datos +* Soporte del editor: chequeo de errores, autocompletado, etc. +* "parsing" de datos * Validación de datos -* Anotación de la API y documentación automática +* Anotación de API y documentación automática -Solo tienes que declararlos una vez. +Y solo tienes que declararlos una vez. -Esa es probablemente la principal ventaja visible de **FastAPI** sobre otros frameworks alternativos (aparte del rendimiento puro). +Probablemente esa sea la principal ventaja visible de **FastAPI** en comparación con otros frameworks alternativos (aparte del rendimiento bruto). diff --git a/docs/es/docs/tutorial/query-params.md b/docs/es/docs/tutorial/query-params.md index 8cc4c5671..09c66a545 100644 --- a/docs/es/docs/tutorial/query-params.md +++ b/docs/es/docs/tutorial/query-params.md @@ -1,10 +1,10 @@ -# Parámetros de query +# Parámetros de Query -Cuando declaras otros parámetros de la función que no hacen parte de los parámetros de path estos se interpretan automáticamente como parámetros de "query". +Cuando declaras otros parámetros de función que no son parte de los parámetros de path, son automáticamente interpretados como parámetros de "query". {* ../../docs_src/query_params/tutorial001.py hl[9] *} -El query es el conjunto de pares de key-value que van después del `?` en la URL, separados por caracteres `&`. +La query es el conjunto de pares clave-valor que van después del `?` en una URL, separados por caracteres `&`. Por ejemplo, en la URL: @@ -17,36 +17,36 @@ http://127.0.0.1:8000/items/?skip=0&limit=10 * `skip`: con un valor de `0` * `limit`: con un valor de `10` -Dado que son parte de la URL son strings "naturalmente". +Como son parte de la URL, son "naturalmente" strings. -Pero cuando los declaras con tipos de Python (en el ejemplo arriba, como `int`) son convertidos a ese tipo y son validados con él. +Pero cuando los declaras con tipos de Python (en el ejemplo anterior, como `int`), son convertidos a ese tipo y validados respecto a él. -Todo el proceso que aplicaba a los parámetros de path también aplica a los parámetros de query: +Todo el mismo proceso que se aplica para los parámetros de path también se aplica para los parámetros de query: * Soporte del editor (obviamente) -* "Parsing" de datos +* "Parsing" de datos * Validación de datos * Documentación automática -## Configuraciones por defecto +## Valores por defecto -Como los parámetros de query no están fijos en una parte del path pueden ser opcionales y pueden tener valores por defecto. +Como los parámetros de query no son una parte fija de un path, pueden ser opcionales y pueden tener valores por defecto. -El ejemplo arriba tiene `skip=0` y `limit=10` como los valores por defecto. +En el ejemplo anterior, tienen valores por defecto de `skip=0` y `limit=10`. -Entonces, si vas a la URL: +Entonces, ir a la URL: ``` http://127.0.0.1:8000/items/ ``` -Sería lo mismo que ir a: +sería lo mismo que ir a: ``` http://127.0.0.1:8000/items/?skip=0&limit=10 ``` -Pero, si por ejemplo vas a: +Pero si vas a, por ejemplo: ``` http://127.0.0.1:8000/items/?skip=20 @@ -54,36 +54,26 @@ http://127.0.0.1:8000/items/?skip=20 Los valores de los parámetros en tu función serán: -* `skip=20`: porque lo definiste en la URL -* `limit=10`: porque era el valor por defecto +* `skip=20`: porque lo configuraste en la URL +* `limit=10`: porque ese era el valor por defecto ## Parámetros opcionales -Del mismo modo puedes declarar parámetros de query opcionales definiendo el valor por defecto como `None`: +De la misma manera, puedes declarar parámetros de query opcionales, estableciendo su valor por defecto en `None`: -{* ../../docs_src/query_params/tutorial002.py hl[9] *} - -En este caso el parámetro de la función `q` será opcional y será `None` por defecto. +{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *} /// check | Revisa -También puedes notar que **FastAPI** es lo suficientemente inteligente para darse cuenta de que el parámetro de path `item_id` es un parámetro de path y que `q` no lo es, y por lo tanto es un parámetro de query. - -/// - -/// note | Nota - -FastAPI sabrá que `q` es opcional por el `= None`. - -El `Union` en `Union[str, None]` no es usado por FastAPI (FastAPI solo usará la parte `str`), pero el `Union[str, None]` le permitirá a tu editor ayudarte a encontrar errores en tu código. +Además, nota que **FastAPI** es lo suficientemente inteligente para notar que el parámetro de path `item_id` es un parámetro de path y `q` no lo es, por lo tanto, es un parámetro de query. /// -## Conversión de tipos de parámetros de query +## Conversión de tipos en parámetros de query -También puedes declarar tipos `bool` y serán convertidos: +También puedes declarar tipos `bool`, y serán convertidos: -{* ../../docs_src/query_params/tutorial003.py hl[9] *} +{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *} En este caso, si vas a: @@ -115,54 +105,56 @@ o http://127.0.0.1:8000/items/foo?short=yes ``` -o cualquier otra variación (mayúsculas, primera letra en mayúscula, etc.) tu función verá el parámetro `short` con un valor `bool` de `True`. Si no, lo verá como `False`. +o cualquier otra variación (mayúsculas, primera letra en mayúscula, etc.), tu función verá el parámetro `short` con un valor `bool` de `True`. De lo contrario, será `False`. -## Múltiples parámetros de path y query +## Múltiples parámetros de path y de query -Puedes declarar múltiples parámetros de path y parámetros de query al mismo tiempo. **FastAPI** sabe cuál es cuál. +Puedes declarar múltiples parámetros de path y de query al mismo tiempo, **FastAPI** sabe cuál es cuál. -No los tienes que declarar en un orden específico. +Y no tienes que declararlos en un orden específico. Serán detectados por nombre: -{* ../../docs_src/query_params/tutorial004.py hl[8,10] *} +{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *} ## Parámetros de query requeridos -Cuando declaras un valor por defecto para los parámetros que no son de path (por ahora solo hemos visto parámetros de query), entonces no es requerido. +Cuando declaras un valor por defecto para parámetros que no son de path (por ahora, solo hemos visto parámetros de query), entonces no es requerido. -Si no quieres añadir un valor específico sino solo hacerlo opcional, pon el valor por defecto como `None`. +Si no quieres agregar un valor específico pero solo hacer que sea opcional, establece el valor por defecto como `None`. -Pero cuando quieres hacer que un parámetro de query sea requerido, puedes simplemente no declararle un valor por defecto: +Pero cuando quieres hacer un parámetro de query requerido, simplemente no declares ningún valor por defecto: {* ../../docs_src/query_params/tutorial005.py hl[6:7] *} -Aquí el parámetro de query `needy` es un parámetro de query requerido, del tipo `str`. +Aquí el parámetro de query `needy` es un parámetro de query requerido de tipo `str`. -Si abres tu navegador en una URL como: +Si abres en tu navegador una URL como: ``` http://127.0.0.1:8000/items/foo-item ``` -...sin añadir el parámetro `needy` requerido, verás un error como: +...sin agregar el parámetro requerido `needy`, verás un error como: ```JSON { - "detail": [ - { - "loc": [ - "query", - "needy" - ], - "msg": "field required", - "type": "value_error.missing" - } - ] + "detail": [ + { + "type": "missing", + "loc": [ + "query", + "needy" + ], + "msg": "Field required", + "input": null, + "url": "https://errors.pydantic.dev/2.1/v/missing" + } + ] } ``` -Dado que `needy` es un parámetro requerido necesitarías declararlo en la URL: +Como `needy` es un parámetro requerido, necesitarías establecerlo en la URL: ``` http://127.0.0.1:8000/items/foo-item?needy=sooooneedy @@ -177,11 +169,11 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy } ``` -Por supuesto que también puedes definir algunos parámetros como requeridos, con un valor por defecto y otros completamente opcionales: +Y por supuesto, puedes definir algunos parámetros como requeridos, algunos con un valor por defecto, y algunos enteramente opcionales: -{* ../../docs_src/query_params/tutorial006.py hl[10] *} +{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *} -En este caso hay 3 parámetros de query: +En este caso, hay 3 parámetros de query: * `needy`, un `str` requerido. * `skip`, un `int` con un valor por defecto de `0`. @@ -189,6 +181,6 @@ En este caso hay 3 parámetros de query: /// tip | Consejo -También podrías usar los `Enum`s de la misma manera que con los [Parámetros de path](path-params.md#valores-predefinidos){.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){.internal-link target=_blank}. ///