Getting Started with Python on Heroku

Getting Started with Python on Heroku

Table of Contents

This quickstart will get you going with a Python application that uses the Flaskweb framework, deployed to Heroku. For Django apps, please see the Getting Started with Django on Heroku.


Local workstation setup

Install the Heroku Toolbelt on your local workstation. This ensures that you have access to the Heroku command-line client, Foreman, and the Git revision control system.
Once installed, you can use the heroku command from your command shell. Log in using the email address and password you used when creating your Heroku account:
$ heroku loginEnter your Heroku credentials.Email: kenneth@example.comPassword:Could not find an existing public key.Would you like to generate one? [Yn]Generating new SSH public key.Uploading ssh public key /Users/kenneth/.ssh/
Press enter at the prompt to upload your existing ssh key or create a new one, used for pushing code later on.

Start Flask app inside a Virtualenv

First, we’ll create an empty top-level directory for our project:
$ mkdir helloflask$ cd helloflask
Next, we’ll create a Python Virtualenv (v0.7):
Make sure you’re using the latest virtualenv release. If you’re using a version that comes with Ubuntu, you may need to add the --no-site-packages flag.
$ virtualenv venv --distributeNew python executable in venv/bin/pythonInstalling distribute...............done.Installing pip...............done.
To use our new virtualenv, we need to activate it. (You must source the virtualenv environment for each terminal session where you wish to run your app.)
Windows users can runvenv\Scripts\activate.bat for the same effect.
$ source venv/bin/activate
Next, install our application’s dependencies with pip. In this case, we will be installing Flask, the web framework, and Gunicorn, the web server.
$ pip install Flask gunicornDownloading/unpacking Flask  Downloading Flask-0.9.tar.gz (481kB): 481kB downloadedDownloading/unpacking gunicorn  Downloading gunicorn-0.17.2.tar.gz (360kB): 360kB downloaded  Running egg_info for package gunicorn
Downloading/unpacking Werkzeug>=0.7 (from Flask)  Downloading Werkzeug-0.8.3.tar.gz (1.1MB): 1.1MB downloadedDownloading/unpacking Jinja2>=2.4 (from Flask)  Downloading Jinja2-2.6.tar.gz (389kB): 389kB downloaded
Installing collected packages: Flask, gunicorn, Werkzeug, Jinja2  Running install for Flask  Running install for gunicorn  Running install for Werkzeug  Running install for Jinja2
Successfully installed Flask gunicorn Werkzeug Jinja2

Now that we have a clean Flask environment to work in, we’ll create our simple application,
import os
from flask import Flask

app = Flask(__name__)

def hello():
    return 'Hello World!'

Declare process types with Procfile

Use a Procfile, a text file in the root directory of your application, to explicitly declare what command should be executed to start a web dyno. In this case, you need to execute Gunicorn with a few arguments.
Here’s a Procfile for our new app. It should be called Procfile and live at the root directory of our project:
web: gunicorn hello:app
You can now start the processes in your Procfile locally using Foreman (installed as part of the Toolbelt):
$ foreman start2013-04-03 16:11:22 [8469] [INFO] Starting gunicorn 0.14.62013-04-03 16:11:22 [8469] [INFO] Listening at: (8469)
Make sure things are working properly curl or a web browser, then Ctrl-C to exit.

Specify dependencies with Pip

Heroku recognizes Python applications by the existence of arequirements.txt file in the root of a repository. This simple format is used by most Python projects to specify the external Python modules the application requires.
Pip has a nice command (pip freeze) that will generate this file for us:
$ pip freeze > requirements.txt
$ cat requirements.txtFlask==0.9Jinja2==2.6Werkzeug==0.8.3gunicorn==0.17.2
Pip can also be used for advanced dependency management. See Python Dependencies via Pip to learn more.

Store your app in Git

Now that we’ve written and tested our application, we need to store the project in a Git repository.
Since our current directory contains a lof of extra files, we’ll want to configure our repository to ignore these files with a .gitignore file:
GitHub provides an excellent Python gitignore file that can be installed system-wide.


Next, we’ll create a new git repository and save our changes.
$ git init$ git add .$ git commit -m "init"

Deploy your application to Heroku

The next step is to push the application’s repository to Heroku. First, we have to get a place to push to from Heroku. We can do this with the heroku createcommand:
$ heroku createCreating stark-window-524... done, stack is cedar | remote heroku added
This automatically added the Heroku remote for our app ( to our repository. Now we can do a simple git push to deploy our application:
$ git push heroku masterCounting objects: 10, done.Delta compression using up to 8 threads.Compressing objects: 100% (8/8), done.Writing objects: 100% (10/10), 3.59 KiB, done.Total 10 (delta 0), reused 0 (delta 0)
-----> Heroku receiving push-----> Python app detected-----> No runtime.txt provided; assuming python-2.7.4.-----> Preparing Python runtime (python-2.7.4)-----> Installing Distribute (0.6.36)-----> Installing Pip (1.3.1)-----> Installing dependencies using Pip (1.3.1)       ...       Successfully installed Flask Werkzeug Jinja2 gunicorn       Cleaning up...-----> Discovering process types       Procfile declares types -> web-----> Compiled slug size is 3.5MB-----> Launching... done, v2 deployed to Heroku
To * [new branch]      master -> master

Visit your application

You’ve deployed your code to Heroku, and specified the process types in aProcfile. You can now instruct Heroku to execute a process type. Heroku does this by running the associated command in a dyno - a lightweight container which is the basic unit of composition on Heroku.
Let’s ensure we have one dyno running the web process type:
$ heroku ps:scale web=1Scaling web processes... done, now running 1
You can check the state of the app’s dynos. The heroku ps command lists the running dynos of your application:
$ heroku ps=== web: `gunicorn hello:app`web.1: up for 5s
Here, one dyno is running.
We can now visit the app in our browser with heroku open.
$ heroku openOpening stark-window-524... done

Dyno idling and scaling

Having only a single web dyno running will result in Heroku periodically idling the dyno after a period of inactivity. This causes a delay of a few seconds for the first request after idling. Subsequent requests will perform normally.
To avoid this, you can scale to more than one web dyno. For example:
$ heroku ps:scale web=2
For each application, Heroku provides 750 free dyno-hours. Running your app at 2 dynos would exceed this free monthly allowance, so let’s scale back:
$ heroku ps:scale web=1

View the logs

Heroku treats logs as streams of time-ordered events aggregated from the output streams of all the dynos running the components of your application. Heroku’sLogplex provides a single channel for all of these events.
View information about your running app using one of the logging commands,heroku logs:
$ heroku logs2011-08-20T16:33:39+00:00 heroku[slugc]: Slug compilation started2011-08-20T16:34:07+00:00 heroku[api]: Config add PYTHONUNBUFFERED by kenneth@heroku.com2011-08-20T16:34:07+00:00 heroku[api]: Release v1 created by kenneth@heroku.com2011-08-20T16:34:07+00:00 heroku[api]: Deploy 67b7e54 by kenneth@heroku.com2011-08-20T16:34:07+00:00 heroku[api]: Release v2 created by kenneth@heroku.com2011-08-20T16:34:08+00:00 heroku[web.1]: State changed from created to starting2011-08-20T16:34:08+00:00 heroku[slugc]: Slug compilation finished2011-08-20T16:34:10+00:00 heroku[web.1]: Starting process with command `gunicorn hello:app`2011-08-20T16:34:10+00:00 app[web.1]:  * Running on heroku[web.1]: State changed from starting to up

Interactive shell

Heroku allows you to run commands in a one-off dyno - scripts and applications that only need to be executed when needed - using the heroku run command. Use this to launch a Python shell attached to your local terminal for experimenting in your app’s environment:
$ heroku run pythonRunning python attached to terminal... up, run.1Python 2.7.4 (default, Apr  6 2013, 22:14:13)[GCC 4.4.3] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> 
From here you can import some of your application modules.

Running a worker

The Procfile format lets you run any number of different process types. For example, let’s say you wanted a worker process to complement your web process:


web: gunicorn hello:app
worker: python
Running more than one dyno for an extended period may incur charges to your account. Read more about dyno-hour costs.
Push this change to Heroku, then launch a worker:
$ heroku ps:scale worker=1Scaling worker processes... done, now running 1
Check heroku ps to see that your worker comes up, and heroku logs to see your worker doing its work.

About Lasha Gogua

    Blogger Comment
    Facebook Comment


Post a Comment