I am developing an app what is using multiple windows. I change the windows with a session_state variable and a condition.
I experienced that every time I reset the window to the initial one, the session_state is being deleted.
As far as I understood the whole meaning of the session_state, it should be used for store variables instead of caching. And a widget should have the state what is declared on the session_state (like it is working with the mirrored widgets case)
I prepared an example code for showing this problem. There are multiple widget, a text input with default value of “ABC”, a checkbox, and 2 mirrored number input. After I change window to the second one, the session state keeps its values, but when I change it back, de values are deleted from the session_state.
Do you have any ideas of what am I doing wrong, or is it a bug, or how could I fix this?
Thank you for your help in advance!
Steps to reproduce
Code snippet:
import streamlit as st
st.set_page_config(layout="wide", page_title="Automatic Resolution Evaluation")
def main():
if "window" not in st.session_state:
st.session_state.window = "init"
st.session_state.txt = "ABC"
st.write(st.session_state)
if st.session_state.window == "init":
st.text_input("TEXT INPUT",
key="txt")
st.number_input("Number",
key="num",
on_change=double)
st.number_input("Double of number",
key="double",
on_change=half)
st.checkbox("Checkbox", key="checkbox")
st.button("Change window", on_click=changeWindow)
elif st.session_state.window == "second":
st.write("Contents of 2nd window...")
st.button("Change window", on_click=changeWindow)
def half():
st.session_state.num = st.session_state.double / 2
def double():
st.session_state.double = st.session_state.num * 2
def changeWindow():
if st.session_state.window == "init":
st.session_state.window = "second"
elif st.session_state.window == "second":
st.session_state.window = "init"
if __name__ == "__main__":
main()
It seems that the session state variables were defined within individual functions thus making it a local variable within those functions rather than a global state variable.
Could you try refactoring the code such that the session state variables are defined outside. Also, if statements should be used to define every session state variables for the first time.
if 'key' not in st.session_state:
st.session_state['key'] = 'value'
If that widget disappears, that key will be removed from session state automatically. (this behavior can be annoying, though there are some good reasons for it. We are looking into options for making keys persist even if widgets are gone, since that is nice in some cases).
That #4 is most of the issue you are experiencing, I believe.
There is a hack to get around this, which is to explicitly set the session state. It’s weird, but it works.
for k, v in st.session_state.items():
st.session_state[k] = v
If you add this at the bottom of your “change window” calback, then the problem goes away.
After refactoring the code the behavior remained the same. It seems that creating widgets with key argument deletes the session_state’s element which has the same key. But this is a bit weird because in this case the mirrored widgets couldn’t work…
I tried some things, and with this code, only 2 variables stay in session_state after returning the initial window: the “window” and the "“txtList”. The rest is deleted.
import streamlit as st
st.set_page_config(layout="wide", page_title="TEST")
def half():
st.session_state.num = st.session_state.double / 2
def double():
st.session_state.double = st.session_state.num * 2
def changeWindow():
if st.session_state.window == "init":
st.session_state.window = "second"
elif st.session_state.window == "second":
st.session_state.window = "init"
def saveTxtList():
st.session_state.txtList = list(st.session_state.txt)
if __name__ == "__main__":
if "window" not in st.session_state:
st.session_state.window = "init"
if "txt" not in st.session_state:
st.session_state.txt = "ABC"
st.write(st.session_state)
if st.session_state.window == "init":
st.text_input("TEXT INPUT",
key="txt",
on_change=saveTxtList)
st.number_input("Number",
key="num",
on_change=double)
st.number_input("Double of number",
key="double",
on_change=half)
st.checkbox("Checkbox", key="checkbox")
st.button("Change window", on_click=changeWindow)
elif st.session_state.window == "second":
st.write("Contents of 2nd window...")
st.button("Change window", on_click=changeWindow)
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.