sata mems
sata mems

Reputation: 29

FastAPI raises "TypeError: <generator object get_db at 0x00...> is not a callable object" when passing function to Depends

I get:

File "C:\PythonProjects\myProject\routers\home.py", line 39, in @router.get("/home", response_class=HTMLResponse)

...

raise TypeError('{!r} is not a callable object'.format(obj)) TypeError: <generator object get_db at 0x000002B68FBDB100> is not a callable object

home.py

    from fastapi import Depends, APIRouter, Request
    from fastapi.templating import Jinja2Templates
    from sqlalchemy.orm import Session
    from starlette.responses import HTMLResponse
    
    from database import SessionLocal, engine
    from models import Base
    
    router = APIRouter()
    templates = Jinja2Templates(directory="templates", autoescape=False)
    Base.metadata.create_all(bind=engine)
    
    
    def get_db():
        try:
            db = SessionLocal()
            yield db
        finally:
            db.close()

@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db())):
    all = db.query()
    return templates.TemplateResponse("home.html", {"request": request, "show": all})

database.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQL_ALCHEMY_DATABASE_URL = "postgresql://postgres:password@localhost/DatabaseName"

engine = create_engine(SQL_ALCHEMY_DATABASE_URL)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

main.py

from fastapi import FastAPI

import models
from database import engine
from routers import home
from starlette.staticfiles import StaticFiles


app = FastAPI()

models.Base.metadata.create_all(bind=engine)

app.mount("/static", StaticFiles(directory="static"), name="static")

app.include_router(home.router)

Upvotes: 1

Views: 632

Answers (3)

Duc Quyet
Duc Quyet

Reputation: 34

You to use as dependency

@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db)):
    all = db.query()
    return templates.TemplateResponse("home.html", {"request": request, "show": all})

instead of

@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db()):
    all = db.query()
    return templates.TemplateResponse("home.html", {"request": request, "show": all})

Upvotes: 0

Chris
Chris

Reputation: 34560

As per FastAPI's documentation:

You only give Depends a single parameter.

This parameter must be something like a function.

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

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 your path operation function.

Hence, in your example, you shouldn't be calling the get_db() function directly, as you have been doing:

@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db())):
    pass                                                     ^^^^^^^^

Instead, just pass it as a parameter to Depends() (i.e., Depends(get_db)):

@router.get("/home", response_class=HTMLResponse)
async def all_skills(request: Request, db: Session = Depends(get_db)):
    pass 

For further details, I would suggest having a look at this answer as well.

Upvotes: 2

Yurii Motov
Yurii Motov

Reputation: 2353

you shouldn't call function you want to use as dependency:

Depends(get_db)

instead of

Depends(get_db())

Upvotes: 3

Related Questions