Awaiting request body in middleware blocks the application
See original GitHub issueDescribe the bug Description in the title
To Reproduce Minimal code:
from typing import Mapping
from fastapi import FastAPI
from starlette.requests import Request
app = FastAPI()
@app.middleware("http")
async def func(request: Request, call_next):
print(await request.json())
return await call_next(request)
@app.post("/")
def read_root(arg: Mapping[str, str]):
return {"Hello": "World"}
Run the application with uvicorn <file>:app
Test the bug with curl localhost:8000 -d '{"status":"ok"}'
Expected behavior
The body of the request is printed, but the curl command stay pending for ever. If it is interrupted (Ctrl-C), the application then print ERROR: Error getting request body:
Environment:
- OS: macOS
- fastapi 0.33.0
- python 3.7.3
- (tested on Ubuntu too with Python 3.7.0 and 3.7.4)
Additional context
- When the route function has no body argument (
def read_root():
), there is no problem : the body is printed and the response send. - Thinking the issue was maybe coming from Starlette, I tested the following code, which works without issue. The bug seems thus to come from fastapi
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
app = Starlette()
@app.middleware("http")
async def func(request: Request, call_next):
print(await request.json())
return await call_next(request)
@app.route('/', methods=["POST"])
def homepage(request):
return JSONResponse({"Hello": "World"})
Issue Analytics
- State:
- Created 4 years ago
- Reactions:16
- Comments:21 (7 by maintainers)
Top Results From Across the Web
FASTAPI custom middleware getting body of request inside
You need to await on the request so the request object is infact ready to be read. This is how I achieved it....
Read more >Middleware - FastAPI
A "middleware" is a function that works with every request before it is processed by any specific path operation. And also with every...
Read more >Conditional Middleware based on request in ASP.NET Core
This post looks at how to configure ASP.NET Core middleware in a way that allows you to have different middleware for different types...
Read more >slack_bolt.async_app API documentation
@app.command("/hello-bolt-python") async def command(ack, body, ... is a built-in middleware that verifies the signature in HTTP Mode requests.
Read more >Blocked code while using middleware and dependency ...
@app.middleware("http") async def log_request(request: Request, call_next): # Code to log incoming request response = await call_next(request) # Code to log ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I think the middleware is unnecessary, should you want to get your payload just do:
But i don’t want to just get the payload of one request, i want to log the payloads of EVERY endpoints of my application. I don’t want for that to add code in every endpoint, that’s the purpose of a middleware.