Flask Backend Application Setup
Tags: python, webdev, flask, webpack
Published: 2021-08-22 18:20:00

Hello.! I hope you are doing great. In the last post we setup our application folder structure and in this one we are setting the backend for our application.

First create <kbd>.env</kbd> file in the root of the folder and add our environment variables to this file.

```.env
SECRET_KEY = "abcdefgh"
FLASK_APP = run.py
FLASK_ENV= development # production/development


# Define the database
# Flask-SQLAlchemy
SQLALCHEMY_DATABASE_URI = "mysql+mysqlconnector://DB_USERNAME:DB_PASSWORD@127.0.0.1:3306/DB_DATABASE"
SQLALCHEMY_TRACK_MODIFICATIONS = False

# Static Assets
STATIC_FOLDER_PATH = "/assets"
STATIC_FOLDER = "assets"
TEMPLATES_FOLDER = "views"
UPLOAD_FOLDER = "application/assets/uploads"
```

Now get a detailed look on the environment variables.

**SECRET_KEY**
A secret key that will be used for securely signing the session cookie and can be used for any other security related needs by extensions or your application. 

**FLASK_APP**
The FLASK_APP environment variable is used to specify how to load the application.

**FLASK_DEBUG**
What environment the app is running in. Flask and extensions may enable behaviors based on the environment, such as enabling debug mode.

**SQLALCHEMY_DATABASE_URI**
The database URI that should be used for the connection.

**SQLALCHEMY_TRACK_MODIFICATIONS**
If set to True, Flask-SQLAlchemy will track modifications of objects and emit signals. The default is None, which enables tracking but issues a warning that it will be disabled by default in the future. This requires extra memory and should be disabled if not needed.

**STATIC_FOLDER_PATH**
can be used to specify a different path for the static files on the web. Defaults to the name of the STATIC_FOLDER folder.

**STATIC_FOLDER**
The folder with static files that is served at STATIC_FOLDER_PATH. Relative to the application root_path or an absolute path. Defaults to 'static'.

**TEMPLATES_FOLDER**
The folder that contains the templates that should be used by the application. Defaults to 'templates' folder in the root path of the application.

**UPLOAD_FOLDER**
The folder that is responsible for our file uploads.

Now open <kbd>config.py</kbd> and create Config class on it and add class properties which reads data from the <kbd>.env</kbd>.


```python
import os
from os import environ


class Config:
    # General Config
    SECRET_KEY = environ.get('SECRET_KEY')
    FLASK_APP = environ.get('FLASK_APP')
    FLASK_DEBUG = environ.get('FLASK_DEBUG')

    BASE_DIR = os.path.abspath(os.path.dirname(__file__))

    # Static Assets
    STATIC_FOLDER_PATH = environ.get('STATIC_FOLDER_PATH')
    STATIC_FOLDER = environ.get('STATIC_FOLDER')
    TEMPLATES_FOLDER = environ.get('TEMPLATES_FOLDER')
    UPLOAD_FOLDER = environ.get('UPLOAD_FOLDER')

    # Flask-SQLAlchemy
    SQLALCHEMY_DATABASE_URI = environ.get('SQLALCHEMY_DATABASE_URI')
    SQLALCHEMY_TRACK_MODIFICATIONS = bool(environ.get('SQLALCHEMY_TRACK_MODIFICATIONS'))
```

So in the <kbd>config.py</kbd> BASE_DIR is use to store the root path of the application folder for use in the future.

Now open application/__init__.py file and start the configuring application. First import the required modules.

```python
from dotenv import load_dotenv
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
```

after that load the ENV variables

```python
load_dotenv()
```
Now set the database constraints names for forigen keys, primary keys and other constrants. Make a dictionary of python.

```python
convention = {
    "ix": 'ix_%(column_0_label)s',
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(column_0_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}
metadata = MetaData(naming_convention=convention)
``` 
After that initialize the SQLAlchemy and the Migrate objects.

```python
db = SQLAlchemy(metadata=metadata)
migrate = Migrate()
```
So at this time our __init__.py file looks like this.

```python
from dotenv import load_dotenv
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
from flask_debugtoolbar import DebugToolbarExtension

load_dotenv()

convention = {
    "ix": 'ix_%(column_0_label)s',
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(column_0_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}
metadata = MetaData(naming_convention=convention)

db = SQLAlchemy(metadata=metadata)
migrate = Migrate()
```

Now open a <kbd>application/settings.py</kbd> file and import the moduels.

```python
from flask import Flask
import os

import config
from application import (
    db,
    migrate
)
```

So we create __init__.py in our application folder so this will make application a python package so in the last we use from statement with application and which db or migrate objects we created in the __init__.py so we are now importing from the applictaion.

Create a <kbd>home.py</kbd> file in our controllers folder and use flask blueprint to create a blueprint for our first route.

```python
from flask import Blueprint, render_template

controller = Blueprint('home', __name__)

@controller.route('/', methods=['GET'])
def index():
    return "Home Controller"
```

Now Create a <kbd>user.py</kbd> file in models folder to create our first model. This will be SQLAlchemy model and also uses for our migartions also.

User class will be extend with db.Model and here we have a special property name __ tablename __ which is use to change the tablename otherwise without __ tablename __ table name will be the class name.

```python
from application import db


class User(db.Model):

    __tablename__ = 'users'

    id = db.Column(
        db.Integer,
        primary_key=True
    )

    name = db.Column(
        db.String(255),
        nullable=False
    )

    email = db.Column(
        db.String(255),
        unique=True,
        nullable=False
    )

    password = db.Column(
        db.String(255),
        nullable=False
    )

    role = db.Column(
        db.String(50),
        nullable=False,
        server_default="user"
    )

    created_at = db.Column(
        db.DateTime,
        server_default=db.func.now(),
        nullable=False
    )

    updated_at = db.Column(
        db.DateTime,
        server_default=db.func.now(),
        nullable=False
    )

```

So Now we have our controller and the model so we can now register those in our applciation.

Now open <kbd>settings.py</kbd> and create three functions in the file first one will be the <kbd>register_blueprints</kbd>,  <kbd>import_models</kbd> and <kbd>initialize_plugins</kbd>.

In the <kbd>register_blueprints</kbd> function import the controller from the controllers and register that controller.

```python
def register_blueprints(app):
    from application.controllers import (
        home
    )

    app.register_blueprint(home.controller)
```

In the <kbd>import_models</kbd> function import the models from the Models and register them in this function.

```python
def import_models():
    # import database models
    from application.models import (
        user
    )
```

Last but not least we have a <kbd>initialize_plugins</kbd> which is used for initialize the flask apps to the flask like SQLAlchemy, Flask Migrate etc.

Now its time to create the our last function in this file which will be the <kbd>initialize_flask_app</kbd> which is responsible to initialize the flask app with configurations which we added in our <kbd>config.py</kbd>.

```python
def initialize_flask_app():
    # Initialize the core application.
    app = Flask(
        __name__,
        instance_relative_config=False,
        template_folder=config.Config.TEMPLATES_FOLDER,
        static_folder=config.Config.STATIC_FOLDER,
        static_url_path=config.Config.STATIC_FOLDER_PATH
    )
    app.config.from_object('config.Config')
    return app
```

**instance_relative_config** 
if set to True relative filenames for loading the config are assumed to be relative to the instance path instead of the application root.

So here I set it to False so we can load our own configs from our own location so at the 2nd last line we set flask app object and read data from the object so we use from_object function from our config file.

So our <kbd>settings.py</kbd> will look like this.

```python
def initialize_plugins(app):
    # Initialize Plugins
    db.init_app(app)
    migrate.init_app(app, db)
```

So at this moment our <kbd>settings.py</kbd> will look like this.

```python
from flask import Flask
import os

import config
from application import (
    db,
    migrate
)


def register_blueprints(app):
    from application.controllers import (
        home
    )

    app.register_blueprint(home.controller)


def initialize_plugins(app):
    # Initialize Plugins
    db.init_app(app)
    migrate.init_app(app, db)


def import_models():
    # import database models
    from application.models import (
        user
    )

def initialize_flask_app():
    # Initialize the core application.
    app = Flask(
        __name__,
        instance_relative_config=False,
        template_folder=config.Config.TEMPLATES_FOLDER,
        static_folder=config.Config.STATIC_FOLDER,
        static_url_path=config.Config.STATIC_FOLDER_PATH
    )
    app.config.from_object('config.Config')
    return app
```

Now open __init__.py file and create <kbd>create_app</kbd> function at the end of the file.

```python
def create_app():
    from application.settings import (
        initialize_flask_app,
        initialize_plugins,
        import_models,
        register_blueprints
    )
    app = initialize_flask_app()

    with app.app_context():
        # initialize plugins
        initialize_plugins(app)

        # register blueprints
        register_blueprints(app)

        # import models
        import_models()

        return app
```

After this function our init.py will look like this.

```python
from dotenv import load_dotenv
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData

load_dotenv()

convention = {
    "ix": 'ix_%(column_0_label)s',
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(column_0_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}
metadata = MetaData(naming_convention=convention)

db = SQLAlchemy(metadata=metadata)
migrate = Migrate()


def create_app():
    from application.settings import (
        initialize_flask_app,
        initialize_plugins,
        import_models,
        register_blueprints
    )
    app = initialize_flask_app()

    with app.app_context():
        # initialize plugins
        initialize_plugins(app)

        # register blueprints
        register_blueprints(app)

        # import models
        import_models()

        return app

```


firstly import all the functions from the <kbd>settings.py</kbd> file. initialize the flask app and set to the app variable.

Now we use app_context() to initialize all the functions which we imported from the <kbd>settings.py</kbd> and after that return the app obejct.

Now its time to add some code to our <kbd>run.py</kbd> to boot our applictaion.

```python
from application import create_app

app = create_app()

if __name__ == '__main__':
    app.run(host='0.0.0.0')
```

Simple import create_app function which we created in our init.py file and get call the function to get the flask object and with run method boot our application.

Now create a Database I cretaed the Database with the name of  <kbd>python_flask_blog</kbd>.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jn9ezgzwyorr2ozwhmf8.png)

and set your Database credentials in your <kbd>.env</kbd> file.

```.env
SQLALCHEMY_DATABASE_URI = "mysql+mysqlconnector://muhammadsaim:muhammadsaim@127.0.0.1:3306/python_flask_blog"
```
Now in your terminal initiate the flask migrate run this commad.

```shell
flask db init
```

This will create some migartion related configuration files in migartions folder which we created on the root folder.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a12qetv4kfe4dw8155k6.png)

Create a migration by running this command.

```shell
flask db migrate -m "Create User table."
```
This will create a file migartion version file to keep track of the changes so we can rollback to our migrations.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jftusgtv8kah5gunm44y.png)

So we commit the migrations now run this command to push this commit to the Database this will cretae the users table.

```shell
flask db upgrade
```

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chcqj67ia10sj2vaft4e.png)

And after that our table is created.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/085hq269ikkuf0kzqr00.png)

We have two tables 1st one is <kbd>alembic_version</kbd> and the other is <kbd>users</kbd> which we created but the first one is used by the migration to track the record of the migration.

Now finaly its time to run our Application for this we have to run this command.

```shell
python run.py
```  

This command will open server and give us the url where our application will be served from our development server.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olasqt2jo59ntiyjavyg.png)

Open your browser and open this link on the broswer and we get the our index route which we cretaed in our home controller after opening this we have a page with written on this **Home Controller**

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac3ctpb0kreusaj7mw9a.png)

Hurray now we have our applictaion up.

You can get the updated code on [GitHub Repo](https://github.com/MuhammadSaim/flask_tutorial_blog)

Thanks for being with me.

See you guys in next post if you have any issue while going with this post feel free to comment.