Hob*_* C. 4 python starlette fastapi
我使用中间件来打印 HTTP 请求正文,以避免print每个函数中出现语句。但是,运行客户端代码时fastapi没有任何响应。
服务器简化为以下代码:
import typing
import uvicorn
from fastapi import FastAPI
from fastapi import Request, Body
app = FastAPI()
@app.middleware('http')
async def debug_request(request: Request, call_next):
_body = await request.body()
print(_body)
#
response = await call_next(request)
return response
@app.put("/")
def _(
_body: typing.Dict
):
# print(_body) # this statement is replaced by the middleware
return {"detail": "ok"}
if __name__ == '__main__':
uvicorn.run(app, host='localhost', port=8000)
Run Code Online (Sandbox Code Playgroud)
客户端代码如下:
import requests
_url = 'http://localhost:8000/'
_json = {
'row_id': '1'
}
resp = requests.put(_url, json=_json)
if not resp.ok:
print('http-code: ', resp.status_code)
print('http-response: ', resp.text)
Run Code Online (Sandbox Code Playgroud)
我还没有解决这个问题的方法,但是,我花了相当多的时间陷入这个悬而未决的问题(对于我的组织中具有多个自定义 MDW 的关键应用程序)。这种挂起基本上是因为@app.middleware("http")基于中间件,是在后端通过继承 Starlette 的BaseHTTPMiddleware. 所以对于显式继承编写的MDW也存在这个问题BaseHTTPMiddleware。造成这种情况的原因相当复杂,这是我目前所了解的:
StreamingResponse一些问题request.json()在 API 的请求生命周期中只允许等待一次,并且BaseHTTPMiddleware还自行创建一个 Request 对象(这会导致挂起问题,因为这是另一个请求)最后一个链接还提到,导致挂起问题的原因是StreamingResponse;响应的读取在第一次读取时不知何故耗尽,当涉及第二次读取时,它会无限期地等待它,这会导致挂起。(这里的第一个和第二个意思是:在 ASGI 应用程序中,消息以各种类型发送到客户端和应用程序http.response.start,http.response.body例如等)