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