-
First Check
Commit to Help
Example Codefrom fastapi import FastAPI, Request
import uvicorn
app = FastAPI()
def setup_post_duplicate_handler(router, subroute):
routeName = ""
routeEndpoint = None
for route in router.routes:
if route.path.endswith(subroute):
routeName = route.name
routeEndpoint = route.endpoint
break
@router.post(subroute, name=routeName)
async def post_method(request: Request):
print("222222")
print(request)
print(await request.form())
args = await request.form()
return await routeEndpoint(**args)
@app.middleware("http")
async def authorization(request: Request, call_next):
print("111111")
print(request)
# print(await request.body()) # this command fix the problem
print(await request.form())
return await call_next(request)
@app.get(
"/foo"
)
async def get_foo(name: str = '[default value]'
) -> str:
return name
setup_post_duplicate_handler(app, "/foo")
if __name__ == '__main__':
uvicorn.run("main:app", host="127.0.0.1", port=5000, reload=False)Descriptionsteps: expected: "123" actual: "[default value]" requerements.txt: Operating SystemLinux Operating System DetailsNo response FastAPI Version0.115.12 Pydantic VersionPython Version3.10.3 Additional Contextif uncomment "print(await request.body())" in authorization() - the problem will gone. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Hello @SailorMax, Few things to cover. This issue actually stems from Starlette’s HTTP middleware: it creates a cached copy of the request by wrapping the ASGI receive function, but it doesn’t handle some cases where the middleware itself consumes the stream (for example, via await request.form()). Once that stream is drained, downstream handlers have nothing left to read.
in your authorization() middleware, you force Starlette to read and cache the entire body, so later reads succeed.
the middleware never drains the stream, and your endpoint can read it normally. Also a small sidenotes: await request.form()
await request.body()In any case this will raise a |
Beta Was this translation helpful? Give feedback.
Hello @SailorMax,
Few things to cover. This issue actually stems from Starlette’s HTTP middleware: it creates a cached copy of the request by wrapping the ASGI receive function, but it doesn’t handle some cases where the middleware itself consumes the stream (for example, via await request.form()). Once that stream is drained, downstream handlers have nothing left to read.
Starlette discourages and may eventually stop supporting the use of this HTTP middleware, so this form-consumption case is unlikely to be fixed upstream.
in your authorization() middleware, you force Starlette to read and cache the …