All notes
BestPractices

Project structure

The following takes Flask as example.

myApp/
    run.py
    venv/
    myApp/              # Our Application Module
        __init__.py
        default_settings.py
        views.py # wcfNote: or the name controller.py/router.py is better?
        module_one/
            __init__.py
            controllers.py
            models.py
        templates/
            module_one/
                hello.html
        static/
            style.css
    README.md
    examples/
    tests/
    doc/

Files

myApp/default_settings.py


import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__)+"/..")

DEBUG = true
PORT = 8080

SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'app.db')

# Secret key for signing cookies
SECRET_KEY = "secret"

dbConfig = {
    "mysql": {
        "user": "root",
        "pass": "secret",
        "tables": {
            "users": "tb_users"
        }
    }
}
otherConfig = "ok..."

# You'd access the values as follows:
dbConfig["mysql"]["tables"]["users"]

wcfNote: if you want to have another custom.py in the root directory to override the default configurations, refer to flask/config.py.

myApp/__init__.py


from flask import Flask
app = Flask(__name__)
# Here __name__ is the package name.

import myApp.views

myApp/views.py


# Must import app from the package, or python will complain "app not defined".
from myApp import app

@app.route('/')
def index():
    return 'Hello World!'

Circular imports on views.py and __init__.py

views.py imports the package (which will automatically calls __init__.py), and __init__.py explicitly imports views.py, so it forms circular imports.

wcfNote: python will read its __init__.py when importing a package, which does not mean that the modules in a package will automatically load __init__.py. So we still need to add "from packageName import app" in views.py.

It is ok since we are not actually using the views in __init__.py and just ensuring the module is imported. There are still some problems with that approach but if you want to use decorators there is no way around that.

run.py


from config import *
from myApp import app
app.run(host='0.0.0.0', port=8080, debug=DEBUG)

For complex application

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. See blueprints.

Or use application dispatch.