Using SocketIO with Python and Flask on Heroku by Alexander Hadik

Sometimes all you want to do is put together small web app with a Python based server. Flask is the go-to choice and it couldn't be easier to use. Launching your app on Heroku with Flask is a well documented process. But things kind of hit a wall when you want to use SocketIO for websockets. Every tutorial online is basically a chat-app with an overly complicated process of integrating Redis, and at the end of the day, doesn't lay out the basics of bare-bones websocket integration. Often times, I simply need a few event handlers - not the full schebang. This tutorial explains how to set up an extremely simple Flask webapp including basic SocketIO event handlers, and launch it to Heroku.

Set Up

Let's get started with our dev environment. We'll log into Heroku, set up a virtual environment for Python and install a few dependencies.

$ heroku login
  Enter your Heroku credentials.

$ mkdir myapp
$ cd myapp
$ virtualenv venv
$ source venv/bin/activate

Now we're working within our virtual environment and can install our dependencies with pip.

$ pip install gunicorn==0.16.1 Flask Flask-SocketIO

Here we're installing gunicorn to be our web server and Flask to be our web framework. We're also install Flask-SocketIO to be our SocketIO server that will handle incoming requests and send responses back out to clients. It's worth noting that we've requested a specific version of gunicorn due to an issue in gunicorn 0.17 specifically. Newer versions may resolve this issue.

Web Template

We'll make a directory for templates and place an HTML page in it.

$ mkdir templates
$ cd templates
$ touch index.html

We'll place the following code in this file. All this code does is let us type content into a text box, send it to our Python server via SocketIO, and wait for the server to echo it back over SocketIO, at which point we display the echoed content.

        <title>Heroku SocketIO</title>
        <script type="text/javascript" src="//"></script>
        <script src=""></script>
        <script type="text/javascript" charset="utf-8">
            var socket = io.connect('http://' + document.domain + ':' + location.port);
            socket.on('echo', function(data){
            function send(){
                socket.emit('send_message', {message : $('form textarea').val()});
                position: relative;
                margin-left: auto;
                margin-right: auto;
                width: 400px;
                width: 100%;
                height: 100px;
        <div class="input">
                <textarea placeholder="Send a message to the server..."></textarea>
                <button type="button" onclick="send(); return false;">Send</button>
        <div id="response">

The first two script tags load the jQuery and SocketIO libraries. The third script tag lays out our communication with the server via SocketIO. First, we set up a handler to listen for 'echo' events sent from the server. In response to this event, we display the event's content on the webpage.

Python Server

The next step is to put together the Flask server in Python.

$ cd ..
$ touch

First, we'll import the dependencies we need.

from flask import Flask, render_template
from flask.ext.socketio import SocketIO
import json

Next we need to set up the app through the Flask framework and create the SocketIO object.

app = Flask(__name__)
socketio = SocketIO(app)

For this app, we only need to route the root directory and render our index.html template when the root is requested. We do that with Flask's syntax:

def index():
    return render_template('index.html',)

Now, it's time to handle the SocketIO events we expect to receive, as we laid out in our HTML template. Our webpage emits an event under the name send_message and receives events with the name echo. Since this app just echos text back to the client, all we need to do is set up a handler for send_message and in response, emit an event with the name echo:

def handle_source(json_data):
    text = json_data['message'].encode('ascii', 'ignore')
    socketio.emit('echo', {'echo': 'Server Says: '+text})

Finally, we just need to make sure the SocketIO server runs when the script is run. So we add the following to the end of our script:

if __name__ == "__main__":

All together, our server code looks like:

from flask import Flask, render_template
from flask.ext.socketio import SocketIO
import json

app = Flask(__name__)
socketio = SocketIO(app)

def index():
    return render_template('index.html',)

def handle_source(json_data):
    text = json_data['message'].encode('ascii', 'ignore')
    socketio.emit('echo', {'echo': 'Server Says: '+text})

if __name__ == "__main__":

Running on Heroku

With our server code and HTML template finished, all we need to do is push our work to Heroku. The first step is to tell Heroku what it needs to do when our dyno spins up. That's of course accomplished with a Procfile:

$ touch Procfile

And we'll place the following in that file:

web: gunicorn --worker-class socketio.sgunicorn.GeventSocketIOWorker --log-file=- server:app

So what does this do? Well it tells Heroku that here we have a web app, and it needs to spin up a gunicorn server for it to run. We'll need a worker for SocketIO which is what the --worker-class argument is doing. We also want to print any errors directly to std out for simplicity. Finally, we inform gunicorn that our script of interest is named server and our Flask app is called 'app'.

Let's test our app by running it with foreman, which is installed as part of the Heroku Toolbelt:

$ foreman start

If everything has gone to plan, you'll see our web app spin up and we can visit it in a web browser to make sure everything works

12:23:31 web.1  | started with pid 83820
12:23:34 web.1  | 2015-01-29 12:23:34 [83820] [INFO] Starting gunicorn 0.16.1
12:23:34 web.1  | 2015-01-29 12:23:34 [83820] [INFO] Listening at: (83820)
12:23:34 web.1  | 2015-01-29 12:23:34 [83820] [INFO] Using worker: socketio.sgunicorn.GeventSocketIOWorker
12:23:34 web.1  | 2015-01-29 12:23:34 [83821] [INFO] Booting worker with pid: 83821

With our app working, all that's left to do is create a Heroku app, commit to Git, and push to deploy:

$ git init
$ git add .
$ git commit -m "init"
$ heroku create
  Creating infinite-beach-1519... done, stack is cedar-14 |
  Git remote heroku added
$ git push heroku master
  Counting objects: 1453, done.
  Delta compression using up to 8 threads.
  Compressing objects: 100% (1382/1382), done.
  Writing objects: 100% (1453/1453), 4.89 MiB | 3.04 MiB/s, done.
  Total 1453 (delta 91), reused 0 (delta 0)
  remote: Compressing source files... done.
  remote: Building source:
  remote: -----> Python app detected
  remote: -----> Stack changed, re-installing runtime
  remote: -----> Installing runtime (python-2.7.9)
  remote: -----> Installing dependencies with pip
  remote: -----> Discovering process types
  remote:        Procfile declares types -> web
  remote: -----> Compressing... done, 46.4MB
  remote: -----> Launching... done, v3
  remote: deployed to Heroku
  remote: Verifying deploy... done.
   * [new branch]      master -> master

Everything launched just fine - now all we have to do is visit our app in a browser and enjoy the fruits of our labor. Good luck with Flask and SocketIO!

NucleoBytes: Channel Coding for Mutation Resistance by Alexander Hadik

What if historians today had access to detailed census data from hundreds or thousands of years ago? It's pretty obvious that our understanding of past cultures would be drastically different. However, what are we doing to prevent the same cycle hundreds of years from now? Where are we storing the massive reams of data that future societies would find invaluable?

The short answer is nowhere useful. It's stored on hard disks, or perhaps metallic platters, some of it tucked away in vaults, some of it not. Few of these storage mediums have adequate life spans. All of them demand resources in terms of space, power, maintenance etc. Even if these disks and platters survived for the next 500 years, there is no guarantee that future societies will have the capability to read these ancient forms of data.

What if we used DNA? An incredibly resilient organic molecule, it's no new idea that DNA is a storage medium ripe for exploration. However, an encoding scheme must be used that protects against the imperfections in DNA synthesis and sequencing, as well as natural degredation over time.

Proposed here is a small stab at a large problem, using Hamming Codes to encode binary data in nucleotides.


GitHub Repository

The Python program found on this GitHub Repo can read any ASCII text file, and encode it in a DNA sequence that is aligned on 13 bits of data in a (13,8) Hamming Code. That is, 5 parity bits for every 8 bits of original data. The output is in FASTA format.

With an encoded file, the same program can be used to decode an encoded DNA sequence, in FASTA format, back to its original content.

The program makes use of the Python multiprocessing library.

Included Files

  • Python script for encoding and decoding
  • resources/: Several testing text files ranging from small to large sizes

Usage takes several command line arguments:

usage: [-h] [--decode] [--encode] [--workers W] input [output]

positional arguments:

optional arguments:
    -h, --help         show this help message and exit
    --decode, -d       decode boolean flag
    --encode, -e       encode boolean flag
    --workers W, -w W  number of processes to spawn

Only two arguments are required:

Specify encoding or decoding:

  • --encode, -e: Convert a text file into DNA, in FASTA format, encoded with (13,8) Hamming Code
  • --decode, -d: Convert a FASTA file of 13 bit aligned DNA (same format as output of --encode) back to its original format.

Specify input file

  • The first non-flag argument is the input text file. For --encode, this is a normal text file. For --decode this is a FASTA formatted Hamming encoded file.

Optional arguments:

  • -h, --help : Get usage documentation
  • -w W : Specify the number of processes (workers) to spawn to make use of multiple cores. Default is 1.
  • output file: The second non-flag positional argument is the output destination. Default is out.txt.


The following libraries are required for this software:

  • bitstring:
  • bitarray:
  • binascii:
  • multiprocessing