Create a Web App and Deploy to the Cloud in 20 minutes with Python
Tags: python, programming, database, codenewbie
Published: 2021-02-11 15:28:11

---
cover_image: https://blog.arctype.com/content/images/2021/02/postgres-heroku-1.png
title: Create a Web App and Deploy to the Cloud in 20 minutes with Python
published: true
date: 2021-02-11 15:30:00 UTC
tags: Python, Programming, Databases, Codenewbie
canonical_url: https://blog.arctype.com/postgres-heroku/?utm_campaign=postgres-heroku&utm_medium=blog&utm_source=dev.to
---
![Create a Web App and Deploy it to the Cloud in 20 minutes with Python](https://blog.arctype.com/content/images/2021/02/heroku-example.gif)<figcaption>SQL Editor: <a href="https://arctype.com?utm_campaign=postgres-heroku&amp;utm_medium=blog&amp;utm_source=dev.to">Arctype</a></figcaption>

If you’ve been looking to deploy your first web app to the cloud, this is a great place to start!

In this tutorial, I'm going to show how to make the web app and database shown in the gif above, and how to deploy it to Heroku so it can be used by anyone.

The article is divided in 3 sections:

1. Creating a Flask app (web application for submitting the form)
2. Setting up a Postgres database with Python (store the data from the submitted forms)
3. Deploying the application to Heroku (hosting the application in the cloud so anyone can use it)

I provide a brief overview of each technology at the beginning of each section, so do not be deterred if you aren't familiar with some of these. 

### Technical Requirements

This guide is targeted towards beginner to intermediate programmers with some familiarity with programming and using the command line.

You will need the following to get started:

- **PostgreSQL**: You need to [download and install Postgres](https://www.postgresql.org/download/) on your local computer.
- **Python 3.6 or newer**: Python installers for different versions and OS are available for download  [here](https://www.python.org/).
- **Heroku Account**: You need to [create a free Heroku account](https://signup.heroku.com/) if you do not already have one. This is where we will deploy the flask app and connect it to a remote Postgres database.

Once you have all the above installed, we can start by setting up our development environment.

## Creating a Flask App for a Registration Form

![Create a Web App and Deploy it to the Cloud in 20 minutes with Python](https://blog.arctype.com/content/images/2021/02/flask_demo.gif)<figcaption>Flask app example</figcaption>

In this section, we're going to create the Flask app shown above.

I’ve already created an example Flask app that renders a simple registration form used to collect information from a user.

Flask is one of the most popular web frameworks written in Python. The flask application I made first makes a request to the endpoints defined in the `app/routes.py` file to retrieve the data that is displayed in the registration form.

It then renders the HTML pages contained in the `Template` folder using the [Jinja Template library](https://jinja.palletsprojects.com/en/2.11.x/templates/).

Instead of starting from scratch, let’s make a copy of the Flask app I created by cloning the Github repo.

Open a command line tool and run the following commands:

```
git clone https://github.com/ToluClassics/Web_Registration_Form.git
cd web_registration_form
```

If you ever get lost, you can view the completed project here: [Flask-Postgres App](https://github.com/ToluClassics/flask_postgres)

Next we’re going to create a virtual environment for this project and install the required dependencies. A virtual environment is an isolated environment for different Python projects. They are helpful to keep packages and dependencies separate between different projects.

Depending on your computer’s operating system, run the following commands:

```
Windows:
$ python3 -m venv env
$ source env/scripts/activate
(env) $ pip install -r requirements.txt


MacOS and UNIX:
$ python -m venv env
$ source env/bin/activate
(env) $ pip install -r requirements.txt
```

To test if our environment is properly set up, let’s try launching the application by entering `flask run` in the virtual environment.

```
(env) derekxiao@Dereks-MBP Web_Registration_Form % flask run
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

Now you can enter the URL above in any browser and view the web form!

### Adding input validations for the registration form

To get more familiar with the code, let’s add input validations to the form class.

We want our app to prevent users from filling out the form with the same username or email address multiple times.

With `wtforms`, you can create a custom validator that is automatically added to each field by creating a method with the name `validate_<field_name>`. In the `app/form.py` file, we will add two methods `validate_email` and `validate_username`. We will query the Registrations table (we’ll create this table later) username and email entered by the user. If it returns a value , we will raise a validation error.

Open the `form.py` file and first import Registrations from the `models.py` file (we'll add this file later).

```
from app.models import Registration
```

And in the `RegistrationForm` class add the following validation methods:

```
def validate_email(self, email):
	user = Registration.query.filter_by(email = email.data).first()
	if user is not None:
		raise ValidationError('Please use a different email address')
    
def validate_username(self, username):
	user = Registration.query.filter_by(username = username.data).first()
	if user is not None:
		raise ValidationError('Please use a different email address')
```

Now let's add in the `models.py` file so we can test the input validation.

## Creating a PostgreSQL Database

First we need to create the database that `models.py` will connect to.

For this tutorial we'll be using a PostgreSQL database. PostgreSQL is an open source, [object-relational database](https://blog.arctype.com/postgres-ordbms-explainer?utm_campaign=postgres-heroku&utm_medium=blog&utm_source=dev.to). And the best part, it’s completely free.

Let’s start by creating a new Postgres database to store the data from submitted registration forms. If you already have a Postgres database, feel free to jump to the next section to start connecting your Flask app to the database.

If you haven’t yet, first [download and install Postgres](https://www.postgresql.org/download/) on your computer.

Now open a new command line window and type `psql`. `psql` is a terminal-based interface to manage your Postgres databases.

Run the command `create database [database name];` to create a new database.

Below is a list of popular `psql` commands to manage your database:

- `\l` : list all available databases
- `dt` : list all tables
- `\d table_name`: describe a table, showing its columns, column type e.t.c
- `\du` : list all users and their roles.
- `\?`: get a list of all psql commands`\q`: to quit psql terminal

Alternatively, you can avoid memorizing the different psql commands and use Arctype's [**free SQL editor**](https://arctype.com?utm_campaign=postgres-heroku&amp;utm_medium=blog&amp;utm_source=dev.to) that provides a modern interface for managing both Postgres and MySQL databases:

![Create a Web App and Deploy it to the Cloud in 20 minutes with Python](https://blog.arctype.com/content/images/2021/02/arctype_demo.gif)<figcaption><a href="https://arctype.com?utm_campaign=postgres-heroku&amp;utm_medium=blog&amp;utm_source=dev.to">Try Arctype Today</a></figcaption>

## Connecting a Flask app to a Local Postgres Database

Next we'll create the database connection to our new Postgres database that will be used inside our `models.py` file. To get started, there are 3 packages to install:

- `flask-sqlalchemy`: A python extension for managing databases
- `flask-migrate`: For making updates to an existing database
- `Pyscopg2`: A Postgresql database adapter for python

In the activated virtual environment terminal run `(env) $ pip install flask-sqlalchemy flask-migrate pyscopg2` to install the packages listed above. If you hit an error installing `pyscopg2`, you may need to install `psycopg2-binary` instead.

The following sections I'll show how to use each package to configure and integrate our Postgres database with our Flask application. The end result will be a Flask app that is able to add new entries to a Postgres table.

### Manage Postgres databases from Python with SQLAlchemy

SQLAlchemy is a library that provides a way to seamlessly integrate python programs and databases. We will use SQLAlchemy as an Object Relational Mapper to convert python classes to tables in our Postgres database.

Flask-SQLAlchemy automatically translates the created models to the syntax of any database (Postgres in our case).

To interact with our database from the application, We need to add the following configuration variables to the config file:

- `SQLALCHEMY_DATABASE_URI`: this is the connection string that tells our Flask app which database to connect to. The usual form of the postgres database connection string is `postgresql://localhost/[YOUR_DATABASE_NAME]`. If your Postgres user has a password, you will need to use a different [URI variant](https://www.postgresql.org/docs/9.3/libpq-connect.html#:~:text=The%20general%20form%20for%20a,param1%3Dvalue1%26...%5D&text=Percent%2Dencoding%20may%20be%20used,words%20listed%20in%20Section%2031.1.).
- `SQLALCHEMY_TRACK_MODIFICATIONS`: We set this to `False` so we do not get a warning from flask every time we make a change to the application.

To make the above changes, open the `config.py` file and add the following variables to the `Config` class:

```
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI') or \
    'postgresql://localhost/[YOUR_DATABASE_NAME]'

SQLALCHEMY_TRACK_MODIFICATIONS = False
```

In the next session, we'll use the `flask-migrate` package to seamlessly handle changes to our database structure.

### Setting up Flask-Migrate to Manage Database Structures

As we scale our application, we may need to make structural changes to our tables without losing all the data already in the database. [Flask-Migrate](https://flask-migrate.readthedocs.io/) is a python extension that handles SQLAlchemy database migrations automatically using Alembic. It also supports multiple database migrations and other functionalities.

Now, we will add a database object that represents our database and also create an instance of the migration class to handle database migrations.

Open the `app/ __init__.py` and first import the flask-migrate and SQLAlchemy packages:

```
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
```

Then add the following variables:

```
db = SQLAlchemy(app) ## Create DB object
migrate = Migrate(app,db) ## Create migration object
```

### Set up the PostgreSQL database model

Now we're finally ready to create the `models.py` file to set up our database model. Database models are used to represent tables and their structures in the database; they determine the schema of the table.

`models.py` will define the structure of our tables and other necessary table information.  We need to create a model (Class) whose attributes are the same as the data fields we intend to store in the database tables.

Inside the `app` directory, create a new file called `models.py` and first import the db instance that we created in the previous section: `from app import db`.

Then create a class with the attributes for each data field in the registration form:

```
class Registration(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    first_name = db.Column(db.String(64))
    last_name = db.Column(db.String(64))
    username = db.Column(db.String(64))
    company = db.Column(db.String(64))
    contact_no = db.Column(db.String(64))
    email = db.Column(db.String(120), index=True, unique=True)
    
    def __repr__ (self):
        return '<User {}>'.format(self.username)
```

The last step is importing the model in the `app\ __init__.py` file: `from app import models`.

If you are working with your own database, we've created a free tool to [design database schemas](https://blog.arctype.com/erd-builder?utm_campaign=postgres-heroku&utm_medium=blog&utm_source=dev.to).

### Creating a new Registrations table in Postgres using Flask

Next, we will instantiate the database from the command line by running `flask db init` in the virtual environment.

First ensure that your `FLASK_APP` environment variable is set before you run this command. You can run the following commands to check:

```
(env) $ python                   
Python 3.8.2 (default, Dec 21 2020, 15:06:04) 
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print(os.environ['FLASK_APP'])
app.py
>>> quit()
```

After you run `flask db init` you should see the following output:

```
(env) $ flask db init
	Creating directory /Users/mac/Desktop/Web_Registration_Form/migrations ... done
  Creating directory /Users/mac/Desktop/Web_Registration_Form/migrations/versions ... done
  Generating /Users/mac/Desktop/Web_Registration_Form/migrations/script.py.mako ... done
  Generating /Users/mac/Desktop/Web_Registration_Form/migrations/env.py ... done
  Generating /Users/mac/Desktop/Web_Registration_Form/migrations/README ... done
  Generating /Users/mac/Desktop/Web_Registration_Form/migrations/alembic.ini ... done
  Please edit configuration/connection/logging settings in
  '/Users/mac/Desktop/Web_Registration_Form/migrations/alembic.ini' before proceeding.
```

From the command logs, we can see that a migrations folder is created in our application. This folder contains files that are needed to migrate tables and update table schemas on our database.

Now that we have a migrations repository, it’s time to migrate the Registration table to the database using the `flask-migrate` extension.

Ensure that your Postgres server is up, then run the `flask db migrate` command to automatically migrate our SQLAlchemy database to the Postgres database that we assigned earlier with the URI in the config file.

```
(env) $ flask db migrate -m "registrations table"
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'registration'
INFO [alembic.autogenerate.compare] Detected added index 'ix_registration_email' on '['email']'
  Generating /Users/mac/Desktop/Web_Registration_Form/migrations/versions/eccfa5d8a3f6_registrations_table.py ... done
```

`flask db migrate` does not make any changes to the database, it only generates the migration script. To make the changes, we use the `flask db upgrade` command. You can also revert the changes by using `flask db downgrade`.

```
(env) $ flask db upgrade
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> eccfa5d8a3f6, registrations table
```
Now we can open Arctype and check if the table was successfully migrated to the local Postgres database

![Create a Web App and Deploy it to the Cloud in 20 minutes with Python](https://blog.arctype.com/content/images/2021/02/Screen-Shot-2021-02-10-at-4.50.06-PM.png)<figcaption><a href="https://arctype.com?utm_campaign=postgres-heroku&amp;utm_medium=blog&amp;utm_source=dev.to">Get Started with Arctype for Free</a></figcaption>

## Inserting Data From a Flask App in Postgres

In this section, we'll update our route function to add the data collected from the webpage to the website.

First, we will update our imports by including our database instance and table model in the `app\routes.py` file:

```
from app.models import Registration
from app import db
from flask import redirect, url_for
```

In the route function, we will create an instance of the `Registration` class and update it with information collected from the form. We then proceed to add and commit the instance to the database.

Add the following if statement inside the `index()` function in `routes.py`:

```
if form.validate_on_submit(): 
        reg_form = Registration(username=form.username.data,email=form.email.data, first_name=form.first_name.data,last_name=form.last_name.data, company=form.company.data,contact_no=form.contact_no.data)
        db.session.add(reg_form)
        db.session.commit()
        return redirect(url_for('index'))
```

## Testing if the Flask App is Inserting Data in Postgres

Let's test our application locally one more time before deploying to Heroku:

```
(env) $ flask run
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

Navigate to [http://127.0.0.1:5000/](http://127.0.0.1:5000/) and submit the form.

After submitting the form, you can check that a new entry was added to your database by checking the Registrations table in Arctype:

![Create a Web App and Deploy it to the Cloud in 20 minutes with Python](https://blog.arctype.com/content/images/2021/02/postgres_update.gif)<figcaption><a href="https://arctype.com?utm_campaign=postgres-heroku&amp;utm_medium=blog&amp;utm_source=dev.to">Try Arctype Today</a></figcaption>

## Deploying the Flask app and Postgres Database to Heroku

Now that we have tested our application locally, it's time to deploy the application and our Postgres database to Heroku so we can access it from anywhere.

The first step is [downloading and installing the Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli).

Then we can log into Heroku from the command line with: `Heroku login`

Once we're logged in, we can [create a new app on Heroku](https://devcenter.heroku.com/articles/creating-apps) with by running: `Heroku create [app-name]`. Heroku apps are in a global namespace, therefore you need to choose a unique name for your application. If you do not specify a name for your application, Heroku will generate a random name for your application.

```
(env) $ Heroku create arctype-registration-app
Creating ⬢ arctype-registration-app... done
https://arctype-registration-app.herokuapp.com/ | https://git.heroku.com/arctype-registration-app.git
```

To proceed with development, we need to update our `requirements.txt` file and create a `Procfile` in our root directory. The `Procfile` is used to declare the commands run by the app on Heroku.

Next, we need to install `gunicorn` which is a python server needed to run the application on Heroku. In the activated python environment, run `pip install gunicorn` to install the `gunicorn` package.

Run `pip freeze > requirements.txt` to update the requirements file. The [`procfile`](https://devcenter.heroku.com/articles/procfile#procfile-naming-and-location) defines processes based using the following format `<process type>: <command>`. Since our application contains a web server (gunicorn), the process type is web and the command will launch the gunicorn server. Therefore, we need to run the command below on the terminal to create the Procfile:

`echo web: gunicorn app:app > Procfile`

Heroku has different[service plans](https://devcenter.heroku.com/articles/heroku-postgres-plans#hobby-tier) for its postgresql offering. Choosing a plan for your application depends on the characteristics of your application and its bandwidth for service downtimes. In this tutorial we will use the [hobby-dev plan](https://devcenter.heroku.com/articles/heroku-postgres-plans#hobby-tier), which is free and serves the purpose we need it for.

Now, we will create a hobby-dev postgres database for our application using the `heroku addons:create heroku-postgresql:hobby-dev --app app-name` command:

```
(env) $ heroku addons:create heroku-postgresql:hobby-dev --app arctype-registration-app
Creating heroku-postgresql:hobby-dev on ⬢ arctype-registration-app... free
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-slippery-96960 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
```

More information on working with postgres databases can be [found here](https://devcenter.heroku.com/articles/heroku-postgresql#connecting-in-python).

Now that we have created a remote postgres database for our application on Heroku, we need to update the `SQLALCHEMY_DATABASE_URI` variable in the `config.py` file with the new database URI. To retrieve the remote database URI, we use the `heroku config --app app-name` command.

Once the URI is updated, the final step is deploying our application to Heroku's servers.

First, we will commit all our files and push to the heroku master branch. Run `git add .` and `git commit -m “heroku commit”`, then `git push heroku main` to deploy to Heroku.

Your app is now live at [`https://your-app-name.herokuapp.com`](https://app-name.herokuapp.com)!

![Create a Web App and Deploy it to the Cloud in 20 minutes with Python](https://lh3.googleusercontent.com/eCvMandZdVanuwd0xAYoAkNxVMHJ6NrgxpxULMXnSmy8km7llhZ7t5RzMgbMCyN2KcbuTm5x2w0dEa9Am94zYqFx8j_06lgCN315RBI6OklH8VP0yazgc72AsO6hoLF0z_CHeuqz)

## Migrating Tables from a Local Postgres Database to Heroku

The last step is migrating the Registrations table that we created in our local Postgres database to the new Heroku database instance. We can do this by running `db create_all()` from the heroku python terminal:

```
(env) $ heroku run python
Running python on ⬢ arctype-registration-app... up, run.9023 (Free)
Python 3.6.12 (default, Sep 29 2020, 17:50:28) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from app import db
>>> db.create_all()
```

To check if the Registrations table was successfully created, connect to the Heroku database from Arctype and you should see the Registrations table.

## Congratulations!

You are now the proud owner of a web app that anyone with internet access can use, from anywhere in the world. Lets zoom out and review what we covered:

1. How a Flask app works
2. Creating a Postgres database
3. Creating a database model in Python using SQLAlchemy
4. Migrating a database in Python using flask-migrate
5. Inserting data into a Postgres database from a Flask app
6. Deploying a Flask app and Postgres database to Heroku

Postgres is a powerful database that is used by large tech companies across the world. [Arctype](https://arctype.com?utm_campaign=postgres-heroku&utm_medium=blog&utm_source=dev.to) is a free SQL editor that makes working with databases easier. [Try Arctype for free today](https://arctype.com?utm_campaign=postgres-heroku&utm_medium=blog&utm_source=dev.to).