---
# System prepended metadata

title: Heroku Deploy with Python
tags: [Heroku Deployment]

---

---
title: Heroku Deploy with Python
tags: Heroku Deployment
---


# Heroku Deployment with Python App


## Prerequisites
- [Git installation instruction](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
- [Heroku CLI installation instruction](https://devcenter.heroku.com/articles/heroku-cli)
- Sign up a Heroku account
- Python version > 3.6


## Main Process

#### Tracking your app with Git
If you have a ready-to-use Python app, you need to initialize a local Git repository and commit your application code to it.
```bash
$ git init
$ git add .
$ git commit -m "First commit"
```

:::danger
Be sure to initialize the Git repository in your app’s root directory. If your app is in a subdirectory of your repository, it won’t run when it is pushed to Heroku.
:::

:::success

If you do not have an app, let's use one that Heroku provide for testing purposes so we can learn the process:

```bash
$ git clone https://github.com/heroku/python-getting-started.git
```
:::

Your app’s code is now tracked in a local Git repository. It has not yet been pushed to any remote servers.
Move into the directory of your app:
```bash
$ cd python-getting-started
```
Install a web server called **Gunicorn** within your app:
```bash
$ pip install gunicorn
```
#### Expected files for Python app deployement
Heroku automatically identifies your app as a Python app if any of the following files are present in its root directory:

* requirements.txt
* setup.py
* Pipfile

If none of these files is present in your app’s root directory, the Python buildpack will fail to identify your application correctly. Now, add your app requirements:

```bash
$ pip freeze > requirements.txt
```


Create a new file with the name: **Procfile** no file extension within your app. Read more on [Procfile](https://devcenter.heroku.com/articles/procfile).
Add to the Procfile the following commands:
```bash
$ web: gunicorn gettingstarted.wsgi
```
Your app will have a different setup i.e:
```bash
$ web: gunicorn app:app
```
The above command tells Heroku to start the web server along with the module and application names.

Install the requirements for your app:
```bash
$ pip install -r requirements.txt
```

### Creating a Heroku remote 
Git remotes are versions of your repository that live on other servers. You deploy your app by pushing its code to a special Heroku-hosted remote that’s associated with your app.

#### For a new Heroku App
The `heroku create CLI` command creates a new empty application on Heroku, along with an associated empty Git repository. If you run this command from your app’s root directory, the empty Heroku Git repository is automatically set as a remote for your local repository.

```bash
$ heroku create <app_name>
```
You can use the git remote command to confirm that a remote named heroku has been set for your app:

```bash
$ git remote -v
```

#### For an existing Heroku App
If you have already created your Heroku app, you can easily add a remote to your local repository with the `heroku git:remote` command. All you need is your Heroku app’s name:
```bash
heroku git:remote -a thawing-inlet-61413
```

:::info
### Renaming remotes (Optional)
By default, the Heroku CLI names all of the Heroku remotes it creates for your app `heroku`. You can rename your remotes with the git remote rename command:
```bash
git remote rename heroku heroku-staging
```
Renaming your Heroku remote can be handy if you have multiple Heroku apps that use the same codebase (for example, the staging and production versions of an app). In this case, each Heroku app has its own remote in your local repository.

The remainder of this article assumes your app has a single Heroku remote that is named **`heroku`**.
:::

### Deploying 
To deploy your app to Heroku, you typically use the git push command to push the code from your local repository’s master branch to your heroku remote, like so:
```bash
$ git push heroku master
```
Use this same command whenever you want to deploy the latest committed version of your code to Heroku.

Note that Heroku only deploys code that you push to the master branch of the heroku remote. Pushing code to another branch of the remote has no effect.


You may need to ensure that at least one instance of your app is up and live:
```bash
$ heroku ps:scale web=1
```
The URL where your app is lve will be displayed or else you can open it in your browser:
```bash
$ heroku open
```
If you'd like to debug some issues, you can view the logs for your app in the CLI:
```bash
$ heroku logs --tail
```
Your app is now live on Heroku for you to test and share with others!

## Connect your app with database - Heroku Posgress
So far, your Python application is served, but without any database connection. If your app is implemented using database, then any database operations performed on the deployed server will likely to show **500 - Internal Server Error**.
### Provisioning Heroku Postgress
Before you provision Heroku Postgres, confirm that it isn’t already provisioned for your app (Heroku automatically provisions Postgres for apps that include certain libraries, such as the pg Ruby gem).

Use the `heroku addons` command to determine whether your app already has Heroku Postgres provisioned:
```bash
$ heroku addons

Add-on                                                      Plan       Price  State
──────────────────────────────────────────────────────────  ─────────  ─────  ───────
heroku-postgresql (postgresql-concave-52656)                hobby-dev  free   created
```


If heroku-postgresql doesn’t appear in your app’s list of add-ons, you can provision it with the following CLI command:

```bash
heroku addons:create heroku-postgresql:<PLAN_NAME>
```

For example, to provision a `hobby-dev` plan database:
```bash
$ heroku addons:create heroku-postgresql:hobby-dev

Creating heroku-postgresql:hobby-dev on ⬢ sushi... 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-concave-52656 as DATABASE_URL
```
:::info
**Optional**: You can specify the version of Postgres you want to provision by including the --version flag in your provisioning command:
```bash
heroku addons:create heroku-postgresql:<PLAN_NAME> --version=9.5
```
:::

Depending on the plan you choose, your database can take up to 5 minutes to become available. You can track its status with the `heroku pg:wait` command, which blocks until your database is ready to use.

As part of the provisioning process, a `DATABASE_URL`config var is added to your app’s configuration. This contains the URL your app uses to access the database. 

To use it within your Python application, for example, Flask-SQLAlchemy application, add this to your .py files that runs the config:
```python
DATABASE_URL = os.environ['DATABASE_URL']
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URL
```
:::info
### Understanding the Heroku Postgres plan (Optional)
Heroku Postgres offers a variety of plans, spread across different tiers of service: **hobby, standard, premium, and enterprise**. The **hobby** plan is free with 10,000 limit of records. For more information on what each plan provides, see [Choosing the Right Heroku Postgres Plan](https://devcenter.heroku.com/articles/heroku-postgres-plans).

Pricing information for Heroku Postgres plans is available on the [Heroku Postgres add-on page](https://elements.heroku.com/addons/heroku-postgresql).

If your app’s requirements eventually outgrow the resources provided by the initial plan you select, you can easily upgrade your database.
:::

### Migrate/Upgrade the Postgres database on Heroku server
To check again whether your application is connected to the deployed Postgres, using the command:
```
$ heroku addons

Add-on                                       Plan       Price  State  
───────────────────────────────────────────  ─────────  ─────  ───────
heroku-postgresql (postgresql-rugged-70692)  hobby-dev  free   created
 └─ as DATABASE
```

But till this point, your connected Posgres database is not upgraded to be compatible with your Python application (i.e. The schema is not created yet). 

The next step you need to do is upgrading the Heroku's Postgres database, using this command:

```bash
heroku run flask db upgrade
```

The `heroku run` command executes the exact code we use locally, but instead on the Heroku server. For more information, read [Heroku run command](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-run).


:::success
## After all the steps, your Python application can run successfully now. :+1: 
:::

## References 
- https://dev.to/davedodea/how-to-deploy-a-python-app-toheroku-5djn
- https://devcenter.heroku.com/articles/git
- https://devcenter.heroku.com/articles/heroku-postgresql#connecting-in-python