Flask-SocketIO, Background Threads , Jquery, Python Demo

This week I’ve been making progress on the Huggable Cloud Pillow website.

In the process I’ve learned about some sweet stuff you can do with Javascript, Python, and Flask-SocketIO.

The first thing to take note of is Flask.

Flask is the tiny server that allows us to host websites using Python to deliver content to the client. While on the server side you can manage complicated back ends or other processes using Python in conjunction with Flask.

This type of development is nice, because you can start seeing results right away but can take on big projects easily.

It might not be the most robust Framework, but its great for small projects…

If you want to get into Flask Web Development checkout this extensive MVA.

Small and simple, Flask is static on its own. This allows us to present static content, like templates and images easily and deals with input from the user using RESTful calls to receive input. This is great for static things with lots of user actions, but if we want something a bit more dynamic we’re going to need another tool.

In this case I’ve found Flask-SocketIO, similar to Flask-Sockets but with a few key differences highlighted by the creator (Miguel Grinberg) here.

Sockets are great for is providing live information with low latency. Basically, you can get info on the webpage without reloading or waiting for long-polling.

There are lots of ways you can extend this functionality to sharing rooms and providing communication with users and all sorts of fun stuff that is highlighted on GitHub with a great chunk of sample code. The following demo is based off of these samples.

For my project, I need the webpage to regularly check for differences in the state of the cloud and present them to the client, while also changing the image the user sees.

At first I tried to implement it using sockets passing information back and forth, but that wasn’t very stable.

The solution I’ve found, uses a background thread that is constantly running while the Flask-SocketIO Application is running, it provides a loop that I use to constantly check state of our queue.

Let’s break it down…
a. I need my website to display the current state of the cloud.
b. The Flask application can get the state by query our azure queue.
c. Once we determine a change of state we can display that information to the webpage.
d. To display the new state to the webpage we need to use a socket.
e. And pass the msg to be displayed.

This demo intends to break down problem a, c, d, and e.

I’ve created this little guide to help another developer get going quickly, with a nice piece of code available on GitHub.

The five steps to this little demo project are as follows:
1. Install Flask-SocketIO into our Virtual Environment
2. Create our background thread
3. Have it emit the current state to our client
4. Call the background thread when our page render_template’s
5. Have the Javascript Catch the emit and format our HTML.
Celebrate! Its Friday!

1.

Flask-SocketIO is a python package that is available for download using

pip install Flask-SocketIO

Make sure you instal it into a Virtual Environment. Check out my earlier tutorial if you need help with this step.

*Edit Here’s the top part of the “main.py” for reference:

#main.py
from gevent import monkey
monkey.patch_all()

import time
from threading import Thread
from flask import Flask, render_template, session, request
from flask.ext.socketio import SocketIO, emit, join_room, disconnect

app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
thread = None

2.

Create our background thread.
You’ll see in the sample code from Flask-SocketIO’s github a simple way to send data to the client regardless of their requests.

For this example we’ll be changing the current time every second and display that to our client.

Background Thread:

def background_stuff():
     """ python code in main.py """
     print 'In background_stuff'
     while True:
         time.sleep(1)
         t = str(time.clock())
         socketio.emit('message', {'data': 'This is data', 'time': t}, namespace='/test')

3

This is the emit statement from above, but is the meat of our interface with SocketIO. Notice how it breaks down…

socketio.emit('message', {'data': 'This is data', 'time': t}, namespace='/test')
socektio.emit('tag', 'data', namespace)

This emit will be sending to the client (Javascript) a message called ‘message’.

When the Javascript catches this message it will be able to pull from the python dicionary msg.data and msg.time to get the result of this package.

4

So how do we call background_stuff?

We can call it wherever we want, but for this simple example we’ll put it right in our ‘/’ base route. So when we navigate to 127.0.0.1:5000 (Local Host) we’ll see the result of our background thread call.

Here’s our route:

@app.route('/')
def index():
    global thread
    if thread is None:
        thread = Thread(target=background_stuff)
        thread.start()
    return render_template('index.html')

Pretty simple… Notice global thread and target=background_stuff

Creating different background threads is a good way to iterate through your changes.

5

Next step is catching this on the other side…

So for our Javascript…

we’ll be using the socket.on method.

socket.on('message', function(msg){
    $('#test').html('<p>' + msg.time + '</p>');
});

When we receive the emit labeled ‘message’ we’ll pick up the msg from the second parameter and have it be available to our JQuery work.

Here’s the small piece of HTML that we’re selecting to edit.

<body>
    <p id='test'>Hello</p>
</body>

I’ve posted all of this code at github.

Feel free to download it and start working with dynamic sites using SocketIO. Please let me know if you have any questions!

Code for SF's Hackathon gave out awesome tattoos!
Code for SF’s Hackathon gave out awesome tattoos!

6 thoughts on “Flask-SocketIO, Background Threads , Jquery, Python Demo”

  1. Thanks a lot for sharing this with all folks you really know what you’re speaking about!

    Bookmarked. Kindly additionally consult with my site =).
    We may have a hyperlink alternate arrangement among us

  2. For article completeness, it would help to add this somewhere:

    “How to import the module”
    `from flask_socketio import SocketIO`

  3. Thanks for sharing.
    My problem with this decorator-style routing is that you can’t really use this in a modular way. For example create a Routing class and define routes as methods of that class.
    In the current way it is hard to avoid globals, as we can see here with thread.

Leave a Reply

Your email address will not be published. Required fields are marked *