A faster way to build and share data apps
Chat interfaces, app fragments, modal dialogs, and database connections for sophisticated applications. These features enable building complex, interactive applications with modern UI patterns.
Build conversational interfaces and chatbots with built-in message containers and input handling.
def chat_message(name, *, avatar=None):
"""
Create chat message container with sender name and optional avatar.
Args:
name (str): Name of the message sender
avatar (str, optional): Avatar image URL, emoji, or user type ("user", "assistant")
Returns:
DeltaGenerator: Chat message container context manager
"""
def chat_input(placeholder=None, key=None, max_chars=None, on_submit=None, args=None, kwargs=None, *, disabled=False):
"""
Display chat input widget for user message entry.
Args:
placeholder (str, optional): Placeholder text when empty
key (str, optional): Unique widget key for state management
max_chars (int, optional): Maximum number of characters allowed
on_submit (callable, optional): Callback function when message is submitted
args (tuple, optional): Arguments for on_submit callback
kwargs (dict, optional): Keyword arguments for on_submit callback
disabled (bool): Whether input is disabled
Returns:
str: Submitted message text or empty string if no submission
"""Example usage:
# Initialize chat history in session state
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat history
for message in st.session_state.messages:
with st.chat_message(message["role"], avatar=message.get("avatar")):
st.write(message["content"])
# Chat input
user_input = st.chat_input("Type your message here...")
if user_input:
# Add user message to history
st.session_state.messages.append({
"role": "user",
"content": user_input,
"avatar": "🧑💻"
})
# Display user message
with st.chat_message("user", avatar="🧑💻"):
st.write(user_input)
# Generate and display assistant response
response = generate_response(user_input) # Your AI logic here
st.session_state.messages.append({
"role": "assistant",
"content": response,
"avatar": "🤖"
})
with st.chat_message("assistant", avatar="🤖"):
st.write(response)Create reusable, independently updating app components for better performance and modularity.
def fragment(func):
"""
Decorator to create app fragment that can update independently.
Args:
func (callable): Function to convert to fragment
Returns:
callable: Fragment function that can be called with arguments
"""Example usage:
@st.fragment
def live_metrics_fragment():
"""Fragment that updates metrics independently."""
col1, col2, col3 = st.columns(3)
with col1:
cpu_usage = get_cpu_usage() # Real-time data
st.metric("CPU Usage", f"{cpu_usage}%")
with col2:
memory_usage = get_memory_usage()
st.metric("Memory", f"{memory_usage}%")
with col3:
active_users = get_active_users()
st.metric("Active Users", active_users)
# Auto-refresh every 5 seconds
time.sleep(5)
st.rerun()
@st.fragment
def data_table_fragment(data, filters):
"""Fragment for data table that updates based on filters."""
filtered_data = apply_filters(data, filters)
st.dataframe(filtered_data)
if st.button("Export Data"):
export_data(filtered_data)
st.success("Data exported!")
# Main app
st.title("Dashboard")
# Independent fragments
live_metrics_fragment() # Updates independently
# Fragment with parameters
data = load_data()
current_filters = st.selectbox("Filter by", ["All", "Active", "Inactive"])
data_table_fragment(data, current_filters)Create modal dialog overlays for focused user interactions and confirmations.
def dialog(title, *, width="small"):
"""
Create modal dialog container that overlays the main content.
Args:
title (str): Dialog title displayed in header
width (str): Dialog width ("small", "medium", "large")
Returns:
DeltaGenerator: Dialog container context manager
"""Example usage:
# Dialog trigger
if st.button("Open Settings"):
st.session_state.show_settings = True
# Dialog content
if st.session_state.get("show_settings", False):
@st.dialog("Application Settings")
def settings_dialog():
st.write("Configure your application settings")
# Settings form
theme = st.selectbox("Theme", ["Light", "Dark"])
notifications = st.checkbox("Enable notifications")
auto_save = st.checkbox("Auto-save changes")
col1, col2 = st.columns(2)
with col1:
if st.button("Save", type="primary"):
save_settings(theme, notifications, auto_save)
st.session_state.show_settings = False
st.rerun()
with col2:
if st.button("Cancel"):
st.session_state.show_settings = False
st.rerun()
settings_dialog()
# Confirmation dialog
if st.button("Delete Item"):
st.session_state.confirm_delete = True
if st.session_state.get("confirm_delete", False):
@st.dialog("Confirm Deletion", width="medium")
def confirm_dialog():
st.warning("Are you sure you want to delete this item?")
st.write("This action cannot be undone.")
col1, col2 = st.columns(2)
with col1:
if st.button("Delete", type="primary"):
delete_item()
st.session_state.confirm_delete = False
st.success("Item deleted!")
st.rerun()
with col2:
if st.button("Cancel"):
st.session_state.confirm_delete = False
st.rerun()
confirm_dialog()Streamlined database connectivity with built-in connection management and query capabilities.
def connection(name, type=None, **kwargs):
"""
Create or retrieve database connection with automatic management.
Args:
name (str): Connection name for reuse
type (str, optional): Connection type ("sql", "snowflake", etc.)
**kwargs: Connection-specific parameters
Returns:
Connection: Database connection object with query methods
"""Example usage:
# SQL database connection
conn = st.connection("my_database", type="sql", url="sqlite:///data.db")
# Execute query
@st.cache_data
def load_data():
return conn.query("SELECT * FROM users WHERE active = 1")
data = load_data()
st.dataframe(data)
# Snowflake connection
snow_conn = st.connection(
"snowflake_db",
type="snowflake",
account=st.secrets["snowflake"]["account"],
user=st.secrets["snowflake"]["user"],
password=st.secrets["snowflake"]["password"],
database="ANALYTICS",
schema="PUBLIC"
)
# Query with parameters
@st.cache_data
def get_sales_data(start_date, end_date):
query = """
SELECT date, product, sales
FROM sales_data
WHERE date BETWEEN %s AND %s
ORDER BY date
"""
return snow_conn.query(query, params=(start_date, end_date))
# Custom connection parameters
postgres_conn = st.connection(
"postgres",
type="sql",
url="postgresql://user:password@localhost/mydb",
engine_kwargs={
"pool_size": 10,
"pool_recycle": 3600
}
)import time
from datetime import datetime
# Initialize chat application
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
st.session_state.user_name = ""
# User setup
if not st.session_state.user_name:
st.session_state.user_name = st.text_input("Enter your name to start chatting:")
if not st.session_state.user_name:
st.stop()
st.title(f"💬 Chat - Welcome {st.session_state.user_name}!")
# Chat history fragment (updates independently)
@st.fragment
def chat_history_fragment():
"""Display chat messages with real-time updates."""
chat_container = st.container(height=400, border=True)
with chat_container:
for message in st.session_state.chat_history:
timestamp = message.get("timestamp", "")
with st.chat_message(message["role"], avatar=message["avatar"]):
st.write(f"**{message['name']}** - {timestamp}")
st.write(message["content"])
# Display chat history
chat_history_fragment()
# Message input
message = st.chat_input("Type your message...")
if message:
# Add message to history
new_message = {
"role": "user",
"name": st.session_state.user_name,
"content": message,
"avatar": "🧑💻",
"timestamp": datetime.now().strftime("%H:%M:%S")
}
st.session_state.chat_history.append(new_message)
# Simulate bot response
if message.lower().startswith("!bot"):
bot_response = generate_bot_response(message[5:]) # Remove "!bot "
bot_message = {
"role": "assistant",
"name": "ChatBot",
"content": bot_response,
"avatar": "🤖",
"timestamp": datetime.now().strftime("%H:%M:%S")
}
st.session_state.chat_history.append(bot_message)
st.rerun()@st.fragment
def metric_cards_fragment():
"""Independent metrics that update frequently."""
col1, col2, col3, col4 = st.columns(4)
with col1:
revenue = get_current_revenue()
st.metric("Revenue", f"${revenue:,.2f}", delta="12.5%")
with col2:
users = get_active_users()
st.metric("Active Users", f"{users:,}", delta="5.2%")
with col3:
conversion = get_conversion_rate()
st.metric("Conversion Rate", f"{conversion:.1f}%", delta="-1.2%")
with col4:
satisfaction = get_satisfaction_score()
st.metric("Satisfaction", f"{satisfaction}/5", delta="0.3")
@st.fragment
def interactive_chart_fragment(data, chart_type, filters):
"""Chart fragment that updates based on user selections."""
filtered_data = apply_dashboard_filters(data, filters)
if chart_type == "Line":
st.line_chart(filtered_data)
elif chart_type == "Bar":
st.bar_chart(filtered_data)
elif chart_type == "Area":
st.area_chart(filtered_data)
# Main dashboard
st.title("📊 Real-time Dashboard")
# Independent metrics (updates every few seconds)
metric_cards_fragment()
# Interactive controls
col1, col2 = st.columns([1, 3])
with col1:
chart_type = st.selectbox("Chart Type", ["Line", "Bar", "Area"])
date_range = st.date_input("Date Range", value=[datetime.now() - timedelta(days=30), datetime.now()])
categories = st.multiselect("Categories", ["Sales", "Marketing", "Support"])
with col2:
# Load data
dashboard_data = load_dashboard_data()
filters = {
"date_range": date_range,
"categories": categories
}
# Interactive chart fragment
interactive_chart_fragment(dashboard_data, chart_type, filters)# Workflow state management
workflow_states = {
"create_project": False,
"edit_item": None,
"confirm_action": None
}
for state_key in workflow_states:
if state_key not in st.session_state:
st.session_state[state_key] = workflow_states[state_key]
# Main interface
st.title("Project Management")
# Action buttons
col1, col2, col3 = st.columns(3)
with col1:
if st.button("➕ New Project", type="primary"):
st.session_state.create_project = True
with col2:
if st.button("📝 Edit Selected"):
if selected_item := get_selected_item():
st.session_state.edit_item = selected_item
with col3:
if st.button("🗑️ Delete Selected"):
if selected_item := get_selected_item():
st.session_state.confirm_action = f"delete_{selected_item['id']}"
# Create Project Dialog
if st.session_state.create_project:
@st.dialog("Create New Project", width="large")
def create_project_dialog():
st.write("Enter project details:")
project_name = st.text_input("Project Name*")
description = st.text_area("Description")
col1, col2 = st.columns(2)
with col1:
start_date = st.date_input("Start Date")
priority = st.selectbox("Priority", ["Low", "Medium", "High"])
with col2:
due_date = st.date_input("Due Date")
assignee = st.selectbox("Assignee", get_team_members())
# Dialog actions
col1, col2 = st.columns(2)
with col1:
if st.button("Create Project", type="primary", disabled=not project_name):
create_new_project({
"name": project_name,
"description": description,
"start_date": start_date,
"due_date": due_date,
"priority": priority,
"assignee": assignee
})
st.session_state.create_project = False
st.success("Project created!")
st.rerun()
with col2:
if st.button("Cancel"):
st.session_state.create_project = False
st.rerun()
create_project_dialog()
# Edit Item Dialog
if st.session_state.edit_item:
@st.dialog("Edit Item", width="medium")
def edit_item_dialog():
item = st.session_state.edit_item
st.write(f"Editing: {item['name']}")
# Editable fields
new_name = st.text_input("Name", value=item['name'])
new_status = st.selectbox("Status", ["Active", "Completed", "On Hold"],
index=["Active", "Completed", "On Hold"].index(item['status']))
# Save/Cancel actions
col1, col2 = st.columns(2)
with col1:
if st.button("Save Changes", type="primary"):
update_item(item['id'], {"name": new_name, "status": new_status})
st.session_state.edit_item = None
st.success("Item updated!")
st.rerun()
with col2:
if st.button("Cancel"):
st.session_state.edit_item = None
st.rerun()
edit_item_dialog()
# Confirmation Dialog
if st.session_state.confirm_action:
@st.dialog("Confirm Action")
def confirmation_dialog():
action = st.session_state.confirm_action
if action.startswith("delete_"):
item_id = action.split("_")[1]
st.warning(f"Are you sure you want to delete item {item_id}?")
st.write("This action cannot be undone.")
col1, col2 = st.columns(2)
with col1:
if st.button("Confirm", type="primary"):
execute_action(action)
st.session_state.confirm_action = None
st.success("Action completed!")
st.rerun()
with col2:
if st.button("Cancel"):
st.session_state.confirm_action = None
st.rerun()
confirmation_dialog()Install with Tessl CLI
npx tessl i tessl/pypi-streamlit