1+ import asyncio
12from typing import Annotated , Any , Final
23
34from fastapi import APIRouter , Depends , FastAPI
45from fastapi .responses import StreamingResponse
56from fastui import AnyComponent , FastUI
67from fastui import components as c
78from fastui .events import PageEvent
9+ from servicelib .fastapi .app_state import SingletonInAppStateMixin
810from starlette import status
911
1012from ..dependencies import get_app
1113from ._constants import API_ROOT_PATH
12- from ._sse_utils import AbstractSSERenderer , render_items_on_change
14+ from ._sse_utils import AbstractSSERenderer , render_items_on_change , update_items
1315
1416_PREFIX : Final [str ] = "/services"
1517
@@ -47,7 +49,7 @@ def api_index() -> list[AnyComponent]:
4749
4850class ServicesSSERenderer (AbstractSSERenderer ):
4951 @staticmethod
50- def render_item (item : Any ) -> AnyComponent :
52+ def get_component (item : Any ) -> AnyComponent :
5153 return c .Paragraph (text = f"{ item } " )
5254
5355
@@ -64,3 +66,40 @@ async def sse_ai_response(
6466@router .get ("/{path:path}" , status_code = status .HTTP_404_NOT_FOUND )
6567async def not_found ():
6668 return {"message" : "Not Found" }
69+
70+
71+ class MockMessagesProvider (SingletonInAppStateMixin ):
72+ app_state_name : str = "mock_messages_provider"
73+
74+ def __init__ (self , app : FastAPI ) -> None :
75+ self .app = app
76+ self ._task : asyncio .Task | None = None
77+
78+ async def _publish_mock_data (self ) -> None :
79+ messages : list [Any ] = []
80+ while True :
81+ await asyncio .sleep (3 )
82+
83+ messages .append ({"name" : "a" , "surname" : "b" })
84+ await update_items (
85+ self .app , renderer_type = ServicesSSERenderer , items = messages
86+ )
87+
88+ def startup (self ) -> None :
89+ self ._task = asyncio .create_task (self ._publish_mock_data ())
90+
91+ async def shutdown (self ) -> None :
92+ if self ._task :
93+ self ._task .cancel ()
94+ await self ._task
95+
96+
97+ def setup_services (app : FastAPI ) -> None :
98+ async def on_startup () -> None :
99+ MockMessagesProvider .get_from_app_state (app ).startup ()
100+
101+ async def on_shutdown () -> None :
102+ await MockMessagesProvider .get_from_app_state (app ).shutdown ()
103+
104+ app .add_event_handler ("startup" , on_startup )
105+ app .add_event_handler ("shutdown" , on_shutdown )
0 commit comments