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.
While lightweight and easy to use, Flask's built-in server is not suitable for production as it doesn't scale well and by default serves only one request at a time.
The Werkzeug reloader spawns a child process so that it can restart that process each time your code changes. Werkzeug is the library that supplies Flask with the development server when you call app.run()
.
See the restart_with_reloader()
function code; your script is run again with subprocess.call()
.
If you set use_reloader
to False
you'll see the behaviour go away, but then you also lose the reloading functionality:
app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)
You can disable the reloader when using the flask run
command too:
FLASK_DEBUG=1 flask run --no-reload
You can use the werkzeug.serving.is_running_from_reloader
function if you wanted to detect when you are in the reloading child process:
from werkzeug.serving import is_running_from_reloader
if is_running_from_reloader():
print(f"################### Restarting @ {datetime.utcnow()} ###################")
However, if you need to set up module globals, then you should instead use the @app.before_first_request
decorator on a function and have that function set up such globals. It'll be called just once after every reload when the first request comes in:
@app.before_first_request
def before_first_request():
print(f"########### Restarted, first request @ {datetime.utcnow()} ############")
Do take into account that if you run this in a full-scale WSGI server that uses forking or new subprocesses to handle requests, that before_first_request
handlers may be invoked for each new subprocess.
If you are using the modern flask run
command, none of the options to app.run
are used. To disable the reloader completely, pass --no-reload
:
FLASK_DEBUG=1 flask run --no-reload
Also, __name__ == '__main__'
will never be true because the app isn't executed directly. Use the same ideas from Martijn's answer, except without the __main__
block.
if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
# do something only once, before the reloader
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
# do something each reload
I had the same issue, and I solved it by setting app.debug
to False
. Setting it to True
was causing my __name__ == "__main__"
to be called twice.
From Flask 0.11, it's recommended to run your app with flask run
rather than python application.py
. Using the latter could result in running your code twice.
As stated here :
... from Flask 0.11 onwards the flask method is recommended. The reason for this is that due to how the reload mechanism works there are some bizarre side-effects (like executing certain code twice...)
I am using plugin - python-dotenv and i will put this on my config file - .flaskenv:
FLASK_RUN_RELOAD=False
and this will avoid flask run twice for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With