如何在烧瓶中发布请求期间提供状态?

时间:2018-08-14 11:47:03

标签: python post flask

我创建了一个页面,允许用户上传excel文件,然后将其解析为列,然后将行一次插入到数据库中500行。

这不是一个很长的过程-25到90秒之间,但是足够长,我想以状态消息和/或形式给用户一些反馈,让他们知道它实际上仍在工作进度条。

我的应用是用烧瓶写的,就像这样:

app.py

from flask import Flask, render_template, request
import tqdm 

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def fun():
    if request.method == 'GET':
        return render_template('index.html')
    else:
        filename = request.form['filename']
        print('opening file') #change from console print to webpage
        df = pandas.read_excel(filename)
        print('File read.. processing data\n') #change from console to webpage
        processData()
        print('connecting to db....\n') #change to webpage print
        db.connect()
        print('connected to db! inserting rows') #change to webpage print
        bulk_inserts = rows/500
        for i in tqdm(range(bulk_inserts)): #wrapping tqdm around range makes a progress bar
            insert500rows() 
        db.commit()
        db.disconnect()
        return 'Complete. ' + str(rows) + ' inserted.' #this gets sent as a post to the page

app.run()

我知道您只能向发布请求发送一个响应,但是如果我只能发送一个响应,那么如何赋予流程用户状态?也许我会采用错误的方式,但是我认为这是一个非常普遍的用例。如果这种方式行不通,我应该如何设置呢?


由于某些原因,被标记为与此question的副本。该问题询问如何将连续的值流打印到屏幕上。我在这里问如何在某些执行点发送消息。我认为所提供的有关Flask-socketio的评论提供了针对不同问题的不同方法。

2 个答案:

答案 0 :(得分:1)

“对一个请求的一个响应”是HTTP协议如何工作的问题:客户端发送查询和一些数据(POST请求),而服务器以其他一些数据进行响应(您的“一个响应”)。尽管可以从技术上使服务器以块的形式发送回响应,但这在实践中却不是这样。一方面,浏览器的处理效果不太好。

您需要以其他方式执行此操作。例如,如注释者所建议的那样,使用SocketIO创建“辅助通道”。然后,您可以通过此副渠道将更新发送给客户端-您可以使用print来代替socketio.emit

在客户端,您将在页面加载时首先订阅SocketIO通道。然后,您可以通过AJAX调用(或在单独的iframe中)提交文件,并使SocketIO连接在页面上保持打开状态,以显示更新。

这样,POST请求与您的“页面加载”分开了。页面上的javascript保持活动状态,可以读取和显示进度更新,并且上传(带有相关的等待时间)在后台进行。

答案 1 :(得分:0)

我也会像@matejcik在他们的答案中解释的那样做,但是还有另一种方法。 websockets所做的是将function isEmpty(obj: Object): Boolean { for (const prop in obj) { if (obj.hasOwnProperty(prop)) { if (obj[prop] instanceof Object) { const rtn = this.isEmpty(obj[prop]); if (rtn === false) { return false; } } else if (obj[prop] || obj[prop] === false) { return false; } } } return true; } 的数据更新后返回到浏览器。还有pushing方法。

您可以定期向服务器发送查询,服务器将为您提供更新。您仍然必须使用pull发送请求,并使用javascript的AJAX函数在两次查询之间等待,但是您要做的基本上是刷新页面而不向用户显示。初学者更容易理解,因为所使用的技术仍然是setTimeout。无需打印新日志,而是将其添加到字符串(或数组)中,并且在发出GET请求时,您将返回此数组,清除文本输出并使用新旧信息写入此新数组。

此方法的效率远低于websockets,但对于原型制作而言,它可以更快。