Search code examples
asynchronousflaskgunicornpython-3.7gevent

How can I start an asynchronous function in Flask / gunicorn / gevent?


I currently have a Flask application

from flask import Flask
import time

app = Flask(__name__)


@app.route('/')
def foobar_view():
    long_running()  # TODO: Just trigger this; don't wait for completion
    return 'Done!'


def long_running():
    print('long_running:start')
    time.sleep(100)
    print('long_running:end')


app.run(host='localhost', port=5000)

started with

gunicorn --worker-class=gevent \
         --worker-connections=1000 \
         --bind 0.0.0.0:5000 my_app.app:app \
         --workers=4 \
         --timeout 120 \
         --keep-alive 120

The app will not have heavy load, and this long_running function will only rarely be triggered. I'm looking for a simple way to run this and I'm open to changes regarding gunicorn / gevent. I'm using Python 3.7.

How can I make long_running execute asynchronously?


Solution

  • The solution could be to run int in a Thread:

    from flask import Flask
    import time
    from threading import Thread
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def foobar_view():
        Thread(target=async_long_running, args=(app, 'works')).start()
        return 'Done!'
    
    
    def async_long_running(app, msg):
        with app.app_context():
            long_running(msg)
    
    def long_running(foo):
        print('long_running:start:{}'.format(foo))
        time.sleep(100)
        print('long_running:end')
    
    
    app.run(host='localhost', port=5000)