Checkin start on real-time stuff so we can merge the bob the branch
This commit is contained in:
parent
dbed1300ad
commit
c2fb1e5d78
2 changed files with 98 additions and 0 deletions
|
@ -12,6 +12,7 @@ from endpoints.web import web
|
||||||
from endpoints.tags import tags
|
from endpoints.tags import tags
|
||||||
from endpoints.registry import registry
|
from endpoints.registry import registry
|
||||||
from endpoints.webhooks import webhooks
|
from endpoints.webhooks import webhooks
|
||||||
|
from endpoints.realtime import realtime
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -26,6 +27,7 @@ application.register_blueprint(tags, url_prefix='/v1')
|
||||||
application.register_blueprint(registry, url_prefix='/v1')
|
application.register_blueprint(registry, url_prefix='/v1')
|
||||||
application.register_blueprint(api, url_prefix='/api')
|
application.register_blueprint(api, url_prefix='/api')
|
||||||
application.register_blueprint(webhooks, url_prefix='/webhooks')
|
application.register_blueprint(webhooks, url_prefix='/webhooks')
|
||||||
|
application.register_blueprint(realtime, url_prefix='/realtime')
|
||||||
|
|
||||||
# Remove this for prod config
|
# Remove this for prod config
|
||||||
application.debug = True
|
application.debug = True
|
||||||
|
|
96
endpoints/realtime.py
Normal file
96
endpoints/realtime.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import logging
|
||||||
|
import redis
|
||||||
|
|
||||||
|
from functools import wraps
|
||||||
|
from flask import request, make_response, Blueprint, abort, Response
|
||||||
|
from flask.ext.login import current_user, logout_user
|
||||||
|
from data import model
|
||||||
|
from app import app
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
realtime = Blueprint('realtime', __name__)
|
||||||
|
|
||||||
|
def api_login_required(f):
|
||||||
|
@wraps(f)
|
||||||
|
def decorated_view(*args, **kwargs):
|
||||||
|
if not current_user.is_authenticated():
|
||||||
|
abort(401)
|
||||||
|
|
||||||
|
if (current_user and current_user.db_user() and
|
||||||
|
current_user.db_user().organization):
|
||||||
|
abort(401)
|
||||||
|
|
||||||
|
if (current_user and current_user.db_user() and
|
||||||
|
current_user.db_user().robot):
|
||||||
|
abort(401)
|
||||||
|
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_view
|
||||||
|
|
||||||
|
|
||||||
|
# Based off of the SSE flask snippet here: http://flask.pocoo.org/snippets/116/
|
||||||
|
|
||||||
|
class ServerSentEvent(object):
|
||||||
|
def __init__(self, data):
|
||||||
|
self.data = data
|
||||||
|
self.event = None
|
||||||
|
self.id = None
|
||||||
|
self.desc_map = {
|
||||||
|
self.data : "data",
|
||||||
|
self.event : "event",
|
||||||
|
self.id : "id"
|
||||||
|
}
|
||||||
|
|
||||||
|
def encode(self):
|
||||||
|
if not self.data:
|
||||||
|
return ""
|
||||||
|
lines = ["%s: %s" % (v, k)
|
||||||
|
for k, v in self.desc_map.iteritems() if k]
|
||||||
|
|
||||||
|
return "%s\n\n" % "\n".join(lines)
|
||||||
|
|
||||||
|
# The current subscriptions
|
||||||
|
subscriptions = []
|
||||||
|
|
||||||
|
@realtime.route("/")
|
||||||
|
def index():
|
||||||
|
debug_template = """
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Server sent events</h1>
|
||||||
|
<div id="event"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var eventOutputContainer = document.getElementById("event");
|
||||||
|
var evtSrc = new EventSource("/realtime/subscribe");
|
||||||
|
|
||||||
|
evtSrc.onmessage = function(e) {
|
||||||
|
console.log(e.data);
|
||||||
|
eventOutputContainer.innerHTML = e.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
return(debug_template)
|
||||||
|
|
||||||
|
|
||||||
|
@realtime.route("/subscribe")
|
||||||
|
@api_login_required
|
||||||
|
def subscribe():
|
||||||
|
def gen():
|
||||||
|
q = Queue()
|
||||||
|
subscriptions.append(q)
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
result = q.get()
|
||||||
|
ev = ServerSentEvent(str(result))
|
||||||
|
yield ev.encode()
|
||||||
|
except GeneratorExit:
|
||||||
|
subscriptions.remove(q)
|
||||||
|
|
||||||
|
return Response(gen(), mimetype="text/event-stream")
|
Reference in a new issue