Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Join theFastAPI Cloud waiting list 🚀
Follow@fastapi onX (Twitter) to stay updated
FollowFastAPI onLinkedIn to stay updated
Subscribe to theFastAPI and friends newsletter 🎉
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor

Sub-dependencies

You can create dependencies that havesub-dependencies.

They can be asdeep as you need them to be.

FastAPI will take care of solving them.

First dependency "dependable"

You could create a first dependency ("dependable") like:

fromtypingimportAnnotatedfromfastapiimportCookie,Depends,FastAPIapp=FastAPI()defquery_extractor(q:str|None=None):returnqdefquery_or_cookie_extractor(q:Annotated[str,Depends(query_extractor)],last_query:Annotated[str|None,Cookie()]=None,):ifnotq:returnlast_queryreturnq@app.get("/items/")asyncdefread_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 theAnnotated version if possible.

fromfastapiimportCookie,Depends,FastAPIapp=FastAPI()defquery_extractor(q:str|None=None):returnqdefquery_or_cookie_extractor(q:str=Depends(query_extractor),last_query:str|None=Cookie(default=None)):ifnotq:returnlast_queryreturnq@app.get("/items/")asyncdefread_query(query_or_default:str=Depends(query_or_cookie_extractor)):return{"q_or_cookie":query_or_default}

It declares an optional query parameterq as astr, and then it just returns it.

This is quite simple (not very useful), but will help us focus on how the sub-dependencies work.

Second dependency, "dependable" and "dependant"

Then you can create another dependency function (a "dependable") that at the same time declares a dependency of its own (so it is a "dependant" too):

fromtypingimportAnnotatedfromfastapiimportCookie,Depends,FastAPIapp=FastAPI()defquery_extractor(q:str|None=None):returnqdefquery_or_cookie_extractor(q:Annotated[str,Depends(query_extractor)],last_query:Annotated[str|None,Cookie()]=None,):ifnotq:returnlast_queryreturnq@app.get("/items/")asyncdefread_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 theAnnotated version if possible.

fromfastapiimportCookie,Depends,FastAPIapp=FastAPI()defquery_extractor(q:str|None=None):returnqdefquery_or_cookie_extractor(q:str=Depends(query_extractor),last_query:str|None=Cookie(default=None)):ifnotq:returnlast_queryreturnq@app.get("/items/")asyncdefread_query(query_or_default:str=Depends(query_or_cookie_extractor)):return{"q_or_cookie":query_or_default}

Let's focus on the parameters declared:

  • Even though this function is a dependency ("dependable") itself, it also declares another dependency (it "depends" on something else).
    • It depends on thequery_extractor, and assigns the value returned by it to the parameterq.
  • It also declares an optionallast_query cookie, as astr.
    • If the user didn't provide any queryq, we use the last query used, which we saved to a cookie before.

Use the dependency

Then we can use the dependency with:

fromtypingimportAnnotatedfromfastapiimportCookie,Depends,FastAPIapp=FastAPI()defquery_extractor(q:str|None=None):returnqdefquery_or_cookie_extractor(q:Annotated[str,Depends(query_extractor)],last_query:Annotated[str|None,Cookie()]=None,):ifnotq:returnlast_queryreturnq@app.get("/items/")asyncdefread_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 theAnnotated version if possible.

fromfastapiimportCookie,Depends,FastAPIapp=FastAPI()defquery_extractor(q:str|None=None):returnqdefquery_or_cookie_extractor(q:str=Depends(query_extractor),last_query:str|None=Cookie(default=None)):ifnotq:returnlast_queryreturnq@app.get("/items/")asyncdefread_query(query_or_default:str=Depends(query_or_cookie_extractor)):return{"q_or_cookie":query_or_default}

Info

Notice that we are only declaring one dependency in thepath operation function, thequery_or_cookie_extractor.

ButFastAPI will know that it has to solvequery_extractor first, to pass the results of that toquery_or_cookie_extractor while calling it.

graph TBquery_extractor(["query_extractor"])query_or_cookie_extractor(["query_or_cookie_extractor"])read_query["/items/"]query_extractor --> query_or_cookie_extractor --> read_query

Using the same dependency multiple times

If one of your dependencies is declared multiple times for the samepath operation, for example, multiple dependencies have a common sub-dependency,FastAPI will know to call that sub-dependency only once per request.

And it will save the returned value in a"cache" and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.

In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameteruse_cache=False when usingDepends:

asyncdefneedy_dependency(fresh_value:Annotated[str,Depends(get_value,use_cache=False)]):return{"fresh_value":fresh_value}

Tip

Prefer to use theAnnotated version if possible.

asyncdefneedy_dependency(fresh_value:str=Depends(get_value,use_cache=False)):return{"fresh_value":fresh_value}

Recap

Apart from all the fancy words used here, theDependency Injection system is quite simple.

Just functions that look the same as thepath operation functions.

But still, it is very powerful, and allows you to declare arbitrarily deeply nested dependency "graphs" (trees).

Tip

All this might not seem as useful with these simple examples.

But you will see how useful it is in the chapters aboutsecurity.

And you will also see the amounts of code it will save you.


[8]ページ先頭

©2009-2026 Movatter.jp