How to make middleware to run on each thread created by FastApi #8865
Replies: 10 comments
-
This is how I have created middleware |
Beta Was this translation helpful? Give feedback.
-
@Kludex Your thumps down means it is not possible or you don't like the question itself? |
Beta Was this translation helpful? Give feedback.
-
I didn't like the fact that you ignored the template and didn't even care to remove it. 😗 |
Beta Was this translation helpful? Give feedback.
-
Oh my bad. I thought I had just a question to be asked. So I have put my question at the last. I am not sure If I can change now. But is my question is valid or not? Is there any workaround to achieve what I am looking for? |
Beta Was this translation helpful? Give feedback.
-
I'm not sure if I completely understand the question. If you can add a code that shows what you're doing and what you expect, it will be clearer. About the issue, removing the stuff that you ignored or using it would be a good idea 😅 |
Beta Was this translation helpful? Give feedback.
-
@Kludex This is the minimal code. from fastapi import FastAPI, Request app = FastAPI() @app.middleware("http") @app.get("{client_id}/items/{item_id}") @app.get("{client_id}/items/{item_id}") So what I am looking for a way to execute middleware in an external thread pool that actually handles the execution when I define my endpoint using def. |
Beta Was this translation helpful? Give feedback.
-
The application context set by middleware is supposed to be used by the downstream thread/process which does the actual execution. We need to set the context for each process/thread per request. We are trying to migrate from Flask to fast API. Flask by default starts the execution in the thread pool, not in the main thread. Hence the context is set per-thread based on the request it handles. |
Beta Was this translation helpful? Give feedback.
-
@Kludex @tiangolo Any thought here? I am new to fast API so may be missing something here. |
Beta Was this translation helpful? Give feedback.
-
Is there any good solution? |
Beta Was this translation helpful? Give feedback.
-
Hi there. First of all @karan-kumar-by edit your question to follow the guidelines and to leave everything clear for someone else who could be the same question Here's an example using contextvars that works for what you are looking for from fastapi import FastAPI, Request
import time
import contextvars
app = FastAPI()
client_id = contextvars.ContextVar("client_id", default="unknown")
@app.middleware("http")
async def client_context(request: Request, call_next):
client_id.set(request.url.path.split('/')[1])
try:
response = await call_next(request)
finally:
client_id.set("unknown")
return response
@app.get("/items_async/{item_id}")
async def read_item_async(item_id):
return {"item_id": item_id}
@app.get("/items/{item_id}")
def read_item(item_id: str):
print(client_id.get())
time.sleep(10)
return {"item_id": item_id} |
Beta Was this translation helpful? Give feedback.
-
First check
Example
Here's a self-contained, minimal, reproducible, example with my use case:
Description
/
.{"Hello": "World"}
.{"Hello": "Sara"}
.Environment
To know the FastAPI version use:
python -c "import fastapi; print(fastapi.__version__)"
To know the Python version use:
Additional context
Main Issue: @tiangolo @dmontagu
I am using a middleware that needs to set a context at each thread pool being created by fast API but as of now only it is done at the main thread. So when the thread pool tries to use the context it is not available. Which is causing errors.
I don't want to set the context on each path in my application.
Let me know if you need more info we can chat or meet if needed.
Beta Was this translation helpful? Give feedback.
All reactions