En este caso, este __call__ es lo que FastAPI usará para verificar parámetros adicionales y sub-dependencias, y esto es lo que se llamará para pasar un valor al parámetro en tu path operation function más adelante.
Luego, podríamos usar este checker en un Depends(checker), en lugar de Depends(FixedContentQueryChecker), porque la dependencia es la instancia, checker, no la clase misma.
Y al resolver la dependencia, FastAPI llamará a este checker así:
checker(q="somequery")
...y pasar lo que devuelva como el valor de la dependencia en nuestra path operation function como el parámetro fixed_content_included:
Todo esto podría parecer artificial. Y podría no estar muy claro cómo es útil todavía.
Estos ejemplos son intencionalmente simples, pero muestran cómo funciona todo.
En los capítulos sobre seguridad, hay funciones de utilidad que están implementadas de esta misma manera.
Si entendiste todo esto, ya sabes cómo funcionan esas herramientas de utilidad para seguridad por debajo.
Dependencias con yield, HTTPException, except y Background Tasks¶
Aviso
Muy probablemente no necesites estos detalles técnicos.
Estos detalles son útiles principalmente si tenías una aplicación FastAPI anterior a 0.121.0 y estás enfrentando problemas con dependencias con yield.
Las dependencias con yield han evolucionado con el tiempo para abarcar los diferentes casos de uso y para corregir algunos problemas, aquí hay un resumen de lo que ha cambiado.
En la versión 0.121.0, FastAPI añadió soporte para Depends(scope="function") para dependencias con yield.
Usando Depends(scope="function"), el exit code después de yield se ejecuta justo después de que la path operation function termina, antes de que la respuesta sea enviada al cliente.
Y cuando se usa Depends(scope="request") (el valor por defecto), el exit code después de yield se ejecuta después de que la respuesta es enviada.
Dependencias con yield y StreamingResponse, Detalles Técnicos¶
Antes de FastAPI 0.118.0, si usabas una dependencia con yield, ejecutaría el exit code después de que la path operation function retornara pero justo antes de enviar la respuesta.
La intención era evitar mantener recursos por más tiempo del necesario, esperando a que la respuesta viajara por la red.
Este cambio también significó que si devolvías un StreamingResponse, el exit code de la dependencia con yield ya habría sido ejecutado.
Por ejemplo, si tenías una sesión de base de datos en una dependencia con yield, el StreamingResponse no podría usar esa sesión mientras transmite datos porque la sesión ya habría sido cerrada en el exit code después de yield.
Este comportamiento se revirtió en 0.118.0, para hacer que el exit code después de yield se ejecute después de que la respuesta sea enviada.
Nota
Como verás más abajo, esto es muy similar al comportamiento anterior a la versión 0.106.0, pero con varias mejoras y correcciones de errores para casos límite.
Hay algunos casos de uso con condiciones específicas que podrían beneficiarse del comportamiento anterior de ejecutar el exit code de las dependencias con yield antes de enviar la respuesta.
Por ejemplo, imagina que tienes código que usa una sesión de base de datos en una dependencia con yield solo para verificar un usuario, pero la sesión de base de datos nunca se usa nuevamente en la path operation function, solo en la dependencia, y la respuesta tarda mucho en enviarse, como un StreamingResponse que envía datos lentamente, pero por alguna razón no usa la base de datos.
En este caso, la sesión de la base de datos se mantendría hasta que la respuesta termine de enviarse, pero si no la usas, entonces no sería necesario mantenerla.
De esa manera la sesión liberaría la conexión a la base de datos, para que otras requests pudieran usarla.
Si tienes un caso de uso diferente que necesita salir temprano de una dependencia con yield, por favor crea un GitHub Discussion Question con tu caso de uso específico y por qué te beneficiaría tener un cierre temprano para dependencias con yield.
Si hay casos de uso convincentes para el cierre temprano en dependencias con yield, consideraría añadir una nueva forma de optar por el cierre temprano.
Dependencias con yield y except, Detalles Técnicos¶
Antes de FastAPI 0.110.0, si usabas una dependencia con yield, y luego capturabas una excepción con except en esa dependencia, y no volvías a lanzar la excepción, la excepción sería automáticamente lanzada/reenviada a cualquier exception handler o al handler de error interno del servidor.
Esto se cambió en la versión 0.110.0 para corregir el consumo de memoria no manejado por excepciones reenviadas sin un handler (errores internos del servidor), y para hacerlo consistente con el comportamiento del código Python regular.
Background Tasks y Dependencias con yield, Detalles Técnicos¶
Antes de FastAPI 0.106.0, lanzar excepciones después de yield no era posible, el exit code en dependencias con yield se ejecutaba después de que la respuesta fuera enviada, así que los Exception Handlers ya habrían sido ejecutados.
Esto se diseñó así principalmente para permitir usar los mismos objetos "yielded" por las dependencias dentro de las background tasks, porque el exit code se ejecutaría después de que las background tasks terminaran.
Esto se cambió en FastAPI 0.106.0 con la intención de no mantener recursos mientras se espera a que la respuesta viaje por la red.
Consejo
Además, una background task es normalmente un conjunto independiente de lógica que debería manejarse por separado, con sus propios recursos (ej. su propia conexión a la base de datos).
Así, de esta manera probablemente tendrás código más limpio.
Si solías depender de este comportamiento, ahora deberías crear los recursos para las background tasks dentro de la background task misma, y usar internamente solo datos que no dependan de los recursos de las dependencias con yield.
Por ejemplo, en lugar de usar la misma sesión de base de datos, crearías una nueva sesión de base de datos dentro de la background task, y obtendrías los objetos de la base de datos usando esta nueva sesión. Y luego, en lugar de pasar el objeto de la base de datos como parámetro a la función de la background task, pasarías el ID de ese objeto y luego obtendrías el objeto nuevamente dentro de la función de la background task.