diff --git a/pyproject.toml b/pyproject.toml index 06e8b22..117cd9e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ dependencies = [ 'fastapi-users[beanie]', 'pydantic-settings', 'uvicorn[standard]', + 'sse-starlette' ] [project.scripts] diff --git a/requirements.txt b/requirements.txt index 4f8b7ab..1e64279 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ fastapi-users[beanie]==12.1.2 fastapi==0.103.2 pydantic-settings==2.0.3 uvicorn[standard]==0.23.2 +sse-starlette==1.6.5 diff --git a/src/unipoll_api/routes/__init__.py b/src/unipoll_api/routes/__init__.py index 033e6e2..4e4aef9 100644 --- a/src/unipoll_api/routes/__init__.py +++ b/src/unipoll_api/routes/__init__.py @@ -5,6 +5,7 @@ from .v2 import router as v2_router from .swagger_docs import create_doc_router from .websocket import router as websocket_router +from .streams import router as streams_router # Function to generate unique operation IDs for different API versions @@ -28,6 +29,7 @@ def create_router(app, default_version): # Default API version router.include_router(endpoints[default_version]) router.include_router(websocket_router, prefix="/ws", tags=["WebSocket"]) + router.include_router(streams_router, tags=["Streams"]) # Add API v1 endpoints to the main router router.include_router(v1_router, diff --git a/src/unipoll_api/routes/streams.py b/src/unipoll_api/routes/streams.py new file mode 100644 index 0000000..1025ce9 --- /dev/null +++ b/src/unipoll_api/routes/streams.py @@ -0,0 +1,13 @@ +from fastapi import APIRouter +from sse_starlette.sse import EventSourceResponse +from unipoll_api.utils.streams import update_generator + + +router = APIRouter() + + +@router.get("/updates", + response_class=EventSourceResponse) +async def event_log(): + updates = update_generator() + return EventSourceResponse(updates) diff --git a/src/unipoll_api/utils/streams.py b/src/unipoll_api/utils/streams.py new file mode 100644 index 0000000..00362d2 --- /dev/null +++ b/src/unipoll_api/utils/streams.py @@ -0,0 +1,16 @@ +import asyncio +from unipoll_api.documents import Resource +from . import colored_dbg as Debug + + +# async def update_generator(resource: Resource): +async def update_generator(): + i = 0 + try: + while True: + i += 1 + yield dict(data=i) + await asyncio.sleep(0.2) + except asyncio.CancelledError as e: + Debug.info("Disconnected from client (via refresh/close)") + raise e