Hi, everyone! How can I use st.date_editor with session state? In this project, the user can edit some data and the run an analysis. The problem is that apparentely there is no session state when it comes to st.date_editor. I’ve seen in a forum a solution which basically saves the edited df to a static df with “on_change” method, but I couldnt reproduce it.
The following Docs page provides example code snippets to save edits to session state
The relevant code snippet mentioned in the above Docs page:
st.data_editor(df, key="data_editor") # 👈 Set a key
st.write("Here's the session state:")
st.write(st.session_state["data_editor"]) # 👈 Access the edited data
Is there any way to store the complete dataframe in the session state, not only the changes?
I have a use case in a mulitpage application, where I need to do changes on a dataframe on one page, which is then used on another page. This does not seem to be straight forward with the current implementation, where only the changes are stored in session state.
One way would be to store the data_editor initial dataframe itself in the session state, and update it when the output changes, as in the code below. This does not work however when updating the data multiple times.
if "initial_df" not in st.session_state:
st.session_state["initial_df"] = pd.DataFrame(
[
{"color": "red", "rating": 4},
{"color": "green", "rating": 5},
{"color": "blue", "rating": 3},
]
)
updated_df = st.data_editor(st.session_state["initial_df"], num_rows="dynamic")
if not st.session_state["initial_df"].equals(updated_df):
st.session_state["initial_df"] = updated_df.copy()
Thanks for the reply @heitormarcal. Saving updated_df in the session_state does not really solve the problem, which is that the every second edited value in the data_editor disappears. When this happens, it seems like the data_editor widget is refreshed with the previous initial_df.
It seems that it’s happening because of this statement:
if not st.session_state["initial_df"].equals(updated_df):
st.session_state["initial_df"] = updated_df.copy()
Instead of initializing like that, try:
if 'initial_df' not in st.session_state:
st.session_state['initial_df'] = ''
if 'updated_df ' not in st.session_state:
st.session_state['updated_df '] = ''
Your approach works for a single-page application. However, I am developing a multipage application, meaning that the data_editor is re-initialized with st.session_state["initial_df"] whenever the user is changing from another page to the page with the data_editor.
With the current implementation, I need to update the st.session_state["initial_df"] with the latest updates. As you point out, this is what causes the edited data to disappear, but I don’t really understand why. A workaround would be to only update it when leaving the page with the data_editor, but I have not found a way to do this.
Not that I’m a Streamlit pro, but I’d give a last chance trying to help you asking if you’re using the latest version of Strealit.
I’m using version 1.28.1 and the session_state does persist when changing pages, which means that I can access an edited df from page “A” on page “B”.
However, and it’s important to mention, everytime I change from one page to another and then go back to the previous, it seems that it resets the edited df, indeed… if that was your point since the beggining, sorry for the confusion! And in case you find a solution, please share!
Yes, exactly. The problem is persisting state between page changes. From my understanding the data_editor widget is a bit different from other widgets, making this challenging.
A solution like the one described here would work if there was a way to do a similar on_change callback when switching page in a multipage app, but as far as I know this is not possible.