I,m getting this error when I try to run my FastApi api.
app = cls(app=app, **options) TypeError: 'module' object is not callable
I'm trying to add a middleware on other folder separeted from main.py and don't know why isn't working. Otherwise when I add the middleware code into main.py works without problems. Here is my code, thank you for your help and excuse my english.
main.py
`
from fastapi import FastAPI
from fastapi import Depends, FastAPI, HTTPException
from fastapi import Request
from routers import rutas
from utils import CheckApiKey
from utils.CheckApiKey import check_api_key
app = FastAPI()
app.add_middleware(CheckApiKey, dispatch=check_api_key) <--- Here calling middleware
app.include_router(rutas.router)
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)`
Middleware CheckApiKey
`
from fastapi import Request
async def check_api_key(request: Request, call_next):
print("ok")
response = await call_next(request)
return response`
For your case it's enough to use decorator to define middleware, i.e.:
@app.middleware('http')
async def check_api_key(request: Request, call_next):
print("ok")
response = await call_next(request)
About exception:
app.add_middleware - receives type object as first argument what mean you should pass class-object here, but you passing whole module that's why you have TypeError
If you want to use app.add_middleware syntax then you should implement custom middleware class over Starlette's BaseHTTPMiddleware (https://www.starlette.io/middleware/#basehttpmiddleware).
For this you have to make subclass that defines async def dispatch(request, call_next) method. For your case:
class CheckApiKey(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
print("ok")
response = await call_next(request)
return response
Edit:
Forgot to mention, you needn't to pass dispatch=check_api_key to app.add_middleware. Simple app.add_middleware(CheckApiKey) should work.
def add_middleware(self, middleware_class: type, **options: typing.Any) that's signature of add_middleware method, as you can see there option kwargs that will be transferred forward to Middleware class and then will be used in middleware's __init__
@SirTelemak Thank you !! working now !
Thanks for the help here @SirTelemak ! :clap: :bow:
Thanks for reporting back and closing the issue :+1:
Most helpful comment
For your case it's enough to use decorator to define middleware, i.e.:
About exception:
app.add_middleware- receives type object as first argument what mean you should pass class-object here, but you passing whole module that's why you have TypeErrorIf you want to use
app.add_middlewaresyntax then you should implement custom middleware class over Starlette'sBaseHTTPMiddleware(https://www.starlette.io/middleware/#basehttpmiddleware).For this you have to make subclass that defines
async def dispatch(request, call_next)method. For your case:Edit:
Forgot to mention, you needn't to pass
dispatch=check_api_keytoapp.add_middleware. Simpleapp.add_middleware(CheckApiKey)should work.def add_middleware(self, middleware_class: type, **options: typing.Any)that's signature of add_middleware method, as you can see thereoptionkwargs that will be transferred forward to Middleware class and then will be used in middleware's__init__