CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-streamlit

The fastest way to build and share data apps

Overview
Eval results
Files

caching-config.mddocs/

Configuration, Caching, and State Management

Application configuration, performance optimization through caching decorators, session state management, and utility functions for app lifecycle control. These capabilities help you build performant, stateful applications with proper configuration management.

Capabilities

Page Configuration

Configure global app settings and appearance.

def set_page_config(
    page_title: str = None,
    page_icon: str = None, 
    layout: str = "centered",
    initial_sidebar_state: str = "auto",
    menu_items: dict = None
) -> None:
    """
    Configure the page settings (must be first Streamlit command).
    
    Parameters:
    - page_title: Title shown in browser tab
    - page_icon: Icon shown in browser tab (emoji or image URL)
    - layout: Page layout ("centered" or "wide")
    - initial_sidebar_state: Initial sidebar state ("auto", "expanded", "collapsed")
    - menu_items: Custom menu items dictionary
    """

Usage Example

import streamlit as st

# Configure page (must be first Streamlit command)
st.set_page_config(
    page_title="My Data App",
    page_icon="📊",
    layout="wide",
    initial_sidebar_state="expanded",
    menu_items={
        'Get Help': 'https://docs.streamlit.io/',
        'Report a bug': "https://github.com/myorg/myapp/issues",
        'About': "This is a demo app built with Streamlit!"
    }
)

st.title("Welcome to My App")

Configuration Options

Access and modify Streamlit's configuration system.

def get_option(key: str):
    """
    Get the value of a configuration option.
    
    Parameters:
    - key: Configuration key (e.g., "theme.primaryColor")
    
    Returns:
    The current value of the configuration option
    """

def set_option(key: str, value) -> None:
    """
    Set the value of a configuration option.
    
    Parameters:
    - key: Configuration key (e.g., "theme.primaryColor")
    - value: New value for the configuration option
    """

Usage Example

import streamlit as st

# Get current configuration
current_theme = st.get_option("theme.base")
st.write(f"Current theme: {current_theme}")

# Set configuration options
st.set_option("theme.primaryColor", "#FF6B6B")
st.set_option("theme.backgroundColor", "#FFFFFF")

# Common configuration options
st.write("Available config categories:")
st.write("- theme.*: UI theme settings")
st.write("- server.*: Server configuration") 
st.write("- browser.*: Browser behavior")
st.write("- logger.*: Logging configuration")

Legacy Caching

Traditional caching decorator for expensive computations.

@cache(persist: bool = False, allow_output_mutation: bool = False, suppress_st_warning: bool = False, hash_funcs: dict = None, max_entries: int = None, ttl: float = None, show_spinner: bool = True)
def cached_function():
    """
    Decorator for caching function results (legacy).
    
    Parameters:
    - persist: Whether to persist cache across sessions
    - allow_output_mutation: Whether to allow mutation of cached results
    - suppress_st_warning: Whether to suppress Streamlit warnings
    - hash_funcs: Custom hash functions for parameters
    - max_entries: Maximum number of cache entries
    - ttl: Time-to-live in seconds
    - show_spinner: Whether to show spinner during computation
    """

Usage Example

import streamlit as st
import pandas as pd
import time

@st.cache
def load_data(file_path):
    """Load data with caching to avoid repeated file reads."""
    time.sleep(2)  # Simulate expensive operation
    return pd.read_csv(file_path)

@st.cache(ttl=3600)  # Cache for 1 hour
def fetch_api_data(api_url):
    """Fetch data from API with time-based cache expiration."""
    # Simulate API call
    time.sleep(1)
    return {"data": "api_result", "timestamp": time.time()}

# Use cached functions
data = load_data("data.csv")
api_result = fetch_api_data("https://api.example.com/data")

st.dataframe(data)
st.json(api_result)

Modern Caching (Experimental)

New caching decorators with improved performance and features.

@experimental_memo(persist: str = None, show_spinner: bool = True, suppress_st_warning: bool = False, max_entries: int = None, ttl: float = None)
def memo_function():
    """
    Decorator for caching data and computations (experimental).
    
    Parameters:
    - persist: Persistence mode ("disk" or None)
    - show_spinner: Whether to show spinner during computation
    - suppress_st_warning: Whether to suppress Streamlit warnings
    - max_entries: Maximum number of cache entries
    - ttl: Time-to-live in seconds
    """

@experimental_singleton(show_spinner: bool = True, suppress_st_warning: bool = False)
def singleton_function():
    """
    Decorator for creating singleton objects (experimental).
    
    Parameters:
    - show_spinner: Whether to show spinner during initialization
    - suppress_st_warning: Whether to suppress Streamlit warnings
    """

Usage Example

import streamlit as st
import pandas as pd
import numpy as np

@st.experimental_memo
def expensive_computation(n):
    """Expensive computation with memo caching."""
    # Simulate heavy computation
    result = np.random.rand(n, n).dot(np.random.rand(n, n))
    return result

@st.experimental_singleton
def get_database_connection():
    """Create singleton database connection."""
    # Simulate database connection setup
    class MockDB:
        def __init__(self):
            self.connected = True
            
        def query(self, sql):
            return pd.DataFrame({"result": [1, 2, 3]})
    
    return MockDB()

# Use modern caching
matrix = expensive_computation(100)
db = get_database_connection()

st.write(f"Matrix shape: {matrix.shape}")
st.dataframe(db.query("SELECT * FROM table"))

Session State

Manage user session data that persists across app reruns.

session_state: SessionStateProxy
# Access via st.session_state

class SessionStateProxy:
    """Session state management interface."""
    
    def __getitem__(self, key: str) -> Any:
        """Get session state value."""
    
    def __setitem__(self, key: str, value: Any) -> None:
        """Set session state value."""
    
    def __contains__(self, key: str) -> bool:
        """Check if key exists in session state."""
    
    def __delitem__(self, key: str) -> None:
        """Delete session state key."""

Usage Example

import streamlit as st

# Initialize session state
if "counter" not in st.session_state:
    st.session_state.counter = 0

if "user_data" not in st.session_state:
    st.session_state.user_data = {}

# Use session state with widgets
col1, col2, col3 = st.columns(3)

with col1:
    if st.button("Increment"):
        st.session_state.counter += 1

with col2:
    if st.button("Decrement"):
        st.session_state.counter -= 1

with col3:
    if st.button("Reset"):
        st.session_state.counter = 0

st.write(f"Counter: {st.session_state.counter}")

# Form data persistence
with st.form("user_form"):
    name = st.text_input("Name", value=st.session_state.user_data.get("name", ""))
    age = st.number_input("Age", value=st.session_state.user_data.get("age", 0))
    
    if st.form_submit_button("Save"):
        st.session_state.user_data["name"] = name
        st.session_state.user_data["age"] = age
        st.success("Data saved to session!")

# Display all session state (for debugging)
with st.expander("Session State Debug"):
    st.write(st.session_state)

Secrets Management

Securely access application secrets and configuration.

secrets: SecretsProxy
# Access via st.secrets

class SecretsProxy:
    """Secrets management interface."""
    
    def __getitem__(self, key: str) -> Any:
        """Get secret value."""
    
    def __contains__(self, key: str) -> bool:
        """Check if secret exists."""

Usage Example

import streamlit as st

# Access secrets (configured in .streamlit/secrets.toml)
db_password = st.secrets["database"]["password"]
api_key = st.secrets["api_key"]

# Use secrets safely
if "database" in st.secrets:
    connection_string = f"postgresql://user:{st.secrets.database.password}@localhost/db"
    st.success("Database configured")
else:
    st.error("Database secrets not found")

# Example secrets.toml structure:
st.code("""
# .streamlit/secrets.toml
api_key = "your-api-key-here"

[database]
host = "localhost"
port = 5432
username = "user"
password = "secret-password"
""", language="toml")

App Control and Lifecycle

Control application execution flow and provide user feedback.

def stop() -> NoReturn:
    """
    Stop execution of the Streamlit script.
    
    Raises:
    StreamlitAPIException: Always (stops execution)
    """

def balloons() -> DeltaGenerator:
    """Display falling balloons animation."""

def snow() -> DeltaGenerator:
    """Display falling snow animation."""

def progress(value: float) -> DeltaGenerator:
    """
    Display a progress bar.
    
    Parameters:
    - value: Progress value between 0.0 and 1.0
    
    Returns:
    DeltaGenerator: Progress bar object that can be updated
    """

def spinner(text: str = "In progress...") -> ContextManager[None]:
    """
    Display a spinner with text during long operations.
    
    Parameters:
    - text: Text displayed next to spinner
    
    Returns:
    Context manager for use with 'with' statement
    """

def echo(code_location: str = "above") -> ContextManager[None]:
    """
    Display code while executing it.
    
    Parameters:
    - code_location: Where to show code ("above" or "below")
    
    Returns:
    Context manager for code echoing
    """

Usage Example

import streamlit as st
import time

# Celebration animations
if st.button("Celebrate!"):
    st.balloons()
    st.success("Congratulations!")

if st.button("Winter Theme"):
    st.snow()
    st.info("Let it snow!")

# Progress bar
progress_bar = st.progress(0)
status_text = st.empty()

for i in range(100):
    progress_bar.progress(i + 1)
    status_text.text(f'Progress: {i+1}%')
    time.sleep(0.01)

status_text.text('Operation completed!')

# Spinner for long operations
with st.spinner('Loading data...'):
    time.sleep(3)  # Simulate long operation
    data = [1, 2, 3, 4, 5]

st.success('Data loaded!')
st.write(data)

# Echo code execution
with st.echo():
    # This code will be displayed and executed
    x = 10
    y = 20
    result = x + y
    st.write(f"The result is {result}")

# Conditional stop
user_input = st.text_input("Enter 'stop' to halt execution:")
if user_input.lower() == 'stop':
    st.error("Execution stopped by user!")
    st.stop()

st.write("This will only show if execution wasn't stopped")

Query Parameters (Experimental)

Access and modify URL query parameters.

def experimental_get_query_params() -> Dict[str, List[str]]:
    """
    Get the current query parameters from the URL.
    
    Returns:
    Dictionary mapping parameter names to lists of values
    """

def experimental_set_query_params(**kwargs) -> None:
    """
    Set query parameters in the URL.
    
    Parameters:
    - **kwargs: Parameter names and values to set
    """

Usage Example

import streamlit as st

# Get current query parameters
query_params = st.experimental_get_query_params()
st.write("Current query parameters:", query_params)

# Use query parameters to set initial state
if "page" in query_params:
    initial_page = query_params["page"][0]
else:
    initial_page = "home"

# Widget that updates URL
page = st.selectbox("Select page:", ["home", "data", "settings"], 
                   index=["home", "data", "settings"].index(initial_page))

# Update query parameters when selection changes
if page != initial_page:
    st.experimental_set_query_params(page=page)

# Multiple parameters
filter_type = st.selectbox("Filter:", ["all", "active", "inactive"])
sort_by = st.selectbox("Sort by:", ["name", "date", "priority"])

# Update multiple parameters
st.experimental_set_query_params(
    page=page,
    filter=filter_type,
    sort=sort_by
)

st.write(f"Current page: {page}")
st.write(f"Filter: {filter_type}, Sort: {sort_by}")

Script Control (Experimental)

Programmatically control script execution flow.

def experimental_rerun() -> NoReturn:
    """
    Rerun the current script (experimental).
    
    Raises:
    StreamlitAPIException: Always (triggers rerun)
    """

Usage Example

import streamlit as st

# Button that triggers rerun
if st.button("Refresh Data"):
    # Clear any cached data if needed
    st.cache.clear()
    
    # Trigger script rerun
    st.experimental_rerun()

# Conditional rerun based on state
if st.session_state.get("needs_refresh", False):
    st.session_state.needs_refresh = False
    st.experimental_rerun()

User Information (Experimental)

Access user information in deployed apps.

experimental_user: UserInfoProxy

class UserInfoProxy:
    """User information access interface (experimental)."""
    
    @property
    def email(self) -> str:
        """Get user's email address (if available)."""

Usage Example

import streamlit as st

# Access user information (only works in deployed apps)
try:
    user_email = st.experimental_user.email
    st.write(f"Welcome, {user_email}!")
except:
    st.write("User information not available (local development)")

# Conditional features based on user
if hasattr(st.experimental_user, 'email'):
    if "@company.com" in st.experimental_user.email:
        st.info("You have admin access")
        admin_section = st.checkbox("Show admin panel")
        if admin_section:
            st.write("Admin controls would go here")

Performance and Caching Best Practices

  • Use @st.cache or @st.experimental_memo for expensive data loading
  • Use @st.experimental_singleton for database connections and ML models
  • Store user input in st.session_state to maintain state across reruns
  • Use st.secrets for sensitive configuration data
  • Set appropriate TTL values for time-sensitive cached data
  • Use suppress_st_warning=True to silence caching warnings in production

Install with Tessl CLI

npx tessl i tessl/pypi-streamlit@1.16.0

docs

caching-config.md

charts-media.md

custom-components.md

display-elements.md

index.md

input-widgets.md

layout-containers.md

tile.json