Autoloading Blueprints in Flask
In all projects, a logical directory structure is important to having logical, maintainable code. My current project using the Flask framework has a directory for blueprints. The structure could cause problems, such as forgetting to register them and having messy imports. This snippet solves those problems.
The Code
for root, dirs, files in os.walk(os.path.join('app', 'blueprints')):
for name in [n for n in files if '__init__.py' not in n and n.endswith('.py')]:
n = os.path.join(root, name)[:-3].replace('/', '.')
module, attr = n.rsplit('.', 1)
imp = __import__(module, fromlist = [attr])
attr = getattr(imp, attr)
if hasattr(attr, 'blueprint'):
app.register_blueprint(attr.blueprint)
Explained
- First, we need to crawl through the specified directory (wherever you keep all your blueprints). Using `os.walk(), we can go through each file and directory starting with the given directory.
- Next, we need to loop through each Python file that isn't the
__init__.py
. The list comprehension turns the list of files into a list of Python files that aren't the__init__.py
file. - We then change the filename to a package name, and split it into the module and the attribute we want to import. We import the module, and grab that attribute (which is the Python file we want to import).
- Finally, we check if that imported file has the blueprint attribute we are after, and if so, we register the blueprint.
This is meant to be run as your application is initialized (say, if you run "run.py" to start your application, you would insert it in there).
Notes
One has to make sure they have the __init__.py
file in each directory, so that it is treated as a module. It doesn't need to contain anything, but it has to be there.
Written 2014-02-25