Have you ever asked yourself why when you create a Python Flask application you pass __name__ to the Flask class?
I definitely did when I started working with Flask and in this tutorial, I want to make it clear to those of you who would like to know more about it.
The variable __name__ is passed as the first argument when creating an instance of the Flask object (a Python Flask application). In this case __name__ represents the name of the application package and it’s used by Flask to identify resources like templates, static assets, and the instance folder.
The best way to understand this is to see it in practice.
So, let’s do it!
A Basic Example of How __name__ Works with Flask
Create a new directory called flask-example, then inside that directory create a virtual environment called venv and activate it.
$ mkdir flask-example
$ cd flask-example
$ python3 -m venv venv
$ . venv/bin/activate
(venv) $
Note: I have created a separate tutorial that shows you more about Python virtual environments.
Then update pip…
(venv) $ python3 -m pip install --upgrade pip
Collecting pip
Using cached pip-21.3.1-py3-none-any.whl (1.7 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.1.1
Uninstalling pip-20.1.1:
Successfully uninstalled pip-20.1.1
Successfully installed pip-21.3.1
…and install Flask in your virtual environment using pip:
(venv) $ pip install flask
Collecting flask
Using cached Flask-2.0.2-py3-none-any.whl (95 kB)
Collecting click>=7.1.2
Using cached click-8.0.3-py3-none-any.whl (97 kB)
Collecting Jinja2>=3.0
Using cached Jinja2-3.0.2-py3-none-any.whl (133 kB)
Collecting itsdangerous>=2.0
Using cached itsdangerous-2.0.1-py3-none-any.whl (18 kB)
Collecting Werkzeug>=2.0
Using cached Werkzeug-2.0.2-py3-none-any.whl (288 kB)
Collecting MarkupSafe>=2.0
Using cached MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl (13 kB)
Installing collected packages: click, MarkupSafe, Jinja2, itsdangerous, Werkzeug, flask
Successfully installed Jinja2-3.0.2 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 flask-2.0.2 itsdangerous-2.0.1
Now, create a file called app.py directly inside the flask-example directory. This file will have the following content:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def example():
return 'The value of __name__ is {}'.format(__name__)
In the first line, we import the Flask class from the flask module.
Then you create your application and pass the __name__ variable (pronounced dunder name) to the Flask class.
The Flask route returns the value of __name__ so we can verify its value when we run the Flask application.
In the return statement, we have used the Python string format method.
To run your application execute the following command inside the flask-example directory:
(venv) $ flask run
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
If you access http://127.0.0.1:5000/ in your browser you will see the following message:
The value of __name__ is app
The value of __name__ is app, the name of the current Python module.
What is the Value of __name__ when a Flask Application is Inside a Package?
Let’s see how the value of __name__ changes if we move app.py inside a package called example1.
To create the example1 package you have to do two things:
- Create a directory called example1 under the flask-example directory.
- Create a file called __init__.py inside the example1 directory.
(venv) $ mkdir example1
(venv) $ touch example1/__init__.py
Then move app.py inside the new package:
(venv) $ mv app.py example1/
(venv) $ ls example1
__init__.py app.py
Run the Flask app by running “flask run” from the example1 directory.
(venv) $ cd example1
(venv) $ flask run
The message you see in the browser when you access http://127.0.0.1:5000/ has changed…
The value of __name__ is example1.app
The value of __name__ is now example1.app.
What is the Value of __name__ When a Flask Application is Defined in the Package’s __init__.py?
Let’s make a small change compared to the previous example:
- Move the code from app.py to __init__.py in example1 package.
- Remove all the code from the app.py file.
We can do this with a single command:
(venv) $ mv app.py __init__.py
Here is what happens when you try to run the Flask app:
(venv) $ pwd
/Coding/Python/Tutorials/flask-example/example1
(venv) $ flask run
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
Usage: flask run [OPTIONS]
Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
According to the error, Flask is not able to identify the application to be executed. As you can see from the error Flask is either looking for:
- The FLASK_APP environment variable (that is not set).
- A module in the current directory called either wsgi.py or app.py.
Let’s use the export command to tell Flask that the application is in the current package using the FLASK_APP environment variable.
(venv) $ pwd
/Coding/Python/Tutorials/flask-example/example1
(venv) $ export FLASK_APP=.
(venv) $ flask run
* Serving Flask app "."
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
The message returned by our app is:
The value of __name__ is example1
And what if we want to run the application from the main directory of our project? (the parent directory of example1).
(venv) $ cd ..
(venv) $ pwd
/Coding/Python/Tutorials/flask-example
In that case we have to set the value of FLASK_APP to the name of the package: example1.
(venv) $ export FLASK_APP=example1
(venv) $ flask run
* Serving Flask app "example1"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
As expected the value of __name__ doesn’t change considering that our Flask app is still in the example1 package:
The value of __name__ is example1
What Does __name__ Mean When Running a Flask Application?
According to this Flask tutorial, the variable __name__ is used to tell where the application is located. This is required to set some paths used by Flask applications.
Let’s see what these paths are by digging into the Flask code…
First of all, here is how the first parameter of the Flask class is described:
:param import_name: the name of the application package
This is pretty self-explanatory…
The first parameter accepted by the constructor of the Flask class is the name of the application package. You can pass this by using the __name__ variable (dunder name).
In the docstring of the Flask class, I see the following section about the first parameter:
So, this confirms that the import_name parameter is used by a Flask application to find resources it needs (on the filesystem).
Interestingly, it says that it’s fine to pass the value of __name__ as import_name parameter if you are running your application in a single module. For example, in the way we have executed it in the first example of this tutorial.
But, it also says that…
If we run our application in a module inside a package (e.g. yourapplication/app.py) it’s good practice to pass the name of the package as first parameter instead of __name__ because of the way some extensions work (e.g. Flask-SQLAlchemy)…
…unless you want to extract the name of the package from __name__ as shown in the docstring above.
Why Do You Pass __name__ to the Flask Class?
We have seen that Flask uses the value of the variable __name__ to identify resources used by your Flask application.
But, which resources does Flask use __name__ for?
In the previous section, we have seen that the name of the first parameter passed when creating an instance of the Flask class is called import_name.
Here is an example of the way this parameter is used in the Flask code.
Method auto_find_instance_path of the Flask class
def auto_find_instance_path(self) -> str:
"""Tries to locate the instance path if it was not provided to the
constructor of the application class. It will basically calculate
the path to a folder named ``instance`` next to your main file or
the package.
.. versionadded:: 0.8
"""
prefix, package_path = find_package(self.import_name)
if prefix is None:
return os.path.join(package_path, "instance")
return os.path.join(prefix, "var", f"{self.name}-instance")
Basically the value of __name__ that we pass as the first argument is used to locate the instance folder if we don’t pass it to the constructor of the Flask application class (through the instance_path parameter).
The instance folder is used in Flask to store configuration files or resources that change at runtime. This is not supposed to be under version control and its content is deployment-specific.
Let’s see what this method returns by creating a Flask application in the Python shell.
From the flask-example directory open the Python shell and import the example1 package.
(venv) $ pwd
/Coding/Python/Tutorials/flask-example
(venv) $ python
Python 3.8.5 (default, Sep 4 2020, 02:22:02)
[Clang 10.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import example1
Use the dir() function to see properties and methods available in the example1 object.
>>> dir(example1)
['Flask', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'app', 'example']
You can see the __name__ attribute whose value, as we have seen before, is the name of the package.
>>> example1.__name__
'example1'
Let’s call the auto_find_instance_path() method by using the app object (an instance of the Flask class).
>>> type(example1.app)
<class 'flask.app.Flask'>
>>> example1.app.auto_find_instance_path()
'/Coding/Python/Tutorials/flask-example/instance'
This is where the instance folder is created by Flask. Next to the package where our Flask application is located.
What is the Value of __name__ When Running a Flask App Directly?
For this final exercise move the content of __init__.py to the app.py file inside the example1 package.
Don’t delete the __init__.py file.
At this point, __init__.py will be empty and the content of app.py will be the following:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def example():
return 'The value of __name__ is {}'.format(__name__)
Now try to run your application from the example1 directory by calling app.py directly:
(venv) $ pwd
/Coding/Python/Tutorials/flask-example/example1
(venv) $ python app.py
(venv) $
Notice that nothing happens??
…that’s because we don’t have a line in our code that runs the app.
Let’s add it at the end of app.py:
app.run()
and then run the app again:
(venv) $ python app.py
* Serving Flask app 'app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Use your browser to check the message returned by the route in the app. You will see the following:
The value of __name__ is __main__
This time the value of __name__ is __main__ (dunder main) because we have called our application directly.
If you want to know more about __main__ I have created another tutorial that explains how __main__ and __name__ work in Python.
Conclusion
I hope the reason why __name__ is passed when creating a Flask application is clearer now.
We have seen how the value of __name__ changes depending on how we structure our Flask application: inside a module or a package.
And now it’s time for you to create your application using Flask. Are you ready?
Claudio Sabato is an IT expert with over 15 years of professional experience in Python programming, Linux Systems Administration, Bash programming, and IT Systems Design. He is a professional certified by the Linux Professional Institute.
With a Master’s degree in Computer Science, he has a strong foundation in Software Engineering and a passion for robotics with Raspberry Pi.