Python – How do I give status in Flask’s publish request?

How do I give status in Flask’s publish request?… here is a solution to the problem.

How do I give status in Flask’s publish request?

I created a page that allows users to upload an excel file, then parse it into columns, and then insert rows into the database 500 rows at a time.

It’s not a very long process – between 25 and 90 seconds, but long enough that I want to give the user some feedback to let them know it’s actually still working – in the form of a status message and/or a progress bar.

This is how my application is written in flask:

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

I know you can only send one response to

a post request, but if I can only send one response, how do I give the user status to the process? Maybe I’m solving this the wrong way, but I think it’s a very common use case. If that doesn’t work, how else should I set it up?


For some reason marked as this A copy of question. The question asks how to print a continuous stream of values to the screen. Here I am asking how to send messages at certain execution points. I think the comments about Flask-socketio offer different ways to solve different problems.

Solution

“One response to a request” is a question of how the HTTP protocol works: the client sends a query and some data (POST request), and the server responds with some other data (your “one response”). While you can technically have the server send back a response fragment in the form of a block, that doesn’t actually work; On the one hand, browsers don’t handle it very well.

You need to do this differently. For example, as suggested by reviewers, create a “side channel” using SocketIO. You can then send updates to the client via this side channel – you can use socketio.emit instead of print.

On the client side, you first subscribe to a SocketIO channel when the page loads. You’ll then submit the file via an AJAX call (or in a separate iframe) and keep the SocketIO connection open on the page to display the updates.

This separates the POST request from your Page Load. JavaScript on the page maintains event status, progress updates can be read and displayed, and uploads (and associated wait times) occur in the background.

Related Problems and Solutions