Controlling the state and title of st.expander()

Hi,
I am new to streamlit, so there is probably an easy way to do this, but basically I have an expanding container in which I’m putting a login widget. I want to control the state of the login widget based on the authentication. It is initialized in the expanded state. On successful login, I want to minimize the expander and change the title of the expander to “Welcome {user name}”

I know session.state might help, but the only implementation I’ve found is to use a dedicated button to switch between the expander states. but that is not possible for the UI I want.
Any help?

1 Like

Hi @raghav_kaul,

Thanks for posting!

Here’s an implementation that you can modify to fit your requirements.

import streamlit as st

def main():
    st.title("Welcome to My Super Cool App")

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

    if st.session_state['is_logged_in']:
        with st.expander(label=f"Welcome {st.session_state['user_name']}", expanded=False):
            st.write("🎉 Hooray! You've unlocked the secret chamber of this app!")
    else:
        with st.expander(label="Please log in", expanded=True):
            user_name = st.text_input("Username")
            password = st.text_input("Password", type="password")

            if st.button("Login", on_click=login, args=(user_name, password)):
                pass

def login(user_name, password):
    if user_name == "User" and password == "supersecret":  # In real life, use secure password handling!
        st.session_state['is_logged_in'] = True
        st.session_state['user_name'] = user_name

# Kick off the app
main()

Let me know if this is helpful.

1 Like

Hi @tonykip, thanks for replying! I think the implementation of the login widget might be a newer one(or older one I don’t know).
Please check my code and help me out with implementing your solution

so what I want to achieve is a command with which I can change the attributes(label and expanded) of login_widget, which I would write under if authentication status:

My confusion is arising from your use of a separate function for login, which is not the case in this repository. the passwords are hashed and the login authenticator is written in a different file. Thank you very much for your patience!

Can you please paste the code in a code block so I can copy it and also include the code for authentication? You can mask out any sensitive information or add dummy values.

code of the screenshot i sent you

    login_widget = st.expander(label="Login", expanded=True)
    with login_widget:  
        authenticator = setup_authenticator() 
        login_collumn,_,_ = st.columns((0.3,0.3,0.4))
        with login_collumn:
            name, authentication_status,username = authenticator.login('', 'main')

        # check authentication 
        if authentication_status: 
            st.write(f'Welcome *{name}*')   
            authenticator.logout('Logout', 'main')
            
           
        if authentication_status == False:
            st.error('Username/password is incorrect')

code for the setup_authenticator() function

import streamlit_authenticator as stauth

from utils.load import load_auth_config

def setup_authenticator():
    
    config = load_auth_config('auth_config.yaml')
    authenticator = stauth.Authenticate(
        config['credentials'],
        config['cookie']['name'],
        config['cookie']['key'],
        config['cookie']['expiry_days'],
    )
    
    return authenticator

the auth_config.yaml file is just a file with the username and hashed passwords which I’m assuming you wont need

and this is the load_auth_config() function

def load_auth_config(auth_config: str) -> Dict[Any, Any]:
    file_path = Path(get_project_root()) / f"config/{auth_config}"
    with file_path.open() as file:
        config = yaml.load(file, Loader=SafeLoader)
    return config

please note this code is old and not written by me and was done hastily so might not be the most efficient way to do this.

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