Skip to content

Structure of the Flask application

Vicki Jackson edited this page Oct 14, 2020 · 4 revisions

Introduction

This document describes the design and structure of the Flask example application.

Outline

The Flask application follows much of the best practice outlined in many places including the excellent Miguel Grinberg Flask-Mega Tutorial. If you're new to Python and Flask then I highly recommend Miguel's tutorial as this will explain many of the concepts used in this application.

Entry point

my_app.py is the entry point of the application. This doesn't do much other than launch the application by executing create_app inside init.py in the main app folder.

The application uses the config.py to hold the application's configuration. As can be seen, you can define different values for whether you want the application to be run in development, testing, staging, or production.

To define which configuration is to be used, the environment variable FLASK_CONFIG is used. This must be set to one of development, testing, staging, production.

The use of this configuration file enables you to change the configuration for each environment. For example, you may want to debug when running in development or testing but not in production. It also allows you to configure different databases to be used for each environment. This file makes it easy to make changes for each environment.

create_app

Inside init.py, various packages are imported and configured for use for the application.

The external packages used are:

  • Flask-Login to provide basic session and login management
  • Authlib to provide OAuth capabilities as required to use auth0.com for user authentication
  • flask-bootstrap for some basic bootstrap styling
  • flask-cdn to easily enable URLs of static content to be re-written to use a CDN
  • Flask-Migrate to help manage database schema changes
  • Flask-Moment to support the formatting of dates within web-pages
  • SQLAlchemy to access the database using a model rather than direct SQL
  • flask-wtf to easily define and validate forms

Blueprints

Blueprints are used extensively to allow grouping of similar features into their own blueprints. This application has four different blueprints to support:

Within each of these folders, you will find an __init__.py file that defines the blueprint, a routes.py file that contains the routes, and a forms.py file if there are any forms used in the views.

Views

Standard Flask views are used to define the URLs accessible to users and the functions to call when the URL is accessed.

Some of the views are decorated with @login_required. This ensures the page is only accessible once the user is logged in.

Many of the views use the Flash concept to show status messages to the user e.g. confirming the receipt of a Contact Us form.

HTML Templates

The HTML templates are contained within a folder called templates. These are standard Jinja2 templates.

All of the templates (other than error pages) extend the base.html template.

This base.html template defines the standard HTML Head section and the navigational bars shown at the top and bottom of each page.

There is a lot of code in the HEAD section of the base.html template to ensure the application is a PWA, contains some basic SEO data and icons to ensure shortcuts show correctly.

Twitter Bootstrap is used to style the pages. Some icons from FontAwesome are also used.

These templates will likely require heavy customization to better meet your needs.

Database definition

The models.py defines the database schema for the application. This Flask application only has one table to store the Users of the application.

Flask-Migrate is used to generate the migration files required to install any schema changes to the database.

The initial file was generated using flask db init and then flask db migrate. This generates the migration file from the models.py file. The migrate command looks to see if there are any changes since it was previously run. If there are, then a new migration file is created.

flask db upgrade updates the database.

These Flask-Migrate commands make use of the 'FLASK_CONFIG' environment variable to determine which database to connect to.

Static content

All static content such as css, javascript, images are contained in a static folder.

Inside the root of this folder, there are some important files.

sitemap.xml and robots.txt. These should be updated to better reflect your application as they're used by search engines to index your site. There are views defined inside routes.py such that these are accessible at the root of your website as required by search engines e.g. <YOUR_WEBSITE_URL>/robots.txt and <YOUR_WEBSITE_URL>/sitemap.xml

manifest.json, offline.html and service-worker.js are used to ensure the app is a fully-functioning Progressive Web App (PWA). Similar to the files needed for search engines, these must be accessible at the root of the website and so there are views defined in the routes.py file.

Depending on your hosting, you may find these static files are served by a web-server such as nginx or you can configure a Content Distribution Network (CDN) to serve these file

Logging

Standard Python logging is used to log debug or error messages. The file log_config.yaml contains the logging configuration.

By default, any log messages with a status of at least WARNING are logged to a file at /tmp/my_app.log. A log message is written when the application first starts.

Error pages

404, 500 and others are defined inside handlers.py. Errors will show the relevant error page via the error templates

Tests

The pytest framework is used along with Selenium to test the UI. The tests are defined within the tests folder

Clone this wiki locally