-1

I have a Flask app that does some processing after the form submit button is pushed

{% if argName is defined %}
<script>
    $(function(){

    var element = document.getElementById('argumentName');
    element.value = '{{ argName }}';
    $(".compbtn:first-child").text('{{ argName }}');
    $(".compbtn:first-child").val('{{ argName }}');

    });
</script>
{% endif %}
<form  action="/explore" method="post" role="form" id="log_form">
    <div class="form-group">
        <div class="row">
            <div class="col-sm-4">
                <input class="span2" id="argumentName" name="argumentName" type="hidden">
                <div class="dropdown">
                    <button class="btn btn-primary dropdown-toggle argbtn" type="button" data-toggle="dropdown">Available Arguments
                                        <span class="caret"></span>
                    </button>
                    <ul class="dropdown-menu argDrop" role="menu" aria-labelledby="dropdownMenu" id="argDropDown">
                    {% for arg in arguments %}
                        <li role="presentation" onclick="$('#argumentName').val('{{ arg }}');"><a role="menuitem" href="#">{{ arg }}</a></li>
                    {% endfor %}
                    </ul>
                </div>
            </div>
            <div class="col-sm-4">
                      Year: <input type="text" name="year" id="year" size="10">
            </div>
            <div class="col-sm-4">
                      Month: <input type="text" name="month" id="month" size="10">
            </div>
        </div>
    </div>
    <input type="submit" class="btn btn-success">
</form>

and here is the server side

@app.route('/explore', methods=['GET', 'POST'])
def explore():
    global unique_arguments
    if not unique_arguments:
        scraper = BasicScraper()
        unique_arguments = scraper.get_arguments()
    arg_name = str(request.form['argumentName'].encode('utf-8').strip())
    if request.form['year'] and request.form['month']:
        form = ReusableForm(request.form)
        app.logger.error(form.errors)
        year_to_look_for = str(request.form['year'].encode('utf-8').strip())
        month_to_look_for = str(request.form['month'].encode('utf-8').strip())
        scraper = BasicScraper()
        scraper.perform_func(arg_name, year_to_look_for, month_to_look_for)
    return render_template('home.html', arguments=unique_arguments, argName=arg_name)

now, i want to periodically return a string to the web page. scraper.perform_func(arg_name, year_to_look_for, month_to_look_for) method can be changed to yield the string i need. I want to display this string at some place on the web page.

This would help me see the progress.

How can i achieve this in Flask?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
AbtPst
  • 7,778
  • 17
  • 91
  • 172

1 Answers1

1

This has been asked a few times in the past (e.g. 1,2), with 2 common solutions. It's not a super simple or quick resolution:

  1. Move background tasks (i.e. scraper.perform_func) to a separate queue or worker service like Celery or Python-RQ for something lighter. Both are very well explained in the flask mega tutorial. What this would result in for you is the process being placed in the queue, and a new Flask route being implemented to read the status of the process (e.g. read text from DB, session).

  2. Switch to using websockets, which will allow async communication between your route and the UI. Flask-SocketIO is a good place to start here.

djnz
  • 2,021
  • 1
  • 13
  • 13