I would like to populate dict along my endpoint run and once it finish log it in the router
when trying to use context vars
from contextvars import ContextVar
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.responses import Response
app = FastAPI()
# Create a ContextVar to store request-specific data
request_state = ContextVar("request_state", default={})
class CustomMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
# Initialize the context variable for this request
token = request_state.set({"start_wrap": "1"})
response = await call_next(request)
# Modify the state after the endpoint
current_state = request_state.get()
current_state["end_wrap"] = "3"
print("Inside middleware after call_next:", current_state)
return response
app.add_middleware(CustomMiddleware)
@app.get("/")
async def root():
current_state = request_state.get()
updated_state = {**current_state, "endpoint": "2"}
request_state.set(updated_state)
print("Inside root endpoint:", request_state.get())
return {"message": "Hello World"}
# For testing purposes
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
I am getting
Inside root endpoint: {'start_wrap': '1', 'endpoint': '2'}
Inside middleware after call_next: {'start_wrap': '1', 'end_wrap': '3'}
I would like to get
Inside root endpoint: {'start_wrap': '1', 'endpoint': '2'}
Inside middleware after call_next: {'start_wrap': '1', 'endpoint': '2' , 'end_wrap': '3'}
-
from what i understood using thread.local() is not a solution since multiple coroutines run within the same thread
-
another solution is to add request:Request to the endpoint signature, pack stuff to request.data and unpack
but assuming i have 50 endpoints in my app I wouldn’t like to add it to each of them, and it look very messy.
Any thoghts how i can solve it ?
have wrote it in the question
Yoav Stern is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.