Using a list of class instances as selectbox options leads to serialization error

I wanted to use the following class

class Metric():
    def __init__(self, label: str, metric: str) -> None:
        self.label = label
        self.metric = metric
    
    def get_label(self) -> str:
        return self.label
    
    def get_metric(self) -> str:
        return self.metric


METRICS = [
    Metric(
        label="Offer Count",
        metric="offer_count",
    ),
    Metric(
        label="Median Price",
        metric="median_price",
    ),
    Metric(
        label="Median Price per Day",
        metric="median_price_per_day",
    ),
    Metric(
        label="Median Offer Count per Request",
        metric="median_offer_count_per_request",
    ),
]

and use the list of Metric instances as options for a selectbox like the following

st.sidebar.selectbox(
        label="Select a metric",
        options=METRICS,
        format_func=lambda metric: metric.get_label(),
)

which leads to this error:

Exception in thread ScriptRunner.scriptThread:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/threading.py", line 980, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/site-packages/streamlit/scriptrunner/script_runner.py", line 289, in _run_script_thread
    widget_states = self._session_state.get_widget_states()
  File "/usr/local/lib/python3.9/site-packages/streamlit/state/safe_session_state.py", line 82, in get_widget_states
    return self._state.get_widget_states()
  File "/usr/local/lib/python3.9/site-packages/streamlit/state/session_state.py", line 576, in get_widget_states
    return self._new_widget_state.as_widget_states()
  File "/usr/local/lib/python3.9/site-packages/streamlit/state/session_state.py", line 249, in as_widget_states
    states = [
  File "/usr/local/lib/python3.9/site-packages/streamlit/state/session_state.py", line 252, in <listcomp>
    if self.get_serialized(widget_id)
  File "/usr/local/lib/python3.9/site-packages/streamlit/state/session_state.py", line 230, in get_serialized
    serialized = metadata.serializer(item.value)
  File "/usr/local/lib/python3.9/site-packages/streamlit/elements/selectbox.py", line 160, in serialize_select_box
    return index_(opt, v)
  File "/usr/local/lib/python3.9/site-packages/streamlit/util.py", line 129, in index_
    raise ValueError("{} is not in iterable".format(str(x)))
ValueError: <Metric.Metric object at 0x7f7edc543940> is not in iterable

The selectbox itself is working absolutely fine. Can someone help me with this issue?

Hi @itsmartinhi, welcome to the Streamlit community!

Is this a simplified example of the class you are trying to provide or is this your actual example? In general, for the pattern you are showing, I’m sure having a class instance here is adding to the code clarity, so the easiest thing would be to remove it and use a list of strings.

Best,
Randy

Thank you for your response!
The class displayed here is kinda simplified. I worked around the issue by wrapping the class instances into a dictionary. Pretty ugly, but it works, and I still have the full functionality of my class.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.