Doing it all as an app
While blueprints are good for organising the code things will start to get messy as the app grows. We can use python modules to create a more organised structure.
- Directoryflaskapp/- Directorystatic/- style.css
 
- Directorytemplates/- index.html
- base.html
 
- __init__.py
- blog.py
- db.py
 
Creating the app
Create a new folder called flaskapp and add a __init__.py file to it. This file will be the entry point for the app.
from flask import Flaskimport contextlibimport os
def create_app(test_config=None) -> Flask:    app = Flask(__name__)    app.config.from_mapping(        SECRET_KEY="dev",        DATABASE=os.path.join(app.instance_path, "flaskapp.sqlite"),    )
    if test_config is None:        # load the instance config, if it exists, when not testing        app.config.from_pyfile("config.py", silent=True)    else:        # load the test config if passed in        app.config.from_mapping(test_config)
    # ensure the instance folder exists    with contextlib.suppress(OSError):        os.makedirs(app.instance_path)
    @app.route("/ping")    def ping() -> str:        return "pong!"
    return app- 
The create_appfunction creates a new Flask appThis function is automatically called by Flask when the app is run. It accepts an optional test_configparameter which can be used to pass in configuration values.
- 
Config is set The app is configured with a SECRET_KEYand aDATABASEpath. TheSECRET_KEYis used by Flask and extensions to keep data safe. TheDATABASEis the path where the SQLite database file will be stored.
- 
A method to load external configuration The config.pyfile in the instance folder can be used to set configuration values. This is useful for setting values that should not be in version control.
- 
The instancefolder is createdThe instancefolder is created if it does not exist. This folder is used to store files that should not be in version control.with contextlib.suppress(OSError):is used to suppress the error if the folder already exists. This is similar to atryandexceptblock.
- 
A ping route is added A simple route is added to check if the app is running. When the /pingroute is accessed, the app will returnpong!.
Running the app
To run our app we can run:
flask --app flaskapp runAdding the blog blueprint
Create a new file called blog.py and add the following code to it.
from flask import Blueprint
blog = Blueprint('blog', __name__)
@blog.route('/')def index():    return 'Hello from the blog'This blueprint will be used to handle all the blog related routes.
Registering the blueprint
Update the __init__.py file to register the blueprint.
    # ensure the instance folder exists    with contextlib.suppress(OSError):        os.makedirs(app.instance_path)
   from .blog import blog   app.register_blueprint(blog)
    @app.route("/ping")    def ping() -> str:        return "pong!"Setting up the database
Following from how we set up the blog blueprint, we can create a new file called db.py and add the following code to it.
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyfrom sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):    pass
db = SQLAlchemy(model_class=Base)
class Post(db.Model):    id = db.Column(db.Integer, primary_key=True)    title = db.Column(db.String(100), nullable=False)    content = db.Column(db.Text, nullable=False)
def init_app(app: Flask):    db.init_app(app)    with app.app_context():        db.create_all()- 
The Baseclass is created as a base for the databases
- 
The dbobject is createdThe dbobject is created using theSQLAlchemyclass. Themodel_classparameter is set to theBaseclass to use it as the base for all models.
- 
The Postmodel is createdThe Postmodel is created with anid,title, andcontentcolumn. Theidcolumn is the primary key. Thetitleandcontentcolumns are set to be not nullable.
- 
The init_appfunction is createdThe init_appfunction is created to initialise the database. Thedbobject is initialised with the app. The database is created with thecreate_allmethod.
In the __init__.py file, import the db module and call the init_app function.
    # ensure the instance folder exists    with contextlib.suppress(OSError):        os.makedirs(app.instance_path)
    from .db import init_app    init_app(app)
    from .blog import blog    app.register_blueprint(blog)With the database set up, we can now add a route to add a post to the database.
 from .db import Post, db
...
@bp.route("/add_post")def add_post():    post = Post(title="Hello World", content="This is my first post")    db.session.add(post)    db.session.commit()    return "Post added" 
 