Why does FastAPI's Depends() work without any parameter passed to it?

895 Views Asked by At

I found the following FastAPI code for authenticating a user with their information gotten from a form:

@app.post("/token")

async def login_for_access_token(form_data:OAuth2PasswordRequestForm = Depends(),
                                 db: Session = Depends(get_db)):

    user = authenticate_user(form_data.username, form_data.password, db)
    if not user:
        raise token_exception()
    
    token_expires = timedelta(minutes=20)
    
    token = create_access_token(user.username,
                                user.id,
                                expires_delta=token_expires)
    return {"token": token}

I'm struggling to understand why in form_data:OAuth2PasswordRequestForm = Depends(), Depends() has no parameter passed to it? I thought that the whole point of Depends() was to be instantiated with a function that gets called before the endpoint function is called.

1

There are 1 best solutions below

0
Chris On BEST ANSWER

In order to avoid code repetition, FastAPI allows declaring the dependency as the type of the parameter, and using Depends() without any parameter in it. For instance:

form_data: OAuth2PasswordRequestForm = Depends()

Hence, since you have already declared OAuth2PasswordRequestForm as the type of the form_data parameter, there is no need to pass it to the Depends() as well.

As per FastAPI's documentation:

Shortcut

But 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).