Python Flask 在执行函数的同时返回 html 页面

2024-03-08

我目前正在使用 Python Flask 创建一个 Web 应用程序,但我遇到了障碍,我不确定我是否正确地思考了它。

因此,我网站的主页只是一个简单的登陆页面,其中包含执行网站功能所需的文本输入。我想要完成的是让网络应用程序在输入文本后执行两件事。首先,服务器获取用户名输入并执行一个函数,该函数不会向用户返回任何内容,而是创建一组记录到 sqlite 数据库中的数据,并在稍后的过程中使用。然后,服务器返回输入用户名后必须进行的调查的网页。但是,服务器执行的功能可能需要长达 2 分钟的时间,具体取决于用户。按照我目前的编码方式,服务器执行该功能,然后一旦完成,它就会返回网页,因此用户会在加载屏幕上停留长达 2 分钟。

@app.route("/survey")
def main(raw_user):
    raw_user = request.args.get("SteamID")      <
    games = createGameDict(user_obj)            <----- the function
    tag_lst = get_tags(games)                   <
    return render_template("survey_page.html")

由于调查不依赖于用户输入,而不是让用户坐在加载屏幕上,我希望他们能够在功能在后台运行时开始调查,这是否可能,以及我将如何去做?


更新:我不得不在 Flask 中多次解决这个问题,所以我编写了一个名为的小型 Flask 扩展Flask执行器 https://github.com/dchevell/flask-executor为我做这件事。它是并发的包装器,提供了一些方便的功能,并且是我处理不需要在 Flask 中分发的后台任务的首选方法。


对于更复杂的后台任务,像芹菜这样的东西是你最好的选择。然而,对于更简单的用例,您想要的是threading module.

考虑以下示例:

from flask import Flask
from time import sleep

app = Flask(__name__)


def slow_function(some_object):
    sleep(5)
    print(some_object)

@app.route('/')
def index():
    some_object = 'This is a test'
    slow_function(some_object)
    return 'hello'

if __name__ == '__main__':
    app.run()

在这里,我们创建一个函数,slow_function()返回之前会休眠五秒钟。当我们在路由函数中调用它时,它会阻止页面加载。运行示例并点击http://127.0.0.1:5000 http://127.0.0.1:5000在浏览器中,您将看到页面在加载前等待五秒钟,然后在终端中打印测试消息。

我们想做的是把slow_function()在不同的线程上。只需添加几行代码,我们就可以使用threading模块将该函数的执行分离到不同的线程上:

from flask import Flask
from time import sleep
from threading import Thread

app = Flask(__name__)


def slow_function(some_object):
    sleep(5)
    print(some_object)

@app.route('/')
def index():
    some_object = 'This is a test'
    thr = Thread(target=slow_function, args=[some_object])
    thr.start()
    return 'hello'

if __name__ == '__main__':
    app.run()

我们在这里做的事情很简单。我们正在创建一个新实例Thread并传递两件事:target,这是我们要运行的函数,并且args,要传递给目标函数的参数。注意,上面没有括号slow_function,因为我们不是runningit - 函数是对象,所以我们传递函数itself to Thread。至于args,这总是需要一个列表。即使您只有一个参数,也请将其包装在一个列表中,以便args得到它所期望的。

当我们的线程准备就绪时,thr.start()执行它。在浏览器中运行此示例,您会注意到索引路由现在立即加载。但再等五秒钟,果然,测试消息将打印在您的终端中。

现在,我们可以在这里停下来 - 但至少在我看来,在路由本身内部实际包含此线程代码有点混乱。如果您需要在另一个路由或不同的上下文中调用此函数怎么办?最好将其分离为自己的功能。您可以使线程行为成为慢速函数本身的一部分,或者您可以创建一个“包装”函数 - 您采用哪种方法在很大程度上取决于您正在做什么以及您的需求是什么。

让我们创建一个包装函数,看看它是什么样子的:

from flask import Flask
from time import sleep
from threading import Thread

app = Flask(__name__)


def slow_function(some_object):
    sleep(5)
    print(some_object)

def async_slow_function(some_object):
    thr = Thread(target=slow_function, args=[some_object])
    thr.start()
    return thr

@app.route('/')
def index():
    some_object = 'This is a test'
    async_slow_function(some_object)
    return 'hello'

if __name__ == '__main__':
    app.run()

The async_slow_function()函数所做的事情几乎与我们之前所做的完全一样 - 现在只是更简洁了一些。您可以在任何路由中调用它,而无需重新重写线程逻辑。您会注意到这个函数实际上返回线程 - 我们没有need对于本例来说是这样,但是稍后您可能想对该线程执行其他操作,因此返回它可以使线程对象在您需要时可用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python Flask 在执行函数的同时返回 html 页面 的相关文章

随机推荐

  • 将 root 中的默认 python 更改为 anaconda 的 python

    我已经在我的系统中安装了 python 2 7 并且还安装了 Anaconda 现在 我正在使用 python 的 anaconda 它运行得很好 不幸的是 我想使用anaconda的python来使用root运行 问题是我无法更改 roo
  • 仅允许接下来的 5 个工作日 jquery datepicker

    我有一个日期选择器 用于设置约会 唯一的问题是老板希望预约日期仅限于接下来的 5 个工作日 我知道如何禁用周末 但我有点不清楚如何做到这一点 以便如果我选择周三 它可以让我选择下周三之前的日期并考虑周末 有人对如何实现这一目标有任何想法吗
  • 无法使用完成处理程序进行抛出操作

    我正在尝试添加一个throws使用完成处理程序添加到我现有的函数 但我不断收到警告说no calls throwing functions occur within try expression 在我抛出错误的部分中 我收到一条错误消息 从
  • 使用 UIBezierPath 绘制圆角

    我有一个设计元素无法弄清楚 希望有人能够指出我正确的方向 我试图构建的元素是这样的 实际上 它是一个圆角矩形 在左侧 顶部和右侧都有描边 底部应该没有描边 我尝试过使用以下代码 Create the rounded rectangle le
  • 如何优化这个 GORM 查询

    我有一个查询 它进行 2 个数据库查询 我是 GORM 的新手 不知道如何使用条件 where 子句或其他内容将其优化为 1 个查询 我也使用 springsecurity 并有一个用于登录安全的 User 类 我有一个带有 User 对象
  • 在特定时间后台获取

    我正在寻找即使应用程序终止也能在后台模式下获取数据的解决方案 对于这个问题有很多教程和答案 但我的问题与其他问题不同 我在 stackoverflow 上没有找到任何合适的解决方案 所以发布了这个问题 我有一个可以解释的场景 我正在使用存储
  • Nhibernate:以相同的精度和小数位映射所有小数

    据我了解 在 NHibernate 中 使用代码映射 我可以指定小数属性的精度和小数位数 如下所示 Property x gt x Dollars m gt m Precision 9 m Scale 6 这很好 但我想知道是否有一种方法可
  • Clojure 的动态变量和绑定的实际用途是什么?

    我看了一下参考资料 http clojure org vars Vars 20and 20the 20Global 20Environment http clojure org vars Vars 20and 20the 20Global
  • 如何在 Ubuntu 16 中下载 Appium 桌面

    我正在尝试在 Ubuntu 16 中下载 Appium Desktop 到目前为止我只是使用终端来运行它 据我所知 对于 Ubuntu 我必须下载他们在 git 上的源代码版本 源代码 tar gz 而不是他们的 exe windows 或
  • 在C中使用枚举类型变量作为字符串的简单方法?

    这就是我想做的 typedef enum ONE TWO THREE Numbers 我正在尝试编写一个函数来执行类似于以下内容的 switch case char num str 10 int process numbers str Nu
  • 为具有抽象复杂类型的模式生成类

    我正在使用一些定义抽象复杂类型的模式 例如
  • 所需类型与找到类型相同

    我想做这个 Foo
  • “Lato”字体在 Safari 中呈现奇怪,而不是在 Chrome 或 Firefox 中呈现

    我使用谷歌网络字体中的 Lato 字体 它在除 safari 之外的所有浏览器上显示良好 我用它font weight 100 以下是不同浏览器的一些屏幕截图 知道什么可能导致它变得非常薄吗 或者如果有办法我可以将其设置为渲染font we
  • 如何在Android中设置EditText的最小和最大字符限制?

    我想设置 EditText 框的最小和最大输入值 我正在为 EditText 创建一个简单的验证 它采用 A Z 和 0 9 值 最小 5 个字符 最大 8 个字符 我设置最大验证和其他验证如下
  • 通过不同的容器修改std容器的内容

    我不知道这是否是正确的方法 但我认为它解释了我想要实现的目标 我有三个向量 std vector
  • 如何检查postgres用户是否存在?

    createuser允许在 PostgreSQL 中创建用户 ROLE 有没有一种简单的方法来检查该用户 名称 是否已经存在 否则 createuser 返回错误 createuser creation of new role failed
  • 在 GKE 下时拒绝EscalatingExec

    我们将 GKE 与 Kubernetes 集群结合使用 我们正在运行的应用程序之一是 Jenkins for CI 不幸的是 Jenkins Slave 需要使用 Docker 来挂载其主机的docker sock 这可能是一种升级漏洞 解
  • 当出现客户端未知错误时如何在 Perforce P4 中设置客户端根

    突然 当我跑步时p4 info在终端中 我注意到客户端根目录未设置 不知道为什么它突然被取消设置 以下是输出 其中显示 客户端未知 代替客户端根目录 我可以通过什么命令设置一样吗 我试过了p4 client and p4 set但可能是 语
  • 使用 Google Analytics for Android SDK 时遇到的问题 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 使用适用于 Android 的 Go
  • Python Flask 在执行函数的同时返回 html 页面

    我目前正在使用 Python Flask 创建一个 Web 应用程序 但我遇到了障碍 我不确定我是否正确地思考了它 因此 我网站的主页只是一个简单的登陆页面 其中包含执行网站功能所需的文本输入 我想要完成的是让网络应用程序在输入文本后执行两