如何解决Flask 视图装饰器和流式内容
Flask 允许用户创建 custom endpoint decorators 和 to stream responses(基本上通过在 flask.Response 中返回一个生成器)。
我想让这两个概念一起工作。这是一个装饰器,它在处理请求之前和之后初始化和关闭上下文。 (在现实生活中,它会做数据库连接相关的事情):
def mydecorator(f):
@wraps(f)
def decorated_function(*args,**kwargs):
print("Start context")
result = f(*args,**kwargs)
print("End context")
return result
return decorated_function
@app.route("/regular")
@mydecorator
def regular_endpoint():
print("start normal")
random_function_that_need_the_decorator_context()
print("end normal")
return render_template("whatever.html")
# prints: start context,start normal,end normal,end context
@app.route("/streamed")
@mydecorator
def streamed_endpoint():
def mygenerator():
print("start generator")
random_function_that_need_the_decorator_context()
for _ in range(1000):
yield "something"
print("end generator")
return Response(mygenerator())
# prints: start context,end context,start generator,end generator
常规端点按预期工作,但流端点失败,因为内部生成器函数需要装饰器上下文,但在生成器函数执行时装饰器上下文已关闭。
有没有办法在生成器执行时保持装饰器上下文打开? 在flask 中有一个stream_with_context 函数,但它似乎只提供flask 请求上下文。使用 after_request 并没有得到更好的结果,因为在执行生成器之前调用了该函数。
解决方法
一旦在服务器上启动响应,Flask 将自动删除请求上下文。这主要是为了防止内存泄漏。因此,您必须明确告诉它保留它。你可以用“stream_with_context”来做到这一点:
from flask import stream_with_context
@app.route("/streamed")
@mydecorator
def streamed_endpoint():
def mygenerator():
print("start generator")
random_function_that_need_the_decorator_context()
for _ in range(1000):
yield "something"
print("end generator")
return Response(stream_with_context(mygenerator()))
在 Flask==1.1.1
中测试和工作
可以找到更多信息here
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。