forked from MaxHalford/flask-sse-no-deps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
65 lines (43 loc) · 1.47 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import queue
import flask
app = flask.Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
class MessageAnnouncer:
def __init__(self):
self.listeners = []
def listen(self):
self.listeners.append(queue.Queue(maxsize=5))
return self.listeners[-1]
def announce(self, msg):
# We go in reverse order because we might have to delete an element, which will shift the
# indices backward
for i in reversed(range(len(self.listeners))):
try:
self.listeners[i].put_nowait(msg)
except queue.Full:
del self.listeners[i]
announcer = MessageAnnouncer()
def format_sse(data: str, event=None) -> str:
"""Formats a string and an event name in order to follow the event stream convention.
>>> format_sse(data=json.dumps({'abc': 123}), event='Jackson 5')
'event: Jackson 5\\ndata: {"abc": 123}\\n\\n'
"""
msg = f'data: {data}\n\n'
if event is not None:
msg = f'event: {event}\n{msg}'
return msg
@app.route('/ping')
def ping():
msg = format_sse(data='pong')
announcer.announce(msg=msg)
return {}, 200
@app.route('/listen', methods=['GET'])
def listen():
def stream():
messages = announcer.listen() # returns a queue.Queue
while True:
msg = messages.get() # blocks until a new message arrives
yield msg
return flask.Response(stream(), mimetype='text/event-stream')