Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
399 views
in Technique[技术] by (71.8m points)

python - Why does running the Flask dev server run itself twice?

I'm using Flask for developing a website and while in development I run flask using the following file:

#!/usr/bin/env python
from datetime import datetime
from app import app
import config

if __name__ == '__main__':
    print('################### Restarting @', datetime.utcnow(), '###################')
    app.run(port=4004, debug=config.DEBUG, host='0.0.0.0')

When I start the server, or when it auto-restarts because files have been updated, it always shows the print line twice:

################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################

Although it is not really a problem (the rest works as expected), I simply wonder why it behaves like this? Any ideas?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...