In Flask 0.11 a flask
CLI was introduced. Both the docs and the changelog state this is recommended.
Starting with Flask 0.11 there are multiple built-in ways to run a development server. The best one is the flask command line utility but you can also continue using the
Flask.run()
method.Command Line
The flask command line script (Command Line Interface) is strongly recommended for development because it provides a superior reload experience due to how it loads the application. The basic usage is like this:
$ export FLASK_APP=my_application $ export FLASK_DEBUG=1 $ flask run
- Added
flask
and theflask.cli
module to start the local debug server through the click CLI system. This is recommended over the oldflask.run()
method as it works faster and more reliable due to a different design and also replacesFlask-Script
.
So far I didn't notice this "superior reload experience". I fail to see the point of using the CLI over a custom script.
If using Flask.run
, I would simply write a python file:
#!/usr/bin/env python3
from my_app import app
if __name__ == '__main__':
app.run(debug=True)
If using the CLI, one would have to specify environment variables. In the CLI docs is stated that this can be integrated in the activate
script of virtualenvwrapper. Personally I consider this to be part of the application and think it should be under version control. Alas, a shell script is needed:
#!/usr/bin/env bash
export FLASK_APP=my_app:app
export FLASK_DEBUG=1
flask run
Of course this will be accompanied by an additional bat script as soon as any Windows users start to collaborate.
Also the first option allows setup written in Python before starting the actual app.
This allows for example
- to parse command line arguments in Python
- to setup logging before running the app
They seem to promote that it's possible to add custom commands. I fail to see why this is better than writing simple Python scripts, optionally exposed through entry points.
Example logging output when using a configured logger using the Python run script:
$ ./run.py
DEBUG 21:51:22 main.py:95) Configured logging
INFO 21:51:22 _internal.py:87) * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
INFO 21:51:22 _internal.py:87) * Restarting with inotify reloader
DEBUG 21:51:22 main.py:95) Configured logging
WARNING 21:51:22 _internal.py:87) * Debugger is active!
INFO 21:51:22 _internal.py:87) * Debugger pin code: 263-225-431
DEBUG 21:51:25 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
DEBUG 21:51:25 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
INFO 21:51:25 _internal.py:87) * Detected change in 'my_app/main.py', reloading
INFO 21:51:26 _internal.py:87) * Restarting with inotify reloader
DEBUG 21:51:26 main.py:95) Configured logging
WARNING 21:51:26 _internal.py:87) * Debugger is active!
INFO 21:51:26 _internal.py:87) * Debugger pin code: 263-225-431
Example logging output when using a configured logger using the CLI:, notice that the root logger couldn't be setup early enough in the process.
$ ./run.sh
* Serving Flask app "appsemble.api.main:app"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with inotify reloader
DEBUG 21:51:33 main.py:95) Configured logging
* Debugger is active!
* Debugger pin code: 187-758-498
DEBUG 21:51:34 main.py:95) Configured logging
DEBUG 21:51:37 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
DEBUG 21:51:37 inotify_buffer.py:61) in-event <InotifyEvent: src_path=b'my_app/main.py', wd=272, mask=IN_MODIFY, cookie=0, name=b'main.py'>
* Detected change in 'my_app/main.py', reloading
INFO 21:51:37 _internal.py:87) * Detected change in 'my_app/main.py', reloading
* Restarting with inotify reloader
INFO 21:51:38 _internal.py:87) * Restarting with inotify reloader
* Debugger is active!
* Debugger pin code: 187-758-498
DEBUG 21:51:38 main.py:95) Configured logging
My actual question is simply:
Why is flask CLI recommended over Flask.run
?