/flask-example

Example Flask App

Primary LanguagePython

Flask Example

An example Flask application with the following goals:

  • Dependency management using poetry
  • Use standard CLI commands, such as flask run and flask db
  • Separate development and production configurations set by FLASK_ENV
  • pytest can run from the project root
  • Uses database migrations
  • Uses database migrations in testing
  • Can use PostGres for testing
  • Creates a separate PostGres database for testing
  • Runs PostGres tests in transactions
  • Can use sqlite for testing
  • Database configuration can be set without modifying committed files
  • Example Blueprint usage
  • Custom CLI commands
  • Can send email from routes and test them via pytest
  • Example S3 bucket access and testing
  • Example Flask-Login usage and testing
  • Example timestamp model mixin
  • Custom Jinja function examples
  • Global template context variable examples

Quickstart

Requires Python 3.10+.

Create a virtual environment:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

Run the development server:

FLASK_DEBUG=true flask run

Run the test suite:

pytest

Poetry

To use Poetry for dependency management, first install Poetry 1.2+.

A shell can be activated with:

poetry shell

And dependencies installed with:

poetry install

A requirements.txt file can be generated with:

poetry export -f requirements.txt --output requirements.txt --without-hashes

Database Configuration

The database URL can be set in a local configuration file located at app/local_config.py. This file will be ignored by git. It should be a valid python module, with uppercase keys for any values that should be added to the Flask configuration. Such as:

SECRET_KEY = 'insecure-do-not-use-me'
S3_BUCKET = 'example-bucket'
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/sqlite.db'

Some systems may require the installation of psycopg2-binary instead of the psycopg2 package.

Tutorials

Example Database Operations

Using an application-factory context:

from sqlalchemy import select
from app import db, create_app
from app.users import User, Permission

app = create_app()

# Database tables only need to be created once
db.create_all(app=app)

# Either use the following with statements, or push an app context with:
# app.app_context().push()

with app.app_context():
    admin = User(email='admin@example.com')
    permission = Permission(user=admin, action="Publish")
    db.session.add(admin, permission)
    db.session.commit()

with app.app_context():
    db.session.scalars(db.select(User).order_by(User.id))

Using Migrations

Get a list of flask commands:

flask db --help

Add migrations to an app (only need to run once):

flask db init

Create a new migration:

flask db migrate -m "New migration"

Perform migrations:

flask db upgrade

Testing Email

Run a local SMTP server:

python -m smtpd -n -c DebuggingServer localhost:1025