在 Flask 中返回立即响应,但在新线程中完成处理

2023-12-31

我有一个从 10 秒开始的过程,但是在 10 秒之后,我不需要将信息返回给用户,而是将其写在 dynamoDB 上,这就是为什么我希望用户不必等待 10 秒。相反,我希望在发布请求后立即得到“成功”响应。

我读了几篇文章并在this https://stackoverflow.com/questions/17293311/flask-end-response-and-continue-processing一,答案是使用 Teardown Callback,但没有示例。

我当时读到this https://stackoverflow.com/questions/30521112/how-teardown-request-works-with-python-flask,但这并不能帮助我解决我的问题。

我当然读过拆卸回调 http://flask.pocoo.org/docs/0.12/reqcontext/#teardown-callbacks and 这个图案 http://flask.pocoo.org/snippets/53/但我不知道如何以其他方式使用它。

我的代码如下所示:

@app.route('/ocr/read_image', methods=['POST'])
def get_text():    
    return jsonify('Success')

@app.teardown_request
def teardown_request(response):        
    time.sleep(10)

它实际上返回“成功”消息,但就在 10 秒之后。

有没有办法在 10 秒之前返回“成功”消息?

我一直在读到芹菜也许是可能的,但如果可以的话我很想避免它。

有谁知道该怎么做?


恕我直言,线程在这里也使事情变得不必要的复杂化。要在不引入线程的情况下完成您想要做的事情,您可以挂接到WSGI响应关闭方法 https://www.python.org/dev/peps/pep-0333/#specification-details。最简单的方法是使用 werkzeug关闭迭代器 http://werkzeug.pocoo.org/docs/0.14/wsgi/#werkzeug.wsgi.ClosingIterator helper.

import traceback
from werkzeug.wsgi import ClosingIterator

class AfterThisResponse:
    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 extensioe
        app.after_this_response = self

        # install middleware
        app.wsgi_app = AfterThisResponseMiddleware(app.wsgi_app, self)

    def flush(self):
        try:
            for fn in self.callbacks:
                try:
                    fn()
                except Exception:
                    traceback.print_exc()
        finally:
            self.callbacks = []

class AfterThisResponseMiddleware:
    def __init__(self, application, after_this_response_ext):
        self.application = application
        self.after_this_response_ext = after_this_response_ext

    def __call__(self, environ, start_response):
        iterator = self.application(environ, start_response)
        try:
            return ClosingIterator(iterator, [self.after_this_response_ext.flush])
        except Exception:
            traceback.print_exc()
            return iterator

然后您可以像这样使用这个扩展:

import flask
import time
app = flask.Flask("after_response")
AfterThisResponse(app)

@app.route("/")
def home():
    @app.after_this_response
    def post_process():
        time.sleep(2)
        print("after_response")

    return "Success!\n"

当您卷曲时,您将立即看到成功,然后 2 秒后在日志中您将看到“after_response”消息:

127.0.0.1 - - [25/Jun/2018 16:15:01] "GET / HTTP/1.1" 200 -
after_response

该解决方案是根据我的答案改编的摘要:

  • Flask 中返回响应后需要执行一个函数 https://stackoverflow.com/questions/18082683/need-to-execute-a-function-after-returning-the-response-in-flask/51027637#51027637
  • Flask结束响应并继续处理 https://stackoverflow.com/questions/17293311/flask-end-response-and-continue-processing/51027454#51027454
  • Flask 返回响应后执行函数 https://stackoverflow.com/questions/48994440/execute-a-function-after-flask-returns-response/51013358#51013358
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Flask 中返回立即响应,但在新线程中完成处理 的相关文章

  • Python:记录垃圾收集器

    我有一个 python 应用程序 有一些性能问题 我想将垃圾收集器的事件 特别是何时调用 添加到我的日志中 是否可以 thanks http docs python org library gc html gc set debug http
  • Python + PostgreSQL + 奇怪的ascii = UTF8编码错误

    我有包含字符的 ascii 字符串 x80 代表欧元符号 gt gt gt print x80 当将包含该字符的字符串数据插入数据库时 我得到 psycopg2 DataError invalid byte sequence for enc
  • Python,将迭代函数变成递归函数

    我创建了一个输出 4 3 2 1 0 1 2 3 4 的迭代函数 def bounce2 n s n for i in range n print n n n 1 if n lt 0 for i in range s 1 print n n
  • 为什么在 Windows 中使用 GetConsoleScreenBufferInfoEx 时控制台窗口会缩小?

    我正在尝试使用 GetConsoleScreenBufferInfoEx 和 SetConsoleScreenBufferInfoEx 设置 Windows 命令行控制台的背景和前景色 我正在 Python 中使用 wintypes 进行此
  • conda 无法从 yml 创建环境

    我尝试运行下面的代码来从 YAML 文件创建虚拟 Python 环境 我在 Ubuntu 服务器上的命令行中运行代码 虚拟环境名为 py36 当我运行下面的代码时 我收到下面的消息 环境也没有被创建 这个问题是因为我有几个必须使用 pip
  • html 解析器 python

    我正在尝试解析一个网站 我正在使用 HTMLParser 模块 问题是我想解析第一个 a href 评论后 但我真的不知道该怎么做 所以我在文档中发现有一个函数叫做handle comment 但我还没有找到如何正确使用它 我有以下内容 i
  • 使用 Scipy imsave 将 Numpy 数组保存到图像时保留未更改的数据

    使用 Scipy 保存二维 Numpy 数组 单个值 时toimage or imsave像素值与 Numpy 数组中的像素值不完全匹配 相反 在某些区域 主要是边缘 图像算法似乎使用某种插值 是否有一个选项可以停止插值并保留准确的数据 例
  • 为 Networkx 图添加标题?

    我希望我的代码创建一个带有标题的图 使用下面的代码 可以创建绘图 但没有标题 有人可以告诉我我做错了什么吗 import pandas as pd import networkx as nx from networkx algorithms
  • str.translate 给出 TypeError - Translate 采用一个参数(给定 2 个参数),在 Python 2 中工作

    我有以下代码 import nltk os json csv string cPickle from scipy stats import scoreatpercentile lmtzr nltk stem wordnet WordNetL
  • 一行Python和SQLite代码,为什么需要加“,”? [复制]

    这个问题在这里已经有答案了 c execute INSERT INTO numbers VALUES random randint 0 100 如果我将上面的代码更改为 c execute INSERT INTO numbers VALUE
  • 一起使用 Flask 和 Tornado?

    我是以下的忠实粉丝Flask 部分是因为它很简单 部分是因为它有很多扩展 http flask pocoo org extensions 然而 Flask 是为了在 WSGI 环境中使用而设计的 而 WSGI 不是非阻塞的 所以 我相信 它
  • 当另一个线程发生事情时从主线程获取数据?

    目前我有一个线程正在运行一个侦听连接的套接字 当它收到连接时 它需要上传在主线程中收集的数据 即从主线程获取数据 但是 我传递了对象的实例 但它从未使用等待连接时收集的数据进行更新 有没有正确的方法来做到这一点 我用谷歌搜索了一下 似乎找不
  • numpy.cov() 返回意外的输出

    我有一个 X 数据集 有 9 个特征和 683 行 683x9 我想获取这个 X 数据集和另一个与 X 具有相同形状的数据集的协方差矩阵 我使用np cov originalData generatedData rowvar False 代
  • 大型数据集上的 Sklearn-GMM

    我有一个很大的数据集 我无法将整个数据放入内存中 我想在这个数据集上拟合 GMM 我可以用吗GMM fit sklearn mixture GMM 重复小批量数据 没有理由重复贴合 只需随机采样您认为机器可以在合理时间内计算的尽可能多的数据
  • 使用Beam IO ReadFromPubSub模块时,可以在Python中提取带有属性的消息吗?尚不清楚是否支持

    尝试将具有存储在 PubSub 中的属性的消息拉取到 Beam 管道中 我想知道是否添加了对 Python 的支持 这就是我无法阅读它们的原因 我看到它存在于Java中 pipeline options PipelineOptions pi
  • 如何向 SCons 构建添加预处理和后处理操作?

    我正在尝试在使用 SCons 构建项目时添加预处理和后处理操作 SConstruct 和 SConscript 文件位于项目的顶部 预处理动作 生成代码 通过调用不同的工具 gt 不知道在此预处理之后将生成的确切文件 可以创建用于决定生成哪
  • 在游戏中实现功能

    我在完成这部分作业时遇到了麻烦 我必须宣布游戏的获胜者 然后输入到函数中 输入所有 if 语句后 我必须创建一个函数def playGame 这必须包括 showRules user getUserChoice computer getCo
  • 从数据集的给定日期范围中提取属于一天的数据

    我有一个数据集 日期范围为 2018 年 1 月 12 日到 8 月 3 日 其中包含一些值 维数为my df数据框是 my df shape 9752 2 每行包含半小时频率 第一行开始于2018 01 12 my df iloc 0 D
  • 为什么用字符串和时间增量转置 DataFrame 会转换数据类型?

    这种行为对我来说似乎很奇怪 id列 字符串 在转置后转换为时间戳df如果另一列是时间增量 import pandas as pd df pd DataFrame id 00115 01222 32333 val 12 14 170 df v
  • 从 pandas 数据框中绘制堆积条形图

    我有数据框 payout df head 10 复制以下 Excel 绘图的最简单 最智能和最快的方法是什么 我尝试过不同的方法 但无法让一切都到位 Thanks 如果您只想要一个堆积条形图 那么一种方法是使用循环来绘制数据框中的每一列 并

随机推荐