I have a Flask app that, basically, searches the web for URLs, passes chunks of those URLs to a worker(url, **kwargs) function that elaborates on each url, and finally renders a results.html template. I want to add a progress indicator in my index.html template, which is used to input some variables that are passed to the webSearch(parameters) function.
This is the scheme of my app:
import all the required modules, included multiprocessing Pool, Manager, etc
from flask_socketio import SocketIO, emit
...
...
setting some helper functions:
def webSearch(parameters):
...
def func1(parameters):
...
def func2(parameters):
...
instantiating the app:
app = Flask(__name__)
socketio = SocketIO(app, namespace="/progress")
defining my worker() function (which is really complex, so I'll just specify a few lines:
def worker(url, number_of_urls_to_be_passed, done_list, **kwargs):
done_list.append(url) #done_list is a list of the urls that have been passed to worker()
progress = len(done_list) / number_of_urls_to_be_passed * 100
socketio.emit('progress', {'progress': progress}, namespace='/progress')
#here the function completes its task
now, I set the remaining part of my app:
@app.route("/", methods=["GET", "POST"])
def index():
#get some input values (keywords, etc) from the index.html template
def run():
urls = webSearch(parameters)
manager = Manager()
done_list = manager.list()
p = Pool(os.cpu_count())
mapfunc = partial(worker, done_list, **kwargs)
p.map(mapfunc, set(urls))
naively, I expected the socketio.emit call defined inside the worker() function to append each elaborated-on url to done_list (which happens) and to emit the progress value to the client.
my basic client javascript:
<script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
<script>
var socket = io.connect('http://' + document.domain + ':' + location.port + '/progress');
socket.on('progress', function (data) {
document.getElementById('progress').style.width = data.progress + '%';
document.getElementById('progress').innerHTML = data.progress + '%';
});
</script>
finally:
if __name__ == "__main__":
socketio.run(app, debug=True, host="0.0.0.0", port="5000")
This set up does not work as no 'progress' value is sent to the client and the field I have in my index.html template is not populated with any ongoing value. No signal detected in the Console as well.
I understand this is not working due to the multiprocessing environment. I tried with multithreading as well and did not succeed.