From faec748ef6b81de62242588a51f6a22b5fc82240 Mon Sep 17 00:00:00 2001 From: Camila Gutierrez Date: Sat, 3 Jul 2021 16:46:49 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Add=20Spanish=20translation=20of?= =?UTF-8?q?=20Tutorial=20-=20Path=20Parameters=20(#2219)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Pedro A. Moreno Co-authored-by: Sebastián Ramírez --- docs/es/docs/tutorial/path-params.md | 244 +++++++++++++++++++++++++++ docs/es/mkdocs.yml | 1 + 2 files changed, 245 insertions(+) create mode 100644 docs/es/docs/tutorial/path-params.md diff --git a/docs/es/docs/tutorial/path-params.md b/docs/es/docs/tutorial/path-params.md new file mode 100644 index 000000000..6432de1cd --- /dev/null +++ b/docs/es/docs/tutorial/path-params.md @@ -0,0 +1,244 @@ +# Parámetros de path + +Puedes declarar los "parámetros" o "variables" con la misma sintaxis que usan los format strings de Python: + +```Python hl_lines="6-7" +{!../../../docs_src/path_params/tutorial001.py!} +``` + +El valor del parámetro de path `item_id` será pasado 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: + +```JSON +{"item_id":"foo"} +``` + +## Parámetros de path con tipos + +Puedes declarar el tipo de un parámetro de path en la función usando las anotaciones de tipos estándar de Python: + +```Python hl_lines="7" +{!../../../docs_src/path_params/tutorial002.py!} +``` + +En este caso, `item_id` es declarado como un `int`. + +!!! check "Revisa" + Esto te dará soporte en el editor dentro de tu función, con chequeos de errores, autocompletado, etc. + +## 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: + +```JSON +{"item_id":3} +``` + +!!! check "Revisa" + Observa que el valor que recibió (y devolvió) tu función es `3`, como un Python `int`, y no un string `"3"`. + + Entonces, con esa declaración de tipos **FastAPI** te da "parsing" automático del request. + +## 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: + +```JSON +{ + "detail": [ + { + "loc": [ + "path", + "item_id" + ], + "msg": "value is not a valid integer", + "type": "type_error.integer" + } + ] +} +``` + +debido a que el parámetro de path `item_id` tenía el valor `"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 + +!!! check "Revisa" + Así, con la misma declaración de tipo de Python, **FastAPI** te da validación de datos. + + Observa que el error también muestra claramente el punto exacto en el que no pasó la validación. + + Esto es increíblemente útil cuando estás desarrollando y debugging 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: + + + +!!! 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) + + Observa que el parámetro de path está declarado como un integer. + +## Beneficios basados en estándares, documentación alternativa + +Debido a que el schema 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: + + + +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. + +Puedes usar las mismas declaraciones de tipos con `str`, `float`, `bool` y otros tipos de datos más complejos. + +Exploraremos varios de estos tipos en los próximos capítulos del tutorial. + +## El orden importa + +Cuando creas *operaciones de path* puedes encontrarte con situaciones en las que tengas un path fijo. + +Digamos algo como `/users/me` que sea para obtener datos del 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. + +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}`: + +```Python hl_lines="6 11" +{!../../../docs_src/path_params/tutorial003.py!} +``` + +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"`. + +## 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. + +### Crea una clase `Enum` + +Importa `Enum` y crea una sub-clase que herede desde `str` y desde `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. + +Luego crea atributos de clase con valores fijos, que serán los valores disponibles válidos: + +```Python hl_lines="1 6-9" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +!!! info "Información" + Las Enumerations (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. + +### Declara un *parámetro de path* + +Luego, crea un *parámetro de path* con anotaciones de tipos usando la clase enum que creaste (`ModelName`): + +```Python hl_lines="16" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +### 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: + + + +### Trabajando con los *enumerations* de Python + +El valor del *parámetro de path* será un *enumeration member*. + +#### Compara *enumeration members* + +Puedes compararlo con el *enumeration member* en el enum (`ModelName`) que creaste: + +```Python hl_lines="17" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +#### Obtén el *enumeration value* + +Puedes obtener el valor exacto (un `str` en este caso) usando `model_name.value`, o en general, `your_enum_member.value`: + +```Python hl_lines="20" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +!!! tip "Consejo" + También podrías obtener el valor `"lenet"` con `ModelName.lenet.value`. + +#### Devuelve *enumeration members* + +Puedes devolver *enum members* desde tu *operación de path* inclusive en un body de JSON anidado (por ejemplo, un `dict`). + +Ellos serán convertidos a sus valores correspondientes (strings en este caso) antes de devolverlos al cliente: + +```Python hl_lines="18 21 23" +{!../../../docs_src/path_params/tutorial005.py!} +``` + +En tu cliente obtendrás una respuesta en JSON como: + +```JSON +{ + "model_name": "alexnet", + "message": "Deep Learning FTW!" +} +``` + +## Parámetros de path parameters que contienen paths + +Digamos que tienes una *operación de path* con un path `/files/{file_path}`. + +Pero necesitas que el mismo `file_path` 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. + +Sin embargo, lo puedes hacer 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. + +### 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: + +``` +/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. + +Entonces lo puedes usar con: + +```Python hl_lines="6" +{!../../../docs_src/path_params/tutorial004.py!} +``` + +!!! tip "Consejo" + Podrías necesitar que el parámetro contenga `/home/johndoe/myfile.txt` con un slash inicial (`/`). + + En este caso la URL sería `/files//home/johndoe/myfile.txt` con un slash doble (`//`) entre `files` y `home`. + +## Repaso + +Con **FastAPI**, usando declaraciones de tipo de Python intuitivas y estándares, obtienes: + +* Soporte en el editor: chequeos de errores, auto-completado, etc. +* "Parsing" de datos +* Validación de datos +* Anotación de la API y documentación automática + +Solo tienes que declararlos una vez. + +Esa es probablemente la principal ventaja visible de **FastAPI** sobre otros frameworks alternativos (aparte del rendimiento puro). diff --git a/docs/es/mkdocs.yml b/docs/es/mkdocs.yml index 2f6e02488..bee119ea9 100644 --- a/docs/es/mkdocs.yml +++ b/docs/es/mkdocs.yml @@ -56,6 +56,7 @@ nav: - Tutorial - Guía de Usuario: - tutorial/index.md - tutorial/first-steps.md + - tutorial/path-params.md - Guía de Usuario Avanzada: - advanced/index.md - async.md