We are trying to use python-socketio to communicate with another server. The event listener functions seem to be executed in other threads and do not share the same session_state.
Is there any workaround for this? I have seen some things about multithreading but don’t know if I can do something like that with socketio.
Steps to reproduce
Code snippet:
import streamlit as st
import socketio
if "some_boolean" not in st.session_state:
st.session_state.some_boolean = True
if "some_param" not in st.session_state:
st.session_state.some_param = 50
sio = socketio.Client()
sio.connect("http://localhost:6000")
@sio.on("*")
def catch_all(messageType, value):
if st.session_state.some_boolean:
st.session_state.some_param = value
Expected behavior:
It would be great if I could access the session_state like that. But any other way would also be great.
Actual behavior:
I am getting following error:
2023-06-21 18:42:55.033 Thread 'Thread-12 (_handle_eio_message)': missing ScriptRunContext
Exception in thread Thread-12 (_handle_eio_message):
Traceback (most recent call last):
File "*/streamlit/runtime/state/session_state.py", line 370, in __getitem__
return self._getitem(widget_id, key)
File "*/streamlit/runtime/state/session_state.py", line 415, in _getitem
raise KeyError
KeyError
...
KeyError: 'st.session_state has no key "some_boolean". Did you forget to initialize it?
The error you encountered suggests that the event listener function (catch_all) executed by the socketio library is running in a separate thread, which doesn’t have access to the st.session_state object. This is because st.session_state is specific to the Streamlit framework and is not designed to be shared across different threads or external libraries.
To work around this limitation and achieve communication between your Streamlit app and the socketio server, you can consider the following approach:
Instead of directly modifying st.session_state, create a separate object or data structure to store the shared state between the socketio events and your Streamlit app.
In your Streamlit app, define a Streamlit SessionState class (or use an existing implementation) that can handle shared state across different sessions. Here’s an example implementation:
By following this approach, you create a separate shared state object that can be accessed and modified by both the event listener function and your Streamlit app. This way, you can achieve communication between the socketio server and your Streamlit app while avoiding conflicts with st.session_state.
Remember to manage synchronization and potential race conditions if multiple threads are modifying the shared state simultaneously. Using appropriate synchronization primitives like locks or thread-safe data structures can help ensure data consistency and avoid conflicts.
Note: The provided example is a basic implementation to demonstrate the concept of shared state. Depending on your specific requirements, you may need to adapt and enhance it to suit your needs.
Thank you so much! we have solved it by writing into a json file so far, but I will look into creating a new session state class as well
You would have to pass the instance to all other functions then right?
We would probably have to rewrite quite a bit of code as the “backend” is not really connected to the streamlit app at all right now, other than the socket. Might not be worth it as we are just doing it for a uni project and the crappy json file solution works for now.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.