I understand that in Streamlit’s multipage app structure, each file in the pages folder is automatically rendered as a separate page in the application’s sidebar. I’m trying to create a Streamlit app where, upon visiting, only a “Sign In” page is initially visible in the sidebar. After a successful sign-in, the app should display the other pages in the sidebar and hide the “Sign In” page.
To achieve this, I need to dynamically show or hide pages in the sidebar based on certain conditions—in this case, whether the user is part of a specified list of users. If the user is on the list, I want to display all pages; otherwise, I only want to display a single page. However, it appears that all files in the pages folder are rendered by default, with no straightforward way to control which pages are displayed based on these conditions.
Use st.Page
and st.navigation
to change what pages are available to a user: Define multipage apps with st.Page and st.navigation - Streamlit Docs
Hi @SiddhantSadangi, thank you for your response!
I’m using OAuth2Session for authentication and then added the following code:
# List of admin names
ADMIN_NAMES = ["Name"]
# Function to show the dashboard based on role
def show_page():
if st.session_state.role == "User":
st.title("User Page")
# Display user-specific pages
user_page = st.Page("user/1_user.py", title="User Page")
account_page = st.Page(logout, title="Log out")
st.navigation([account_page, user_page])
elif st.session_state.role == "Admin":
st.title("Admin Page")
# Display both admin and user pages for admins
user_page = st.Page("user/1_user.py", title="User Page")
admin_page_1 = st.Page("admin/2_admin.py", title="Admin Page 1")
account_page = st.Page(logout, title="Log out")
st.navigation([account_page, user_page, admin_page_1])
# Check if the user is already authenticated and their role
def main():
if "oauth_token" in st.session_state:
user_name = st.session_state.user_info['name'] # Get the user's name
st.write(f"Hello, {user_name}!")
# Check if the user is an admin
if user_name in ADMIN_NAMES:
st.session_state.role = "Admin"
else:
st.session_state.role = "User"
# Show the appropriate content based on the user's role
show_page()
else:
if 'oauth_token' not in st.session_state and 'code' in st.query_params:
handle_oauth_callback() # Handle the OAuth callback and retrieve user info
else:
st.write("You are not logged in. Please log in to continue.")
redirect_to_login(False) # Redirect to login page
if __name__ == "__main__":
main()
However, it’s not functioning as expected. After logging in, the sidebar doesn’t appear. I’m new to using Streamlit and would really appreciate your help with this. Thanks in advance!
Hi,
st.navigation returns the current page which can be executed by .run() method, you need to incorporate .run() method in your code.
pg = st.navigation([st.Page("page_1.py"), st.Page(page_2)])
pg.run()
The only reason I see for the sidebar not being displayed is the oauth_token
not being in session state, or st.session_state.role not in ["User", "Admin"]
.
After logging in, can you write the contents of st.session_state
to check if the oauth_token
and roles are as expected?
You can also simplify show_page()
to as follows:
def show_page():
user_page = st.Page("user/1_user.py", title="User Page")
account_page = st.Page(logout, title="Log out")
admin_page_1 = st.Page("admin/2_admin.py", title="Admin Page 1")
if st.session_state.role == "User":
st.title("User Page")
# Display user-specific pages
st.navigation([account_page, user_page])
elif st.session_state.role == "Admin":
st.title("Admin Page")
# Display both admin and user pages for admins
st.navigation([account_page, user_page, admin_page_1])
Since account and user pages will be shown irrespective of the role, try moving them outside the if-else block to see if the sidebar is now being rendered