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.
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 inDepends()
, instead of having to write the full class again inside ofDepends(CommonQueryParams)
.