I am building a middleware to log calls to functions among other things.
I have read about
FastAPI: How to get raw URL path from request?, which suggests to use request.scope.get("route")
, which works when used in the endpoint function. However, in the middleware, request.scope has no attribute "route". I am unsure of what a scope really is and why it changes in the middleware, but how can i work around this ?
@app.get("/success/{id}", status_code=201)
def success():
return
app.add_middleware(RequestInfo)
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import Request
class RequestInfo(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
logger.info("Hello")
# Doing some things
Middlewares are called before the routing (https://github.com/encode/starlette/issues/685#issuecomment-550240999). So, in that point there is no easy way to get this information.
Consider using custom APIRoute instead. It's quite similar to middleware in functionality, but it's called after the routing.
from typing import Callable
from fastapi import FastAPI
from fastapi.routing import APIRoute
class LoggingRouter(APIRoute):
def get_route_handler(self) -> Callable:
print(self.dependant.path)
return super().get_route_handler()
app = FastAPI()
app.router.route_class = LoggingRouter
@app.get("/success/{id}", status_code=201)
def success(id: str):
return id
Read more about custom APIRoute: https://fastapi.tiangolo.com/how-to/custom-request-and-route/