Dependencias¶
🌐 Traducción por IA y humanos
Esta traducción fue hecha por IA guiada por humanos. 🤝
Podría tener errores al interpretar el significado original, o sonar poco natural, etc. 🤖
Puedes mejorar esta traducciónayudándonos a guiar mejor al LLM de IA.
FastAPI tiene un sistema deInyección de Dependencias muy poderoso pero intuitivo.
Está diseñado para ser muy simple de usar, y para hacer que cualquier desarrollador integre otros componentes conFastAPI de forma muy sencilla.
Qué es la "Inyección de Dependencias"¶
"Inyección de Dependencias" significa, en programación, que hay una manera para que tu código (en este caso, tuspath operation functions) declare las cosas que necesita para funcionar y utilizar: "dependencias".
Y luego, ese sistema (en este casoFastAPI) se encargará de hacer lo que sea necesario para proporcionar a tu código esas dependencias necesarias ("inyectar" las dependencias).
Esto es muy útil cuando necesitas:
- Tener lógica compartida (la misma lógica de código una y otra vez).
- Compartir conexiones a bases de datos.
- Imponer seguridad, autenticación, requisitos de roles, etc.
- Y muchas otras cosas...
Todo esto, mientras minimizas la repetición de código.
Primeros Pasos¶
Veamos un ejemplo muy simple. Será tan simple que no es muy útil, por ahora.
Pero de esta manera podemos enfocarnos en cómo funciona el sistema deInyección de Dependencias.
Crear una dependencia, o "dependable"¶
Primero enfoquémonos en la dependencia.
Es solo una función que puede tomar todos los mismos parámetros que unapath operation function puede tomar:
fromtypingimportAnnotatedfromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}@app.get("/items/")asyncdefread_items(commons:Annotated[dict,Depends(common_parameters)]):returncommons@app.get("/users/")asyncdefread_users(commons:Annotated[dict,Depends(common_parameters)]):returncommons🤓 Other versions and variants
Tip
Prefer to use theAnnotated version if possible.
fromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}@app.get("/items/")asyncdefread_items(commons:dict=Depends(common_parameters)):returncommons@app.get("/users/")asyncdefread_users(commons:dict=Depends(common_parameters)):returncommonsEso es todo.
2 líneas.
Y tiene la misma forma y estructura que todas tuspath operation functions.
Puedes pensar en ella como unapath operation function sin el "decorador" (sin el@app.get("/some-path")).
Y puede devolver lo que quieras.
En este caso, esta dependencia espera:
- Un parámetro de query opcional
qque es unstr. - Un parámetro de query opcional
skipque es unint, y por defecto es0. - Un parámetro de query opcional
limitque es unint, y por defecto es100.
Y luego solo devuelve undict que contiene esos valores.
Información
FastAPI agregó soporte paraAnnotated (y comenzó a recomendarlo) en la versión 0.95.0.
Si tienes una versión anterior, obtendrás errores al intentar usarAnnotated.
Asegúrate deActualizar la versión de FastAPI al menos a la 0.95.1 antes de usarAnnotated.
ImportarDepends¶
fromtypingimportAnnotatedfromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}@app.get("/items/")asyncdefread_items(commons:Annotated[dict,Depends(common_parameters)]):returncommons@app.get("/users/")asyncdefread_users(commons:Annotated[dict,Depends(common_parameters)]):returncommons🤓 Other versions and variants
Tip
Prefer to use theAnnotated version if possible.
fromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}@app.get("/items/")asyncdefread_items(commons:dict=Depends(common_parameters)):returncommons@app.get("/users/")asyncdefread_users(commons:dict=Depends(common_parameters)):returncommonsDeclarar la dependencia, en el "dependant"¶
De la misma forma en que usasBody,Query, etc. con los parámetros de tupath operation function, usaDepends con un nuevo parámetro:
fromtypingimportAnnotatedfromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}@app.get("/items/")asyncdefread_items(commons:Annotated[dict,Depends(common_parameters)]):returncommons@app.get("/users/")asyncdefread_users(commons:Annotated[dict,Depends(common_parameters)]):returncommons🤓 Other versions and variants
Tip
Prefer to use theAnnotated version if possible.
fromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}@app.get("/items/")asyncdefread_items(commons:dict=Depends(common_parameters)):returncommons@app.get("/users/")asyncdefread_users(commons:dict=Depends(common_parameters)):returncommonsAunque usasDepends en los parámetros de tu función de la misma manera que usasBody,Query, etc.,Depends funciona un poco diferente.
Le das aDepends un solo parámetro.
Este parámetro debe ser algo como una función.
No la llames directamente (no agregues los paréntesis al final), solo pásala como un parámetro aDepends().
Y esa función toma parámetros de la misma manera que laspath operation functions.
Consejo
Verás qué otras "cosas", además de funciones, pueden usarse como dependencias en el próximo capítulo.
Cada vez que llega un nuevo request,FastAPI se encargará de:
- Llamar a tu función de dependencia ("dependable") con los parámetros correctos.
- Obtener el resultado de tu función.
- Asignar ese resultado al parámetro en tupath operation function.
graph TBcommon_parameters(["common_parameters"])read_items["/items/"]read_users["/users/"]common_parameters --> read_itemscommon_parameters --> read_usersDe esta manera escribes código compartido una vez yFastAPI se encarga de llamarlo para tuspath operations.
Revisa
Nota que no tienes que crear una clase especial y pasarla en algún lugar aFastAPI para "registrarla" o algo similar.
Solo la pasas aDepends yFastAPI sabe cómo hacer el resto.
Compartir dependenciasAnnotated¶
En los ejemplos anteriores, ves que hay un poquito deduplicación de código.
Cuando necesitas usar la dependenciacommon_parameters(), tienes que escribir todo el parámetro con la anotación de tipo yDepends():
commons:Annotated[dict,Depends(common_parameters)]Pero como estamos usandoAnnotated, podemos almacenar ese valorAnnotated en una variable y usarlo en múltiples lugares:
fromtypingimportAnnotatedfromfastapiimportDepends,FastAPIapp=FastAPI()asyncdefcommon_parameters(q:str|None=None,skip:int=0,limit:int=100):return{"q":q,"skip":skip,"limit":limit}CommonsDep=Annotated[dict,Depends(common_parameters)]@app.get("/items/")asyncdefread_items(commons:CommonsDep):returncommons@app.get("/users/")asyncdefread_users(commons:CommonsDep):returncommonsConsejo
Esto es solo Python estándar, se llama un "alias de tipo", en realidad no es específico deFastAPI.
Pero porqueFastAPI está basado en los estándares de Python, incluidoAnnotated, puedes usar este truco en tu código. 😎
Las dependencias seguirán funcionando como se esperaba, y lamejor parte es que lainformación de tipo se preservará, lo que significa que tu editor podrá seguir proporcionándoteautocompletado,errores en línea, etc. Lo mismo para otras herramientas comomypy.
Esto será especialmente útil cuando lo uses en unagran code base donde useslas mismas dependencias una y otra vez enmuchaspath operations.
Usarasync o no usarasync¶
Como las dependencias también serán llamadas porFastAPI (lo mismo que tuspath operation functions), las mismas reglas aplican al definir tus funciones.
Puedes usarasync def odef normal.
Y puedes declarar dependencias conasync def dentro depath operation functions normalesdef, o dependenciasdef dentro depath operation functionsasync def, etc.
No importa.FastAPI sabrá qué hacer.
Nota
Si no lo sabes, revisa la secciónAsync:"¿Con prisa?" sobreasync yawait en la documentación.
Integración con OpenAPI¶
Todas las declaraciones de request, validaciones y requisitos de tus dependencias (y sub-dependencias) se integrarán en el mismo esquema de OpenAPI.
Así, la documentación interactiva tendrá toda la información de estas dependencias también:

Uso simple¶
Si lo ves, laspath operation functions se declaran para ser usadas siempre que unpath y unaoperación coincidan, y luegoFastAPI se encarga de llamar la función con los parámetros correctos, extrayendo los datos del request.
En realidad, todos (o la mayoría) de los frameworks web funcionan de esta misma manera.
Nunca llamas directamente a esas funciones. Son llamadas por tu framework (en este caso,FastAPI).
Con el sistema de Inyección de Dependencias, también puedes decirle aFastAPI que tupath operation function también "depende" de algo más que debe ejecutarse antes que tupath operation function, yFastAPI se encargará de ejecutarlo e "inyectar" los resultados.
Otros términos comunes para esta misma idea de "inyección de dependencias" son:
- recursos
- proveedores
- servicios
- inyectables
- componentes
Plug-ins deFastAPI¶
Las integraciones y "plug-ins" pueden construirse usando el sistema deInyección de Dependencias. Pero, de hecho, en realidadno hay necesidad de crear "plug-ins", ya que al usar dependencias es posible declarar una cantidad infinita de integraciones e interacciones que se vuelven disponibles para tuspath operation functions.
Y las dependencias se pueden crear de una manera muy simple e intuitiva que te permite simplemente importar los paquetes de Python que necesitas, e integrarlos con tus funciones de API en un par de líneas de código,literalmente.
Verás ejemplos de esto en los próximos capítulos, sobre bases de datos relacionales y NoSQL, seguridad, etc.
Compatibilidad deFastAPI¶
La simplicidad del sistema de inyección de dependencias hace queFastAPI sea compatible con:
- todas las bases de datos relacionales
- bases de datos NoSQL
- paquetes externos
- APIs externas
- sistemas de autenticación y autorización
- sistemas de monitoreo de uso de la API
- sistemas de inyección de datos de response
- etc.
Simple y Poderoso¶
Aunque el sistema de inyección de dependencias jerárquico es muy simple de definir y usar, sigue siendo muy poderoso.
Puedes definir dependencias que a su vez pueden definir dependencias ellas mismas.
Al final, se construye un árbol jerárquico de dependencias, y el sistema deInyección de Dependencias se encarga de resolver todas estas dependencias por ti (y sus sub-dependencias) y proporcionar (inyectar) los resultados en cada paso.
Por ejemplo, digamos que tienes 4 endpoints de API (path operations):
/items/public//items/private//users/{user_id}/activate/items/pro/
entonces podrías agregar diferentes requisitos de permiso para cada uno de ellos solo con dependencias y sub-dependencias:
graph TBcurrent_user(["current_user"])active_user(["active_user"])admin_user(["admin_user"])paying_user(["paying_user"])public["/items/public/"]private["/items/private/"]activate_user["/users/{user_id}/activate"]pro_items["/items/pro/"]current_user --> active_useractive_user --> admin_useractive_user --> paying_usercurrent_user --> publicactive_user --> privateadmin_user --> activate_userpaying_user --> pro_itemsIntegrado conOpenAPI¶
Todas estas dependencias, al declarar sus requisitos, también añaden parámetros, validaciones, etc. a tuspath operations.
FastAPI se encargará de agregar todo al esquema de OpenAPI, para que se muestre en los sistemas de documentación interactiva.







