mkhorasani / Streamlit-Authenticator

A secure authentication module to validate user credentials in a Streamlit application.
Apache License 2.0
1.37k stars 229 forks source link

Cannot instantiate authenticator object in multiple pages: DuplicatedWidgetId #156

Open mattiatantardini opened 2 months ago

mattiatantardini commented 2 months ago

I'm following the documentation at steps 1 and 2, which states that one needs to recreate the Authenticator object and call the login method on each page of a multipage app.

I'm testing the functionality but cannot recreate the object in a different page. The exception is the following:

DuplicateWidgetID: There are multiple widgets with the same key='init'.

To fix this, please make sure that the key argument is unique for each widget you create.

Traceback:

File "/home/mattia/develop/caritas/zaccheo/zaccheo-ui/app.py", line 46, in <module>
    anagrafica_page()
File "/home/mattia/develop/caritas/zaccheo/zaccheo-ui/app/pages/anagrafica.py", line 13, in anagrafica_page
    authenticator = stauth.Authenticate(
                    ^^^^^^^^^^^^^^^^^^^^
File "/home/mattia/venvs/venv-zaccheo-ui/lib/python3.11/site-packages/streamlit_authenticator/authenticate/__init__.py", line 53, in __init__
    self.cookie_handler             =   CookieHandler(cookie_name,
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mattia/venvs/venv-zaccheo-ui/lib/python3.11/site-packages/streamlit_authenticator/authenticate/cookie/__init__.py", line 39, in __init__
    self.cookie_manager         =   stx.CookieManager()
                                    ^^^^^^^^^^^^^^^^^^^
File "/home/mattia/venvs/venv-zaccheo-ui/lib/python3.11/site-packages/extra_streamlit_components/CookieManager/__init__.py", line 22, in __init__
    self.cookies = self.cookie_manager(method="getAll", key=key, default={})
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mattia/venvs/venv-zaccheo-ui/lib/python3.11/site-packages/streamlit_option_menu/streamlit_callback.py", line 20, in wrapper_register_widget
    return register_widget(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I looked at the source code and it seems to me that there is no way to pass an explicit key to the CookieManager instantiated within the Authenticate object, which results for the CookieManager to always use the default init key.

My code follows.

app.py

import yaml
from yaml.loader import SafeLoader

import streamlit as st
import streamlit_authenticator as stauth
from streamlit_option_menu import option_menu

from app.pages.anagrafica import anagrafica_page

if __name__ == "__main__":

    with st.sidebar:
        st.title("My app")

    with open('./settings/users.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['pre-authorized']
    )

    authenticator.login()

    if st.session_state["authentication_status"]:
        with st.sidebar:
            # authenticator.logout()  
            st.write(f'Welcome *{st.session_state["name"]}*')

            page = option_menu(
                menu_title="Menù",
                options=["Anagrafica", "Tessere", "Scontrini", "Prodotti"],
                icons=["people-fill", "card-text", "receipt", "tag-fill"],
            )

        if page == "Anagrafica":
            anagrafica_page()

    elif st.session_state["authentication_status"] is False:
        st.error('Username/password is incorrect')
    elif st.session_state["authentication_status"] is None:
        st.warning('Please enter your username and password')

app.pages.anagrafica.py

import yaml
from yaml.loader import SafeLoader

import streamlit as st
import streamlit_authenticator as stauth

def anagrafica_page():

    with open('./settings/users.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['pre-authorized'],
        # key="anagrafica-auth"
    )

    authenticator.login()

    st.title("Anagrafica")

Environment:

Is there some sort of bug or am I missing something?

AngelicSage commented 3 weeks ago

I think that it might be the path you're in. It could also be that there might be an init file where there shouldn't be.

anderson-klabin commented 3 weeks ago

Same problem here

mkhorasani commented 3 weeks ago

Dear all, this issue will be resolved in the next release.