-
-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
00eae13
commit 8927d85
Showing
15 changed files
with
273 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import asyncio | ||
from microdot import Microdot | ||
from microdot.sse import with_sse | ||
|
||
app = Microdot() | ||
|
||
|
||
@app.route('/events') | ||
@with_sse | ||
async def events(request, sse): | ||
for i in range(10): | ||
await asyncio.sleep(1) | ||
await sse.send({'counter': i}) | ||
|
||
|
||
app.run(debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import asyncio | ||
import json | ||
|
||
|
||
class SSE: | ||
def __init__(self): | ||
self.event = asyncio.Event() | ||
self.queue = [] | ||
|
||
async def send(self, data, event=None): | ||
if isinstance(data, (dict, list)): | ||
data = json.dumps(data) | ||
elif not isinstance(data, str): | ||
data = str(data) | ||
data = f'data: {data}\n\n' | ||
if event: | ||
data = f'event: {event}\n{data}' | ||
self.queue.append(data) | ||
self.event.set() | ||
|
||
|
||
def sse_response(request, event_function, *args, **kwargs): | ||
"""Return a response object that initiates an event stream. | ||
:param request: the request object. | ||
:param event_function: an asynchronous function that will send events to | ||
the client. The function is invoked with ``request`` | ||
and an ``sse`` object. The function should use | ||
``sse.send()`` to send events to the client. | ||
:param args: additional positional arguments to be passed to the response. | ||
:param kwargs: additional keyword arguments to be passed to the response. | ||
Example:: | ||
@app.route('/events') | ||
async def events_route(request): | ||
async def events(request, sse): | ||
# send an unnamed event with string data | ||
await sse.send('hello') | ||
# send an unnamed event with JSON data | ||
await sse.send({'foo': 'bar'}) | ||
# send a named event | ||
await sse.send('hello', event='greeting') | ||
return sse_response(request, events) | ||
""" | ||
sse = SSE() | ||
|
||
async def sse_task_wrapper(): | ||
await event_function(request, sse, *args, **kwargs) | ||
sse.event.set() | ||
|
||
task = asyncio.create_task(sse_task_wrapper()) | ||
|
||
class sse_loop: | ||
def __aiter__(self): | ||
return self | ||
|
||
async def __anext__(self): | ||
event = None | ||
while sse.queue or not task.done(): | ||
try: | ||
event = sse.queue.pop(0) | ||
break | ||
except IndexError: | ||
await sse.event.wait() | ||
sse.event.clear() | ||
if event is None: | ||
raise StopAsyncIteration | ||
return event | ||
|
||
async def aclose(self): | ||
task.cancel() | ||
|
||
return sse_loop(), 200, {'Content-Type': 'text/event-stream'} | ||
|
||
|
||
def with_sse(f): | ||
"""Decorator to make a route a Server-Sent Events endpoint. | ||
This decorator is used to define a route that accepts SSE connections. The | ||
route then receives a sse object as a second argument that it can use to | ||
send events to the client:: | ||
@app.route('/events') | ||
@with_sse | ||
async def events(request, sse): | ||
for i in range(10): | ||
await asyncio.sleep(1) | ||
await sse.send(f'{i}') | ||
""" | ||
async def sse_handler(request, *args, **kwargs): | ||
return sse_response(request, f, *args, **kwargs) | ||
|
||
return sse_handler |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
from tests.test_microdot import * # noqa: F403 | ||
from tests.test_multidict import * # noqa: F403 | ||
from tests.test_request import * # noqa: F403 | ||
from tests.test_response import * # noqa: F403 | ||
from tests.test_urlencode import * # noqa: F403 | ||
from tests.test_url_pattern import * # noqa: F403 | ||
from tests.test_websocket import * # noqa: F403 | ||
from tests.test_cors import * # noqa: F403 | ||
from tests.test_utemplate import * # noqa: F403 | ||
from tests.test_session import * # noqa: F403 | ||
from tests.test_microdot import * # noqa: F401, F403 | ||
from tests.test_multidict import * # noqa: F401, F403 | ||
from tests.test_request import * # noqa: F401, F403 | ||
from tests.test_response import * # noqa: F401, F403 | ||
from tests.test_urlencode import * # noqa: F401, F403 | ||
from tests.test_url_pattern import * # noqa: F401, F403 | ||
from tests.test_websocket import * # noqa: F401, F403 | ||
from tests.test_sse import * # noqa: F401, F403 | ||
from tests.test_cors import * # noqa: F401, F403 | ||
from tests.test_utemplate import * # noqa: F401, F403 | ||
from tests.test_session import * # noqa: F401, F403 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.