Session state pandas data frame

Summary

Just starting out with Streamlit and this is my first post so please be gentle :slight_smile:
I’m sure I’m missing something very obvious in the session state but the SS for my df1 stays FALSE

Steps to reproduce

Code snippet:

import streamlit as st
import pandas as pd
import random
from datetime import datetime, timedelta

st.set_page_config(layout="wide")
"st.session_state object:",st.session_state

@st.experimental_memo(show_spinner=True, suppress_st_warning=True)
def makeDF():
    
# Create a list of specific dates
    date1 = datetime.strptime("12/01/2023", "%m/%d/%Y")
    date2 = datetime.strptime("11/01/2023", "%m/%d/%Y")
    names = ['John', 'Mike', 'Emily', 'Jessica', 'David', 'Rachel', 'Michael', 'Sarah', 'Mark', 'Jessica']
    data = {'date': ([date1]*5) + ([date2]*5),
            'name': names}
    df = pd.DataFrame(data)

    return df
    
if "default_checkbox_value" not in st.session_state:
    st.session_state["default_checkbox_value"] = False

if "df1" not in st.session_state:
    st.session_state['df1'] = False


checkbox_statusses = []


if st.button('Get the df', key='GetDF'):
    
    df = makeDF()
    st.session_state['df1'] = df


if st.session_state['df1'] is True:

    # just testing i get here

    st.write(st.session_state['df1'])

    for i, value  in enumerate(st.session_state['df1']['name']):
        print(i,value)
        
        checkbox_statusses.append(
            st.checkbox(
                value, key=str(i) + value, value=st.session_state["default_checkbox_value"]
            )
        )


Expected behavior:

  • Checkboxes should only be displayed when the GetDF button is clicked.
  • User clicks on GetDF button that will generate a DF.
  • A checkbox will be created that represents a Name in the DF
  • When the checkbox is clicked, all the checkboxes should remain visible…

Actual behavior:

I can’t get the list of checkboxes to appear.

Debug info

  • Streamlit, version 1.13.0
  • Python version: 3.7.6
  • Using Conda? PipEnv? PyEnv? Pex?
  • OS version: Mac 13.0.1 (22A400)
  • Browser version: Safari Version 16.1 (18614.2.9.1.12)

Additional information

this solution is here creates an empty dataframe by default and then appends new data which might be an approach to explore, but surely there is more simpler solution.

I think you are almost there.

  • Checkboxes should only be displayed when the DF is clicked.

What do you mean by “when the DF is clicked”?

  • User clicks on GetDF button that will generate a DF.

It does, and the DataFrame is assiged to session_state["df1"]. You can’t see it because you are displaying session_state before the assignment happens.

  • A checkbox will be created that represents a Name in the DF

You create the checkboxes only when session_state["df1"] is True, but that never happens. It is False at first, then a DataFrame after the user clicks the button.

Checkboxes should only be displayed when the GetDF button is clicked.

Ok, this gives me the expected behaviour.

adding a new st.session_state[‘df_ready’].

can someone explain why this works and original code does not?

import streamlit as st
import pandas as pd
import random
from datetime import datetime, timedelta

st.set_page_config(layout="wide")
"st.session_state object:",st.session_state

@st.experimental_memo(show_spinner=True, suppress_st_warning=True)
def makeDF():
    
# Create a list of specific dates
    date1 = datetime.strptime("12/01/2023", "%m/%d/%Y")
    date2 = datetime.strptime("11/01/2023", "%m/%d/%Y")
    names = ['John', 'Mike', 'Emily', 'Jessica', 'David', 'Rachel', 'Michael', 'Sarah', 'Mark', 'Jessica2']
    data = {'date': ([date1]*5) + ([date2]*5),
            'name': names}
    df = pd.DataFrame(data)
    return df
    
if "default_checkbox_value" not in st.session_state:
    st.session_state["default_checkbox_value"] = False

if "df1" not in st.session_state:
    st.session_state['df1'] = False

if "df_ready" not in st.session_state:
    st.session_state['df_ready'] = 0


checkbox_statusses = []

if st.button('Get the df', key='GetDF'):
    
    df = makeDF()
    st.session_state['df1'] = df
    st.session_state['df_ready'] = 1


if  st.session_state['df_ready'] == 1 :

    # just testing i get here
  
    for i, value  in enumerate(st.session_state['df1']['name']):
        print(i,value)
        
        checkbox_statusses.append(
            st.checkbox(
                value, key=str(i) + value, value=st.session_state["default_checkbox_value"]
            )
        )

As I said above, you originally were creating the checkboxes on the condition session_state["df1"] is True, which is always False. session_state["df1"] was either False or a DataFrame but never True.

thanks @Goyo !!

using the following gives me the expected behaviour

if isinstance(st.session_state['df1'], pd.DataFrame):

without the need for the newly created st.session_state['df_ready']

Hi @Kai,

FWIW, the pattern I would suggest in general is setting the session state key to None before it is set, and then checking for None, something like this:

if "df" not in st.session_state:
    st.session_state["df"] = None

...
if something_something:
    st.session_state["df"] = pd.DataFrame(...)
...

if st.session_state["df"] is not None:
   ...

That makes it slightly simpler to check, and then you can be sure that at any given time, that entry in session state is either None, or a pd.DataFrame, without having to explicitly use isinstance

2 Likes