I have a network client that connects to a streaming server and returns the messages it receives via the asynchronous iterator protocol. The messages are then added to a "storage" object as follows:
storage = MessageStorage()
async with NetworkClient(uri) as client:
await client.setup(...)
async for message in client:
storage.add(message)
In Shiny for Python, I'd like to connect to the server and display the storage as soon as it changes. How do I do that?
Wrapping the code above in an async
function definition as e.g.
@reactive.effect
async def start_streaming():
async with NetworkClient(uri) as client:
...
blocks the application, and the UI never renders.
Calling the co-routine with asyncio.create_task
does not block, but the for loop body is called way too often.
@reactive.effect
async def _():
asyncio.create_task(start_streaming())
AFAIK, the @extended_task
iterator won't help here either, because it is designed to run a long-running task which returns, whereas my loop doesn't return. I tried yield
ing, but got this error:
ExtendedTask can only be used with async functions".
Maybe I wasn't calling it correctly, though.