Boilerplate Flask Dashboards
Reference codebase used in all Flask Dashboards provided by the AppSeed platform
Open-Source codebase used by all Flask Dashboards provided by AppSeed.
  • Up-to-date dependencies: Flask 2.0.1
  • ​SCSS compilation via Gulp
  • Bootstrap 5 Design: Volt Dashboard (demo link)
  • DBMS & Tools: SQLite / PostgreSQL / SQLAlchemy ORM, Flask-Migrate
  • Modular design with Blueprints
  • Session-Based authentication (via flask_login), Forms validation
  • Deployment scripts: Docker, Gunicorn / Nginx, HEROKU
  • Free Support via Github (issues tracker) and Discord.
Links
  • ​Source Code - released on Github (MIT License)
  • Product ROADMAP:
    • Up-to-date dependencies
    • Improved authentication:
      • Password reset, Email confirmation on register
    • Extended user model: custom fiels: Name, Surname, Address, User Photo
    • API via Flask-RestX
    • Data Tables - paginated information
    • Sample Charts
    • Social Login for Google and Github
    • Deployment:
      • Docker
      • HEROKU, AWS Ec2, Google Cloud, Azure
    • Payments: One-time payments via Stripe Checkout​

Environment

To use the stater, Python3 should be installed properly in the workstation. If you are not sure if Python is properly installed, please open a terminal and type python --version. The full list with dependencies and tools required to build the app:
  • ​Python3 - the programming language used to code the app
  • ​GIT - used to clone the source code from the Github repository
  • Basic development tools (g++ compiler, python development libraries ..etc) used by Python to compile the app dependencies in your environment.

Start in Docker

The project comes with Docker support that allows a quick start in any environment
Step #1 - Get the source code
  • Download the ZIP from the product page
  • Use GIT tool in the terminal to clone the source code
1
$ git clone https://github.com/app-generator/boilerplate-code-flask-dashboard
2
$ cd boilerplate-code-flask-dashboard
Copied!
Step #2 - Execute Docker commands
1
$ docker-compose pull # download the modules
2
$ docker-compose build # local build
3
$ docker-compose up # start the app
Copied!
Visit http://localhost:85 in your browser. The app should be up & running.
Note: for Linux-based systems the above commands might require sudo execution. Here is a sample:
1
$ sudo docker-compose pull
2
$ sudo docker-compose build
3
$ sudo docker-compose up -d # execute demonized via '-d' argument
Copied!

Build the app

To built and start the app locally, follow the steps:
Step #1 - Get the source code
  • Download the ZIP from the product page
  • Using GIT tool in the terminal to clone the source code
Step #2 - Install modules using a Virtual Environment
1
$ # Virtualenv modules installation (Unix based systems)
2
$ virtualenv env
3
$ source env/bin/activate
4
$
5
$ # Virtualenv modules installation (Windows based systems)
6
$ # virtualenv env
7
$ # .\env\Scripts\activate
8
$
9
$ # Install modules - SQLite Storage
10
$ pip3 install -r requirements.txt
Copied!
Step #3 - Setup environment
1
$ # Set the FLASK_APP environment variable
2
$ (Unix/Mac) export FLASK_APP=run.py
3
$ (Windows) set FLASK_APP=run.py
4
$ (Powershell) $env:FLASK_APP = ".\run.py"
5
$
6
$ # Set up the DEBUG environment
7
$ # (Unix/Mac) export FLASK_ENV=development
8
$ # (Windows) set FLASK_ENV=development
9
$ # (Powershell) $env:FLASK_ENV = "development"
Copied!
Step #4 - Start the app
1
$ # Start the application (development mode)
2
$ # --host=0.0.0.0 - expose the app on all network interfaces (default 127.0.0.1)
3
$ # --port=5000 - specify the app port (default 5000)
4
$ flask run
Copied!
At this point, we can visit the app in the browser http://127.0.0.1:5000/. By default, the app will redirect guest users to the login page. To access the private pages:
  • Create a new user using the registration page
  • Authenticate using the login page

App Codebase (simplified)

Starter uses a simple codebase (no Blueprints) with a structure presented below:
1
< PROJECT ROOT >
2
|
3
|-- apps/
4
| |
5
| |-- home/ # The App that serve HTML files
6
| |-- authentication/ # Handles authentication
7
| |
8
| |-- static/
9
| | |-- <css, JS, images> # CSS files, Javascripts files
10
| |
11
| |-- templates/ # All Templates
12
| | |-- includes/ # UI Components
13
| | |-- layouts/ # Master pages
14
| | |-- accounts/ # Authentication pages
15
| | |-- home/ # UI Kit Pages
16
| |
17
| config.py # Set up the app
18
| __init__.py # Initialize the app
19
|
20
|-- requirements.txt # Dendencies - SQLite storage
21
|-- requirements-mysql.txt # Dendencies - Mysql DMBS
22
|-- requirements-pqsql.txt # Dendencies - PostgreSql DMBS
23
|
24
|-- Dockerfile # Deployment
25
|-- docker-compose.yml # Deployment
26
|-- gunicorn-cfg.py # Deployment
27
|-- nginx # Deployment
28
| |-- appseed-app.conf # Deployment
29
|
30
|-- .env # Inject Configuration via Environment
31
|-- run.py # Start the app - WSGI gateway
32
|
33
|-- ******************************
Copied!

App Bootstrap Flow

  • run.py loads the .env file
  • Initialize the app using the specified profile: Debug or Production
    • If env.DEBUG is set to True the SQLite storage is used
    • If env.DEBUG is set to False the specified DB driver is used (MySql, PostgreSQL)
  • Call the app factory method create_app defined in apps/**init**.py
  • Redirect the guest users to Login page
  • Unlock the pages served by home blueprint for authenticated users
.env (saved in the root of the project)
1
# File: `.env`
2
​
3
DEBUG=True # Enable/Disable the development environment
4
​
5
SECRET_KEY=S3cr3t_Key # The Key used by Flask to encrypt session information
6
​
7
# Database production settings (If DEBUG=False)
8
​
9
DB_ENGINE=postgresql # DBMS
10
DB_NAME=appseed-flask # Database Name
11
DB_HOST=localhost # Database Host
12
DB_PORT=5432 # Database Port
13
DB_USERNAME=appseed # DB Username
14
DB_PASS=pass # DB Password
Copied!
run.py (simplified version)
1
# File: run.py
2
​
3
DEBUG = config('DEBUG', default=True)
4
​
5
# Create the WSGI app, using the app factory pattern
6
app = create_app( app_config )
7
​
8
# Migrate automatically the app using Flask Migrate library
9
Migrate(app, db)
Copied!
apps/__init__.py (simplified version)
1
# File: apps/__init__.py
2
​
3
db = SQLAlchemy() # Invoke SQLAlchemy
4
login_manager = LoginManager() # Invoke Login Manager
5
​
6
def register_extensions(app):
7
db.init_app(app) # Inject SQLAlchemy magic
8
login_manager.init_app(app) # Add Login Manager to the app
9
​
10
# Register app blueprints: `authentication`, `home`
11
def register_blueprints(app):
12
for module_name in ('authentication', 'home'):
13
module = import_module('app.{}.routes'.format(module_name))
14
app.register_blueprint(module.blueprint)
15
​
16
# Create the tables (automatically)
17
def configure_database(app):
18
​
19
@app.before_first_request
20
def initialize_database():
21
db.create_all()
22
​
23
# Create the WSGI app using the factory pattern
24
def create_app(config):
25
app = Flask(__name__)
26
app.config.from_object(config)
27
register_extensions(app)
28
register_blueprints(app)
29
configure_database(app)
30
return app
Copied!
The apps/__init__.py constructs the app by putting together a short-list of things:
  • Invoke SQLAlchemy
  • Invoke and inject the Login Manager into the app
  • Load the configuration from config.py file
  • Register the app blueprints
  • Check if the database tables are created
  • return the WSGI app

App Codebase

The starter defines two blueprints:
  • Home blueprint - serve HTM pages for authenticated users
  • Authentication blueprint - handles the login, logout, and registration flow
Apps / Authentication Blueprint structure
1
< PROJECT ROOT >
2
|
3
|-- apps/
4
| |
5
| |-- authentication/ # Handles auth routes (login and register)
6
| |-- routes.py # Define authentication routes
7
| |-- models.py # Defines models
8
| |-- forms.py # Define auth forms (login and register)
9
|
10
|-- **************************
Copied!
Apps / Home Blueprint structure
1
< PROJECT ROOT >
2
|
3
|-- apps/
4
| |
5
| |-- home/ # A simple app that serve HTML files
6
| | |-- routes.py # Define app routes
7
| |
8
| |-- static/
9
| | |-- <css, JS, images> # CSS files, Javascripts files
10
| |
11
| |-- templates/ # Templates used to render pages
12
| |-- includes/ # HTML chunks and components
13
| | |-- navigation.html # Top menu component
14
| | |-- sidebar.html # Sidebar component
15
| | |-- footer.html # App Footer
16
| | |-- scripts.html # Scripts common to all pages
17
| |
18
| |-- layouts/ # Master pages
19
| | |-- base-fullscreen.html # Used by Authentication pages
20
| | |-- base.html # Used by common pages
21
| |
22
| |-- accounts/ # Authentication pages
23
| | |-- login.html # Login page
24
| | |-- register.html # Register page
25
| |
26
| |-- home/ # UI Kit Pages
27
| |-- index.html # Index page
28
| |-- 404-page.html # 404 page
29
| |-- *.html # All other pages
30
|
31
|
32
|-- **************************************
Copied!

Recompile CSS

To recompile SCSS files, follow this setup:
Step #1 - Install tools
  • ​NodeJS 12.x or higher
  • ​Gulp - globally
    • npm install -g gulp-cli
  • ​Yarn (optional)
Step #2 - Change the working directory to assets folder
1
$ cd apps/static/assets
Copied!
Step #3 - Install modules (this will create a classic node_modules directory)
1
$ npm install
2
// OR
3
$ yarn
Copied!
Step #4 - Edit & Recompile SCSS files
1
$ gulp scss
Copied!
The generated files are saved in static/assets/css directory.

App Configuration

The configuration file apps/config.py defines a dual configuration controlled via the .env file ( DEBUG variable)
Debug Config - default configuration used for development
This configuration becomes active if .env file has the DEBUG file set to True
1
# Development/Debug configuration
2
​
3
# Set up the App SECRET_KEY
4
SECRET_KEY = config('SECRET_KEY', default='S#perS3crEt_007')
5
​
6
# This will create a file in <app> FOLDER
7
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'db.sqlite3')
8
SQLALCHEMY_TRACK_MODIFICATIONS = False
Copied!
During the first request, the SQLite database and tables are automatically created in the root in the project.
Hint: to visualize the SQLite database content an external tool should be installed: DB Browser for SQLite it might be a good choice.
Production Config - production configuration
This configuration becomes active if .env file has the DEBUG file set to False
1
# Production configuration
2
​
3
SESSION_COOKIE_HTTPONLY = True
4
REMEMBER_COOKIE_HTTPONLY = True
5
REMEMBER_COOKIE_DURATION = 3600
6
​
7
# PostgreSQL database
8
SQLALCHEMY_DATABASE_URI = '{}://{}:{}@{}:{}/{}'.format(
9
config( 'DB_ENGINE' , default='postgresql' ),
10
config( 'DB_USERNAME' , default='appseed' ),
11
config( 'DB_PASS' , default='pass' ),
12
config( 'DB_HOST' , default='localhost' ),
13
config( 'DB_PORT' , default=5432 ),
14
config( 'DB_NAME' , default='appseed-flask' )
15
)
Copied!
In this configuration profile, the database defaults to a PostgreSQL DBMS. Make sure the .env has the right credentials to access the database.

App Tables

The file apps/authentication/models.py (Base Blueprint) defines the table(s) used by the application. Being a simple starter, by default the following tabes are defined:
  • Table #1 - Users with fields:
    • Id - Primary key, unique
    • user - Store the username
    • email - The email address
    • password - Hashed password

App Forms

The file app/authentication/forms.py (Base Blueprint) defines the table(s) used by the application. Being a simple starter, by default the following forms are defined:
  • Form #1 - LoginForm with fields:
    • username
    • password
  • Form #2 - RegisterForm with fields:
    • username - used to authenticate
    • email - email address
    • password - used to authenticate

App Routing

The routing rules are defined by Base and Home blueprints as specified below. This is the public zone of the app.
Base Blueprint - routing file apps/authentication/routes.py
  • /login route is resolved by login() method
  • /register route is resolved by register() method
  • /logout route calls the logout_user() defined in flask_login​
Registered ERROR handlers
  • 404 Error - Page not found
  • 403 Error - Access Forbidden
  • 500 Error - Internal Error
Home Blueprint - routing file apps/home/routes.py
This blueprint will serve requested pages from apps/home/templates directory to authenticated users. The authentication status is checked by @login_required decorator.
  • /<template> route resolved by route_template().
    • If a requested page is not found a default 404 page is returned to the user

Pages & Assets

Pages and all assets defined in the UI Kits are served by the app using both blueprints:
  • Home Blueprint manage the static assets - apps/authentication/static/assets
  • Home Blueprint store the layout master pages, HTML chunks (footer. header, scripts) and login, registration pages
  • Base Blueprint serve the HTML pages (index, page-404, etc) and the rest of the pages defined in the UI kit.
1
< PROJECT ROOT >
2
|
3
|-- apps/
4
| |
5
| |-- home/ # A simple app that serve HTML files
6
| | |-- routes.py # Define app routes
7
| |
8
| |-- authentication/ # Handles auth routes (login and register)
9
| | |-- routes.py # Define authentication routes
10
| | |-- models.py # Defines models
11
| | |-- forms.py # Define auth forms (login and register)
12
| |
13
| |-- static/
14
| | |-- <css, JS, images> # CSS files, Javascripts files
15
| |
16
| |-- templates/ # Templates used to render pages
17
| |-- includes/ # HTML chunks and components
18
| | |-- navigation.html # Top menu component
19
| | |-- sidebar.html # Sidebar component
20
| | |-- footer.html # App Footer
21
| | |-- scripts.html # Scripts common to all pages
22
| |
23
| |-- layouts/ # Master pages
24
| | |-- base-fullscreen.html # Used by Authentication pages
25
| | |-- base.html # Used by common pages
26
| |
27
| |-- accounts/ # Authentication pages
28
| | |-- login.html # Login page
29
| | |-- register.html # Register page
30
| |
31
| |-- home/ # UI Kit Pages
32
| |-- index.html # Index page
33
| |-- 404-page.html # 404 page
34
| |-- *.html # All other pages
35
|
36
|-- ************************************************************************
Copied!

Data Structures

The Flask starter exposes a short-list with data structures used globally across the app:

current_user object

Constructed by Flask-Login can be used to detect if the current request is executed by an authenticated user or not. The object has global visibility and can be used in all app controllers and handlers but also in views.
How it works
app/authentication/models.py define the callback functions required by Flask-Login library:
1
# File: app/authentication/models.py
2
​
3
@login_manager.user_loader
4
def user_loader(id):
5
return User.query.filter_by(id=id).first()
6
​
7
@login_manager.request_loader
8
def request_loader(request):
9
username = request.form.get('username')
10
user = User.query.filter_by(username=username).first()
11
return user if user else None
Copied!
Usage in contoler (Sample file)
1
def sample_method(path):
2
​
3
# Redirect guests users to login page
4
if not current_user.is_authenticated:
5
return redirect(url_for('login'))
Copied!
Usage in view
1
<div class="collapse navbar-collapse" id="navigation">
2
<ul class="navbar-nav ml-auto">
3
​
4
<!-- The Usage of <current_user> object -->
5
<div data-gb-custom-block data-tag="if"></div>
6
​
7
<!-- Html chunk rendered for authenticated users-->
8
​
9
<li class="nav-item">
10
<a href="/" class="nav-link text-primary">
11
<i class="tim-icons icon-minimal-left"></i> Back to Dashboard
12
</a>
13
</li>
14
​
15
16
​
17
<div data-gb-custom-block data-tag="else">
18
​
19
<!-- Html chunk rendered for guests users-->
20
​
21
<li class="nav-item ">
22
<a href="{{ url_for('register') }}" class="nav-link">
23
<i class="tim-icons icon-laptop"></i> Register
24
</a>
25
</li>
26
<li class="nav-item ">
27
<a href="{{ url_for('login') }}" class="nav-link">
28
<i class="tim-icons icon-single-02"></i> Login
29
</a>
30
</li>
31
​
32
33
​
34
</div>
35
​
36
</ul>
37
</div>
Copied!
Last modified 1mo ago