Question: I have a FastAPI backend and i'm trying to implement an APIRoute class to handle logic before and after the request (logging). # app.py from fastapi import FastAPI, APIRouter from backend.app.routers import questions API_VERSION = "v1" app = FastAPI(lifespan=lifespan) api_v1_router = APIRouter(prefix=f"/{API_VERSION}") api_v1_router.include_router(questions.router) app.include_router(api_v1_router) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=80)  # questions.py from typing import Callable from fastapi import APIRouter, Request, Response class LoggingAPIRoute(APIRoute): @staticmethod async def access_log_req(request: Request) -> None: print("request...") @staticmethod async def access_log_res(request: Request, response: Response) -> None: print("response...") async def get_route_handler(self) -> Callable: original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: await self.access_log_req(request=request) try: response = await original_route_handler(request) await self.access_log_res(request=request, response=response) return response except Exception as e: return "oh snap!" return custom_route_handler router = APIRouter(route_class=LoggingAPIRoute) @router.post("/retrieve", response_class=JSONResponse) async def retrieve(request: Request, auth_result: str = Security(auth.verify)): pass  Calling the v1/retrieve with curl causes an exception to be thrown: TypeError: the first argument must be callable. When removing LoggingAPIRoute usage from the router, the problem is solved. Any ideas? curl localhost:80/v1/retrieve -X POST INFO: 127.0.0.1:52860 - "POST /v1/retrieve HTTP/1.1" 500 Internal Server Error ERROR: Exception in ASGI application Traceback (most recent call last): File "/Users/boss/foo/.venv/lib/python3.13/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ self.scope, self.receive, self.send ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/Users/boss/foo/.venv/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/boss/foo/.venv/lib/python3.13/site-packages/fastapi/applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/middleware/errors.py", line 187, in __call__ raise exc File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/middleware/errors.py", line 165, in __call__ await self.app(scope, receive, _send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/middleware/cors.py", line 85, in __call__ await self.app(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py", line 62, in __call__ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app raise exc File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app await app(scope, receive, sender) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/routing.py", line 714, in __call__ await self.middleware_stack(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/routing.py", line 734, in app await route.handle(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/routing.py", line 288, in handle await self.app(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/routing.py", line 76, in app await wrap_app_handling_exceptions(app, request)(scope, receive, send) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app raise exc File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app await app(scope, receive, sender) File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/routing.py", line 73, in app response = await f(request) ^^^^^^^^^^^^^^^^ File "/Users/boss/foo/.venv/lib/python3.13/site-packages/starlette/concurrency.py", line 36, in run_in_threadpool func = functools.partial(func, *args, **kwargs) TypeError: the first argument must be callable 

Answer: The error was caused by defining the get_route_handler method of LoggingAPIRoute as a coroutine function (async). Removing async before the function definition solved it. class LoggingAPIRoute(APIRoute): @staticmethod async def access_log_req(request: Request) -> None: print("request...") @staticmethod async def access_log_res(request: Request, response: Response) -> None: print("response...") def get_route_handler(self) -> Callable: # <------------ This is now not async original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: await self.access_log_req(request=request) try: response = await original_route_handler(request) await self.access_log_res(request=request, response=response) return response except Exception as e: return "oh snap!" return custom_route_handler