I'm building a Streamlit app to analyze Excel files. In the app, I have a selectbox where users can choose a column from the uploaded Excel file. However, each time I change the value of the selectbox to a different column, the entire page refreshes. This behavior is not desired as it disrupts the user experience. How can I modify the code to prevent the page from refreshing every time the selectbox value changes?
import streamlit as st
import pandas as pd
import helpers.script as script
@st.cache_data # Cache the function based on month and year
def get_excel_path(month, year):
return script.get_data(month, year) # Call the original function
def read_excel_file(uploaded_file):
"""Reads the uploaded CSV file and returns a pandas DataFrame."""
try:
df = pd.read_excel(uploaded_file)
return df
except Exception as e:
st.error(f"Error reading the file: {e}")
return None
def display_unique_values(df, selected_column):
"""Displays the unique values in the selected column."""
if selected_column:
unique_values = df[selected_column].unique()
st.write(f"Unique values in '{selected_column}':")
st.dataframe(unique_values)
st.title("Excel File Analyzer")
year = st.number_input("Enter Year:", min_value=2024, max_value=None)
month = st.number_input("Enter Month (1-12)", min_value=1, max_value=12, step=1)
excel_path = None
df = None
if st.button("Generate Report"):
excel_path = get_excel_path(month, year)
if excel_path is not None:
df = read_excel_file(excel_path)
if df is not None:
# Get all column names
column_options = list(df.columns)
# Create a selectbox
selected_column = st.selectbox("Select a column:", column_options, key="column_selectbox")
display_unique_values(df.copy(), selected_column) # Avoid modifying original DataFrame
st.stop()
EDIT: I tried a mock app, I used a file uploader to check if it is working and it worked perfectly and it is the same excel file that I am getting the path of from the helper function, below is the code, I used the code from this mock app to the main app so that it may work too, but it did not.
import streamlit as st
import pandas as pd
def read_excel_file(uploaded_file):
"""Reads the uploaded CSV file and returns a pandas DataFrame."""
try:
df = pd.read_excel(uploaded_file)
return df
except Exception as e:
st.error(f"Error reading the file: {e}")
return None
def display_unique_values(df, selected_column):
"""Displays the unique values in the selected column."""
if selected_column:
unique_values = df[selected_column].unique()
st.write(f"Unique values in '{selected_column}':")
st.dataframe(unique_values)
st.title("Excel File Analyzer")
uploaded_file = st.file_uploader("Choose an Excel file", type="xlsx")
if uploaded_file is not None:
df = read_excel_file(uploaded_file)
if df is not None:
# Get all column names
column_options = list(df.columns)
# Create a selectbox
selected_column = st.selectbox("Select a column:", column_options)
display_unique_values(df.copy(), selected_column) # Avoid modifying original DataFrame
st.stop()
In Streamlit every time updating it will read all code from top to bottom. However, you can avoid that by using Caching. Caching is checking 2 situation. The first one is in whether the function parameters are same or not, and checking inside function is the same or not. If both are the same then streamlit will skip executing this function. So best way is put caching each function that it won't change.
You can need to take a look at the Caching documentation in Streamlit. Here is the link for you.
https://docs.streamlit.io/library/advanced-features/caching#advanced-usage