Fragments
Streamlit reruns the script from top to bottom upon user interaction. In version 1.37.0, it introduced fragments to allow rerunning a portion of your code instead of your full script.
Why Fragments
Fragments are versatile and applicable to a wide variety of circumstances. Here are a few common scenarios where fragments are useful:
- Your app has multiple visualizations, and each one takes time to load, but you have a filter input that only updates one of them.
- You have a dynamic form that doesn't need to update the rest of your app (until the form is complete).
- You want to automatically update a single component or group of components to stream data.
Usage
Streamlit provides a decorator (st.fragment) to turn any function into a fragment function. User interaction on any widget within a fragment function, will only rerun the fragment instead of a full rerun. Example:
import streamlit as st
@st.fragment
def fragment_function():
if st.button("Hi!"):
st.write("Hi back!")
fragment_function()If you want the main body of your fragment to appear in the sidebar or another container, call your fragment function inside a context manager.
with st.sidebar:
fragment_function()NOTE
In Streamlit, container elements are components or layouts that help organize and group related elements together.
Return Value
Streamlit ignores the return values of fragment functions during reruns, so it’s recommended not to define return values in these functions. Instead, if your fragment needs to share data with the rest of your app, use Session State.
Clearing Elements
- Elements drawn within the fragment: If your fragment draws elements in the main part of the fragment’s body, they are cleared and redrawn in place whenever the fragment reruns. So, no new elements are added each time the fragment runs.
- Elements drawn outside the fragment: If your fragment writes to containers outside its main body, these elements are not cleared during each rerun. They will accumulate and appear repeatedly, leading to duplication until the full script is rerun.
- Widget Placement: A fragment can't draw widgets in containers outside of its main body. If you want to draw widgets from a fragment, they need to be part of the main body of the fragment.
Prevent accumulation in containers
If you’re writing elements to containers outside the fragment and want to prevent accumulation or duplication, use st.empty() containers. st.empty() creates a container that can hold a single element, and it automatically clears the previous element when a new one is drawn inside.
See this tutorial from official docs to create a fragment across multiple containers.
Trigger full script rerun
If you need to trigger a full script rerun from within a fragment, you can do so using st.rerun(). This will force the app to start over from the top, clearing all elements and running every command again.
See this tutorial from official docs for more info
Automatic Reruns
Streamlit fragments provide the run_every parameter, which allows fragments to rerun automatically at a specified time interval. These reruns are in addition to any reruns (fragment or full-script) triggered by your user.
TIP
You can dynamically stop the automatic rerun, by passing None to run_every parameter.
@st.fragment(run_every="10s")
def auto_function():
# This will update every 10 seconds!
df = get_latest_updates()
st.line_chart(df)
auto_function()Limitations
- Fragments can't detect changes in input values. For dynamic input and output, it is recommended to use Session State within fragment functions.
- Using caching and fragments on the same function is unsupported.
- Fragments can't render widgets in externally-created containers; widgets can only be in the main body of a fragment.
