When you learn Flask, you are told to create your Flask application instances by passing
__name__ as the first argument to the
Flask class. Most developers do this without thinking, and without knowing what it achieves.
In this article we are going to look at
Flask(__name__) in depth. By the end you will not only have a full understanding of this pattern, but you will also know when to deviate from it and pass other values.
What is __name__?
Python sets the
__name__ variable to the module name, so the value of this variable will vary depending on the Python source file in which you use it.
For example, in a module named test.py that is located in the top-level directory of the application, the value of
test. If the test.py module is located inside a Python package called my_package, then the value of
There are two special exceptions with regards to the value of
- Inside a __init__.py package constructor module, the value of
__name__is the package name, without
__init__. For example, in my_package/__init__.py, the value of
- In the main module of the application (the file you run the Python interpreter on) the value of
__name__has the special value of
Flask Documentation on __name__
If you read the Flask documentation, the first argument to the
Flask class is called
import_name. It is described as "the name of the application package". The documentation suggests that you "usually" create the Flask instance by passing
__name__ for this argument, without going into any details on why.
In the sub-section titled "About the First Parameter" there is a little more information about the purpose of the
import_name argument, with a list of three different purposes for it:
- Find resources on the filesystem
- Used by extensions to improve debugging information
- A lot more (???)
Very confusing, right? Let's look at these one by one.
This is actually easier to understand that it may seem initially. The term "resources" in this context refers to additional files needed by the application, such as static and template files. Did you ever stop to think about how Flask knows where to look for these files?
The way it works is as follows. Flask takes the argument passed as
import_name, which is the name of an imported package, and tries to use it to figure out what the root path of the application is by looking for the module object with that name. Once it knows this path, it appends the static and template directory names and that is where it goes to get those files.
There is a function in the
flask/helpers.py module called
get_root_path() that Flask uses to obtain the root directory of the application. This function does all the dirty work of navigating the Python import system to locate the module with the name that was given as the
Let's take a quick look at the
get_root_path() function. For the following test I'm going to use the microblog application featured in my Flask Mega-Tutorial. With this application correctly installed, I'm going to start a Python session and call the
get_root_path() function with a few different values to see what the results are:
>>> from flask.helpers import get_root_path # the app package >>> get_root_path('app') '/home/miguel/microblog/app' # the flask package >>> get_root_path('flask') '/home/miguel/microblog/venv/lib/python3.8/site-packages/flask' # the threading package >>> get_root_path('threading') '/home/miguel/.pyenv/versions/3.8.6/lib/python3.8' # the config.py module >>> get_root_path('config') '/Users/mgrinberg/Documents/dev/python/microblog' # the app/models.py module >>> get_root_path('app.models') '/Users/mgrinberg/Documents/dev/python/microblog/app' # the app.api package >>> get_root_path('app.api') '/Users/mgrinberg/Documents/dev/python/microblog/app/api' # the app.api.auth.py module >>> get_root_path('app.api.auth') '/Users/mgrinberg/Documents/dev/python/microblog/app/api'
From these examples we can derive the rules that Flask uses to determine the root path:
- If you call
Flask()passing the name of a package as an argument, then the root path of the application is the directory where the package is located.
- If you call
Flask()passing the name of a module as an argument, then the root path of the application is the directory of the package in which the module is located.
There is a second usage of the
import_name argument. Flask has an obscure feature called instance folders, which are special folders where configuration files that are not under source control can be stored. The method to determine the location of the instance folder for an application is the same, the
import_name is used to find a root path, and then an instance subdirectory is added to it.
I should note that both the default root and instance paths can be overriden in the Flask constructor with the
Improving Debugging Information In Flask Extensions
This one was very tricky to figure out. The only Flask extension I have found that uses the
import_name argument is Flask-SQLAlchemy. The extension has a get_debug_queries() function that collects and logs all the queries that are issued during the life of a request. One of the attributes that are logged is the place in the application source code where the query was issued. Obtaining this information is actually quite hard, Flask-SQLAlchemy walks up the call stack at the time the query completes until it finds a source location that matches the import name of the application.
While this is a very cool technique, it is also very magical and obscure. I have not seen it used in any other Flask extensions.
A Lot More
I scanned the Flask source code for other usages of the
import_name parameter and found two more cases that are worth mentioning.
One is the
Blueprint class, which takes the blueprint name as first argument, and
import_name as second. The usage of the argument in blueprints is related to finding blueprint specific resources, and it works in the same way as in the application instance.
The other interesting place where the
import_name argument is used is in giving the application instance a name. The name of the application appears when you print the application instance:
>>> from flask import Flask >>> app = Flask('foo') >>> app <Flask 'foo'>
This name is assigned to the main group of the Click command-line interface. If you were to attach the Flask CLI of your project as a group into a parent CLI, then this name would be the group name that you would use to access the Flask application commands.
I hope you now have a better understanding of the common practice of calling
Flask(__name__). If you have any remaining questions regarding this topic, feel free to ask me below in the comments section!