I’m running long-running streaming requests and other async tasks that I want cancelled when an app session ends.
So I spent quite some time searching the forums, the web in general, and streamlit’s source for a way to stop an async loop when an app session has ended.
I came up with this simple approach that I haven’t seen before and I’m curious to learn what you think about it.
import asyncio from datetime import datetime import streamlit as st from streamlit.runtime import get_instance from streamlit.runtime.scriptrunner import get_script_run_ctx async def watch(test): print("new session") runtime = get_instance() ctx = get_script_run_ctx() while runtime.is_active_session(ctx.session_id): test.text(str(datetime.now())) await asyncio.sleep(0.1) print("session ended") test = st.empty() asyncio.run(watch(test))
- I can close and re-open tabs or reload them at will. The loop will stop iterating and the script runner will shutdown cleanly. I could also abort any ongoing requests or other streams.
- Yes, get_instance and get_script_run_ctx is considered using internals, but the surface is very limited
- Ideally i’d like a session end signal to stop the coroutine without having to check for state in a loop.
- I can’t use the ScriptRunners on_event SHUTDOWN signal. If the coroutine loop was infinite, it would keep running and never emit the signal.
I hope this is helpful to someone, or insulting enough to elicit a reply