St.experimental_fragment works in 1.34, but in 1.36 throws "Fragments cannot write to elements outside of their container"

python==3.10.2
streamlit==1.34 (ok)
streamlit==1.36 (error)

I have a “base” dataframe, and then I want to filter it using fragment, to avoid rerunning whole script, including reloading the “base” dataframe. My real code is much more complicated than the snippet below, but the idea is the same. It was working fine with streamlit 1.34, when I upgraded to 1.36, I get the exception “Fragments cannot write to elements outside of their container”.

import streamlit as st
import pandas as pd
from streamlit.delta_generator import DeltaGenerator


@st.experimental_fragment
def fragment_function(
    filters_container_empty: DeltaGenerator,
    data_container_empty: DeltaGenerator,
):
    filters_container_empty.write("Filters")
    data_container_empty.write("Filtered data")
    value_filter = filters_container_empty.selectbox(
        "Filter:", options=df_main["VALUE"].unique().tolist()
    )
    df_filtered= df_main[df_main["VALUE"] == value_filter]
    data_container_empty.dataframe(df_filtered)


col_main, col_fragment = st.columns([0.6, 0.4])
with col_main:
    cnt_main = st.container(border=True)
    data = {
        "KEY": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        "VALUE": ["A", "B", "C", "D", "E", "A", "B", "C", "D", "E"],
    }
    df_main = pd.DataFrame(data)
    cnt_main.dataframe(df_main)

with col_fragment:
    filters_container = st.container(height=100, border=True)
    data_container = st.container(height=200, border=True)
    fragment_function(
        filters_container.empty(),
        data_container.empty(),
    )

with 1.34 I get expected result:

with 1.36 I get an exception when I try to place a selectbox inside the “filters_container_empty” container:

but I can “write” to it (filters_container_empty.write(“Filters”)).

am I missing something?

UPDATE:
when I move the container creation to the function itself, no exception is thrown
is this an expected behavior?
if so, why I “write” works, but “selectbox” doesn’t work?

Also, it appears, that the “experimental_” prefix was removed in the API help, but not in the code itself. So API refers to “st.fragment” while all other references (including the actual code) say “st.experimental_fragment”

It is experimental_fragment everywhere except the side bar.

There is a warning in the docs:

Fragments can only contain widgets in their main body. Fragments can’t render widgets to externally created containers.

This is new in streamlit 1.36, as stated in the release notes:

Fragments no longer support rendering widgets outside of their main body (#8756).

See the linked issue for the rationale.

Because st.write doesn’t create any widgets.

Thank you for such quick and detailed answer.

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