pypi-streamlit

Description
A faster way to build and share data apps
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/pypi-streamlit@1.50.0

state-management.md docs/

1
# State Management
2
3
Session state, query parameters, and context management for maintaining application state across interactions. Streamlit provides powerful state management capabilities that persist data between script reruns.
4
5
## Capabilities
6
7
### Session State
8
9
Persistent state management that survives script reruns, enabling stateful applications.
10
11
```python { .api }
12
session_state: SessionStateProxy
13
```
14
15
Session state acts like a dictionary that persists across app reruns. Any data stored in session state will be available in subsequent reruns until the session ends.
16
17
**Key Properties:**
18
- **Persistence**: Values persist across script reruns
19
- **Dictionary-like**: Supports standard dict operations (get, set, del, keys, etc.)
20
- **Widget Integration**: Automatically syncs with widget values when `key` parameter is used
21
- **Initialization**: Values can be initialized on first access
22
23
Example usage:
24
```python
25
# Initialize session state
26
if "count" not in st.session_state:
27
st.session_state.count = 0
28
29
# Access and modify state
30
if st.button("Increment"):
31
st.session_state.count += 1
32
33
st.write(f"Count: {st.session_state.count}")
34
35
# Store complex data
36
if "data" not in st.session_state:
37
st.session_state.data = {"users": [], "settings": {}}
38
39
# Widget state integration
40
name = st.text_input("Name", key="user_name")
41
# st.session_state.user_name now contains the input value
42
43
# Callback functions with state
44
def update_data():
45
st.session_state.data["last_update"] = datetime.now()
46
47
st.button("Update", on_click=update_data)
48
```
49
50
**Common Patterns:**
51
```python
52
# Conditional initialization
53
if "initialized" not in st.session_state:
54
st.session_state.initialized = True
55
st.session_state.user_data = load_user_data()
56
57
# Page state management
58
if "current_page" not in st.session_state:
59
st.session_state.current_page = "home"
60
61
# Multi-step forms
62
if "form_step" not in st.session_state:
63
st.session_state.form_step = 1
64
65
# Data caching in state
66
if "processed_data" not in st.session_state:
67
st.session_state.processed_data = expensive_computation()
68
```
69
70
### Query Parameters
71
72
URL query parameter management for shareable and bookmarkable app states.
73
74
```python { .api }
75
query_params: QueryParamsProxy
76
```
77
78
Query parameters provide a way to encode app state in the URL, making it possible to share specific app states or bookmark particular views.
79
80
**Key Properties:**
81
- **URL Integration**: Automatically syncs with browser URL
82
- **Shareable**: URLs can be shared to recreate app state
83
- **Dictionary-like**: Standard dict operations for parameter access
84
- **Type Handling**: All values are strings (conversion needed for other types)
85
86
Example usage:
87
```python
88
# Read query parameters
89
params = st.query_params
90
page = params.get("page", "home") # Default to "home"
91
user_id = params.get("user_id")
92
93
# Set query parameters (updates URL)
94
st.query_params["page"] = "dashboard"
95
st.query_params["filter"] = "active"
96
97
# Multiple parameters
98
st.query_params.update({
99
"view": "table",
100
"sort": "name",
101
"order": "asc"
102
})
103
104
# Clear specific parameter
105
if "temp_param" in st.query_params:
106
del st.query_params["temp_param"]
107
108
# Clear all parameters
109
st.query_params.clear()
110
111
# Type conversion (all query params are strings)
112
if "page_num" in st.query_params:
113
page_num = int(st.query_params["page_num"])
114
else:
115
page_num = 1
116
```
117
118
**Common Patterns:**
119
```python
120
# Page routing with query params
121
page = st.query_params.get("page", "home")
122
123
if page == "home":
124
show_home_page()
125
elif page == "data":
126
show_data_page()
127
128
# Filter state in URL
129
filters = {
130
"category": st.query_params.get("category", "all"),
131
"status": st.query_params.get("status", "active"),
132
"sort": st.query_params.get("sort", "name")
133
}
134
135
# Update URL when filters change
136
if st.selectbox("Category", options, key="cat_filter") != filters["category"]:
137
st.query_params["category"] = st.session_state.cat_filter
138
139
# Shareable dashboard state
140
st.query_params.update({
141
"chart_type": selected_chart,
142
"date_range": f"{start_date}_{end_date}",
143
"metrics": ",".join(selected_metrics)
144
})
145
```
146
147
### Context Information
148
149
Access to current execution context and environment information.
150
151
```python { .api }
152
context: ContextProxy
153
```
154
155
Context provides access to information about the current execution environment, headers, and request details.
156
157
**Key Properties:**
158
- **Headers**: Access to HTTP headers from the request
159
- **Environment**: Information about the execution context
160
- **Request Details**: Client and server information
161
162
Example usage:
163
```python
164
# Access request headers
165
headers = st.context.headers
166
user_agent = headers.get("User-Agent", "Unknown")
167
referer = headers.get("Referer")
168
169
# Client information
170
st.write(f"User Agent: {user_agent}")
171
172
# Check for specific headers
173
if "Authorization" in headers:
174
auth_token = headers["Authorization"]
175
user = validate_token(auth_token)
176
```
177
178
### Legacy Query Parameter Functions (Deprecated)
179
180
These functions are deprecated but still available for backward compatibility.
181
182
```python { .api }
183
def experimental_get_query_params():
184
"""
185
Get current query parameters (deprecated).
186
187
Returns:
188
dict: Current query parameters
189
190
Note:
191
Deprecated in favor of st.query_params
192
"""
193
194
def experimental_set_query_params(**kwargs):
195
"""
196
Set query parameters (deprecated).
197
198
Args:
199
**kwargs: Query parameters to set
200
201
Note:
202
Deprecated in favor of st.query_params
203
"""
204
```
205
206
### State Management Patterns
207
208
#### Widget State Synchronization
209
210
```python
211
# Automatic state sync with key parameter
212
name = st.text_input("Name", key="user_name")
213
# st.session_state.user_name is automatically updated
214
215
# Manual state access
216
if st.session_state.user_name:
217
st.write(f"Hello, {st.session_state.user_name}!")
218
219
# Callback with state update
220
def on_name_change():
221
st.session_state.greeting = f"Hello, {st.session_state.user_name}!"
222
223
st.text_input("Name", key="user_name", on_change=on_name_change)
224
```
225
226
#### Multi-Step Workflows
227
228
```python
229
# Initialize workflow state
230
if "step" not in st.session_state:
231
st.session_state.step = 1
232
st.session_state.form_data = {}
233
234
# Step navigation
235
if st.session_state.step == 1:
236
name = st.text_input("Enter name")
237
if st.button("Next") and name:
238
st.session_state.form_data["name"] = name
239
st.session_state.step = 2
240
st.rerun()
241
242
elif st.session_state.step == 2:
243
email = st.text_input("Enter email")
244
col1, col2 = st.columns(2)
245
with col1:
246
if st.button("Previous"):
247
st.session_state.step = 1
248
st.rerun()
249
with col2:
250
if st.button("Submit") and email:
251
st.session_state.form_data["email"] = email
252
submit_form(st.session_state.form_data)
253
st.success("Form submitted!")
254
```
255
256
#### Conditional State Initialization
257
258
```python
259
# Initialize state with default values
260
defaults = {
261
"user_preferences": {"theme": "light", "language": "en"},
262
"app_data": {"last_sync": None, "version": "1.0"},
263
"ui_state": {"sidebar_expanded": True, "current_tab": 0}
264
}
265
266
for key, value in defaults.items():
267
if key not in st.session_state:
268
st.session_state[key] = value
269
270
# Or with a helper function
271
def init_state(key, default_value):
272
if key not in st.session_state:
273
st.session_state[key] = default_value
274
275
init_state("counter", 0)
276
init_state("messages", [])
277
init_state("user_data", {})
278
```
279
280
#### URL-Driven Navigation
281
282
```python
283
# URL-based page routing
284
def navigate_to(page_name):
285
st.query_params["page"] = page_name
286
st.rerun()
287
288
# Page selector that updates URL
289
current_page = st.query_params.get("page", "home")
290
291
pages = {
292
"home": "🏠 Home",
293
"data": "πŸ“Š Data",
294
"settings": "βš™οΈ Settings"
295
}
296
297
# Create navigation
298
selected = st.selectbox("Navigate to:",
299
options=list(pages.keys()),
300
format_func=lambda x: pages[x],
301
index=list(pages.keys()).index(current_page) if current_page in pages else 0
302
)
303
304
if selected != current_page:
305
navigate_to(selected)
306
307
# Display current page
308
if current_page == "home":
309
st.title("Home Page")
310
elif current_page == "data":
311
st.title("Data Page")
312
elif current_page == "settings":
313
st.title("Settings Page")
314
```
315
316
#### State Persistence Across Sessions
317
318
```python
319
# Save state to external storage
320
def save_state():
321
state_data = {
322
"user_preferences": st.session_state.get("user_preferences", {}),
323
"app_settings": st.session_state.get("app_settings", {})
324
}
325
# Save to file, database, etc.
326
save_to_storage(user_id, state_data)
327
328
def load_state():
329
# Load from file, database, etc.
330
state_data = load_from_storage(user_id)
331
if state_data:
332
st.session_state.update(state_data)
333
334
# Initialize with saved state
335
if "loaded" not in st.session_state:
336
load_state()
337
st.session_state.loaded = True
338
339
# Save state periodically or on changes
340
if st.button("Save Preferences"):
341
save_state()
342
st.success("Preferences saved!")
343
```