Skip to content
Snippets Groups Projects
user avatar
Michael Kyriakou authored
597b3ddf
History

Python3 Flask Template

A started template for Flask web apps using Python 3.8. This started template includes:

  • Dynamic frontend templates (not React)
  • Database support
  • Imperial LDAP user authentication
  • Multiple environments (development and production)

This template is useful if you would like to create a backend REST API, optionally coupled with a simple dynamic frontend.

Getting started

Once you have created your new app, take a few minutes to look through the files to familiarise yourself with the project structure.

  • app.py : entry point to the Flask app
  • templates/ : contains the frontend dynamic HTML files
  • static/ : contains the static frontend assets (images, stylesheets and scripts)
  • blueprints/ : contains all the application routes
  • models/ : contains all the database models
  • database/ : contains the database creation
  • config/ : contains the app settings for the different environments

The first change you should make is to set the APP_NAME variable in config/config.py to whatever you app's name is.

To start the application locally, you can just run python3 app.py and this will launch the app on port 5000 (by default). You will notice a message in the console saying:

WARNING: Could not connect to the given database URL!

To fix this, you should set the environment variable DATABASE_URL accordingly. If you have PostgreSQL running locally, you can use that. Alternatively, you could use SQLite which is much simpler and does not require installation.

If you do not want to use a database yet, you can ignore this warning and delete any routes that interact with the database.

If you navigate to http://localhost:5000, you will see the response created by the route defined in blueprints/home.py.

You will also notice the lines Environment: production and Debug mode: off when the Flask application starts in the console. To enable debug mode, you must set the environment variable ENV to dev, ie: export ENV=dev (see config/config.py for more details on different environments).

Tutorial 1: Adding a new route

Tutorial 2: Adding database interaction

Tutorial 3: Configuring a test environment

Flask Migrations

A table in flask is called a "Model", all models need to extend "db.Model". You have been provided with two models, "Person" and "PhoneNumber" which is a 1-many relationship; a "Person" can be many "PhoneNumber".

Adding a new table

  1. Use an existing model as a guide.

  2. Modify the "models" package to import your model, otherwise flask will not see it and not be able to migrate it.

  3. Run a new migration when you're happy with your model.

Tutorial: connect to your database

You will need to specify the database connection strings for development ("debug" or "dev") and for production ("prod").

TIP: do not use SQLite if you plan to make use of flask migrations.

  1. Navigate to: config/config.py

  2. CTRL + F, then type in: db_configs

  3. Within this array, modify the existing single entry.

  4. The "bind_key_name" is the identifier Flask uses to uniquely identify your database amongst all other databases in your application. Currently only one is used, however if, say, three were in use, then the "bind_key_name" is very important. As such, it must be unique. Change the value to something more descriptive.

  5. Make sure you add a static variable as well under the "DB Bindings" region, as you'll need to be able to reference this binding from the outside when creating models for the database this binding will be for.

  6. Change the "debug_env_var_key" and "prod_env_var_key" values to be the environment variable key values that contain your connection strings for the "debug" and "prod" databases respectively. NOTE: that to speed up development you may use the "force" optional parameter variants, however this is discouraged as it exposes your connection string in your git repository.

Running a Migration

When you run a migration for the first time the "migrations" directory will be constructed.

Managing Migrations

The "migrations" directory contains all migrations you have performed on every database this app uses. It contains the subdirectories "dev" and "prod", then subdirectories identified by the binding keys used.

You have been provided with the binding "first_db". Running a migration will result in the following path being accessible:

migrations/dev/first_db/

It is very important that you do not delete anything from this directory, since flask migrate will also store a migration history in correspondance to the directory's contents in your database, under the "alembic" table.

Tutorial: checking your migration script

Flask migrate will automatically generate a migration script based on the differences between your database represented in flask (this application) and the actual database. It may be incorrect, or may not fully complete the migration you want. To resolve this, you should check the migration script, and verify it does what you want it to do.

  1. Navigate to: models/first_db_models/phone_number.py

  2. It is very useful for rows in a database to have a "created_at" attribute so you know when the row was first inserted. Comment out the new under the TODO, and remove the TODO.

  3. Run "RunMigration" depending on your Operating System.

  4. Navigate to: migrations/dev/first_db/versions

  5. You should see a new python file created in here under some hash code, open the file.

  6. Verify the file is doing an "add_column" operation.

  7. Complete the migration by pressing ENTER, calling the script's "upgrade" method.

Troubleshooting

Consistency violation, cannot find version

Delete/drop the "alembic" table for the database and delete the associated migration directory.