A faster way to build and share data apps
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.
Persistent state management that survives script reruns, enabling stateful applications.
session_state: SessionStateProxySession 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.
Key Properties:
key parameter is usedExample usage:
# Initialize session state
if "count" not in st.session_state:
st.session_state.count = 0
# Access and modify state
if st.button("Increment"):
st.session_state.count += 1
st.write(f"Count: {st.session_state.count}")
# Store complex data
if "data" not in st.session_state:
st.session_state.data = {"users": [], "settings": {}}
# Widget state integration
name = st.text_input("Name", key="user_name")
# st.session_state.user_name now contains the input value
# Callback functions with state
def update_data():
st.session_state.data["last_update"] = datetime.now()
st.button("Update", on_click=update_data)Common Patterns:
# Conditional initialization
if "initialized" not in st.session_state:
st.session_state.initialized = True
st.session_state.user_data = load_user_data()
# Page state management
if "current_page" not in st.session_state:
st.session_state.current_page = "home"
# Multi-step forms
if "form_step" not in st.session_state:
st.session_state.form_step = 1
# Data caching in state
if "processed_data" not in st.session_state:
st.session_state.processed_data = expensive_computation()URL query parameter management for shareable and bookmarkable app states.
query_params: QueryParamsProxyQuery parameters provide a way to encode app state in the URL, making it possible to share specific app states or bookmark particular views.
Key Properties:
Example usage:
# Read query parameters
params = st.query_params
page = params.get("page", "home") # Default to "home"
user_id = params.get("user_id")
# Set query parameters (updates URL)
st.query_params["page"] = "dashboard"
st.query_params["filter"] = "active"
# Multiple parameters
st.query_params.update({
"view": "table",
"sort": "name",
"order": "asc"
})
# Clear specific parameter
if "temp_param" in st.query_params:
del st.query_params["temp_param"]
# Clear all parameters
st.query_params.clear()
# Type conversion (all query params are strings)
if "page_num" in st.query_params:
page_num = int(st.query_params["page_num"])
else:
page_num = 1Common Patterns:
# Page routing with query params
page = st.query_params.get("page", "home")
if page == "home":
show_home_page()
elif page == "data":
show_data_page()
# Filter state in URL
filters = {
"category": st.query_params.get("category", "all"),
"status": st.query_params.get("status", "active"),
"sort": st.query_params.get("sort", "name")
}
# Update URL when filters change
if st.selectbox("Category", options, key="cat_filter") != filters["category"]:
st.query_params["category"] = st.session_state.cat_filter
# Shareable dashboard state
st.query_params.update({
"chart_type": selected_chart,
"date_range": f"{start_date}_{end_date}",
"metrics": ",".join(selected_metrics)
})Access to current execution context and environment information.
context: ContextProxyContext provides access to information about the current execution environment, headers, and request details.
Key Properties:
Example usage:
# Access request headers
headers = st.context.headers
user_agent = headers.get("User-Agent", "Unknown")
referer = headers.get("Referer")
# Client information
st.write(f"User Agent: {user_agent}")
# Check for specific headers
if "Authorization" in headers:
auth_token = headers["Authorization"]
user = validate_token(auth_token)These functions are deprecated but still available for backward compatibility.
def experimental_get_query_params():
"""
Get current query parameters (deprecated).
Returns:
dict: Current query parameters
Note:
Deprecated in favor of st.query_params
"""
def experimental_set_query_params(**kwargs):
"""
Set query parameters (deprecated).
Args:
**kwargs: Query parameters to set
Note:
Deprecated in favor of st.query_params
"""# Automatic state sync with key parameter
name = st.text_input("Name", key="user_name")
# st.session_state.user_name is automatically updated
# Manual state access
if st.session_state.user_name:
st.write(f"Hello, {st.session_state.user_name}!")
# Callback with state update
def on_name_change():
st.session_state.greeting = f"Hello, {st.session_state.user_name}!"
st.text_input("Name", key="user_name", on_change=on_name_change)# Initialize workflow state
if "step" not in st.session_state:
st.session_state.step = 1
st.session_state.form_data = {}
# Step navigation
if st.session_state.step == 1:
name = st.text_input("Enter name")
if st.button("Next") and name:
st.session_state.form_data["name"] = name
st.session_state.step = 2
st.rerun()
elif st.session_state.step == 2:
email = st.text_input("Enter email")
col1, col2 = st.columns(2)
with col1:
if st.button("Previous"):
st.session_state.step = 1
st.rerun()
with col2:
if st.button("Submit") and email:
st.session_state.form_data["email"] = email
submit_form(st.session_state.form_data)
st.success("Form submitted!")# Initialize state with default values
defaults = {
"user_preferences": {"theme": "light", "language": "en"},
"app_data": {"last_sync": None, "version": "1.0"},
"ui_state": {"sidebar_expanded": True, "current_tab": 0}
}
for key, value in defaults.items():
if key not in st.session_state:
st.session_state[key] = value
# Or with a helper function
def init_state(key, default_value):
if key not in st.session_state:
st.session_state[key] = default_value
init_state("counter", 0)
init_state("messages", [])
init_state("user_data", {})# URL-based page routing
def navigate_to(page_name):
st.query_params["page"] = page_name
st.rerun()
# Page selector that updates URL
current_page = st.query_params.get("page", "home")
pages = {
"home": "🏠 Home",
"data": "📊 Data",
"settings": "⚙️ Settings"
}
# Create navigation
selected = st.selectbox("Navigate to:",
options=list(pages.keys()),
format_func=lambda x: pages[x],
index=list(pages.keys()).index(current_page) if current_page in pages else 0
)
if selected != current_page:
navigate_to(selected)
# Display current page
if current_page == "home":
st.title("Home Page")
elif current_page == "data":
st.title("Data Page")
elif current_page == "settings":
st.title("Settings Page")# Save state to external storage
def save_state():
state_data = {
"user_preferences": st.session_state.get("user_preferences", {}),
"app_settings": st.session_state.get("app_settings", {})
}
# Save to file, database, etc.
save_to_storage(user_id, state_data)
def load_state():
# Load from file, database, etc.
state_data = load_from_storage(user_id)
if state_data:
st.session_state.update(state_data)
# Initialize with saved state
if "loaded" not in st.session_state:
load_state()
st.session_state.loaded = True
# Save state periodically or on changes
if st.button("Save Preferences"):
save_state()
st.success("Preferences saved!")Install with Tessl CLI
npx tessl i tessl/pypi-streamlit