FastAPI StreamingResponse 不使用生成器函数进行流式处理
FastAPI 的 StreamingResponse 旨在在数据可用时将数据流式传输回客户端。但是,有报告称在使用生成器函数时 StreamingResponse 无法按预期工作。本文将调查此问题的潜在原因并提供解决方案。
阻塞操作和生成器函数
Python 中的生成器函数可以定义一系列值,这些值是一次产生一个。但是,如果在生成器函数内执行阻塞操作(例如 time.sleep()),它可能会阻塞事件循环,从而阻止 FastAPI 将数据流式传输到客户端。
Def 与Async Def
FastAPI 根据生成器函数是否使用 def 或 async def 语法以不同方式处理 StreamingResponse。如果生成器函数是使用 async def 语法定义的,FastAPI 会假定它是一个异步生成器,并在线程池或任务池中执行它。但是,如果生成器函数使用 def 语法,FastAPI 会将其识别为阻塞生成器,并使用 iterate_in_threadpool() 在单独的线程中运行它。
推荐方法
为了避免阻塞操作并确保正确的流式传输,建议使用异步生成器函数(async def)。如有必要,任何阻塞操作都应在外部线程池中执行并等待,以避免中断事件循环。
响应媒体类型
在某些情况下,浏览器可能会缓冲文本/纯文本响应以检查 MIME 类型。为了防止这种情况,建议指定不同的媒体类型,例如 text/event-stream、application/json,或将 X-Content-Type-Options 标头设置为 nosniff。
示例
这是一个具有用于流数据的生成器函数的工作 FastAPI 应用程序的示例:
from fastapi import FastAPI, StreamingResponse, Request from fastapi.responses import HTMLResponse import asyncio app = FastAPI() @app.get("/stream") async def streaming_data(request: Request): def generate_data(): for i in range(10): yield b'some fake data\n\n' await asyncio.sleep(0.5) return StreamingResponse(generate_data(), media_type="text/event-stream")
结论
通过避免阻塞操作,使用异步生成器函数并指定适当的媒体类型,您可以确保 FastAPI StreamingResponse 按预期工作,从而使您能够高效地将数据流式传输到客户端。
以上是为什么 FastAPI 的 StreamingResponse 不使用生成器函数进行流式传输?的详细内容。更多信息请关注PHP中文网其他相关文章!