Sous-dépendances¶
🌐 Traduction par IA et humains
Cette traduction a été réalisée par une IA guidée par des humains. 🤝
Elle peut contenir des erreurs d'interprétation du sens original, ou paraître peu naturelle, etc. 🤖
Vous pouvez améliorer cette traduction en nous aidant à mieux guider le LLM d'IA.
Vous pouvez créer des dépendances qui ont des sous-dépendances.
Elles peuvent être aussi profondes que nécessaire.
FastAPI se chargera de les résoudre.
Créer une première dépendance « dependable »¶
Vous pouvez créer une première dépendance (« dependable ») comme :
from typing import Annotated
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)],
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(
query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
):
return {"q_or_cookie": query_or_default}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: str | None = Cookie(default=None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
Elle déclare un paramètre de requête optionnel q de type str, puis le retourne simplement.
C'est assez simple (pas très utile), mais cela nous aidera à nous concentrer sur le fonctionnement des sous-dépendances.
Créer une seconde dépendance, « dependable » et « dependant »¶
Vous pouvez ensuite créer une autre fonction de dépendance (un « dependable ») qui, en même temps, déclare sa propre dépendance (elle est donc aussi un « dependant ») :
from typing import Annotated
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)],
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(
query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
):
return {"q_or_cookie": query_or_default}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: str | None = Cookie(default=None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
Concentrons-nous sur les paramètres déclarés :
- Même si cette fonction est elle‑même une dépendance (« dependable »), elle déclare aussi une autre dépendance (elle « dépend » d'autre chose).
- Elle dépend de
query_extractoret affecte la valeur renvoyée au paramètreq.
- Elle dépend de
- Elle déclare également un cookie
last_queryoptionnel, de typestr.- Si l'utilisateur n'a fourni aucune requête
q, nous utilisons la dernière requête utilisée, que nous avons enregistrée auparavant dans un cookie.
- Si l'utilisateur n'a fourni aucune requête
Utiliser la dépendance¶
Nous pouvons ensuite utiliser la dépendance avec :
from typing import Annotated
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)],
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(
query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
):
return {"q_or_cookie": query_or_default}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: str | None = Cookie(default=None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
Info
Notez que nous ne déclarons qu'une seule dépendance dans la fonction de chemin d'accès, query_or_cookie_extractor.
Mais FastAPI saura qu'il doit d'abord résoudre query_extractor, pour passer ses résultats à query_or_cookie_extractor lors de son appel.
graph TB
query_extractor(["query_extractor"])
query_or_cookie_extractor(["query_or_cookie_extractor"])
read_query["/items/"]
query_extractor --> query_or_cookie_extractor --> read_query
Utiliser la même dépendance plusieurs fois¶
Si l'une de vos dépendances est déclarée plusieurs fois pour le même chemin d'accès, par exemple si plusieurs dépendances ont une sous-dépendance commune, FastAPI saura n'appeler cette sous-dépendance qu'une seule fois par requête.
Et il enregistrera la valeur renvoyée dans un « cache » et la transmettra à tous les « dependants » qui en ont besoin dans cette requête spécifique, au lieu d'appeler la dépendance plusieurs fois pour la même requête.
Dans un scénario avancé où vous savez que vous avez besoin que la dépendance soit appelée à chaque étape (éventuellement plusieurs fois) dans la même requête au lieu d'utiliser la valeur « mise en cache », vous pouvez définir le paramètre use_cache=False lors de l'utilisation de Depends :
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
return {"fresh_value": fresh_value}
Astuce
Privilégiez la version Annotated si possible.
async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
return {"fresh_value": fresh_value}
Récapituler¶
En dehors de tout le jargon utilisé ici, le système d'injection de dépendances est assez simple.
Ce ne sont que des fonctions qui ressemblent aux fonctions de chemin d'accès.
Mais il est très puissant et vous permet de déclarer des « graphes » (arbres) de dépendances imbriquées aussi profondément que vous le souhaitez.
Astuce
Tout cela peut ne pas sembler très utile avec ces exemples simples.
Mais vous verrez à quel point c'est utile dans les chapitres sur la sécurité.
Et vous verrez aussi la quantité de code que cela vous fera économiser.