3/18/2019 Structure of a Flask Project - Just lepture
JUST LEPTURE
Apr 21, 2018 / Hsiaoming Yang
Structure of a Flask Project
Flask is very flexible, it has no certain pattern of a project folder
structure. Here is my suggestions.
Flask itself is very flexible. It has no certain pattern for a project folder structure, which
is very good for experienced developers to organize things in their own favors. Howev-
er, people new to Flask will get confused, they need some guide on it, and usually they
are going to find something works but not good (or even bad).
I didn't know such a problem until someone reported an issue to Authlib. And I can't un-
derstand the problem either. Then another person explained it to me with a project
structure, I finally got it. I was terrified that lots of posts, guide, boilerplates are back-
ward importing modules from project root __init__.py :
# project/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
db.init_app(app)
# project/auth/models.py
from .. import db
class User(db.Model):
# define columns
The code itself will work, but when your projects grow, sooner or later you will face a
cyclic dependencies problem. For instance, another extension requires to init with the
User model:
# project/__init__.py
from flask_sqlalchemy import SQLAlchemy
from another_extension import AnotherExtension
from project.auth.models import User
db = SQLAlchemy()
ext = AnotherExtension(User)
Oops, a cyclic dependency occurs. Because auth.models is importing db from the root,
root can not import User module. This is a common cyclic problem, not limited to Flask.
It is easy to fix, but junior developers may find it very hard. So why not avoid such thing
from the very begining? Actually, if you have read the official documentation, in appli-
cation factories you can find this piece of code:
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.model import db
db.init_app(app)
from yourapplication.views.admin import admin
https://lepture.com/en/2018/structure-of-a-flask-project 1/6
3/18/2019 Structure of a Flask Project - Just lepture
from yourapplication.views.frontend import frontend
app.register_blueprint(admin)
app.register_blueprint(frontend)
return app
See, we put db in yourapplication.model .
I always keep this one certain rule when writing modules and packages:
“ Don't backward import from root __init__.py .
That's why I submitted a ticket to Flask as soon as I found this problem. People need a
guide on folder structure. And here I'm going to share my suggestions. But think it your-
self, don't treat mine as a golden rule.
Functional Based Structure
There are many ways to setup your project folder structure. One is by its function. For
instance:
project/
__init__.py
models/
__init__.py
base.py
users.py
posts.py
...
routes/
__init__.py
home.py
account.py
dashboard.py
...
templates/
base.html
post.html
...
services/
__init__.py
google.py
mail.py
...
All things are grouped by its function. If it hehaves as a model, put it in models folder; if
it behaves as a route, put it in routes folder. Build a create_app factory in
project/__init__.py , and init_app of everything:
# project/__init__.py
from flask import Flask
def create_app()
from . import models, routes, services
app = Flask(__name__)
models.init_app(app)
routes.init_app(app)
services.init_app(app)
return app
Here is a trick by me. In official documentation, db of Flask-SQLAlchemy is registered in
this way:
from project.models import db
db.init_app(app)
https://lepture.com/en/2018/structure-of-a-flask-project 2/6
3/18/2019 Structure of a Flask Project - Just lepture
So my trick is define a init_app in every folder's __init__.py , and unify the init
progress as one:
# project/models/__init__.py
from .base import db
def init_app(app):
db.init_app(app)
# project/routes/__init__.py
from .users import user_bp
from .posts import posts_bp
# ...
def init_app(app):
app.register_blueprint(user_bp)
app.register_blueprint(posts_bp)
# ...
App Based Structure
Another famous folder structure is app based structure, which means things are
grouped bp application. For instance:
project/
__init__.py
db.py
auth/
__init__.py
route.py
models.py
templates/
blog/
__init__.py
route.py
models.py
templates/
...
Each folder is an application. This pattern is used by default in Django. It doesn't mean
this pattern is better, you need to choose a folder structure depending on your project.
And sometime, you will have to use a mixed pattern.
It is the same as above, we can init_app as:
# project/__init__.py
from flask import Flask
def create_app()
from . import db, auth, blog
app = Flask(__name__)
db.init_app(app)
auth.init_app(app)
blog.init_app(app)
return app
Configuration
Loading configuration would be another issue that many people find difficult, it is also a
folder structure problem. I don't know how other people are doing, I'm just sharing my
solution.
1. Put a settings.py in project folder, treat it as static configuration.
2. Load configration from environment variable.
https://lepture.com/en/2018/structure-of-a-flask-project 3/6
3/18/2019 Structure of a Flask Project - Just lepture
3. Update configration within create_app .
Here is a basic folder structure for configration:
conf/
dev_config.py
test_config.py
project/
__init__.py
settings.py
app.py
Define a create_app to load settings and environment variable:
# project/__init__.py
import os
from flask import Flask
def create_app(config=None)
app = Flask(__name__)
# load default configuration
app.config.from_object('project.settings')
# load environment configuration
if 'FLASK_CONF' in os.environ:
app.config.from_envvar('FLASK_CONF')
# load app sepcified configuration
if config is not None:
if isinstance(config, dict):
app.config.update(config)
elif config.endswith('.py'):
app.config.from_pyfile(config)
return app
This FLASK_CONF is a python file path which contains configrations. It can be any name
you want, e.g. your project is called Expanse, you can name it as EXPANSE_CONF .
I use this FLASK_CONF to load production configurations.
***
Again, Flask is very flexible, there is no certain patterns. You can always find your fa-
vors. These are just my suggestions, do not blind by anyone.
I don't like to write posts like this. But there are so many wrong guide, I hope this post
can get a better SEO, so that bad posts don't mislead people.
ENJOY #Flask
SUBSCRIBE TO JUST LEPTURE
Get the latest posts delivered right to your inbox. We hate spam too.
Your Email Address SUBSCRIBE
You can also subscribe via RSS.
READ THIS
Announcement of Authlib
A Python library for OAuth/OpenID Authentication. With Authlib, you can create OAuth servers
with ease.
11 Comments Just lepture
1 Login
https://lepture.com/en/2018/structure-of-a-flask-project 4/6
3/18/2019 Structure of a Flask Project - Just lepture
Recommend 1 t Tweet f Share Sort by Best
Join the discussion…
LOG IN WITH OR SIGN UP WITH DISQUS ?
Name
Preslav Rachev • 6 months ago
Is it a standard procedure to bootstrap the app inside the project dir's `__init__.py` file?
21 △ ▽ • Reply • Share ›
lepture Writer > Preslav Rachev • 6 months ago
No. You can put it in other file too.
22 △ ▽ • Reply • Share ›
AppZeenuser > Preslav Rachev • 2 months ago
preslavrachev yes but
△ ▽ • Reply • Share ›
Huajian Jiang • 3 months ago
请问 如果 我的 flask app 工程的 static,template 目录 是 放在 res 目录下的,配置 Flask 的 static_folder
= 'res/static' 和 template_folder = 'res/template' 会报 模板找不到 的错误,请问 如何 处理这种 目录 结构
问题呢?
3△ ▽ • Reply • Share ›
Rabia Iftikhar • 2 months ago
I am newbies in Flask. Thank you for such an amazing article. It really helped a lot in structuring my
project (y)
△ ▽ • Reply • Share ›
Chen Woo • 3 months ago
,
There is a mistake in spelling "If it hehaves as a model,..."
△ ▽ • Reply • Share ›
MintyCrypto • 6 months ago
For 'Functional Based Structure' you have a line to 'from .base import db' in project/models/__init__.py
In the tree view above, there is no base file (other than base.html)
Above that you mention putting db in yourapplication.model
It's not clear to me where the db is actually being imported from in this article. The way I'm reading is
that you're defining the db in yourapplication.model then trying to import it in models/__init__.py. But
this seems wrong. Is there a clear example or repo I can look at? Thanks!
△ ▽ • Reply • Share ›
maric chen • 6 months ago
great post!!
△ ▽ • Reply • Share ›
Fernando • 7 months ago
Iam beginning in Flask, this article is very helpful (y)
△ ▽ • Reply • Share ›
PB • a year ago
I've found this very helpful. I've refactored most of my application with your factories example. Where do
you suggest putting Unit test files?
△ ▽ • Reply • Share ›
timfeirg > PB • 10 months ago
for example https://github.com/projecte...
△ ▽ • Reply • Share ›
ALSO ON JUST LEPTURE
PyCon JP 2018 記 三藩記
4 comments • 6 months ago 11 comments • a year ago
很棒呀! 今年 PyCon China 办的也还不
TaoBeier — lepture — 只是簡單記錄一下 :)
Avatar 错,评价较往年高很多。 Avatar
日光一日遊 利器拾遺
7 comments • 2 years ago 9 comments • 2 years ago
Riophae Lee — 最喜欢第一张和最后一张,质感很棒 lepture — 社交网络俗称圈子,天然就是封闭的。
Avatar Avatar
✉ Subscribe d Add Disqus to your siteAdd DisqusAdd Disqus' Privacy PolicyPrivacy PolicyPrivacy
https://lepture.com/en/2018/structure-of-a-flask-project 5/6
3/18/2019 Structure of a Flask Project - Just lepture
Just lepture Archive English Chinese
TYPLOG
https://lepture.com/en/2018/structure-of-a-flask-project 6/6