Large Applications as Packages ​
Imagine a simple flask application structure that looks like this:
/yourapplication
yourapplication.py
/static
style.css
/templates
layout.html
index.html
login.html
...
/yourapplication
yourapplication.py
/static
style.css
/templates
layout.html
index.html
login.html
...
While this is fine for small applications, for larger applications it’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 folder yourapplication
inside the existing one and move everything below it. Then rename yourapplication.py
to __init__.py
. (Make sure to delete all .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
...
/yourapplication
/yourapplication
__init__.py
/static
style.css
/templates
layout.html
index.html
login.html
...
But how do you run your application now? The naive python yourapplication/__init__.py
will not work. Let’s just say that Python does not want modules in packages to be the startup file. But that is not a big problem, just add a new file called pyproject.toml
next to the inner yourapplication
folder with the following contents:
[project]
name = "yourapplication"
dependencies = [
"flask",
]
[build-system]
requires = ["flit_core<4"]
build-backend = "flit_core.buildapi"
[project]
name = "yourapplication"
dependencies = [
"flask",
]
[build-system]
requires = ["flit_core<4"]
build-backend = "flit_core.buildapi"
Install your application so it is importable:
$ pip install -e .
$ pip install -e .
To use the flask
command and run your application you need to set the --app
option that tells Flask where to find the application instance:
$ flask --app yourapplication run
$ flask --app yourapplication run
What did we gain from this? Now we can restructure the application a bit into multiple modules. The only thing you have to remember is the following quick checklist:
the Flask application object creation has to be in the
__init__.py
file. That way each module can import it safely and the__name__
variable will resolve to the correct package.all the view functions (the ones with a
route()
decorator on top) have to be imported in the__init__.py
file. Not the object itself, but the module it is in. Import the view module after the application object is created.
Here’s an example __init__.py
:
from flask import Flask
app = Flask(__name__)
import yourapplication.views
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!'
from yourapplication import app
@app.route('/')
def index():
return 'Hello World!'
You should then end up with something like that:
/yourapplication
pyproject.toml
/yourapplication
__init__.py
views.py
/static
style.css
/templates
layout.html
index.html
login.html
...
/yourapplication
pyproject.toml
/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 this case views.py
depends on __init__.py
). Be advised that this is a bad idea in general but here it is actually fine. The reason for this is that we are not actually using the views in __init__.py
and just ensuring the module is imported and we are doing that at the bottom of the file.
Working with Blueprints ​
If you have larger applications it’s recommended to divide them into smaller groups where each group is implemented with the help of a blueprint. For a gentle introduction into this topic refer to the Modular Applications with Blueprints chapter of the documentation.