130

When building a Flask service in Python and setting the debug mode on, the Flask service will initialise twice. When the initialisation loads caches and the like, this can take a while. Having to do this twice is annoying when in development (debug) mode. When debug is off, the Flask service only initialises once.

How to stop Flask from initialising twice in Debug Mode?

Smi
  • 13,850
  • 9
  • 56
  • 64
Matt Alcock
  • 12,399
  • 14
  • 45
  • 61

2 Answers2

187

The simplest thing to do here would be to add use_reloader=False to your call to app.run - that is: app.run(debug=True, use_reloader=False)

Alternatively, you can check for the value of WERKZEUG_RUN_MAIN in the environment:

if os.environ.get("WERKZEUG_RUN_MAIN") == "true":
    # The reloader has already run - do what you want to do here

However, the condition is a bit more convoluted when you want the behavior to happen any time except in the loading process:

if not app.debug or os.environ.get("WERKZEUG_RUN_MAIN") == "true":
    # The app is not in debug mode or we are in the reloaded process
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • 4
    How can you still use reloader but have certain things initialised only once? – Sergey Orshanskiy Oct 04 '14 at 22:21
  • @osa - I added a brief explanation of an alternative that might let you use the reloader – Sean Vieira Oct 04 '14 at 22:56
  • 2
    `use_reloader=False` worked perfectly for me. – tmthyjames Dec 05 '14 at 02:21
  • 7
    This answer implies there is no solution, only a workaround? Disabling the reloader is not usually an acceptable trade off. – Gringo Suave Jun 13 '17 at 01:44
  • The solution is to either, "don't use the reloader" *or* "check for the `WERKZEUG_RUN_MAIN` environment variable before doing the expensive work. – Sean Vieira Jun 14 '17 at 02:48
  • 1
    This does not work for me, because `app.debug` returns `False` even when Flask is in debug mode, i.e. `app.run(host='0.'0.0.0', port=80, debug=True)` – Pygmalion Oct 19 '19 at 06:46
  • 1
    It seems that the problem is that `app.run` should be the last command, and before you run `app.run` you cannot know the state of Flask. – Pygmalion Oct 19 '19 at 06:57
  • 2
    I found a corner case to this, it seems using `FLASK_ENV=development` does *not* set `add.debug` to true. In the end I'm using `if not (app.debug or os.environ.get("FLASK_ENV") == "development") or os.environ.get("WERKZEUG_RUN_MAIN") == "true":`. Good luck figure that one out in 6 months... – Yann Bizeul May 26 '20 at 21:38
20

You can use the before_first_request hook:

@app.before_first_request
def initialize():
    print "Called only once, when the first request comes in"
Tagman
  • 176
  • 2
  • 11
Alex Morega
  • 4,132
  • 1
  • 24
  • 25
  • 7
    Thanks alex but if I am doing cache warming or pre populating stuff like a 'classifier' will this get called before the first request, making the first request slow or on startup of the flask service. – Matt Alcock Feb 26 '12 at 15:37
  • 18
    Downvote. When the app reloads, `before_first_request` will be called again after the first request that follows. – Sergey Orshanskiy Oct 04 '14 at 22:23