Widget/Checkbox state doesn't persist on rerun

Hey, I started using custom components on an older version of streamlit and I got a problem of a warning showing up instead of the custom components because of a timeout issue. I resolved this by updating streamlit to 0.84. However now checkbox values don’t persist when I use st.experimental_rerun().

Say a checkbox is selected, and I execute st.experimental_rerun() then, after the reload, the checkbox shows as selected but it returns False. Which means that I need to unselect and reselect for streamlit to detect the checkbox as selected

Hey @Leopoldo_Zugasti,

First, Welcome to the Streamlit Community!!! :wave: :tada: :partying_face:

Can you post your code/GitHub link so we can see exactly how you are using st.experimental_rerun? With the new release of Session State, running experimental_rerun within a call back can have some weird behaviour that the team is looking into. But I just need to see exactly how you are using it first!

Happy Streamlit-ing!
Marisa

Hey Marisa, thank you for the fast reply, I can’t send you a github link because the github repo I work on is currently private :confused:. However here are some screenshots, they are all in order of execution:
Users can press “Select dataset folder” at anytime
image

This is what calls experimental_rerun()

This happens right after and it creates the checkbox menu

This is where I use the true or false value of checkboxes to draw on images

1 Like

Hey @Leopoldo_Zugasti,

Ok thanks for the code snippets. It looks like your using experimental_rerun to force a restart on your script and your not using the new callback feature from session state to call st.experimental_rerun correct?

Happy Streamlit-ing
Marisa

Yes correct

1 Like

@Marisa_Smith

I think this may also be of value, I’m using SessionState.py from another post:

"""Hack to add per-session state to Streamlit.

Usage
-----

>>> import SessionState
>>>
>>> session_state = SessionState.get(user_name='', favorite_color='black')
>>> session_state.user_name
''
>>> session_state.user_name = 'Mary'
>>> session_state.favorite_color
'black'

Since you set user_name above, next time your script runs this will be the
result:
>>> session_state = get(user_name='', favorite_color='black')
>>> session_state.user_name
'Mary'

"""
try:
    import streamlit.ReportThread as ReportThread
    from streamlit.server.Server import Server
except Exception:
    # Streamlit >= 0.65.0
    import streamlit.report_thread as ReportThread
    from streamlit.server.server import Server


class SessionState(object):
    def __init__(self, **kwargs):
        """A new SessionState object.

        Parameters
        ----------
        **kwargs : any
            Default values for the session state.

        Example
        -------
        >>> session_state = SessionState(user_name='', favorite_color='black')
        >>> session_state.user_name = 'Mary'
        ''
        >>> session_state.favorite_color
        'black'

        """
        for key, val in kwargs.items():
            setattr(self, key, val)


def get(**kwargs):
    """Gets a SessionState object for the current session.

    Creates a new object if necessary.

    Parameters
    ----------
    **kwargs : any
        Default values you want to add to the session state, if we're creating a
        new one.

    Example
    -------
    >>> session_state = get(user_name='', favorite_color='black')
    >>> session_state.user_name
    ''
    >>> session_state.user_name = 'Mary'
    >>> session_state.favorite_color
    'black'

    Since you set user_name above, next time your script runs this will be the
    result:
    >>> session_state = get(user_name='', favorite_color='black')
    >>> session_state.user_name
    'Mary'

    """
    # Hack to get the session object from Streamlit.

    ctx = ReportThread.get_report_ctx()

    this_session = None

    current_server = Server.get_current()
    if hasattr(current_server, '_session_infos'):
        # Streamlit < 0.56
        session_infos = Server.get_current()._session_infos.values()
    else:
        session_infos = Server.get_current()._session_info_by_id.values()

    for session_info in session_infos:
        s = session_info.session
        if (
            # Streamlit < 0.54.0
            (hasattr(s, '_main_dg') and s._main_dg == ctx.main_dg)
            or
            # Streamlit >= 0.54.0
            (not hasattr(s, '_main_dg') and s.enqueue == ctx.enqueue)
            or
            # Streamlit >= 0.65.2
            (not hasattr(s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr)
        ):
            this_session = s

    if this_session is None:
        raise RuntimeError(
            "Oh noes. Couldn't get your Streamlit Session object. "
            'Are you doing something fancy with threads?')

    # Got the session object! Now let's attach some state into it.

    if not hasattr(this_session, '_custom_session_state'):
        this_session._custom_session_state = SessionState(**kwargs)

    return this_session._custom_session_state

Ah,

Ok, did you know that Streamlit 0.84 has the release of the internally supported session state feature (no more SessionState.py required). I wonder if the presence of the old session state python file hack is causing a strange error?

Can you try using the new session_state feature in your code to see if that fixes it?

Check out our release notes: Version 0.84.0

also here is a link to the blog post on session_state: Store Information Across App Interactions | Session State

Happy Streamlit-ing!
Marisa

1 Like

Hey @Marisa_Smith,

I tried and it indeed fixed most of the issues but I have one new one:
image

This is created by this:

Notice that the radio buttons should only appear if the checkbox named “Segmentation” is checked but it is not.

To understand when this occurs I’ll try to quickly summarize what my app does:
I can open datasets and depending on which annotations it has there will be different checkboxes that appear

So this occurs when I open a dataset with “segmentation” select the checkbox, then open a dataset without “segmentation” where this checkbox vanishes and then open again a dataset with “segmentation” again, where the checkbox reappears, unselected and yet the radio buttons appear underneath as if it was selected.

I know that explanation is quite convoluted but hopefully it still makes sense

Hi,
FYI, I recently issued a ticket on streamlit GitHub repo; Component values are not restored properly after st.experimental_rerun() · Issue #3533 · streamlit/streamlit · GitHub which looks same as this topic, while there is no reply/solution there yet.

1 Like

Hi @whitphx,

We just released a 0.84.1 patch that I believe fixes this bug! After you upgrade to version 0.84.1, the remaining radio options from your example are reset to Bacon and Sausage, respectively.

Best, :balloon:
Snehan

3 Likes

Thank you, @snehankekre!

1 Like