Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flask application with background threads

I am creating a flask application, for one request I need to run some long running job which is not required to wait on the UI. I will create a thread and send a message to UI. The thread will calculate and update the database. But, UI will see a message upon submit. Below is my implementation, but it is running the thread and then sending the output to UI which is not I prefer. How can I run this thread in the background?

@app.route('/someJob')
def index():
    t1 = threading.Thread(target=long_running_job)
    t1.start()
    return 'Scheduled a job'

def long_running_job
    #some long running processing here

How can I make thread t1 to run the background and immediately send message in return?

like image 560
San Avatar asked Mar 24 '14 16:03

San


People also ask

How do I run a Flask in the background?

Make sure, you close the terminal and not press Ctrl + C. This will allow it to run in background even when you log out. To stop it from running , ssh in to the pi again and run ps -ef |grep nohup and kill -9 XXXXX where XXXX is the pid you will get ps command.

Does Flask have multithreading?

As of Flask 1.0, flask server is multi-threaded by default. Each new request is handled in a new thread. This is a simple Flask application using default settings.

Is Flask good for large applications?

For large enterprise-level apps, using Flask with Django is sometimes the best approach – combining the smaller components from Flask and Admin Panel from Django. Now that you know what works best in different situations, find out the problems your web app should address and select the right framework for yourself.


Video Answer


3 Answers

Try this example, tested on Python 3.4.3 / Flask 0.11.1

from flask import Flask
from time import sleep
from concurrent.futures import ThreadPoolExecutor

# DOCS https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor
executor = ThreadPoolExecutor(2)

app = Flask(__name__)


@app.route('/jobs')
def run_jobs():
    executor.submit(some_long_task1)
    executor.submit(some_long_task2, 'hello', 123)
    return 'Two jobs were launched in background!'


def some_long_task1():
    print("Task #1 started!")
    sleep(10)
    print("Task #1 is done!")


def some_long_task2(arg1, arg2):
    print("Task #2 started with args: %s %s!" % (arg1, arg2))
    sleep(5)
    print("Task #2 is done!")


if __name__ == '__main__':
    app.run()
like image 112
Denys Synashko Avatar answered Oct 27 '22 21:10

Denys Synashko


Check out Flask-Executor which uses concurrent.futures in the background and makes your life very easy.

from flask_executor import Executor

executor = Executor(app)

@app.route('/someJob')
def index():
    executor.submit(long_running_job)
    return 'Scheduled a job'

def long_running_job
    #some long running processing here

This not only runs jobs in the background but gives them access to the app context. It also provides a way to store jobs so users can check back in to get statuses.

like image 20
Dylan Anthony Avatar answered Oct 27 '22 21:10

Dylan Anthony


The best thing to do for stuff like this is use a message broker. There is some excellent software in the python world meant for doing just this:

  • Celery (http://www.celeryproject.org/), and
  • RQ (http://python-rq.org/).

Both are excellent choices.

It's almost never a good idea to spawn a thread the way you're doing it, as this can cause issues processing incoming requests, among other things.

If you take a look at the celery or RQ getting started guides, they'll walk you through doing this the proper way!

like image 13
rdegges Avatar answered Oct 27 '22 23:10

rdegges