为了账号安全,请及时绑定邮箱和手机立即绑定

FastAPI中的流式响应解析

标签:
Python Flask API

FastAPI 支持通过 StreamingResponse 实现流式响应。还有一个 Starlette 实现的服务器发送事件(EventSourceResponse)可以在这里找到:here。问题是,它们有何不同?

FastAPI 中的 StreamingResponse 与 Starlette 中的 EventSourceResponse 的对比

StreamingResponse 是 FastAPI 中的一种响应类型,用于处理流式数据。相比之下,EventSourceResponse 是 Starlette 中的一种响应类型,主要用于实现服务器发送事件 (SSE) 功能。这里,我们将探讨这两种响应类型的异同。

关于StreamingResponse的简述(流响应)来自 FastAPI 文档: 如下:

这很模糊,没什么帮助 -_-。如果我们来看一看上面定义的 FastAPI 应用程序的响应网络请求,看起来是这样的。

有一件事特别显眼。Transfer-Encoding: chunked.

如果我们看一下 Mozilla 开发者网站上的相关文档:

指令

[ _chunked_](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#chunked)

数据以一系列块的形式传输。在这种情况下,会省略[_Content-Length_]头部字段,在每个块的开始需添加当前块长度的十六进制表示,后面跟着'_\r\n_',紧随其后是块自身,再跟一个'_\r\n_'。唯一的区别是其长度为零。其后跟随一个尾部,由一个(可能为空的)头部字段序列组成。

这里的关键点是,当服务器在发送第一个响应数据块前还不知道内容长度时,可以使用 Transfer-Encoding: chunked 头部。很明显,这就是 StreamingResponse 的全部操作,它只是开始发送带有 Transfer-Encoding 标头为 chunks 的响应数据块,并不再指定 content-length。

来自sysid blog的 EventSourceResponse 描述:

服务器发送事件(SSE)是 HTML 标准的一部分,而不是直接属于 HTTP 标准1。它们定义了一个协议,该协议对 HTTP 层是透明的,不会扰乱任何下层协议。

在核心上,SSE 实际上只是一个 _Content-Type 头,它告诉客户端响应将分块传送。它还通知浏览器,每当接收到新的数据块时,浏览器就将这些数据块暴露给代码,而不是等到整个请求完成,就像 WebSocket 的帧一样2

有点帮助,要点是:

  • SSE 只是一个 _Content-Type_ 事件流头。SSE 即 Server-Sent Events。

我们可以构建一个使用 EventSourceResponse: 的 FastAPI 应用:

from fastapi import FastAPI  
from fastapi.responses import StreamingResponse  
import json  
from sse_starlette import EventSourceResponse  

app = FastAPI()  
def fake_video_streamer():  
    try:  
        for i in range(10):  
            yield {  
                    "data": json.dumps(f"数据点 {i}"),  
                    "event": "数据段",  
                }  
        yield {"event": "完成"}  
    except:  
        yield {  
            "event": "错误",  
            "data": json.dumps(  
                {"HTTP状态码": 500, "信息": "服务器内部错误"}  
            ),  
        }  
        raise  

@app.get("/")  
async def main():  
    return EventSourceResponse(fake_video_streamer())

我们来看看网络的响应头信息:

最显眼的是:

  • 内容类型为: [text/event-stream](https://html.spec.whatwg.org/multipage/iana.html#text/event-stream)

在内容类型中添加 MIME 类型,表示文档、文件或字节集合的类型和格式。由于它是 HTML 标准的一部分,因此很容易编写客户端代码通过定义的接口(比如)读取服务器发送的带有 MIME 类型 [text/event-stream](https://html.spec.whatwg.org/multipage/iana.html#text/event-stream) 的事件(分块响应流) → EventSource

这里有这样一个很棒的关于使用React.js处理SSE的gist:这个链接

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消