Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Depends with no parameter do?

I am trying to implement JWT with fastapi. Currently looking at the following libraries fastapi-users FastAPI JWT Auth

In both cases, I see Depends() in method parameter. What does Depends do when there is nothing in the parameter?

https://github.com/frankie567/fastapi-users/blob/master/fastapi_users/router/auth.py

@router.post("/login")
    async def login(
        response: Response, credentials: OAuth2PasswordRequestForm = Depends()
    ):

https://indominusbyte.github.io/fastapi-jwt-auth/usage/basic/

@app.post('/login')
def login(user: User, Authorize: AuthJWT = Depends()):

I undestand when there's a function inside the parameter but would you teach me what it does when there's no parameter with Depends?

like image 992
codingdaddy Avatar asked Dec 30 '25 07:12

codingdaddy


2 Answers

Depends() without arguments is just a shortcut for classes as dependencies.

You see that we are having some code repetition here, writing CommonQueryParams twice:

commons: CommonQueryParams = Depends(CommonQueryParams)

FastAPI provides a shortcut for these cases, in where the dependency is specifically a class that FastAPI will "call" to create an instance of the class itself.

For those specific cases, you can do the following:

Instead of writing:

commons: CommonQueryParams = Depends(CommonQueryParams)

...you write:

commons: CommonQueryParams = Depends()

You declare the dependency as the type of the parameter, and you use Depends() as its "default" value (that after the =) for that function's parameter, without any parameter in Depends(), instead of having to write the full class again inside of Depends(CommonQueryParams).

like image 130
alex_noname Avatar answered Dec 31 '25 23:12

alex_noname


In both cases, I see Depends() in method parameter. What does Depends do when there is nothing in the parameter?

It's a great question.

Assume you have the following code.

from fastapi import FastAPI, Depends
from pydantic import BaseModel
from typing import Optional


class Location(BaseModel):
    city: str
    country: str
    state: str


app = FastAPI()


@app.post("/withoutdepends")
async def with_depends(location: Location):
    return location


@app.post("/withdepends")
async def with_depends(location: Location = Depends()):
    return lcoation

We have the same Location model in two different endpoints, one uses Depends other one not.

What is the difference?

Since FastAPI is based on OpenAPI specification, we can start discovering the difference from auto-generated Swagger's docs.

This is without Depends, it expects a Request Body.

This is with Depends, it expects them as Query parameters.

How this is useful and how it works?

Actually, this is it, it expects a Callable there.

But when you use a Pydantic Model with Depends, it actually creates a query parameter for parameter inside init __init__ function.

So for example, this is the model we used above.

class Location(BaseModel):
    city: str
    country: str
    state: str

It becomes this with Depends.


class Location(BaseModel):
    def __init__(self, city: str, country: str, state: str) -> None:
        ...

Then they will become query parameters. This is the OpenAPI schema for the /withdepends endpoint.

"parameters": [
    {
        "required":true,
        "schema":{
            "title":"City",
            "type":"string"
        },
        "name":"city",
        "in":"query"
    },
    {
        "required":true,
        "schema":{
            "title":"Country",
            "type":"string"
        },
        "name":"country",
        "in":"query"
    },
    {
        "required":true,
        "schema":{
            "title":"State",
            "type":"string"
        },
        "name":"state",
        "in":"query"
    }
]

This is the OpenAPI schema it created for /withoutdepends endpoint.

"requestBody": {
    "content":{
        "application/json":{
            "schema":{
                "$ref":"#/components/schemas/Location"
            }
        }
    },
    "required":true
}

Conclusion

Instead of request body, you can create query parameters with the same model.

Pydantic models are very useful for the cases when you have +5 parameters. But it expects a request body by default. But OpenAPI specification doesn't allow request body in GET operations. As it says in the specification.

GET, DELETE and HEAD are no longer allowed to have request body because it does not have defined semantics as per RFC 7231.

So by using Depends you are able to create query parameters for your GET endpoint, with the same model.

like image 21
Yagiz Degirmenci Avatar answered Dec 31 '25 23:12

Yagiz Degirmenci