'AttributeError: 'Depends' object has no attribute 'query' FastAPI
So I am trying to write simple function here, but everytime I run swagger I got above mentioned error.
Here's my function:
def authenticate_user(username: str, password: str, db: Session = Depends(bd.get_db)):
user = db.query(bd.User.username).filter(username == username).first()
if not user:
return False
if not verify_password(password, user.password_hash):
return False
return user
and here's my get_db function it is pretty standard:
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
I've noticed that Depends(bd.get_db)
works perfectly fine within endpoint functions (the ones with @app.post
/@app.get
decorators), but somehow doesn't work within plain functions.
Apparently I don't quite understand the concept of dependency injections, but I can't quite grasp it yet.
Any help would be appreciated. Thank you kindly!
Solution 1:[1]
This page helped me a lot, https://github.com/tiangolo/fastapi/issues/1693#issuecomment-665833384
you can't use Depends in your own functions, it has to be in FastAPI functions, mainly routes. You can, however, use Depends in your own functions when that function is also a dependency, so could can have a chain of functions.
Eg, a route uses Depends to resolve a 'getcurrentuser', which also uses Depends to resolve 'getdb', and the whole chain will be resolved. But if you then call 'getcurrentuser' without using Depends, it won't be able to resolve 'getdb'.
What I do is get the DB session from the route and then pass it down through every layer and function. I believe this is also better design.
Solution 2:[2]
I had a similar problem trying to run a background task which was also defined as an endpoint. What I did to circumvent the issue was to create a wrapper around it. I'm not sure what scenario are you facing, but I think my example can help.
Here is my code:
DB Function for dependency injection
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Function definition without endpoint decorator
async def function(args, db:Session):
... do stuff ...
... interact with db ...
return "success!"
Endpoint function
@app.post("/function_endpoint/")
async def function_endpoint(args, db:Session=Depends(get_db)):
return await function(args, db)
Now, I can call function
without loosing endpoint functionality and duplicate code
Complex routine in need of background task
@app.post("/complex_routine/")
async def complex_routine_endpoint(
args, background_tasks:BackgroundTasks, db:Session=Depends(get_db)
):
... do complex stuff ...
... call other functions and pass db ...
background_tasks.add_task(function, args, db)
return "all good!"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | DharmanBot |