How to remember state of the button?

I am tying to use streamlit authenticator in my code.
If I run the code below, then, it works fine:

import yaml
from yaml.loader import SafeLoader
import streamlit as st
import streamlit_authenticator as stauth

#Page Title
st.set_page_config( page_title="Trial Run of Chat with Documents by Awais", 
                    page_icon=":books:",
                    initial_sidebar_state= "collapsed",
                    layout="centered")
#st.markdown(styl, unsafe_allow_html=True)
#st.write(css, unsafe_allow_html=True)


with open('./config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)
try:
    if authenticator.register_user('Register user', preauthorization=False):
        st.success('User registered successfully')
except Exception as e:
    st.error(e)

Now, if I try to activate same widget after some button click, then, register_user_form.form_submit_button('Register') status is always false. The status is always false because Streamlit will rerun the script whenever I will interact with the application. For example, following case will always results in register_user_form.form_submit_button('Register') = False

import yaml
from yaml.loader import SafeLoader
import streamlit as st
import streamlit_authenticator as stauth

#Page Title
st.set_page_config( page_title="Trial Run of Chat with Documents by Awais", 
                    page_icon=":books:",
                    initial_sidebar_state= "collapsed",
                    layout="centered")
#st.markdown(styl, unsafe_allow_html=True)
#st.write(css, unsafe_allow_html=True)


with open('./config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)


# Creating a new user registration widget
if st.button('Register User'):
    if authenticator.register_user('Register user', preauthorization=False):
        st.success('User registered successfully')

How can I remember the state of button to be used in other code?

1 Like

You store it in session_state.

Hi @Awais ,

can you try the below modified code and let us know.

import yaml
from yaml.loader import SafeLoader
import streamlit as st
import streamlit_authenticator as stauth

#Page Title
st.set_page_config( page_title="Trial Run of Chat with Documents by Awais", 
                    page_icon=":books:",
                    initial_sidebar_state= "collapsed",
                    layout="centered")
#st.markdown(styl, unsafe_allow_html=True)
#st.write(css, unsafe_allow_html=True)


with open('./config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)

# Define a function to register user and use caching to remember the session
@st.cache(allow_output_mutation=True)
def register_user():
    if authenticator.register_user('Register user', preauthorization=False):
        return True
    return False

# Creating a new user registration widget
if st.button('Register User'):
    if register_user():
        st.success('User registered successfully')

Regards
Sridhar
Happy Streamliting…

I tried the code below and result is same (i.e. register_user_form.form_submit_button('Register') is False. I replaced @st.cache(allow_output_mutation=True) with @st.cache_data(experimental_allow_widgets=True).

import yaml
from yaml.loader import SafeLoader
import streamlit as st
import streamlit_authenticator as stauth

#Page Title
st.set_page_config( page_title="Trial Run of Chat with Documents by Awais", 
                    page_icon=":books:",
                    initial_sidebar_state= "collapsed",
                    layout="centered")
#st.markdown(styl, unsafe_allow_html=True)
#st.write(css, unsafe_allow_html=True)


with open('./config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)

@st.cache_data(experimental_allow_widgets=True)
def register_user():
    if authenticator.register_user('Register user', preauthorization=False):
        return True
    return False

# Creating a new user registration widget
if st.button('Register User'):
    if register_user():
        st.success('User registered successfully')

I tried using this session_state using coding below. However the issue still exists:

import yaml
from yaml.loader import SafeLoader
import streamlit as st
import streamlit_authenticator as stauth

#Page Title
st.set_page_config( page_title="Trial Run of Chat with Documents by Awais", 
                    page_icon=":books:",
                    initial_sidebar_state= "collapsed")
                   # layout="centered")
#st.markdown(styl, unsafe_allow_html=True)
#st.write(css, unsafe_allow_html=True)


with open('./config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)

#Initialize session_stat
if 'page' not in st.session_state:
    st.session_state.page = 'Start Up Screen'
else:
    st.session_state.page = st.session_state.page 

if st.session_state.page == 'Start Up Screen':
    st.header("Trial Run of Chat with Documents :books:")
    with st.form(key='Home Page'):
        c1, c2, c3,c4 = st.columns(4)
        if c1.form_submit_button(label='Employee Log in'):
            st.session_state.page = 'Employee Login Screen'
        elif c2.form_submit_button(label='Admin Log in'):
            st.session_state.page = 'Admin Login Screen'
        #Reg New User
        elif st.form_submit_button(label='New User? Register here'):
            st.session_state.page = 'Registration Screen'
        print("Status after home page is ",st.session_state.page)
elif st.session_state.page == 'Registration Screen':
    print("Status after entering register screen is ",st.session_state.page)
    if authenticator.register_user('Register user', preauthorization=True):
        st.success('User registered successfully')
        st.session_state.page = 'Registration Finished'
    else:
        st.session_state.page = 'Start Up Screen'
    print("Status after clicking register screen is ",st.session_state.page)

I have put some print options for debugging in the code above. Status of st.session_state.page becomes Start Up Screen because script is rerun after clicking Register button defined inside form.
Below is the picture of Register button in the end of form.

Now your code has become way more complex, it has three buttons instead of one, and you are trying to store not the state of a button but… something related to three buttons plus the return value of authenticator.register_user(). I wouldn’t know what to do with that.

The best advice I can give you is: try to solve the problem as stated in the OP first, improve from there in small steps.

Here is simple code that has only one button and will get output of the function. This code will produce same result i.e. register_user_form.form_submit_button('Register') is False.

import yaml
from yaml.loader import SafeLoader
import streamlit as st
import streamlit_authenticator as stauth

#Page Title
st.set_page_config( page_title="Trial Run of Chat with Documents by Awais", 
                    page_icon=":books:",
                    initial_sidebar_state= "collapsed")
                   # layout="centered")

with open('./config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)

#Initialize session_stat
if 'page' not in st.session_state:
    st.session_state.page = 'Start Up Screen'
else:
    st.session_state.page = st.session_state.page 

if st.session_state.page == 'Start Up Screen':
    st.header("Trial Run of Chat with Documents :books:")
    with st.form(key='Home Page'):
        c1, c2, c3,c4 = st.columns(4)
        if c3.form_submit_button(label='New User? Register here'):
            st.session_state.page = 'Registration Screen'
        print("Status after home page is ",st.session_state.page)
elif st.session_state.page == 'Registration Screen':
    print("Status after entering register screen is ",st.session_state.page)
    if authenticator.register_user('Register user', preauthorization=True):
        st.success('User registered successfully')
        st.session_state.page = 'Registration Finished'
    else:
        st.session_state.page = 'Start Up Screen'
    print("Status after clicking register screen is ",st.session_state.page)

Here’s a helpful general resource about button state:

Here’s an attempt to rewrite your script using python structural pattern matching and using callbacks so that the session state always gets updated at the top of the screen

import streamlit as st


def registration_pressed():
    st.session_state.page = "Registration Screen"


def user_registered():
    st.session_state.registered = True


# Initialize session_stat
if "page" not in st.session_state:
    st.session_state.page = "Start Up Screen"

if "registered" not in st.session_state:
    st.session_state.registered = False

match st.session_state.page, st.session_state.registered:
    case ("Start Up Screen", *any):
        st.header("Trial Run of Chat with Documents :books:")
        st.button(label="New User? Register here", on_click=registration_pressed)
    case ("Registration Screen", False):
        st.header("Trial Run of Chat with Documents :books:")
        st.subheader("Registration Form")
        st.text_input("Name")
        st.text_input("Email")
        st.text_input("Password")
        st.button("Register", on_click=user_registered)
    case ("Registration Screen", True):
        st.success("User registered successfully")
        st.header("Chat with Documents :books:")
    case _:
        st.write("Something went wrong")
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.