__name__
should not always be used as the first argument particularly if the application is in a package instead of a single module, then its 'usually recommended to hardcode the package name' in order to simplify debugging with the Flask-SQLAlchemy extension for example. For reference see the section on 'About the First Parameter' in http://flask.pocoo.org/docs/0.10/api/.
In the case when using a package there is a way to avoid hardcoding the package name with a special configuration which forces __name__
to resolve to the package name as desribed in Larger Applications. First, note that a Python package is not simply a directory containing modules which are Python source files; it must also contain an __init__.py
file (except for Python3 namespace packages). One function of __init__.py
files is to prevent unintentional namespace conflicts as mentioned in An Introduction to Python: Section 6.4. In the case of flask, its convenient to define a flask app in a package's __init__.py
in order to enable use of __name__
since in that case it resolves to the package name which is identical to the package's base directory name and has a file attribute with which its absolute pathname can be determined. A working flask/Python3 project demonstrating this configuration is available at flaskdemo.
Regarding understanding the first parameter in flask instance initialization, first of all if its missing and there are no remaining arguments, then when attempting to run the flask app it immediately fails with "TypeError: __init__()
missing 1 required positional argument: 'import_name'". Second, if a nonexistent pathname is provided for it, then the application's and its resources root is set to the cwd (current working directory) and attempts to access resources would fail unless they are in the cwd which is not necessarily always the case and a limitation anyway.
Further details can be obtained by examining the flask sources, particularly app.py as well as helpers.py. In an Anaconda3 installation they are located in Lib\site-packages\flask. From a brief review, what I found is that class Flask is defined in app.py and its
__init__
method begins with:
def __init__(self, import_name, static_path=None, static_url_path=None,
static_folder='static', template_folder='templates',
instance_path=None, instance_relative_config=False):
_PackageBoundObject.__init__(self, import_name, template_folder=template_folder)
...
class _PackageBoundObject is defined in helpers.py and it has an open_resource()
function
that returns open(os.path.join(self.root_path, resource), mode)
where
self.root_path = get_root_path(self.import_name)
The root in root_path
refers to 'the path of a package or the folder that contains a module'. get_root_path
goes though a series of attempts to resolve it starting with the module name if its available and has a file attribute. In all cases absent exceptions it returns an absolute pathname which defaults to cwd if it has not been already been resolved with a module name whenpkgutil.get_loader(import_name) == None
or import_name == '__main__'
, which happens when running a flask app interactively instead of from a file.