Fastapi: middleware on different folder not working

Created on 13 Jul 2020  路  3Comments  路  Source: tiangolo/fastapi

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`

question

Most helpful comment

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__

All 3 comments

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:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RogerioDosSantos picture RogerioDosSantos  路  3Comments

DrPyser picture DrPyser  路  3Comments

zero0nee picture zero0nee  路  3Comments

kkinder picture kkinder  路  3Comments

Wytamma picture Wytamma  路  3Comments