Streamlit Version 1.12 Bug?

I am using the same python code with streamlit v1.11 and v1.12.

But my dashboard seem to malfunction when using version1.12.
Please help!!

import plotly.express as px  # pip install plotly-express
import streamlit as st  # pip install streamlit
import pandas as pd
import codecs
import csv

counter = 0

def interactive_plot(a, b):
    global counter
    col1, col2 = st.columns(2)
    x_axis_val = col1.selectbox('Select the X-axis', options=df.columns, key=counter)
    y_axis_val = col2.selectbox('Select the Y-axis', options=df.columns, key=counter)
    plot = px.scatter(df[a:b], x=x_axis_val, y=y_axis_val)
    st.plotly_chart(plot, use_container_width=True)
    counter += 1


def interactive_sheet(a, b):
    parameterSelected = st.multiselect('Choose your parameters', df.columns)
    #parameterSelected.append['Timestamp']
    #nonRequired = [x for x in df if x not in parameterSelected]
    csvDisplayed = df
    st.dataframe(csvDisplayed[a:b])

st.set_page_config(page_title="XXX Dashboard", page_icon=":bar_chart:", layout="wide")
st.title(":bar_chart: XXX Dashboard")
st.markdown("##")

st.sidebar.header("Please upload a file:")
upload_file = st.sidebar.file_uploader('Select an XXX diagnostic file')

if upload_file is not None and 'data' not in st.session_state:
	st.session_state.data = None
if upload_file is not None and st.session_state.data is None:
	# Pandas data cleaning & formatting
	csv_reader = csv.reader(codecs.iterdecode(upload_file, 'utf-8'))	
	st.session_state.data = df

if dashboard == 'Custom':
    if upload_file is not None:
        try:
            df = st.session_state.data
            col1, col2 = st.columns(2)
            initialTime = col1.selectbox('Select the initial time', options=df['Timestamp'], key=counter)
            finalTime = col2.selectbox('Select the final time',
                                       options=df['Timestamp'][df[df['Timestamp'] == initialTime].index.values[0]:-1],
                                       key=counter)
            # Update the CSV
            interactive_sheet(df[df['Timestamp'] == initialTime].index.values[0], df[df['Timestamp'] == finalTime].index.values[0])

            # Data Visualization
            interactive_plot(df[df['Timestamp'] == initialTime].index.values[0], df[df['Timestamp'] == finalTime].index.values[0])
	    counter = counter +1
        except:
            pass
elif dashboard == 'None':
    st.header("Select a mode to continue")


This is what it look like when using version 1.11


This is using version 1.12

I tried to reproduce your issue, but was having trouble due to the a few pieces missing (e.g. dashboard and df are undefined).

My first suggestion would be to remove the try, except, and see what errors are being generated, if any. I suspect there are some errors that are being eaten by that except: that might be helpful to diagnose the issue.

If that doesn’t help, would you be able to share a more complete code example, and ideally even a sample file that would demonstrate the issue?

I am still unable to solve the issue.

This is the sample of the code.

# Import Libraries
import plotly.express as px  # pip install plotly-express
import streamlit as st  # pip install streamlit
import pandas as pd
import codecs
import csv

counter = 0


# Define functions
def interactive_plot(a, b):
    global counter
    col1, col2 = st.columns(2)
    x_axis_val = col1.selectbox('Select the X-axis', options=df.columns, key=counter)
    y_axis_val = col2.selectbox('Select the Y-axis', options=df.columns, key=counter)
    plot = px.scatter(df[a:b], x=x_axis_val, y=y_axis_val)
    st.plotly_chart(plot, use_container_width=True)
    counter += 1


def interactive_sheet(a, b):
    parameterSelected = st.multiselect('Choose your parameters', df.columns)
    nonRequired = [x for x in df if x not in parameterSelected]
    csvDisplayed = df.drop(nonRequired, axis=1)
    st.dataframe(csvDisplayed[a:b])


# Page Header
st.set_page_config(page_title="XXX Dashboard", page_icon=":bar_chart:", layout="wide")
st.title(":bar_chart: XXX Dashboard")
st.markdown("##")

# Setup the CSV file reader
st.sidebar.header("Please upload a file:")
upload_file = st.sidebar.file_uploader('Select an XXX diagnostic file')

########################################################################################################################
# Data Cleaning
if upload_file is not None and 'data' not in st.session_state:
     st.session_state.data = None
if upload_file is not None and st.session_state.data is None:
    # Convert to CSV using utf-8 decoding
    csv_reader = csv.reader(codecs.iterdecode(upload_file, 'utf-8'))
    # Save the CSV into a list
    data_list = []
    for i, line in enumerate(csv_reader):
        data_list.append(line)
    df = pd.DataFrame(data_list)
    st.session_state.data = df
    print("Data cleaned")
########################################################################################################################

# Navigate through different pages
st.sidebar.header("Mode:")
dashboard = st.sidebar.selectbox(
    'Please select your dashboard:',
    ('None', 'Default', 'Custom'))

if dashboard == 'Custom':
    if upload_file is not None:
        df = st.session_state.data
        col1, col2 = st.columns(2)
        initialTime = col1.selectbox('Select the initial time', options=df[0], key=counter)
        finalTime = col2.selectbox('Select the final time',
                                   options=df[0][df[df[0] == initialTime].index.values[0]:-1],
                                   key=counter)
        # Update the CSV
        interactive_sheet(df[df[0] == initialTime].index.values[0], df[df[0] == finalTime].index.values[0])
        counter = counter +1
        # Data Visualization
        interactive_plot(df[df[0] == initialTime].index.values[0], df[df[0] == finalTime].index.values[0])

elif dashboard == 'None':
    st.header("Select a mode to continue")

@Jgan0290 It looks like you have indeed found a bug! I reported it on Github: Streamlit 1.12.0 doesn't allow the same key for widgets with different names · Issue #5164 · streamlit/streamlit · GitHub

Fortunately, you can work around this fairly easily without switching your streamlit version. Instead of using key=counter, you can do something like key=f"{counter}-final", and as long as you add some unique string to each different widget, it works fine. Here’s a version of your code with a couple of changes to the key that seems to work for me.

# Import Libraries
import codecs
import csv

import pandas as pd
import plotly.express as px  # pip install plotly-express
import streamlit as st  # pip install streamlit

counter = 0

# Define functions
def interactive_plot(a, b):
    global counter
    st.write("Rigth now", counter)
    col1, col2 = st.columns(2)
    x_axis_val = col1.selectbox("Select the X-axis", options=df.columns, key=counter)
    y_axis_val = col2.selectbox("Select the Y-axis", options=df.columns, key=f"{counter}-y")
    plot = px.scatter(df[a:b], x=x_axis_val, y=y_axis_val)
    st.plotly_chart(plot, use_container_width=True)
    counter += 1


def interactive_sheet(a, b):
    parameterSelected = st.multiselect("Choose your parameters", df.columns)
    nonRequired = [x for x in df if x not in parameterSelected]
    csvDisplayed = df.drop(nonRequired, axis=1)
    st.dataframe(csvDisplayed[a:b])


# Page Header
st.set_page_config(page_title="XXX Dashboard", page_icon=":bar_chart:", layout="wide")
st.title(":bar_chart: XXX Dashboard")
st.markdown("##")

st.sidebar.write("Streamlit version", st.__version__)

# Setup the CSV file reader
st.sidebar.header("Please upload a file:")
upload_file = st.sidebar.file_uploader("Select an XXX diagnostic file")

########################################################################################################################
# Data Cleaning
if upload_file is not None and "data" not in st.session_state:
    st.session_state.data = None
if upload_file is not None and st.session_state.data is None:
    # Convert to CSV using utf-8 decoding
    csv_reader = csv.reader(codecs.iterdecode(upload_file, "utf-8"))
    # Save the CSV into a list
    data_list = []
    for i, line in enumerate(csv_reader):
        data_list.append(line)
    df = pd.DataFrame(data_list)
    st.session_state.data = df
    print("Data cleaned")
########################################################################################################################

# Navigate through different pages
st.sidebar.header("Mode:")
dashboard = st.sidebar.selectbox(
    "Please select your dashboard:", ("None", "Default", "Custom")
)

st.write("Counter", counter)

if dashboard == "Custom":
    if upload_file is not None:
        df = st.session_state.data
        col1, col2 = st.columns(2)
        initialTime = col1.selectbox(
            "Select the initial time", options=df[0], key=counter
        )
        finalTime = col2.selectbox(
            "Select the final time",
            options=df[0][df[df[0] == initialTime].index.values[0] : -1],
            key=f"{counter}-finaltime",
        )
        # Update the CSV
        interactive_sheet(
            df[df[0] == initialTime].index.values[0],
            df[df[0] == finalTime].index.values[0],
        )
        counter = counter + 1
        # Data Visualization
        interactive_plot(
            df[df[0] == initialTime].index.values[0],
            df[df[0] == finalTime].index.values[0],
        )

elif dashboard == "None":
    st.header("Select a mode to continue")
1 Like

Turns out, this is not in fact a bug, but it is new behavior. It is an intended change, to make sure that we keep track of widget state better. So now, you have to have unique keys for each widget that you create, even if they have different labels. Streamlit 1.12.0 doesn't allow the same key for widgets with different labels · Issue #5164 · streamlit/streamlit · GitHub

1 Like

It works!!! Thank you very much for the help.