Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start a flask application in separate thread

I'm currently developing a Python application on which I want to see real-time statistics. I wanted to use Flask in order to make it easy to use and to understand.

The issue is that my Flask server should start at the very beginning of my Python application and stop at the very end. It should look like this:

def main():
    """ My main application """
    from watcher.flask import app
    # watcher.flask define an app as in the Quickstart flask documentation.
    # See: http://flask.pocoo.org/docs/0.10/quickstart/#quickstart

    app.run() # Starting the flask application

    do_my_stuff()

    app.stop() # Undefined, for the idea 

Because I need my application context (for the statistics), I can't use a multiprocessing.Process. Then I was trying to use a threading.Thread, but it looks like Werkzeug doesn't like it:

 * Running on http://0.0.0.0:10079/
Exception in thread Flask Server:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File ".../develop-eggs/watcher.flask/src/watcher/flask/__init__.py", line 14, in _run
    app.run(host=HOSTNAME, port=PORT, debug=DEBUG)
  File ".../eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 772, in run
    run_simple(host, port, self, **options)
  File ".../eggs/Werkzeug-0.7-py2.7.egg/werkzeug/serving.py", line 609, in run_simple
    run_with_reloader(inner, extra_files, reloader_interval)
  File ".../eggs/Werkzeug-0.7-py2.7.egg/werkzeug/serving.py", line 524, in run_with_reloader
    signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
ValueError: signal only works in main thread

How can I do that without running Flask in the main thread?

like image 421
FunkySayu Avatar asked Jul 07 '15 09:07

FunkySayu


People also ask

How do I run a Flask in a separate thread?

To start a Python Flask application in separate thread, we set the use_reloader to False when we call app. run . And then we create a Thread instance with the Flask app by setting the function that calls app. run as the value of the target argument.

How do I run a Flask app on a different port?

To change the host and port that the Python flask command uses, we can use the -h flag to change the host and the -p flag to change the port. to run our flask app with the host set to localhost and the port set to 3000.

Does Flask use multiple threads?

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.

How do I run a Flask from a different IP?

If you use the flask executable to start your server, use flask run --host=0.0. 0.0 to change the default from 127.0. 0.1 and open it up to non-local connections.


3 Answers

You're running Flask in debug mode, which enables the reloader (reloads the Flask server when your code changes).

Flask can run just fine in a separate thread, but the reloader expects to run in the main thread.


To solve your issue, you should either disable debug (app.debug = False), or disable the reloader (app.use_reloader=False).

Those can also be passed as arguments to app.run: app.run(debug=True, use_reloader=False).

like image 145
Thomas Orozco Avatar answered Oct 19 '22 11:10

Thomas Orozco


Updated answer for Python 3 that's a bit simpler:

from flask import Flask                                                         
import threading

data = 'foo'
host_name = "0.0.0.0"
port = 23336
app = Flask(__name__)

@app.route("/")
def main():
    return data

if __name__ == "__main__":
    threading.Thread(target=lambda: app.run(host=host_name, port=port, debug=True, use_reloader=False)).start()
like image 43
skeller88 Avatar answered Oct 19 '22 12:10

skeller88


If you are looking for accessing iPython terminal in Flask run your application in a separate thread. Try this example:

from flask import Flask                                                         
import thread

data = 'foo'
app = Flask(__name__)

@app.route("/")
def main():
    return data

def flaskThread():
    app.run()

if __name__ == "__main__":
    thread.start_new_thread(flaskThread, ())

(Run this file in iPython)

like image 20
Rashid Mv Avatar answered Oct 19 '22 11:10

Rashid Mv