Flask Ajax在执行前返回多个状态

时间:2017-05-15 12:16:13

标签: javascript python ajax python-3.x flask

我有一个用于烧瓶应用的网络前端,它在后端进行了一些繁重的计算,然后通过JSON将计算出的数据传递到前端以获得图表。

问题是,计算需要几分钟,理想情况下我希望前端知道请求的完成次数和状态,而不是静静地坐在那里。

JS Ajax请求前端:

function runBacktest() {
        $.ajax({
            type: "POST",
            url: '/backtest',
            data: {
                run_partial: 1,
                use_saved_model: false,
                saved_model_file: 'model.h5'
            },
            dataType: "json",
            success: function(data) {
                //Successful data
            },
            error: function () {
                alert('There was a problem contacting the server.');
            }
        });
    }

Python后端:

@webapp.route('/backtest', methods=['POST'])
def backtest():
    print('> Running Backtest...')
    """Calculation code goes on here"""
    print('Percent Completed: \r{0:.1f}%'.format(round(pct_done,1)), end='')

    """Serialise each agent instance into a dictionary and put in list to be converted to JSON object"""
    agents_serialised = [agent.__dict__ for agent in bt_engine.agents]

    return json.dumps(agents_serialised)

问题是,我怎样才能将我在stdout上打印的百分比,每次百分比变化都传递到前端?然后在完成后传递json数据?

2 个答案:

答案 0 :(得分:2)

更多Flasky方法是将生成器传递给响应。根据我的阅读,这是使用Flask传输数据的首选方法。这是一个非常抽象的例子。看看here我对不同问题的回答,我在回复中使用生成器更加充实并测试了脚本。

def do_calcs():
    while(more_calculations):
        """do your calculations and figure out the percentage."""
        agents_serialized = [agent.__dict__ for agent in bt_engine.agents]
        yield json.dumps({percent: percent, agents: agents_serialized})

在你的路线中:

return Response(do_calcs(), mimetype='text/json')

答案 1 :(得分:1)

为了更新百分比类型的东西,我们需要在前端和后端之间建立socket连接.Flask有一个很好的包,这是socket.io。并且还为socket.io提供了javascript支持。

Blog帖子有助于构建此

我相信你可以用这个来构建,因为我以前做过。

示例Python代码:

from flask import Flask, render_template
from flask.ext.socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

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

@socketio.on('my percentage event', namespace='/test')
def test_message(message):
    #create pertage opertion here
    emit('percentage status', {'data': message['data']}, broadcast=True)

示例javascript代码:

$(document).ready(function(){
    var socket = io.connect('http://' + document.domain + ':' + location.port + '/test');

    socket.on('percentage status', function(msg) {
        //portion for update the percentage
    });

});

这些代码并不完全正确,但您可以将其作为参考。