gpt4 book ai didi

python - FastAPI 中间件查看响应

转载 作者:行者123 更新时间:2023-12-03 20:21:11 42 4
gpt4 key购买 nike

我尝试为 FastAPI 编写一个简单的中间件来查看响应主体。

在这个例子中,我只记录正文内容:

app = FastAPI()

@app.middleware("http")
async def log_request(request, call_next):
logger.info(f'{request.method} {request.url}')
response = await call_next(request)
logger.info(f'Status code: {response.status_code}')
async for line in response.body_iterator:
logger.info(f' {line}')
return response

但是看起来我以这种方式“消耗”了 body ,导致了这个异常:
  ...
File ".../python3.7/site-packages/starlette/middleware/base.py", line 26, in __call__
await response(scope, receive, send)
File ".../python3.7/site-packages/starlette/responses.py", line 201, in __call__
await send({"type": "http.response.body", "body": b"", "more_body": False})
File ".../python3.7/site-packages/starlette/middleware/errors.py", line 156, in _send
await send(message)
File ".../python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 515, in send
raise RuntimeError("Response content shorter than Content-Length")
RuntimeError: Response content shorter than Content-Length

尝试查看响应对象时,我看不到任何其他方式来读取其内容。正确的做法是什么?

最佳答案

我对 FastAPI 中间件也有类似的需求,虽然不理想,但我们最终得到的结果是:

app = FastAPI()

@app.middleware("http")
async def log_request(request, call_next):
logger.info(f'{request.method} {request.url}')
response = await call_next(request)
logger.info(f'Status code: {response.status_code}')
body = b""
async for chunk in response.body_iterator:
body += chunk
# do something with body ...
return Response(
content=body,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.media_type
)


请注意,这样的实现在响应流式传输不适合您的服务器 RAM 的主体时存在问题(想象一下 100GB 的响应)。

根据您的应用程序的功能,您将决定它是否有问题。

在某些端点产生大量响应的情况下,您可能希望避免使用中间件,而是实现自定义 ApiRoute。这个自定义的 ApiRoute 在使用 body 时会有同样的问题,但你可以将它的使用限制在特定的端点上。

https://fastapi.tiangolo.com/advanced/custom-request-and-route/ 了解更多信息

关于python - FastAPI 中间件查看响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60778279/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com