# Boilerplate Flask Apps

All Flask Apps generated by AppSeed share the same codebase structure and features

* Reference Codebase - [Flask Apps Boilerplate](https://github.com/app-generator/boilerplate-code-flask)
* SQLite database, Flask-SQLAlchemy ORM
* Session-Based auth flow (login, register)
* Deployment scripts: Docker, Gunicorn / Nginx, Heroku

## ✨ Environment

To use the starter, [Python3](https://www.python.org) should be installed properly in the workstation. If you are not sure if Python is installed, please open a terminal and type `python --version`. Here is the full list with dependencies and tools required to build the app:

* [Python3](https://www.python.org) - the programming language used to code the app
* [GIT](https://git-scm.com) - 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.
* (Optional) `Docker` - a popular virtualization software

\\

## ✨ Start the app in Docker

> 👉 **Step 1** - Download the code from the GH repository (using `GIT`)

```bash
$ # Get the code
$ git clone https://github.com/app-generator/boilerplate-code-flask.git
$ cd boilerplate-code-flask
```

> 👉 **Step 2** - Start the APP in `Docker`

```bash
$ docker-compose up --build 
```

Visit `http://localhost:5085` in your browser. The app should be up & running.

\\

## ✨ Manual Build

> Download the code

```bash
$ # Get the code
$ git clone https://github.com/app-generator/boilerplate-code-flask.git
$ cd boilerplate-code-flask
```

\\

### 👉 Set Up for `Unix`, `MacOS`

> Install modules via `VENV`

```bash
$ virtualenv env
$ source env/bin/activate
$ pip3 install -r requirements.txt
```

> Set Up Flask Environment

```bash
$ export FLASK_APP=run.py
$ export FLASK_ENV=development
```

> Start the app

```bash
$ flask run
```

At this point, the app runs at `http://127.0.0.1:5000/`.

\\

### 👉 Set Up for `Windows`

> Install modules via `VENV` (windows)

```
$ virtualenv env
$ .\env\Scripts\activate
$ pip3 install -r requirements.txt
```

> Set Up Flask Environment

```bash
$ # CMD 
$ set FLASK_APP=run.py
$ set FLASK_ENV=development
$
$ # Powershell
$ $env:FLASK_APP = ".\run.py"
$ $env:FLASK_ENV = "development"
```

> Start the app

```bash
$ flask run
```

At this point, the app runs at `http://127.0.0.1:5000/`.

\\

## ✨ Manage App `Users`

By default, the starter is not provided with users.

### 👉 Create Users

By default, the app redirects guest users to authenticate. In order to access the private pages, follow this set up:

* Start the app via `flask run`
* Access the `registration` page and create a new user:
  * `http://127.0.0.1:5000/register`
* Access the `sign in` page and authenticate
  * `http://127.0.0.1:5000/login`\\

## ✨ Codebase structure

The project is coded using a simple and intuitive structure presented below:

```bash
< PROJECT ROOT >
   |
   |-- apps/
   |    |
   |    |-- home/                           # A simple app that serve HTML files
   |    |    |-- routes.py                  # Define app routes
   |    |
   |    |-- authentication/                 # Handles auth routes (login and register)
   |    |    |-- routes.py                  # Define authentication routes  
   |    |    |-- models.py                  # Defines models  
   |    |    |-- forms.py                   # Define auth forms (login and register) 
   |    |
   |    |-- static/
   |    |    |-- <css, JS, images>          # CSS files, Javascripts files
   |    |
   |    |-- templates/                      # Templates used to render pages
   |    |    |-- includes/                  # HTML chunks and components
   |    |    |    |-- navigation.html       # Top menu component
   |    |    |    |-- footer.html           # App Footer
   |    |    |    |-- scripts.html          # Scripts common to all pages
   |    |    |
   |    |    |-- layouts/                   # Master pages
   |    |    |    |-- base-fullscreen.html  # Used by Authentication pages
   |    |    |    |-- base.html             # Used by common pages
   |    |    |
   |    |    |-- accounts/                  # Authentication pages
   |    |    |    |-- login.html            # Login page
   |    |    |    |-- register.html         # Register page
   |    |    |
   |    |    |-- home/                      # UI Kit Pages
   |    |         |-- index.html            # Index page
   |    |         |-- page-404.html         # 404 page
   |    |         |-- *.html                # All other pages
   |    |    
   |  config.py                             # Set up the app
   |    __init__.py                         # Initialize the app
   |
   |-- requirements.txt                     # App Dependencies
   |
   |-- .env                                 # Inject Configuration via Environment
   |-- run.py                               # Start the app - WSGI gateway
   |
   |-- ************************************************************************
```

\\

## ✨ Application Bootstrap Flow

The entry point of the project is the `run.py` file where the project configuration is bundled. The `most important files` that make the project functional are listed below:

* `run.py` is the application entry point
  * read the `Debug` flag from `.env`
  * import the `db` object from `apps` package
  * import the `create_app` helper from `apps`
* `Flask` application is built by `create_app`
  * If `Debug=True` - SQLite is used (development mode)
  * If `Debug=False` - SQLite is used (production mode)
* Configuration
  * is defined in `apps/config.py`

\\

## ✨ How the `Flask App` object is constructed

The file that constructs the core features of our application is `apps/__init__.py`. The most important steps are listed below:

* Invokes SQLAlchemy to build the `db` object.
  * Using `SQLAlchemy` we can manage the database information with ease
* Invokes LoginManager to build the `login_manager` object.
  * `login_manager` manage the authentication layer (login, logout, register)
* Defines `create_app` helper that does the following:
  * create the `Flask` app object
  * injects `db` and `login_manager` objects
  * loads the `configuration`
  * register `default blueprints`:
    * `authentication` - handles the authentication routes
    * `home` - serve all the pages saved in the `apps/templates/home` folder
  * initialize the database
    * `db.create_all()` - create all tables

\\

## ✨ Application Blueprints

The codebase is built using a modular design that uses `blueprints`. By default, the project comes with a two `blueprints`

### 👉 Authentication Blueprint

> Definition: `apps/authentication`. The core files:

* `__init__.py` - defines the Blueprint object
* `models.py` - defines the `Users` model
* `forms.py` - defines the `Login` and `Registration` forms
* `utils.py` - helpers used to hass and verify the password
* `routes` - manages the authentication routes:
  * `login`
  * `register`
  * `logout`

### 👉 Home Blueprint

This module returns all pages saved in the `templates/home` directory to authenticated users. In case a page is not found, a generic page is returned using a `404` HTTP error status.

\\

## ✨ UI Assets and Templates

The project comes with a modern UI fully migrated and usable with Django Template Engine.

### 👉 Page Templates

All pages and components are saved inside the `apps/templates` directory. Here are the standard directories:

* `templates/layouts`: UI masterpages
* `templates/includes`: UI components (used across multiple pages)
* `templates/accounts`: login & registration page
* `templates/home`: all other pages served via a generic routing by `apps/home` app

```bash
< PROJECT ROOT >
   |
   |-- apps/
   |    |
   |    |-- home/                      # A simple app that serve HTML files
   |    |-- authentication/            # Handles auth routes (login and register)
   |    |
   |    |-- static/
   |    |    |-- <css, JS, images>     # CSS files, Javascripts files
   |    |
   |    |-- templates/                 # Templates used to render pages
   |         |-- includes/             # HTML chunks and components
   |         |    |-- navigation.html  # Top menu component
   |         |    |-- footer.html      # App Footer
   |         |    |-- scripts.html     # Scripts common to all pages
   |         |
   |         |-- layouts/              # Master pages
   |         |    |-- base.html        # Used by common pages
   |         |
   |         |-- accounts/             # Authentication pages
   |         |    |-- login.html       # Login page
   |         |    |-- register.html    # Register page
   |         |
   |         |-- home/                 # UI Kit Pages
   |              |-- index.html       # Index page
   |              |-- page-404.html    # 404 page
   |              |-- *.html           # All other pages
   |
   |-- ************************************************************************
```

\\

### 👉 Static Assets

The static assets used by the project (`JS`, `CSS`, `images`) are saved inside the `apps/static/assets` folder. This path can be customized with ease via `ASSETS_ROOT` variable saved in the `.env` file.

> How it works

* `.env` defines the `ASSETS_ROOT` variable
* `apps/config.py` read the value of `ASSETS_ROOT` and defaults to `/static/assets` if not found:

```python
# content of apps/config.py (truncated content)

ASSETS_ROOT = os.getenv('ASSETS_ROOT', '/static/assets') 
```

* All pages and components use the `config.ASSETS_ROOT` variable. Here is a sample extracted from `templates/layouts/base.html`:

```html
<head>

    <!-- Source Code -->
    <link rel="stylesheet" href="{{ config.ASSETS_ROOT }}/css/style.css">

    <!-- RUNTIME -->
    <link rel="stylesheet" href="/static/assets/css/style.css">
```

At runtime, the `href` property is resolved to `/static/assets/css/style.css` based on the value saved in the `.env` file:

```
# No Slash at the end
ASSETS_ROOT=/static/assets
```

\\

## ✨ Customisation

### 👉 Set up the MySql Database

**Note:** Make sure your Mysql server is properly installed and accessible.

> **Step 1** - Create the MySql Database to be used by the app

* `Create a new MySql` database
* `Create a new user` and assign full privilegies (read/write)

> **Step 2** - Install `flask_mysqldb` package

```bash
$ pip install flask_mysqldb
```

> **Step 3** - Edit the `.env` to match your MySql DB credentials. Make sure `DEBUG` is set to `False`.

* `DB_ENGINE` : `mysql`
* `DB_NAME` : default value = `appseed_db`
* `DB_HOST` : default value = `localhost`
* `DB_PORT` : default value = `3306`
* `DB_USERNAME`: default value = `appseed_db_usr`
* `DB_PASS` : default value = `pass`

\\

Here is a sample:

```
# .env sample

DEBUG=False                 # False enables the MySql Persistence

DB_ENGINE=mysql             # Database Driver
DB_NAME=appseed_db          # Database Name
DB_USERNAME=appseed_db_usr  # Database User
DB_PASS=STRONG_PASS_HERE    # Password 
DB_HOST=localhost           # Database HOST, default is localhost 
DB_PORT=3306                # MySql port, default = 3306 
```

At this point, the app should use `MySql` for the persistence layer.

\\

### 👉 Static Assets for `production`

As explained in the [Static Assets](#static-assets) section, the assets are managed via:

* `apps/static/assets` - the folder where `JS`, `CSS`, and `images` files are saved
* `ASSETS_ROOT` - environment variable, that defaults to `/static/assets` if not defined

In production, the contents of the `apps/static/assets` files should be copied to an external (public) directory and the `ASSETS_ROOT` environment variable updated accordingly.

For instance, if the `static` files are copied to `https://cdn.your-server.com/datta-able-assets`, the `.env` file should be updated as below:

```
# No Slash at the end
ASSETS_ROOT=https://cdn.your-server.com/datta-able-assets
```

## 🚀 Where to go from here

* 👉 Access the [support](https://appseed.us/support/) page in case something is missing
* 👉 Use the [App Generator](https://appseed.us/generator) to generate a new project
