Skip to content
No description, website, or topics provided.
Python HTML Shell
Branch: master
Clone or download

Latest commit

Latest commit a13896a Apr 10, 2016


Type Name Latest commit message Commit time
Failed to load latest commit information.
example Bit of text on the example pages Oct 19, 2012
.gitignore packaging bugfix Jun 18, 2014
LICENSE Add license Oct 13, 2015
MANIFEST packaging bugfix Jun 18, 2014 Updated small typos code examples in Nov 5, 2015 PEP8 Fixes Sep 20, 2013
requirements.txt Added Oct 18, 2012 Fix project url Apr 10, 2016


A simple Flask extension for HTML5 server-sent events support, powered by Redis

The extension provides 2 things - a blueprint with a single route for streaming events, and a helper function to send messages to subscribers:

from flask import Flask, json
from flask.ext.sse import sse, send_event

app = Flask(__name__)
app.register_blueprint(sse, url_prefix='/stream')

def send_message():
    send_event('myevent', json.dumps({"message": "Hello!"}))

You can then subscribe to these events in a supported browser:

<!DOCTYPE html>
  <meta charset="utf-8" />
    var source = new EventSource("{{ url_for('') }}");
    source.addEventListener('myevent', function(e) {
        var data = JSON.parse(;
        // handle event
    }, false);

The source comes with a basic example

Clients can subscribe to different channels by setting 'channel' on the query string, which defaults to 'sse'. These correspond to redis channels.

def send_message():
    send_event('myevent', json.dumps({"line": "Something happened"}), channel='logs')

var source = new EventSource("{{ url_for('', channel='logs') }}")    

Being a blueprint, you can attach a before_request handler to handle things like access control:

def check_access():
    if request.args.get('channel') == 'firehose' and not g.user.is_admin():


Redis connection details are read from the applications config using the following keys (defaults in [])

  • SSE_REDIS_HOST [localhost]
  • SSE_REDIS_PORT [6379]
  • SSE_REDIS_DB [0]


Subscribers will connect and block for a long time, so you should seriously consider running under an asynchronous WSGI server, such as gunicorn+gevent (like the example)

I should also say I'm not really maintaining this beyond accepting the odd pull request - it was built as an experiment but I'm not using it in anger on anything production. I wont be publishing it on PyPi myself for the same reasons - if I start using it properly then it will go on PyPi and have some tests put around it.


Inspired by django-sse

You can’t perform that action at this time.