gpt4 book ai didi

python - Flask:通过写入客户端来流式传输数据?

转载 作者:太空宇宙 更新时间:2023-11-03 14:23:47 24 4
gpt4 key购买 nike

我有将数据序列化为类文件对象的现有代码:

def some_serialization_function(file):
file.write(...)

在Flask中,我希望能够将序列化后的数据直接发送给客户端,无需先将其缓冲在内存中。

我查看了 werkzeug 的 ResponseStreamMixin,但我认为它不能在没有缓冲的情况下工作:

class StreamResponse(flask.Response, werkzeug.wrappers.ResponseStreamMixin):
pass

@app.route("/data")
def get_data():
r = StreamResponse()
some_serialization_function(r.stream) # everything is buffered into memory
return r # buffered data is sent after return

我发现的所有流数据示例都是基于生成器的,它们以相反的方向工作(即数据是从生成器中“拉出”,而不是通过写入调用“推出”),所以我想知道,有没有办法在 Flask 中直接“写入”客户端?

编辑 - 更清楚一点:我正在寻找一种方法来提供由“some_serialization_function(...)”(我无法轻易更改)生成的数据,而没有让该函数写入所有内容的内存/IO 开销首先将数据写入缓冲区/文件。

(我怀疑临时文件最终会成为解决之道,因为与通过网络实际发送数据的开销相比,IO 开销并不显着。另外我主要关心的是内存开销)。

最佳答案

您可以创建一个特殊的类似文件的对象,该对象为流式传输到客户端的生成器提供数据。这是一个使用队列的快速而肮脏的实现:

from queue import Queue

class StreamWriter(object):
def __init__(self):
self.queue = Queue()

def write(self, str):
self.queue.put(str)

def read(self):
str = self.queue.get()
self.queue.task_done()
if str == '~':
return None
return str

def close(self):
self.write('~') # indicate EOF

这只不过是一个发布-订阅类型的队列。 read() 方法将阻塞,直到在另一个线程中写入内容。

现在您可以使用生成器流式传输响应。以下示例显示了一个将序列化函数作为参数的生成器。序列化函数在后台线程中执行,并接收类文件对象作为参数。

def generate_response(serialize):
file = StreamWriter()
def serialize_task():
serialize(file)
file.close()
threading.Thread(target=serialize_task).start()
while True:
chunk = file.read()
if chunk is None:
break
yield chunk

希望对您有所帮助!

关于python - Flask:通过写入客户端来流式传输数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23484491/

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