Flask提供了Response对象来处理HTTP响应。可以通过在视图函数中返回一个Response对象,然后使用Response对象的iter方法来实现将数据流式传输到客户端。
1.1 循环生成迭代数据块
from flask import Flask, Response, stream_with_context, requestapp = Flask(__name__)@app.route('/stream')
def stream_data():def generate():for i in range(10):# 使用了查询参数stop来控制是否停止发送响应。如果请求的URL中包含stop=true,那么流响应将被中止。if request.args.get('stop') == 'true':breakyield f'Data: {i}\n'return Response(stream_with_context(generate()))if __name__ == '__main__':app.run()
1.2文件内容流式读取
from flask import Flask, Response, stream_with_contextapp = Flask(__name__)@app.route('/')
def stream_file():def generate():#定义了一个名为stream_file的路由,该路由对应的处理函数中打开了一个文件并逐行生成文件内容。yield关键字用于将每行数据逐一传输给客户端。with open('example.txt', 'r') as f:for line in f:yield linereturn Response(stream_with_context(generate()))if __name__ == '__main__':app.run()
1.3 流式下载大文件
import os
from flask import Flask, Responsedef download_file(file_path):def generate():if not os.path.exists(file_path):raise 'file not found!'with open(file_path, 'rb') as f:while True:chunk = f.read(chunk_size=10*1024*1024)if not chunk:breakyield chunk#return Response(generate(), content_type='application/octet-stream')#上面的可以正常下载,但是只有实时速度,没有文件大小,不知道下了多少或者什么时候下完,可以改成下面的response = Response(generate(), mimetype='application/gzip')# mimetype根据实际压缩文件类型修改匹配即可。response.headers['Content-length']= os.stat(str(file_path)).st_sizereturn response
设置数据流的相关参数
通过使用Response对象的一些方法,可以设置响应头信息,以及其他一些参数。
- content_type:设置响应头中的Content-Type字段。
- mimetype:设置响应头中的Content-Type字段。这个方法和content_type是等价的。
- status:设置响应的HTTP状态码。默认为200。
- headers:设置其他的响应头信息。可以使用字典或者werkzeug.datastructures.Headers对象。
- set_cookie:设置Cookie。