pythonloggingfastapipython-loggingstarlette

How to log raw HTTP request/response in Python FastAPI?


We are writing a web service using Python FastAPI that is going to be hosted in Kubernetes. For auditing purposes, we need to save the raw JSON body of the request/response for specific routes. The body size of both request and response JSON is about 1MB, and preferably, this should not impact the response time. How can we do that?


Solution

  • You may try to customize APIRouter like in FastAPI official documentation:

    import time
    from typing import Callable
    
    from fastapi import APIRouter, FastAPI, Request, Response
    from fastapi.routing import APIRoute
    
    
    class TimedRoute(APIRoute):
        def get_route_handler(self) -> Callable:
            original_route_handler = super().get_route_handler()
    
            async def custom_route_handler(request: Request) -> Response:
                before = time.time()
                response: Response = await original_route_handler(request)
                duration = time.time() - before
                response.headers["X-Response-Time"] = str(duration)
                print(f"route duration: {duration}")
                print(f"route response: {response}")
                print(f"route response headers: {response.headers}")
                return response
    
            return custom_route_handler
    
    
    app = FastAPI()
    router = APIRouter(route_class=TimedRoute)
    
    
    @app.get("/")
    async def not_timed():
        return {"message": "Not timed"}
    
    
    @router.get("/timed")
    async def timed():
        return {"message": "It's the time of my life"}
    
    
    app.include_router(router)