Add event ID to the SSE implementation (#213)

This commit is contained in:
Hamsanger
2024-03-11 10:52:43 +11:00
committed by GitHub
parent a0ea439def
commit 904d5fcaa2
2 changed files with 9 additions and 1 deletions

View File

@@ -12,7 +12,7 @@ class SSE:
self.event = asyncio.Event() self.event = asyncio.Event()
self.queue = [] self.queue = []
async def send(self, data, event=None): async def send(self, data, event=None, event_id=None):
"""Send an event to the client. """Send an event to the client.
:param data: the data to send. It can be given as a string, bytes, dict :param data: the data to send. It can be given as a string, bytes, dict
@@ -20,6 +20,8 @@ class SSE:
Any other types are converted to string before sending. Any other types are converted to string before sending.
:param event: an optional event name, to send along with the data. If :param event: an optional event name, to send along with the data. If
given, it must be a string. given, it must be a string.
:param event_id: an optional event id, to send along with the data. If
given, it must be a string.
""" """
if isinstance(data, (dict, list)): if isinstance(data, (dict, list)):
data = json.dumps(data).encode() data = json.dumps(data).encode()
@@ -28,6 +30,8 @@ class SSE:
elif not isinstance(data, bytes): elif not isinstance(data, bytes):
data = str(data).encode() data = str(data).encode()
data = b'data: ' + data + b'\n\n' data = b'data: ' + data + b'\n\n'
if event_id:
data = b'id: ' + event_id.encode() + b'\n' + data
if event: if event:
data = b'event: ' + event.encode() + b'\n' + data data = b'event: ' + event.encode() + b'\n' + data
self.queue.append(data) self.queue.append(data)

View File

@@ -23,6 +23,8 @@ class TestWebSocket(unittest.TestCase):
async def handle_sse(request, sse): async def handle_sse(request, sse):
await sse.send('foo') await sse.send('foo')
await sse.send('bar', event='test') await sse.send('bar', event='test')
await sse.send('bar', event='test', event_id='id42')
await sse.send('bar', event_id='id42')
await sse.send({'foo': 'bar'}) await sse.send({'foo': 'bar'})
await sse.send([42, 'foo', 'bar']) await sse.send([42, 'foo', 'bar'])
await sse.send(ValueError('foo')) await sse.send(ValueError('foo'))
@@ -34,6 +36,8 @@ class TestWebSocket(unittest.TestCase):
self.assertEqual(response.headers['Content-Type'], 'text/event-stream') self.assertEqual(response.headers['Content-Type'], 'text/event-stream')
self.assertEqual(response.text, ('data: foo\n\n' self.assertEqual(response.text, ('data: foo\n\n'
'event: test\ndata: bar\n\n' 'event: test\ndata: bar\n\n'
'event: test\nid: id42\ndata: bar\n\n'
'id: id42\ndata: bar\n\n'
'data: {"foo": "bar"}\n\n' 'data: {"foo": "bar"}\n\n'
'data: [42, "foo", "bar"]\n\n' 'data: [42, "foo", "bar"]\n\n'
'data: foo\n\n' 'data: foo\n\n'