The problem I’m facing is pertaining to the login button.
The issue is that when user logs in with right credential, then logs out, then logs in again.
In this second login, the user has to click the login button twice.
I don’t know what the issue might be. Has to be with session states but I thought they are persistent even in multi-page app.
Also, as a sidenote, sometimes in the first try when logging in, I get this faulty behavior and need to click again. What might be the issue?
Below is a small sample of the full code.
(My full code can be found at this Github Repository: GitHub - yashmehtakristal/KristalGPT-test: testing the authentication of KristalGPT.
This is my mainapp.py:
# All imports
__import__('pysqlite3')
import sys
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
import streamlit as st
# Setting page config & header
st.set_page_config(page_title="Kristal Retriever", page_icon="📖", layout="wide", initial_sidebar_state="expanded")
st.header("📖 Kristal Retriever")
import openai
import os
import tempfile
from tempfile import NamedTemporaryFile
from streamlit_extras.app_logo import add_logo
from st_pages import Page, Section, add_page_title, show_pages, hide_pages
from database_helper_functions import sign_up, fetch_users
import streamlit_authenticator as stauth
# Add the logo to the sidebar
add_logo("https://assets-global.website-files.com/614a9edd8139f5def3897a73/61960dbb839ce5fefe853138_Kristal%20Logotype%20Primary.svg")
show_pages(
[
Page("main.py","Login", "🗝️"),
Page("pages/home.py", "About", "😀"),
# Section(name = "Bulk Upload", icon="📚"),
Page("pages/bulk_upload_basic.py", "Bulk Upload - Basic", "📚"),
Page("pages/bulk_upload_advanced.py", "Bulk Upload - Advanced", "📚"),
# Section(name = "QA Basic", icon="❓"),
Page("pages/qa_basic.py", "Q&A - Basic", "❓"),
Page("pages/qa_advanced.py", "Q&A - Advanced", "❓"),
# Section(name = "Chatbot", icon="💬"),
# Page("pages/chatbot_without_memory.py", "Chatbot - Basic", "💬"),
# Page("pages/chatbot_with_memory.py", "Chatbot - Advanced", "💬")
]
)
# Session state variable to save "logged out" boolean value
if "logged_out" not in st.session_state:
st.session_state.logged_out = False
# Session state variable to save "logged in" boolean value
if "logged_in" not in st.session_state:
st.session_state.logged_in = False
# st.session_state['authentication_status']
if "authentication_status" not in st.session_state:
st.session_state.authentication_status = False
# Hide particular pages if not logged in
if not st.session_state.logged_in:
hide_pages(["About", "Bulk Upload - Basic", "Bulk Upload - Advanced", "Q&A - Basic", "Q&A - Advanced"])
# Hide particular pages if logged out
if st.session_state.logged_out:
hide_pages(["About", "Bulk Upload - Basic", "Bulk Upload - Advanced", "Q&A - Basic", "Q&A - Advanced"])
# Session state variable to save "username"
if "username" not in st.session_state:
st.session_state.username = ''
# Session state variable to save "Authenticator" object
if "Authenticator" not in st.session_state:
st.session_state.Authenticator = None
# Session state variable to save "Logout" object
if "logout" not in st.session_state:
st.session_state.logout = False
if "authentication_status" not in st.session_state:
st.session_state.authentication_status = False
if "credentials" not in st.session_state:
st.session_state.credentials = {}
# Calling the fetch_users() function which returns a dictionary of users
users = fetch_users()
# Will store the respective keys in the dictionary in the following lists
emails = []
usernames = []
passwords = []
for user in users:
emails.append(user['key'])
usernames.append(user['username'])
passwords.append(user['password'])
# Storing the credentials for each user in a dictionary
credentials = {'usernames': {}}
for index in range(len(emails)):
credentials['usernames'][usernames[index]] = {'name': emails[index], 'password': passwords[index]}
st.session_state.credentials = credentials
# Create an authentication object of the credentials
# Along, with the name of the cookie (to reauthenticate user without them re-entering credentials, so they can refresh page without providing their password again)
# Write random key to hash a cookies signature (abcdef)
# Specify number of days cookie can be used for (30 days)
Authenticator = stauth.Authenticate(credentials, cookie_name = 'Streamlit', key = 'abcdef', cookie_expiry_days = 0)
# Authenticator = stauth.Authenticate(credentials, cookie_name = 'Streamlit', key = 'abcdef', cookie_expiry_days = 30)
# Save Authenticator to session state
st.session_state.Authenticator = Authenticator
email, authentication_status, username = Authenticator.login('Login', 'main') # Get the email, authentication status and username from Login module
st.session_state.authentication_status = authentication_status
# st.rerun()
st.write("After authentication")
st.write("Authentication status variable", authentication_status)
st.write("Authentication status session state", st.session_state.authentication_status)
info, info1 = st.columns(2)
# If username is provided
if username:
# If username in the usernames list (from database)
if username in usernames:
# Save the username to session state
st.session_state.username = username
# st.rerun()
# Inside if loop
st.write("Inside if loop")
st.write("Authentication status variable", authentication_status)
st.write("Authentication status session state", st.session_state.authentication_status)
# If authentication status is True
# If st.session_state['authentication_status'] is True:
if authentication_status is True:
# Setting session state of logged in = True
# & log out = False
st.session_state.logged_in = True
st.session_state.logout = False
# let User see app
st.sidebar.subheader(f'Welcome {username}')
logout_button = Authenticator.logout('Log Out', 'sidebar')
# If user has clicked logged_out button, update the state variables
if logout_button:
st.session_state.logged_out = True
st.session_state.logged_in = False
# ERROR HANDLING
# st.session_state['authentication_status'] is False
elif authentication_status is False:
with info:
st.error('Incorrect Password or username')
else:
# Inside else loop
st.write("Inside else loop")
st.write("Authentication status variable", authentication_status)
st.write("Authentication status session state", st.session_state.authentication_status)
with info:
st.warning('Please feed in your credentials')
else:
with info:
st.warning('Username does not exist, Please Sign up')
I have a multi-page app, but let’s take this one page (test.py) for example:
import streamlit as st
from streamlit_extras.app_logo import add_logo
from st_pages import Page, Section, add_page_title, show_pages, hide_pages
import streamlit_authenticator as stauth
# Setting page config & header
st.set_page_config(page_title = "Kristal Retriever", page_icon = "📖", layout = "wide", initial_sidebar_state = "expanded")
st.header("📖 Kristal Retriever")
# Hide particular pages if not logged in
if not st.session_state.logged_in:
hide_pages(["Bulk Upload - Basic", "Bulk Upload - Advanced", "Q&A - Basic", "Q&A - Advanced"])
# Hide particular pages if logged out
if st.session_state.logged_out:
hide_pages(["Bulk Upload - Basic", "Bulk Upload - Advanced", "Q&A - Basic", "Q&A - Advanced"])
# Add the logo to the sidebar
add_logo("https://assets-global.website-files.com/614a9edd8139f5def3897a73/61960dbb839ce5fefe853138_Kristal%20Logotype%20Primary.svg")
import openai
import os
import tempfile
from tempfile import NamedTemporaryFile
from database_helper_functions import sign_up, fetch_users
import streamlit_authenticator as stauth
# let User access app only if logged in = True & logged out = False
if st.session_state.logged_in is True and st.session_state.logout is False:
# st.write()
st.sidebar.subheader(f'Welcome {st.session_state.username}')
st.write(st.session_state.Authenticator)
#st.session_state.Authenticator.logout('Log Out', 'sidebar')
Authenticator = stauth.Authenticate(st.session_state.credentials, cookie_name = 'Streamlit', key = 'abcdef', cookie_expiry_days = 0)
logout_button = Authenticator.logout('Log Out', 'sidebar')
# If user has clicked logged_out button, update the state variables
if logout_button:
st.session_state.logged_out = True
st.session_state.logged_in = False
st.session_state.authentication_status = False
# st.write("Before Rerun")
# st.write(st.session_state.logged_out, st.session_state.logged_in)
# st.write("XXXX")
st.rerun()
# Display Markdown of the main page
st.markdown("Markdown page")
else:
st.write("Authentication status session state", st.session_state.authentication_status)
st.info("Seems like you are not logged in. Please head over to the Login page to login", icon="ℹ️")