Larger Applications
Imagine a simple flask application structure that looks like this:
- /yourapplication
- yourapplication.py
- /static
- style.css
- /templates
- layout.html
- index.html
- login.html
- ...
While this is fine for small applications, for larger applicationsit’s a good idea to use a package instead of a module.The tutorial is structured to use the package pattern,see the example code.
Simple Packages
To convert that into a larger one, just create a new folderyourapplication
inside the existing one and move everything below it.Then rename yourapplication.py
to init.py
. (Make sure to deleteall .pyc
files first, otherwise things would most likely break)
You should then end up with something like that:
- /yourapplication
- /yourapplication
- __init__.py
- /static
- style.css
- /templates
- layout.html
- index.html
- login.html
- ...
But how do you run your application now? The naive pythonyourapplication/init.py
will not work. Let’s just say that Pythondoes not want modules in packages to be the startup file. But that is nota big problem, just add a new file called setup.py
next to the inneryourapplication
folder with the following contents:
- from setuptools import setup
- setup(
- name='yourapplication',
- packages=['yourapplication'],
- include_package_data=True,
- install_requires=[
- 'flask',
- ],
- )
In order to run the application you need to export an environment variablethat tells Flask where to find the application instance:
- $ export FLASK_APP=yourapplication
If you are outside of the project directory make sure to provide the exactpath to your application directory. Similarly you can turn on thedevelopment features like this:
- $ export FLASK_ENV=development
In order to install and run the application you need to issue the followingcommands:
- $ pip install -e .
- $ flask run
What did we gain from this? Now we can restructure the application a bitinto multiple modules. The only thing you have to remember is thefollowing quick checklist:
the Flask application object creation has to be in the
init.py
file. That way each module can import it safely and thename variable will resolve to the correct package.all the view functions (the ones with a
route()
decorator on top) have to be imported in theinit.py
file.Not the object itself, but the module it is in. Import the view moduleafter the application object is created.
Here’s an example init.py
:
- from flask import Flask
- app = Flask(__name__)
- import yourapplication.views
And this is what views.py
would look like:
- from yourapplication import app
- @app.route('/')
- def index():
- return 'Hello World!'
You should then end up with something like that:
- /yourapplication
- setup.py
- /yourapplication
- __init__.py
- views.py
- /static
- style.css
- /templates
- layout.html
- index.html
- login.html
- ...
Circular Imports
Every Python programmer hates them, and yet we just added some:circular imports (That’s when two modules depend on each other. In thiscase views.py
depends on init.py
). Be advised that this is abad idea in general but here it is actually fine. The reason for this isthat we are not actually using the views in init.py
and justensuring the module is imported and we are doing that at the bottom ofthe file.
There are still some problems with that approach but if you want to usedecorators there is no way around that. Check out theBecoming Big section for some inspiration how to deal with that.
Working with Blueprints
If you have larger applications it’s recommended to divide them intosmaller groups where each group is implemented with the help of ablueprint. For a gentle introduction into this topic refer to theModular Applications with Blueprints chapter of the documentation.