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

Dependencies

FastAPI has a very powerful but intuitiveDependency Injection system.

It is designed to be very simple to use, and to make it very easy for any developer to integrate other components withFastAPI.

What is "Dependency Injection"

"Dependency Injection" means, in programming, that there is a way for your code (in this case, yourpath operation functions) to declare things that it requires to work and use: "dependencies".

And then, that system (in this caseFastAPI) will take care of doing whatever is needed to provide your code with those needed dependencies ("inject" the dependencies).

This is very useful when you need to:

  • Have shared logic (the same code logic again and again).
  • Share database connections.
  • Enforce security, authentication, role requirements, etc.
  • And many other things...

All these, while minimizing code repetition.

First Steps

Let's see a very simple example. It will be so simple that it is not very useful, for now.

But this way we can focus on how theDependency Injection system works.

Create a dependency, or "dependable"

Let's first focus on the dependency.

It is just a function that can take all the same parameters that apath operation function can take:

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)):returncommons

That's it.

2 lines.

And it has the same shape and structure that all yourpath operation functions have.

You can think of it as apath operation function without the "decorator" (without the@app.get("/some-path")).

And it can return anything you want.

In this case, this dependency expects:

  • An optional query parameterq that is astr.
  • An optional query parameterskip that is anint, and by default is0.
  • An optional query parameterlimit that is anint, and by default is100.

And then it just returns adict containing those values.

Info

FastAPI added support forAnnotated (and started recommending it) in version 0.95.0.

If you have an older version, you would get errors when trying to useAnnotated.

Make sure youUpgrade the FastAPI version to at least 0.95.1 before usingAnnotated.

ImportDepends

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)):returncommons

Declare the dependency, in the "dependant"

The same way you useBody,Query, etc. with yourpath operation function parameters, useDepends with a new parameter:

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)):returncommons

Although you useDepends in the parameters of your function the same way you useBody,Query, etc,Depends works a bit differently.

You only giveDepends a single parameter.

This parameter must be something like a function.

Youdon't call it directly (don't add the parenthesis at the end), you just pass it as a parameter toDepends().

And that function takes parameters in the same way thatpath operation functions do.

Tip

You'll see what other "things", apart from functions, can be used as dependencies in the next chapter.

Whenever a new request arrives,FastAPI will take care of:

  • Calling your dependency ("dependable") function with the correct parameters.
  • Get the result from your function.
  • Assign that result to the parameter in yourpath operation function.
graph TBcommon_parameters(["common_parameters"])read_items["/items/"]read_users["/users/"]common_parameters --> read_itemscommon_parameters --> read_users

This way you write shared code once andFastAPI takes care of calling it for yourpath operations.

Check

Notice that you don't have to create a special class and pass it somewhere toFastAPI to "register" it or anything similar.

You just pass it toDepends andFastAPI knows how to do the rest.

ShareAnnotated dependencies

In the examples above, you see that there's a tiny bit ofcode duplication.

When you need to use thecommon_parameters() dependency, you have to write the whole parameter with the type annotation andDepends():

commons:Annotated[dict,Depends(common_parameters)]

But because we are usingAnnotated, we can store thatAnnotated value in a variable and use it in multiple places:

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):returncommons

Tip

This is just standard Python, it's called a "type alias", it's actually not specific toFastAPI.

But becauseFastAPI is based on the Python standards, includingAnnotated, you can use this trick in your code. 😎

The dependencies will keep working as expected, and thebest part is that thetype information will be preserved, which means that your editor will be able to keep providing you withautocompletion,inline errors, etc. The same for other tools likemypy.

This will be especially useful when you use it in alarge code base where you usethe same dependencies over and over again inmanypath operations.

Toasync or not toasync

As dependencies will also be called byFastAPI (the same as yourpath operation functions), the same rules apply while defining your functions.

You can useasync def or normaldef.

And you can declare dependencies withasync def inside of normaldefpath operation functions, ordef dependencies inside ofasync defpath operation functions, etc.

It doesn't matter.FastAPI will know what to do.

Note

If you don't know, check theAsync:"In a hurry?" section aboutasync andawait in the docs.

Integrated with OpenAPI

All the request declarations, validations and requirements of your dependencies (and sub-dependencies) will be integrated in the same OpenAPI schema.

So, the interactive docs will have all the information from these dependencies too:

Simple usage

If you look at it,path operation functions are declared to be used whenever apath andoperation matches, and thenFastAPI takes care of calling the function with the correct parameters, extracting the data from the request.

Actually, all (or most) of the web frameworks work in this same way.

You never call those functions directly. They are called by your framework (in this case,FastAPI).

With the Dependency Injection system, you can also tellFastAPI that yourpath operation function also "depends" on something else that should be executed before yourpath operation function, andFastAPI will take care of executing it and "injecting" the results.

Other common terms for this same idea of "dependency injection" are:

  • resources
  • providers
  • services
  • injectables
  • components

FastAPI plug-ins

Integrations and "plug-ins" can be built using theDependency Injection system. But in fact, there is actuallyno need to create "plug-ins", as by using dependencies it's possible to declare an infinite number of integrations and interactions that become available to yourpath operation functions.

And dependencies can be created in a very simple and intuitive way that allows you to just import the Python packages you need, and integrate them with your API functions in a couple of lines of code,literally.

You will see examples of this in the next chapters, about relational and NoSQL databases, security, etc.

FastAPI compatibility

The simplicity of the dependency injection system makesFastAPI compatible with:

  • all the relational databases
  • NoSQL databases
  • external packages
  • external APIs
  • authentication and authorization systems
  • API usage monitoring systems
  • response data injection systems
  • etc.

Simple and Powerful

Although the hierarchical dependency injection system is very simple to define and use, it's still very powerful.

You can define dependencies that in turn can define dependencies themselves.

In the end, a hierarchical tree of dependencies is built, and theDependency Injection system takes care of solving all these dependencies for you (and their sub-dependencies) and providing (injecting) the results at each step.

For example, let's say you have 4 API endpoints (path operations):

  • /items/public/
  • /items/private/
  • /users/{user_id}/activate
  • /items/pro/

then you could add different permission requirements for each of them just with dependencies and sub-dependencies:

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_items

Integrated withOpenAPI

All these dependencies, while declaring their requirements, also add parameters, validations, etc. to yourpath operations.

FastAPI will take care of adding it all to the OpenAPI schema, so that it is shown in the interactive documentation systems.


[8]ページ先頭

©2009-2026 Movatter.jp