Summary
Hello everyone, I am a beginner with streamlit and have created a basic multi page app. Now whenever I am changing the pages which are the endpoints, all the input data is lost. How can I have it in such a way that the input data remains even if I change pages.
This is the page where I am entering inputs. Now if I change the page.
And come back to the previous page.
All the input data is gone.
How can I avoid this to happen and the data stays even after changing pages.
This is my code:
Code snippet:
import streamlit as st
st.title('Haystack Editor')
with st.sidebar:
numberq = st.number_input('Enter number of total Questions',min_value=0,step=1,key='numberq')
head1, head2 = st.columns([3,3])
if head1.button('Load'):
head1.write('File Loaded')
else:
pass
if head2.button('Save'):
head2.write('File Saved')
else:
pass
question = []
con = []
qno = []
ans = []
for i in range(numberq):
con.append('')
question.append('')
ans.append('')
qno.append(0)
for i in range(numberq):
con[i] = st.container()
qno[i] = con[i].number_input(str(i+1)+'. Add or remove Q&A',min_value=0,step=1)
col1, col2 = con[i].columns([5, 5])
que = []
for j in range(qno[i]):
que.append('')
question[i] = que
for j in range(qno[i]):
question[i][j] = col1.text_input('Container '+str(i+1)+' Question '+str(j+1),label_visibility="visible" if j == 0 else "collapsed")
ans[i] = col2.text_area('Container '+str(i+1)+' Answer',label_visibility="visible")
Debug info
- Streamlit version: 1.14.0
- Python version: 3.8.0
- Using Conda
Thank you for your time.
You’ll need to use session_state to park your information while you navigate away from the page. Here’s a short example of committing some information from inputs into a dictionary within session_state.
I also made a little video recently about session_state: Session State Introduction
import streamlit as st
# Initialize on first page load so there is something to look up
if 'page1' not in st.session_state:
st.session_state.page1 = {'A':'','B':0}
# A function to save information to session_state, bound to a submit button
def submit():
st.session_state.page1 = {'A':st.session_state.page1A,
'B':st.session_state.page1B}
st.button('Submit', on_click=submit)
# Input widgets. Keys allow you to grab their saved info directly. Initial value grabbed from
# your designated save point in session_state allows them to re-render at your saved value
# when navigating back to the page
st.text_input('A', key='page1A', value = st.session_state.page1['A'])
st.number_input('B', key='page1B', value = st.session_state.page1['B'])
1 Like
Totally agree with @mathcatsand – you need to rely on session state rather than simply using lists.
Here’s a quick attempt to rewrite your app to explicitly store all of the questions in st.session_state. This seems to work after some brief testing, but you may need to tweak it.
import streamlit as st
st.title("Haystack Editor")
if "num_questions" not in st.session_state:
st.session_state.num_questions = 0
if "questions" not in st.session_state:
st.session_state.questions = {}
with st.sidebar:
st.session_state.num_questions = st.number_input(
"Enter number of total Questions",
min_value=0,
step=1,
value=st.session_state.num_questions,
)
head1, head2 = st.columns([3, 3])
if head1.button("Load"):
head1.write("File Loaded")
else:
pass
if head2.button("Save"):
head2.write("File Saved")
else:
pass
for i in range(st.session_state.num_questions):
if i not in st.session_state.questions:
st.session_state.questions[i] = {"qa_num": 1, "questions": {}, "ans": ""}
question = st.session_state.questions[i]
con = st.container()
question["qa_num"] = con.number_input(
str(i + 1) + ". Add or remove Q&A",
min_value=0,
step=1,
value=question["qa_num"],
)
col1, col2 = con.columns([5, 5])
for j in range(question["qa_num"]):
if j not in question["questions"]:
question["questions"][j] = ""
question["questions"][j] = col1.text_input(
"Container " + str(i + 1) + " Question " + str(j + 1),
label_visibility="visible" if j == 0 else "collapsed",
value=question["questions"][j],
)
question["ans"] = col2.text_input(
"Container " + str(i + 1) + " Answer",
label_visibility="visible",
value=question["ans"],
)
st.session_state.questions[i] = question
1 Like
Thank you @mathcatsand, @blackary for the response. I am trying the code
@blackary The code is working but in the number input buttons there is a problem I need to click twice for plus or minus for some reason. Can you please help with this.
Hi @Devershi_Vashistha,
Yeah, I see that issue. I have a solution, but it involves a workaround that I’ll explain:
There’s a known bug with session state that is tied to widgets. when you switch pages (feel free to go to widget state not synced between multiple pages · Issue #4989 · streamlit/streamlit · GitHub and
the issue if you would like), so it’s a bit more complicated because of that. But if you put these lines at the top of each page in your app, it fixes that issue, and you can make a simpler version of this page.
Put this on the top of each page:
for k, v in st.session_state.items():
st.session_state[k] = v
Then this will work for that first page:
import streamlit as st
st.title("Haystack Editor")
if "num_questions" not in st.session_state:
st.session_state.num_questions = 0
for k, v in st.session_state.items():
st.session_state[k] = v
with st.sidebar:
num_questions = st.number_input(
"Enter number of total Questions",
min_value=0,
step=1,
key="num_questions",
)
head1, head2 = st.columns([3, 3])
if head1.button("Load"):
head1.write("File Loaded")
else:
pass
if head2.button("Save"):
head2.write("File Saved")
else:
pass
for i in range(num_questions):
if f"qa_num_{i}" not in st.session_state:
st.session_state[f"qa_num_{i}"] = 0
if f"ans_{i}" not in st.session_state:
st.session_state[f"ans_{i}"] = ""
con = st.container()
qa_num = con.number_input(
str(i + 1) + ". Add or remove Q&A",
min_value=0,
step=1,
key=f"qa_num_{i}",
)
col1, col2 = con.columns([5, 5])
for j in range(qa_num):
if f"question_{i}_{j}" not in st.session_state:
st.session_state[f"question_{i}_{j}"] = ""
col1.text_input(
"Container " + str(i + 1) + " Question " + str(j + 1),
label_visibility="visible" if j == 0 else "collapsed",
key=f"question_{i}_{j}",
)
col2.text_input(
"Container " + str(i + 1) + " Answer",
label_visibility="visible",
key=f"ans_{i}",
)
Hi @blackary I tried the code but this one is not saving information on changing pages.
Hi @blackary @mathcatsand I am still unbale to save data on changing page without the buggy buttons which requires to click twice to change anything by them. Can you please help?
@Devershi_Vashistha Did you put this on the top of every page in your app?
Ok sorry, I only pasted the code on the first page but after putting on every page it is working. Thank you @blackary .