Menu Close

Python Web Development with Flask — Logging, App Commands, and Blueprints

Flask is a simple web framework written in Python.

In this article, we’ll look at how to develop simple Python web apps with Flask.

Logging

Flask comes with a logger.

We can use it with the app.logger object.

For example, we can write:

from flask import Flask
from markupsafe import escape

app = Flask(__name__)

@app.route('/')
def index():
    app.logger.debug('A value for debugging')
    app.logger.warning('A warning occurred (%d apples)', 42)
    app.logger.error('An error occurred')
    return 'hello'

to call methods to do various levels of logging.

Add App Commands

We can add app commands with Flask.

This way, we can automate tasks that are otherwise manual.

For example, we can create a task to initialize a database by writing:

app.py

from flask import Flask, current_app, g
import os
import sqlite3
import click
from flask.cli import with_appcontext

def get_db():
    if 'db' not in g:
        g.db = sqlite3.connect(
            'db.sqlite',
            detect_types=sqlite3.PARSE_DECLTYPES
        )
        g.db.row_factory = sqlite3.Row
    return g.db

def close_db(e=None):
    db = g.pop('db', None)
    if db is not None:
        db.close()

def init_db():
    db = get_db()
    with current_app.open_resource('schema.sql') as f:
        db.executescript(f.read().decode('utf8'))

@click.command('init-db')
@with_appcontext
def init_db_command():
    init_db()
    click.echo('Initialized the database.')

app = Flask(__name__)
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)

@app.route('/')
def index():
    return 'hello'

schema.sql

DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;

CREATE TABLE user (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  username TEXT UNIQUE NOT NULL,
  password TEXT NOT NULL
);

CREATE TABLE post (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  author_id INTEGER NOT NULL,
  created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  title TEXT NOT NULL,
  body TEXT NOT NULL,
  FOREIGN KEY (author_id) REFERENCES user (id)
);

The following code:

@click.command('init-db')
@with_appcontext
def init_db_command():
    init_db()
    click.echo('Initialized the database.')

creates our command.

We pass in the command name into the @click.command decorator.

init-db is the name of the command we registered.

The with_appcontext decorator is also required to use the app context.

In the init_db function, we call get_db to get the database connection.

Then we call current_app.open_resource to get the SQL script with the and run it with db.executescript .

We call:

app.teardown_appcontext(close_db)

to close the database connection.

Now we run:

flask init-db

to run the init-db command to run our schema.sql script to create the tables.

Blueprints

To separate our apps into smaller modules, we can use blueprints.

For example, we can write:

app.py

from flask import Flask
from auth import bp
app = Flask(__name__)
app.register_blueprint(bp)

auth.py

from flask import Blueprint

bp = Blueprint('auth', __name__, url_prefix='/auth')
@bp.route('/register', methods=('GET', 'POST'))
def register():
    return 'register'

to create the auth blueprint.

We use the Blueprint class to create the blueprint.

The first argument is the name.

__name__ is the location that the blueprint is defined in.

The 3rd argument is the URL prefix.

To register a route in the blueprint, we call the @bp.route decorator like we do with the app.route decorator.

Then to register the blueprint, we write:

app.register_blueprint(bp)

to register the blueprint.

Conclusion

We can add logging, app commands, and blueprints with Flask.

Posted in flask, Python