Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
iwootten committed Aug 25, 2014
0 parents commit dc5f270
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 0 deletions.
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Celery-SocketIO Example
==============

A super simple example to demonstrate how to monitor celery task progress
in realtime by using Flask-SocketIO

Example
-------
from celery import Celery
from flask import Flask, render_template
from flask.ext.socketio import SocketIO, emit

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

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

def background_celery_thread():
app = Celery(broker='amqp://guest:[email protected]:49153//')
my_monitor(app)

@socketio.on('my event')
def test_message(message):
emit('my response', {'data': 'got it!'})

def my_monitor(app):

with app.connection() as connection:
recv = app.events.Receiver(connection, handlers={
'*': do_something,
})
recv.capture(limit=None, timeout=None, wakeup=True)

if __name__ == '__main__':
socketio.run(app)

Resources
---------

- [Tutorial](http://blog.miguelgrinberg.com/post/easy-websockets-with-flask-and-gevent)
- [Documentation](http://pythonhosted.org/Flask-SocketIO)
- [PyPI](https://pypi.python.org/pypi/Flask-SocketIO)

71 changes: 71 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from gevent import monkey
monkey.patch_all()

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

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

def my_monitor(app):
state = app.events.State()

def announce_tasks(event):
global count

state.event(event)

# task name is sent only with -received event, and state
# will keep track of this for us.
if 'uuid' in event:
task = state.tasks.get(event['uuid'])

count += 1

socketio.emit('my response', {'data': 'EVENT %s: %s[%s] %s' % (
event['type'], task.name, task.uuid, task.info(), ), 'count': count},
namespace='/test')

print('TASK %s: %s[%s] %s' % (event['type'],
task.name, task.uuid, task.info(), ))

with app.connection() as connection:
recv = app.events.Receiver(connection, handlers={
'*': announce_tasks,
})
recv.capture(limit=None, timeout=None, wakeup=True)

def background_celery_thread():
app = Celery(broker='amqp://guest:[email protected]:49153//')
my_monitor(app)

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

@socketio.on('connect', namespace='/test')
def test_connect():
global count
count += 1

emit('my response', {'data': 'Connected', 'count': count})


@socketio.on('disconnect', namespace='/test')
def test_disconnect():
print('Client disconnected')


if __name__ == '__main__':
socketio.run(app)
18 changes: 18 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Flask==0.10.1
Flask-SocketIO==0.3.8
Jinja2==2.7.2
MarkupSafe==0.18
Werkzeug==0.9.4
amqp==1.4.6
anyjson==0.3.3
billiard==3.3.0.18
celery==3.1.13
gevent==1.0
gevent-socketio==0.3.6
gevent-websocket==0.9.2
greenlet==0.4.2
itsdangerous==0.23
kombu==3.0.21
pytz==2014.4
ujson==1.33
wsgiref==0.1.2
27 changes: 27 additions & 0 deletions templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Flask-SocketIO Test</title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
namespace = '/test'; // change to an empty string to use the global namespace

// the socket.io documentation recommends sending an explicit package upon connection
// this is specially important when using the global namespace
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);

// event handler for server sent data
// the data is displayed in the "Received" section of the page
socket.on('my response', function(msg) {
$('#log').append('<br>Received #' + msg.count + ': ' + msg.data);
});
});
</script>
</head>
<body>
<h1>Celery-SocketIO</h1>
<div id="log"></div>
</body>
</html>

0 comments on commit dc5f270

Please sign in to comment.