Skip to content

Commit

Permalink
fix: update experimental_fragment to fragment (#1131)
Browse files Browse the repository at this point in the history
* fix: update experimental_fragment to fragment

* Preserve release notes

* Version consistency

---------

Co-authored-by: Debbie Matthews <[email protected]>
  • Loading branch information
horw and sfc-gh-dmatthews authored Aug 12, 2024
1 parent ba5041d commit 07e0f86
Show file tree
Hide file tree
Showing 12 changed files with 35 additions and 37 deletions.
2 changes: 1 addition & 1 deletion content/develop/api-reference/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1965,7 +1965,7 @@ with st.form(key='my_form'):
Define a fragment to rerun independently from the rest of the script.

```python
@st.experimental_fragment(run_every="10s")
@st.fragment(run_every="10s")
def fragment():
df = get_data()
st.line_chart(df)
Expand Down
2 changes: 1 addition & 1 deletion content/develop/api-reference/control-flow/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def email_form():
Define a fragment to rerun independently from the rest of the script.

```python
@st.experimental_fragment(run_every="10s")
@st.fragment(run_every="10s")
def fragment():
df = get_data()
st.line_chart(df)
Expand Down
16 changes: 7 additions & 9 deletions content/develop/concepts/architecture/fragments.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ slug: /develop/concepts/architecture/fragments

# Working with fragments and partial reruns

Reruns are a central part of every Streamlit app. When users interact with widgets, your script reruns from top to bottom, and your app's frontend is updated. Streamlit provides several features to help you develop your app within this execution model. Streamlit version 1.33.0 introduced fragments to allow rerunning a portion of your code instead of your full script. As your app grows larger and more complex, these partial reruns help your app be efficient and performant. Fragments give you finer, easy-to-understand control over your app's execution flow.
Reruns are a central part of every Streamlit app. When users interact with widgets, your script reruns from top to bottom, and your app's frontend is updated. Streamlit provides several features to help you develop your app within this execution model. Streamlit version 1.37.0 introduced fragments to allow rerunning a portion of your code instead of your full script. As your app grows larger and more complex, these partial reruns help your app be efficient and performant. Fragments give you finer, easy-to-understand control over your app's execution flow.

Before you read about fragments, we recommend having a basic understanding of [caching](/develop/concepts/architecture/caching), [Session State](/concepts/architecture/session-state), and [forms](/develop/concepts/architecture/forms).

Expand All @@ -19,14 +19,14 @@ Fragments are versatile and applicable to a wide variety of circumstances. Here

## Defining and calling a fragment

Streamlit provides a decorator ([`st.experimental_fragment`](/develop/api-reference/execution-flow/st.fragment)) to turn any function into a fragment function. When you call a fragment function that contains a widget function, a user triggers a _partial rerun_ instead of a full rerun when they interact with that fragment's widget. During a partial rerun, your fragment function is re-executed. Anything within the main body of your fragment is updated on the frontend, while the rest of your app remains the same. We'll describe fragments written across multiple containers later on.
Streamlit provides a decorator ([`st.fragment`](/develop/api-reference/execution-flow/st.fragment)) to turn any function into a fragment function. When you call a fragment function that contains a widget function, a user triggers a _partial rerun_ instead of a full rerun when they interact with that fragment's widget. During a partial rerun, your fragment function is re-executed. Anything within the main body of your fragment is updated on the frontend, while the rest of your app remains the same. We'll describe fragments written across multiple containers later on.

Here is a basic example of defining and calling a fragment function. Just like with caching, remember to call your function after defining it.

```python
import streamlit as st

@st.experimental_fragment
@st.fragment
def fragment_function():
if st.button("Hi!"):
st.write("Hi back!")
Expand All @@ -50,13 +50,13 @@ import streamlit as st

st.title("My Awesome App")

@st.experimental_fragment()
@st.fragment()
def toggle_and_text():
cols = st.columns(2)
cols[0].toggle("Toggle")
cols[1].text_area("Enter text")

@st.experimental_fragment()
@st.fragment()
def filter_and_file():
cols = st.columns(2)
cols[0].checkbox("Filter")
Expand Down Expand Up @@ -89,10 +89,10 @@ If you need to trigger a full-script rerun from inside a fragment, call [`st.rer

## Automate fragment reruns

`st.experimental_fragment` includes a convenient `run_every` parameter that causes the fragment to rerun automatically at the specified time interval. These reruns are in addition to any reruns (fragment or full-script) triggered by your user. The automatic fragment reruns will continue even if your user is not interacting with your app. This is a great way to show a live data stream or status on a running background job, efficiently updating your rendered data and _only_ your rendered data.
`st.fragment` includes a convenient `run_every` parameter that causes the fragment to rerun automatically at the specified time interval. These reruns are in addition to any reruns (fragment or full-script) triggered by your user. The automatic fragment reruns will continue even if your user is not interacting with your app. This is a great way to show a live data stream or status on a running background job, efficiently updating your rendered data and _only_ your rendered data.

```python
@st.experimental_fragment(run_every="10s")
@st.fragment(run_every="10s")
def auto_function():
# This will update every 10 seconds!
df = get_latest_updates()
Expand Down Expand Up @@ -144,7 +144,5 @@ Caching saves you from unnecessarily running a piece of your app while the rest
## Limitations and unsupported behavior

- Fragments can't detect a change in input values. It is best to use Session State for dynamic input and output for fragment functions.
- Calling fragments within fragments is unsupported.
- Using caching and fragments on the same function is unsupported.
- Using fragments within callback functions is unsupported.
- Fragments can't render widgets in externally-created containers; widgets can only be in the main body of a fragment.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Streamlit lets you turn functions into [fragments](/develop/concepts/architectur
- The following must be installed in your Python environment:

```text
streamlit>=1.33.0
streamlit>=1.37.0
```

- You should have a clean working directory called `your-repository`.
Expand Down Expand Up @@ -56,7 +56,7 @@ def orange_cats():
st.markdown("🐾 🐾 🐾 🐾")


@st.experimental_fragment
@st.fragment
def herd_black_cats(card_a, card_b, card_c):
st.button("Herd the black cats")
container_a = card_a.container()
Expand All @@ -70,7 +70,7 @@ def herd_black_cats(card_a, card_b, card_c):
black_cats()


@st.experimental_fragment
@st.fragment
def herd_orange_cats(card_a, card_b, card_c):
st.button("Herd the orange cats")
container_a = card_a.container()
Expand Down Expand Up @@ -171,10 +171,10 @@ with st.sidebar:

Since each fragment will span across the sidebar and three additional containers, you'll use the sidebar to hold the main body of the fragment and pass the three containers as function arguments.

1. Use an [`@st.experimental_fragment`](/develop/api-reference/execution-flow/st.fragment) decorator and start your black-cat fragment definition.
1. Use an [`@st.fragment`](/develop/api-reference/execution-flow/st.fragment) decorator and start your black-cat fragment definition.

```python
@st.experimental_fragment
@st.fragment
def herd_black_cats(card_a, card_b, card_c):
```

Expand Down Expand Up @@ -229,7 +229,7 @@ Since each fragment will span across the sidebar and three additional containers
1. Similarly define your orange-cat fragment function.

```python
@st.experimental_fragment
@st.fragment
def herd_orange_cats(card_a, card_b, card_c):
st.button("Herd the orange cats")
container_a = card_a.container()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Streamlit lets you turn functions into [fragments](/develop/concepts/architectur
- The following must be installed in your Python environment:

```text
streamlit>=1.33.0
streamlit>=1.37.0
```

- You should have a clean working directory called `your-repository`.
Expand Down Expand Up @@ -80,7 +80,7 @@ else:
run_every = None


@st.experimental_fragment(run_every=run_every)
@st.fragment(run_every=run_every)
def show_latest_data():
last_timestamp = st.session_state.data.index[-1]
st.session_state.data = pd.concat(
Expand Down Expand Up @@ -204,7 +204,7 @@ def get_recent_data(last_timestamp):

### Initialize Session State values for your app

Since you will dynamically change the `run_every` parameter of `@st.experimental_fragment()`, you'll need to initialize the associated variables and Session State values before defining your fragment function. Your fragment function will also read and update values in Session State, so you can define those now to make the fragment function easier to understand.
Since you will dynamically change the `run_every` parameter of `@st.fragment()`, you'll need to initialize the associated variables and Session State values before defining your fragment function. Your fragment function will also read and update values in Session State, so you can define those now to make the fragment function easier to understand.

1. Initialize your data for the first app load in a session.

Expand Down Expand Up @@ -267,12 +267,12 @@ Since you will dynamically change the `run_every` parameter of `@st.experimental

### Build a fragment function to stream data

To allow the user to turn data streaming on and off, you must set the `run_every` parameter in the `@st.experimental_fragment()` decorator.
To allow the user to turn data streaming on and off, you must set the `run_every` parameter in the `@st.fragment()` decorator.

<Collapse title="Complete function to show and stream data" expanded={false}>

```python
@st.experimental_fragment(run_every=run_every)
@st.fragment(run_every=run_every)
def show_latest_data():
last_timestamp = st.session_state.data.index[-1]
st.session_state.data = pd.concat(
Expand All @@ -284,10 +284,10 @@ def show_latest_data():

</Collapse>

1. Use an [`@st.experimental_fragment`](/develop/api-reference/execution-flow/st.fragment) decorator and start your function definition.
1. Use an [`@st.fragment`](/develop/api-reference/execution-flow/st.fragment) decorator and start your function definition.

```python
@st.experimental_fragment(run_every=run_every)
@st.fragment(run_every=run_every)
def show_latest_data():
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Streamlit lets you turn functions into [fragments](/develop/concepts/architectur
- The following must be installed in your Python environment:

```text
streamlit>=1.33.0
streamlit>=1.37.0
```

- You should have a clean working directory called `your-repository`.
Expand Down Expand Up @@ -62,7 +62,7 @@ def get_data():
return data


@st.experimental_fragment
@st.fragment
def show_daily_sales(data):
time.sleep(1)
with st.container(height=100):
Expand Down Expand Up @@ -248,7 +248,7 @@ Since the daily sales data updates with every new date selection, you'll turn th
<Collapse title="Complete function to display daily sales data" expanded={false}>

```python
@st.experimental_fragment
@st.fragment
def show_daily_sales(data):
time.sleep(1)
selected_date = st.date_input(
Expand Down Expand Up @@ -282,10 +282,10 @@ def show_daily_sales(data):

</Collapse>

1. Use an [`@st.experimental_fragment`](/develop/api-reference/execution-flow/st.fragment) decorator and start your function definition.
1. Use an [`@st.fragment`](/develop/api-reference/execution-flow/st.fragment) decorator and start your function definition.

```python
@st.experimental_fragment
@st.fragment
def show_daily_sales(data):
```

Expand Down Expand Up @@ -472,7 +472,7 @@ Now, you have a functioning app that uses a fragment to prevent unnecessarily re
1. Add three containers to fix the height of elements in the `show_daily_sales` function.

```python
@st.experimental_fragment
@st.fragment
def show_daily_sales(data):
time.sleep(1)
with st.container(height=100): ### ADD CONTAINER ###
Expand Down
2 changes: 1 addition & 1 deletion python/api-examples-source/execution.fragment-rerun.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
st.session_state.clicks = 0


@st.experimental_fragment
@st.fragment
def count_to_five():
if st.button("Plus one!"):
st.session_state.clicks += 1
Expand Down
2 changes: 1 addition & 1 deletion python/api-examples-source/execution.fragment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
st.session_state.fragment_runs = 0


@st.experimental_fragment
@st.fragment
def fragment():
st.session_state.fragment_runs += 1
st.button("Rerun fragment")
Expand Down
2 changes: 1 addition & 1 deletion python/api-examples-source/execution.fragment_balloon.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import time


@st.experimental_fragment
@st.fragment
def release_the_balloons():
st.button("Release the balloons", help="Fragment rerun")
st.balloons()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def orange_cats():
st.markdown("🐾 🐾 🐾 🐾")


@st.experimental_fragment
@st.fragment
def herd_black_cats(card_a, card_b, card_c):
st.button("Herd the black cats")
container_a = card_a.container()
Expand All @@ -36,7 +36,7 @@ def herd_black_cats(card_a, card_b, card_c):
black_cats()


@st.experimental_fragment
@st.fragment
def herd_orange_cats(card_a, card_b, card_c):
st.button("Herd the orange cats")
container_a = card_a.container()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get_data():
return data


@st.experimental_fragment
@st.fragment
def show_daily_sales(data):
time.sleep(1)
with st.container(height=100):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def toggle_streaming():
run_every = None


@st.experimental_fragment(run_every=run_every)
@st.fragment(run_every=run_every)
def show_latest_data():
last_timestamp = st.session_state.data.index[-1]
st.session_state.data = pd.concat(
Expand Down

0 comments on commit 07e0f86

Please sign in to comment.