lukasmasuch/streamlit-pydantic

InputUI.render_ui silences important streamlit exceptions

falcaopetri opened this issue · 1 comments

Describe the bug:
My specific use case was combining sp.pydantic_form and a List data field:

from typing import List

import streamlit_pydantic as sp
from pydantic import BaseModel, Field

class ShowcaseModel(BaseModel):
    int_list: List[int] = Field(..., title="Int List title", description="Int List desc")
    str_list: List[str]

session_data = sp.pydantic_form(
    key="form",
    model=ShowcaseModel
)

This yields the following:

Note: I'm filing this as a bug since the current behavior renders a hard to debug, unexpected UI.

Expected behaviour:
I expected something similar to using sp.pydantic_input:

Additional context:
streamlit does not support buttons inside forms (see feature request in streamlit/streamlit#4892).
This is the real culprit of the half-rendered output. But it has a pretty way to inform users about what happened:

import streamlit as st

with st.form(key="key"):
    st.button("label")
    submit_button = st.form_submit_button(label="submit")

Possible Fix:
Considering the example in this issue, the rendering process stops at the first st.button found:

self._render_list_add_button(key, add_col, data_list)

Then streamlit raises a StreamlitAPIException, that is silenced within InputUI.render_ui:

try:
value = self._render_property(streamlit_app, property_key, property)
if not self._is_value_ignored(property_key, value):
self._store_value(property_key, value)
except Exception:
pass

It would be helpful to do at least one of:

  • Warn users when using sp.pydantic_form+fields that use buttons
  • Re-raise StreamlitAPIException (so streamlit properly renders it)
  • Log the exception (similarly to OutputUI.render_ui)

A similar issue can happen in other scenarios that trigger the except -> pass behavior.

I can also create a PR if you point me in the right direction.

Taik commented

Thanks for this issue -- I also got bit by this.