19

The following ways allows me to launch the Flask server.

Option 1:

set FLASK_APP = app.py
flask run

Option 2:

set FLASK_APP = app.py
python -m flask run

Option 3:

python app.py

What is the difference between using either of this?

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
variable
  • 8,262
  • 9
  • 95
  • 215

2 Answers2

17
$ python app.py

This is the simplest, standard way of calling the Python interpreter to run any Python script. It is not specific to Flask. The app.py may or may not have a if __name__ == "__main__" block (see What does if __name__ == "__main__": do?), but if you are going to do this for Flask, it is required to have __main__ method that calls app.run().

From the Flask docs:

The alternative way to start the application is through the Flask.run() method. This will immediately launch a local server exactly the same way the flask script does.

Example:

if __name__ == '__main__':
    app.run()

The docs also state why even though this works, it is not recommended:

This works well for the common case but it does not work well for development which is why 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, sometimes crashing without message or dying when a syntax or import error happens).

This way is also problematic if you need to modify run configurations (ex. port) depending on the host environment. For example, you need to use port 5500 instead of the default 5000 when running on a certain machine. You can of course do this with os.environ and app.run(port=5500), but it's going to be "messy" modifying the code based on environment-related configs that are unrelated to the code.

That is why we have the second way, the flask command line tool.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'
$ set FLASK_APP=app.py 
$ flask run --port=5500

You can now maintain your code to be independent of any external environment configurations. Aside from that, the flask CLI tool has a lot of other options for configuration and debugging, such as enabling/disabling DEBUG mode, listing routes (flask routes), and getting env vars from .env files.

Notice also that your app does not have to explicitly call app.run and __name__ now isn't going to be __main__. This is helpful for cases where your app is just part of a bigger package and/or it needs to be run from some other directory. See the Larger Applications section of the Flask docs.

Finally, we have the third way:

$ python -m flask run

This is another standard way of running Python scripts. It is also not specific to Flask. From the docs:

When called with -m module-name, the given module is located on the Python module path and executed as a script.

This means flask will be searched from the invoked python module search path. This is particularly useful when your environment has multiple versions of Python and you want to make sure you are using the correct Python version and env with Flask. It can also be useful when you have multiple Flask installations for multiple projects. It explicitly sets which Python interpreter to use to call the flask CLI tool.

$ python3.8 -m flask --version
Python 3.8.10
Flask 1.1.2
Werkzeug 1.0.1
$ python3.8 -m flask run

$ python3.7 -m flask --version
Python 3.7.4
Flask 1.1.1
Werkzeug 0.16.0
$ python3.7 -m flask run

$ python -m flask --version
Python 2.7.16
Flask 1.0.3
Werkzeug 0.14.1
$ python -m flask run
Mike
  • 1,279
  • 7
  • 18
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
  • The flask quickstart (https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application) does not mention using app.run method. So is it best practice to run the flask app via Flask command rather than python command? And to configure the host and server via the command line rather then in the code? – variable Nov 07 '19 at 11:26
  • 1
    @variable I would say yes to both questions. When the `flask` command line tool was introduced, it became the recommended approach to running your Flask app, as it separates environment-specific configurations from your actual web app code (ex. port, enable debugging, etc.) – Gino Mempin Nov 07 '19 at 23:43
5
flask run

This one looks for an executable (called flask) on your PATH, the first one executes with a parameter run, which will make the flask helper run the application by calling FLASK_APP.

python -m flask run

This one looks for an executable called python on your PATH, the first one executes receiving -m as argument, which is supposed to run a module (flask) and then pass the parameter run to it. The key difference here, is that as it executes the first found executable on PATH, you can run a totally different Flask from the first one. You can also run a different python version's Flask.

python app.py

This calls the first python executable on PATH, and passes app.py as argument. It will make python run the app.py script, which may or may not have app.run() (This is what starts Flask). If you don't have anything inside app.py, it won't call Flask's server.

Alexander Santos
  • 1,458
  • 11
  • 22
  • Assuming all necessary code is in app.py, then what is technical difference between running either if this approaches? – variable Oct 25 '19 at 19:23
  • No explicit difference (considering the same environment). But, as i said, if you have Python 2 on PATH before Python 3, for example, and you want to run it on Python 3, Python 2 would get called. The same for flask, if you point to a different flask's version on PATH before the one you want, it would get called. You can use `python -m flask app.py` just to confirm that the same Python you are using is the one that will run flask. – Alexander Santos Oct 25 '19 at 19:32
  • How does using -m confirm about the python verison? – variable Oct 25 '19 at 19:42
  • Because the python part of python -m means you can explicitly state which python to use. You can write python -m flask run to use whatever the default python is, or /usr/bin/python3.6 -m flask run, or explicitly point your system to exactly the version of python you want – Dave Thomas May 24 '20 at 13:11