2

I'm design a web application with python flask, the processing flow is like:

  1. User choose a specified a URL, and ask server site to do some time-consuming task;
  2. The time-consuming task is then running in a new thread;
  3. After #2 is done, server will update some info regarding the URL, I need to refresh the page in #1

I don't know how to notify the "completion" status to front-end so as to refresh the page.

Anyone can help me out? Thanks

Matt
  • 67
  • 1
  • 2
  • 6

1 Answers1

4

Using flask-socketio would probably work for what you're asking. It establishes a connection between the front-end and back-end that lets the backend emit a message and the front-end registers a callback that fires when it receives the event.

$ pip install flask-socketio

app.py

import json
import time

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

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


@app.route('/')
def hello(name=None):
    return render_template('index.html')


@socketio.on('long-running-event')
def handle_my_custom_event(input_json):
    time.sleep(5)
    emit('processing-finished', json.dumps({'data': 'finished processing!'}))


if __name__ == '__main__':
    socketio.run(app)

templates/index.html

<html>
<body>
<button id="long-running-operation">Process data</button>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
    var socket = io.connect('http://' + document.domain + ':' + location.port);

    let button = document.getElementById('long-running-operation');

    button.addEventListener('click', () => {
      socket.emit('long-running-event', {data: 'process data'});
    });

    socket.on('processing-finished', function (data) {
      alert(JSON.parse(data).data)
    });

</script>
</body>
</html>

Then run the app with python app.py. Visit the app in the browser at http://127.0.0.1:5000/ and click the button. The button will send the 'long-running-event' request to flask and flask processes it by sleeping for 5 seconds to simulate a long running process. Then flask emits the 'processing-finished message and javascript fires the callback registered to listen for that event by alerting the message that flask sent.

2achary
  • 642
  • 2
  • 6
  • 9
  • Can other function call this handle _my_custom_event? – Matt Nov 18 '18 at 15:08
  • You probably already have a function to kick off this time-consuming task. I imagine you could just call that function instead of calling `time.sleep`. – 2achary Nov 19 '18 at 01:22
  • I follow your sample code, but when click the button, nothing happen, no error, no warning, no message.... – Matt Nov 19 '18 at 06:28
  • With this example, after you click the button, nothing will happen for about 5 seconds, then an alert should pop up. Did you check for errors in both the flask terminal output and the browser console? – 2achary Nov 19 '18 at 16:08
  • I located the error, and shot by adding: – Matt Nov 20 '18 at 06:20