当线程完成时,如何在Flask中更改渲染的模板?

时间:2016-12-25 06:44:24

标签: python multithreading heroku flask backgroundworker

我有一个功能,可以抓取网页上的数据并计算搜索分数。但是,这可能需要一段时间,有时网页会在完成执行之前超时。

所以我创建了一个执行函数的单独线程,并loading.html告诉客户端数据仍在收集中。函数在线程结束后,如何重新加载网页以显示显示分数的output.html

这是我目前的简单版本:

from flask import Flask
from flask import render_template
from threading import Thread

app = Flask(__name__)

@app.route("/")
def init():
    return render_template('index.html')

@app.route("/", methods=['POST'])
def load():
    th = Thread(target=something, args=())
    th.start()
    return render_template('loading.html')

def something():
    #do some calculation and return the needed value

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

如何在帖子render_template('output.html', x=score)内完成something()后,将我的应用路由到th

我正在努力避免像redis这样的任务队列,因为我想在网络上部署这个应用程序而且我不想招致费用(这更像是一个实验和爱好)。

使用代码的详细答案将有很大帮助,因为我不熟悉烧瓶和多线程

1 个答案:

答案 0 :(得分:2)

一种简单的方法是向 thread_status 端点发出循环Ajax请求,为您提供有关当前正在运行的任务的信息。

string s = "10101010011";
int zeros = s.Count(x => x == '0');
int ones = s.Count(x => x == '1');
Console.WriteLine(zeros < ones);
Console.ReadLine();

所以在 loading.html 中只需插入一个循环Ajax import time from flask import Flask, jsonify from flask import render_template from threading import Thread app = Flask(__name__) th = Thread() finished = False @app.route("/") def init(): return render_template('index.html') @app.route("/", methods=['POST']) def load(): global th global finished finished = False th = Thread(target=something, args=()) th.start() return render_template('loading.html') def something(): """ The worker function """ global finished time.sleep(5) finished = True @app.route('/result') def result(): """ Just give back the result of your heavy work """ return 'Done' @app.route('/status') def thread_status(): """ Return the status of the worker thread """ return jsonify(dict(status=('finished' if finished else 'running'))) if __name__ == "__main__": app.run(debug=True) 请求:

get()

如果您愿意,甚至可以通过进度计数器附加此信息。但是你需要注意防止线程多次运行。