Does the new session_state feature resolves the issue of app getting reset while using two buttons? My app’s 2nd button click actually resets the entire app and takes me back to the state where the first button was not pressed.
Does the session_state helps to use both the buttons? Can anyone share an example please?
Disclaimer: Novice streamlit user
Hello @arindam, welcome to the forum!
Yes it does! Now there is many ways to solve this issue.
Let’s take this basic non-working example:
import streamlit as st data =  if st.button("Load data"): data = ["This", "Is", "My", "Data"] if st.button("Uppercase data"): data = [item.upper() for item in data] st.write(data)
Behind that pattern, the idea is to divide the app in multiple sequential step, eventually taking parameters between steps to choose and filter some data.
So we must make sure to go from one step to another, while keeping our data and without executing the previous steps as our script reruns from the beginning.
import streamlit as st # An alias for our state state = st.session_state # A function to easily go from one step to another def change_step(next_step): state.step = next_step # Let's initialize our session state if "data" not in state: state.data =  state.step = "init" # Step 1 if state.step == "init": st.button("Load data", on_click=change_step, args=["load"]) # Step 2 if state.step == "load": state.data = ["This", "Is", "My", "Data"] st.button("Uppercase data", on_click=change_step, args=["upper"]) # Step 3 if state.step == "upper": state.data = [item.upper() for item in state.data] # We print our data everytime st.write(state.data)
Thanks for the quick reply @okld . But somehow I still can’t manage to do this. It is still refreshing my app on 2nd button click.
My code is a bit long, not sure how to send the code as a file here.
One thing I have in my code is the 2nd button is inside a nested if condition. The initial if condition has a Submit button and once that submit button is clicked, it does some processing and goes to a download button within that if condition. Now when I click the Download button, it refreshes entire app.
You could try the following in your case:
import streamlit as st if "submitted" not in st.session_state: st.session_state.submitted = False if st.button("Submit") or st.session_state.submitted: st.session_state.submitted = True if st.button("Download"): st.session_state.submitted = False st.write("Download clicked!")
So I am currently facing a challenge. I am working towards building a multi-page like streamlit app with the help of buttons.
From the sidebar when a button like button1 is pressed I want the app to display another set of buttons like bb1 in my case and when that is clicked display some plot.
Similarly I want to display bb2 when button2 is clicked and when bb2 is clicked display some chart.
I have used the code below but here when I click button 1 both bb1 and bb2 are showing up. Could you please help me with a fix or sample code to work on the same.
session_state1 = SessionState.get(checkboxed=False) session_state2 = SessionState.get(checkboxed=False) tday = st.sidebar.date_input('Date Input') lc, mc, rc = st.columns(3) button1 = st.sidebar.button("Open Interest") button2 = st.sidebar.button("FII/DII Data") button3 = st.sidebar.button("Trading Strategy") if button1 or session_state1.checkboxed: session_state1.checkboxed = True df = fnodata(tday) option = lc.selectbox( 'Symbol', df['SYMBOL'].unique()) option_exp = mc.selectbox( 'Expiry DATE', df['EXPIRY_DT'].unique()) option_inst = rc.selectbox( 'INSTRUMENT', df['INSTRUMENT'].unique()) #Getting CMP gcmp = get_cmp(df, option) # Graph data as per user choice filterdata = filtered_data(df, option, option_exp, option_inst, gcmp) bb1 = lc.button("Generate OI Graphs") if bb1: session_state1.checkboxed = False oi_chart = oi_chart_graph(filterdata) coi_chart = coi_chart_graph(filterdata) # Plotting OI Graph st.plotly_chart(oi_chart) # Plotting OI Change Graph st.plotly_chart(coi_chart) if button2 or session_state2.checkboxed: session_state2.checkboxed = True df1 = fiidiidata(tday) client_type = lc.selectbox('Client', df1['Client Type'].unique()) date_fii = rc.selectbox('Contract Date', df1['Date'].unique()) bb2 = rc.button("Generate FII Graphs") if bb2: session_state2.checkboxed = False fii_chart = get_fii_chart(df1) st.plotly_chart(fii_chart) st.write(df1.tail())
In short, I need help with a sample code that is able to do the following:
Display 3 buttons on the sidebar which I have been able to do.
Display bb1 when button 1 is clicked, and when this bb1 is clicked display a set of graphs.
Display bb2 when button 2 is clicked, and when this bb2 is clicked display another set of graphs.
My code is showing both bb1 and bb2 when button1 is clicked.
Thanks a lot for taking out time and reading this!
Is there a reason you use the old SessionState hack instead of the new
SessionState is a singleton, which means that in your app you can have only one instance of it.
So when you create your two
session_state2, they actually reference the same
SessionState object, and
checkboxed will be the same for your two buttons.
Ideally you’d do something like this:
# Using the new st.session_state if "button1_clicked" not in st.session_state: st.session_state.button1_clicked = False st.session_state.button2_clicked = False # Or if for some reason you cannot use it, here's with the old version session_state = SessionState.get( button1_clicked=False, button2_clicked=False, )
Then in your conditions you’d do:
if button1 or st.session_state.button1_clicked: # ... # With the old session state, just drop the `st.` if button1 or session_state.button1_clicked: # ...
Hey @okld ,
Thank You so much for guiding me and helping me with this. I have tried your technique and it is working perfectly now.
Also, thanks for making me aware of the new streamlit st.session_state, I will keep using that from now on.
Thank You so much, once again!
@okld Did someone say that you are a Champ? That was an awesome solution and many thanks for rescuing me from hitting my head in the wall
I will close this thread, much appreciated.