Mohamed-512 / Extra-Streamlit-Components

An all in one place, to find complex or just not available components by default on streamlit.
Apache License 2.0
466 stars 59 forks source link

Cookie manager triggers a rerun #58

Closed benlindsay closed 6 months ago

benlindsay commented 7 months ago

I've noticed that creating the cookie manager triggers a rerun of the streamlit app, which makes it difficult to work with.

For example, with this app:

import extra_streamlit_components as stx
import streamlit as st

cookie_manager = stx.CookieManager()
st.session_state["run_count"] = st.session_state.get("run_count", 0) + 1
st.write("run_count:", st.session_state["run_count"])

It will flash "run_count: 1" faster than the eye can see and then land immediately on "run_count: 2".

Now, if we add time.sleep(2) after the CookieManager() call:

import extra_streamlit_components as stx
import streamlit as st
import time

cookie_manager = stx.CookieManager()
time.sleep(2)
st.session_state["run_count"] = st.session_state.get("run_count", 0) + 1
st.write("run_count:", st.session_state["run_count"])

The rerun happens during the sleep, before the increment happens, and we land on "run_count: 1".

This rerun complicates things like buttons, since the rerun reverts the buttons state back to False. For example, with this app:

import extra_streamlit_components as stx
import streamlit as st
import time

if st.button("Button"):
    st.session_state["button_clicked"] = True
    cookie_manager = stx.CookieManager()
    time.sleep(2)
    st.write("Button clicked")
st.session_state["run_count"] = st.session_state.get("run_count", 0) + 1
st.write("run_count:", st.session_state["run_count"])

We will never see the "Button clicked" message, because the rerun is triggered by CookieManager() which takes place during the sleep, and when the rerun occurs, st.button("Button") is now False. To get the button click to trigger actions that occur after the CookieManager() call, we need to use session state like this (or something similar):

import extra_streamlit_components as stx
import streamlit as st
import time

if st.session_state.get("button_clicked", False):
    st.write("In session state if statement")
    st.session_state["button_clicked"] = False
if st.button("Button"):
    st.session_state["button_clicked"] = True
    cookie_manager = stx.CookieManager()
    time.sleep(2)
    st.write("In button if statement")
st.session_state["run_count"] = st.session_state.get("run_count", 0) + 1
st.write("run_count:", st.session_state["run_count"])

Is this expected behavior? Is there a way to prevent the rerun? Any help would be appreciated.

benlindsay commented 7 months ago

Additional discussion here: https://discuss.streamlit.io/t/cookies-support-in-streamlit/16144/35

Mohamed-512 commented 6 months ago

Should be fixed in 0.1.70

informatica92 commented 1 week ago

I am currently using the 0.1.71 but it seems that the rerun triggered by calling stx.CookieManager() is still present.

Anyone else with the same issue?