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

2024-05-17 05:44:38 发布

您现在位置:Python中文网/ 问答频道 /正文

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

所以我的网站主页只是一个简单的登陆页面,需要输入文本来执行网站功能。我要做的是让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")

既然调查不依赖于用户的输入,而不是让用户坐在加载屏幕上,我希望他们能够在功能在后台工作时启动调查,有可能吗?我该怎么做?在


Tags: 数据函数用户功能服务器web网页get
1条回答
网友
1楼 · 发布于 2024-05-17 05:44:38

更新:我已经在Flask中多次解决这个问题,所以我编写了一个名为Flask-Executor的小Flask扩展来为我解决这个问题。它是一个包装同期期货这提供了一些方便的特性,并且是我处理不需要在Flask中分发的后台任务的首选方法。在


对于更复杂的背景任务,像芹菜之类的东西是你最好的选择。但是,对于更简单的用例,您需要的是threading模块。在

考虑以下示例:

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(),该函数在返回之前休眠5秒钟。当我们在route函数中调用它时,它会阻止页面加载。运行示例并在浏览器中点击http://127.0.0.1:5000,您将看到页面在加载前等待五秒钟,之后测试消息将在终端中打印出来。在

我们要做的是将slow_function()放到另一个线程上。只需几行额外的代码,我们就可以使用threading模块将此函数的执行分离到另一个线程上:

^{pr2}$

我们在这里做的很简单。我们正在创建一个Thread的新实例并传递给它两个东西:一个是target,这是我们要运行的函数,args,是要传递给目标函数的参数。注意,slow_function上没有括号,因为我们不是在运行函数是对象,所以我们将函数本身传递给Thread。至于args,它总是需要一个列表。即使只有一个参数,也要将其包装在一个列表中,这样args就能得到它所期望的结果。在

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

现在,我们可以到此为止了-但至少在我看来,在路由本身中包含线程代码有点混乱。如果需要在另一个路径或不同的上下文中调用此函数,该怎么办?最好把它分成自己的功能。您可以将线程行为作为slow函数本身的一部分,也可以创建一个“wrapper”函数——您采用哪种方法在很大程度上取决于您正在做什么以及您的需求是什么。在

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

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()

async_slow_function()函数与我们之前所做的几乎完全相同,只是现在更整洁了一点。您可以在任何路径中调用它,而不必重写线程逻辑。您会注意到,这个函数实际上返回了线程—对于这个例子,我们不需要这个函数,但是您以后可能还需要对该线程执行其他操作,因此如果您需要线程对象,那么返回它将使thread对象可用。在

相关问题 更多 >