2017-05-15 1 views
2

Ich habe ein Web-Frontend für eine Flask-App, die einige schwere Berechnungen am Back-End durchführt, bevor die berechneten Daten per JSON an das Frontend übergeben werden.Flask Ajax gibt mehrere Status zurück vor der Ausführung

Das Problem ist, dauert die Berechnung mehrere Minuten, und im Idealfall möchte ich das Front-End wissen, die% erledigt und Status der Anfrage, anstatt still dort sitzen.

JS Ajax-Request-Front-End:

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-Backend:

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

Frage ist, wie ich so etwas wie der Prozentsatz passieren kann getan, die ich auf stdout bin Druck auf jede Veränderung des Prozentsatzes, zum Frontend? Gefolgt von dann die Json-Daten übergeben, sobald es fertig ist?

Antwort

1

Für die Aktualisierung der prozentualen Art von Zeug brauchen wir socket Verbindung zwischen Front-End und Back-End .Flasche haben ein tolles Paket tun dies, das ist socket.io. Und es gibt Javascript-Unterstützung auch für die socket.io.

Blog Post, die diese

Ich bin sicher zu bauen können Ihnen helfen, mit diesem zu bauen, weil ich es vorher getan.

Probe Python Code:

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) 

Probe javascript Code:

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

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

}); 

Diese Code sind nicht genau, aber Sie können als Referenz verwenden.

2

Ein Flasky-Ansatz wäre, einen Generator an die Antwort zu übergeben. Nach dem, was ich gelesen habe, ist dies der bevorzugte Ansatz zum Streamen von Daten mit Flask. Hier ist ein sehr abstraktes Beispiel. Suchen Sie here für meine Antwort auf andere Frage, wo ich ein mehr ausgearbeitetes und getestetes Skript mit einem Generator in einer Antwort habe.

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

Und in Ihrer Route:

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

Wenn Sie dies tun werden, ich die [ 'xhr' Parameter] empfehlen (https://stackoverflow.com/questions/22502943/ jquery-ajax-progress-via-xhr), um auf der Clientseite einen Fortschrittsereignis-Listener für die Anforderung hinzuzufügen. Auf diese Weise kann Ihr JavaScript tatsächlich einen Blick auf diese JSON-Objekte werfen, die während der Anfrage gesendet werden. –

Verwandte Themen