可悲的是,将响应返回给客户端后,拆卸回调不执行:
import flaskimport timeapp = flask.Flask("after_response")@app.teardown_requestdef teardown(request): time.sleep(2) print("teardown_request")@app.route("/")def home(): return "Success!n"if __name__ == "__main__": app.run()
卷曲时,您会注意到在显示响应之前有2s的延迟,而不是卷曲立即结束,然后在2s之后记录。日志进一步确认了这一点:
teardown_request127.0.0.1 - - [25/Jun/2018 15:41:51] "GET / HTTP/1.1" 200 -
返回响应后执行的正确方法是使用WSGI中间件,该中间件向响应迭代器的close方法添加了一个钩子。这不像
teardown_request装饰器那么简单,但是仍然很简单:
import tracebackfrom werkzeug.wsgi import ClosingIteratorclass AfterResponse: def __init__(self, app=None): self.callbacks = [] if app: self.init_app(app) def __call__(self, callback): self.callbacks.append(callback) return callback def init_app(self, app): # install extension app.after_response = self # install middleware app.wsgi_app = AfterResponseMiddleware(app.wsgi_app, self) def flush(self): for fn in self.callbacks: try: fn() except Exception: traceback.print_exc()class AfterResponseMiddleware: def __init__(self, application, after_response_ext): self.application = application self.after_response_ext = after_response_ext def __call__(self, environ, start_response): iterator = self.application(environ, start_response) try: return ClosingIterator(iterator, [self.after_response_ext.flush]) except Exception: traceback.print_exc() return iterator
然后可以这样使用:
@app.after_responsedef after(): time.sleep(2) print("after_response")
从外壳程序中,您将看到响应立即返回,然后2秒钟后
after_response它将返回日志:
127.0.0.1 - - [25/Jun/2018 15:41:51] "GET / HTTP/1.1" 200 -after_response
这是此处提供的先前答案的摘要。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)