| name | streamlit |
| description | Fast Python framework for building interactive web apps, dashboards, and data visualizations without HTML/CSS/JavaScript. Use when user wants to create data apps, ML demos, dashboards, data exploration tools, or interactive visualizations. Transforms Python scripts into web apps in minutes with automatic UI updates. |
Streamlit
Overview
Streamlit is a Python framework for rapidly building and deploying interactive web applications for data science and machine learning. Create beautiful web apps with just Python - no frontend development experience required. Apps automatically update in real-time as code changes.
When to Use This Skill
Activate when the user:
- Wants to build a web app, dashboard, or data visualization tool
- Mentions Streamlit explicitly
- Needs to create an ML/AI demo or prototype
- Wants to visualize data interactively
- Asks for a data exploration tool
- Needs interactive widgets (sliders, buttons, file uploads)
- Wants to share analysis results with stakeholders
Installation and Setup
Check if Streamlit is installed:
python3 -c "import streamlit; print(streamlit.__version__)"
If not installed:
pip3 install streamlit
Create and run your first app:
# Create app.py with Streamlit code
streamlit run app.py
The app opens automatically in your browser at http://localhost:8501
Basic App Structure
Every Streamlit app follows this simple pattern:
import streamlit as st
# Set page configuration (must be first Streamlit command)
st.set_page_config(
page_title="My App",
page_icon="📊",
layout="wide"
)
# Title and description
st.title("My Data App")
st.write("Welcome to my interactive dashboard!")
# Your app code here
# Streamlit automatically reruns from top to bottom when widgets change
Core Capabilities
1. Displaying Text and Data
import streamlit as st, pandas as pd
# Text elements
st.title("Main Title")
st.header("Section Header")
st.subheader("Subsection Header")
st.text("Fixed-width text")
st.markdown("**Bold** and *italic* text")
st.caption("Small caption text")
# Code blocks
st.code("""
def hello():
print("Hello, World!")
""", language="python")
# Display data
df = pd.DataFrame({
'Column A': [1, 2, 3],
'Column B': [4, 5, 6]
})
st.dataframe(df) # Interactive table
st.table(df) # Static table
st.json({'key': 'value'}) # JSON data
# Metrics
st.metric(
label="Revenue",
value="$1,234",
delta="12%"
)
2. Interactive Widgets
import streamlit as st
# Text input
name = st.text_input("Enter your name")
email = st.text_input("Email", type="default")
password = st.text_input("Password", type="password")
text = st.text_area("Long text", height=100)
# Numbers
age = st.number_input("Age", min_value=0, max_value=120, value=25)
slider_val = st.slider("Select a value", 0, 100, 50)
range_val = st.slider("Select range", 0, 100, (25, 75))
# Selections
option = st.selectbox("Choose one", ["Option 1", "Option 2", "Option 3"])
options = st.multiselect("Choose multiple", ["A", "B", "C", "D"])
radio = st.radio("Pick one", ["Yes", "No", "Maybe"])
# Checkboxes
agree = st.checkbox("I agree to terms")
show_data = st.checkbox("Show raw data")
# Buttons
if st.button("Click me"):
st.write("Button clicked!")
# Date and time
date = st.date_input("Select date")
time = st.time_input("Select time")
# File upload
uploaded_file = st.file_uploader("Choose a file", type=['csv', 'xlsx', 'txt'])
if uploaded_file is not None:
df = pd.read_csv(uploaded_file)
st.dataframe(df)
# Download button
st.download_button(
label="Download data",
data=df.to_csv(index=False),
file_name="data.csv",
mime="text/csv"
)
3. Charts and Visualizations
import streamlit as st
import pandas as pd, numpy as np, matplotlib.pyplot as plt
import plotly.express as px
# Sample data
df = pd.DataFrame({
'x': range(10),
'y': np.random.randn(10)
})
# Streamlit native charts
st.line_chart(df)
st.area_chart(df)
st.bar_chart(df)
# Scatter plot with map data
map_data = pd.DataFrame(
np.random.randn(100, 2) / [50, 50] + [37.76, -122.4],
columns=['lat', 'lon']
)
st.map(map_data)
# Matplotlib
fig, ax = plt.subplots()
ax.plot(df['x'], df['y'])
ax.set_title("Matplotlib Chart")
st.pyplot(fig)
# Plotly (interactive)
fig = px.scatter(df, x='x', y='y', title="Interactive Plotly Chart")
st.plotly_chart(fig, use_container_width=True)
# Altair, Bokeh, and other libraries also supported
4. Layout and Containers
import streamlit as st
# Columns
col1, col2, col3 = st.columns(3)
with col1:
st.header("Column 1")
st.write("Content here")
with col2:
st.header("Column 2")
st.write("More content")
with col3:
st.header("Column 3")
st.write("Even more")
# Tabs
tab1, tab2, tab3 = st.tabs(["Overview", "Data", "Settings"])
with tab1:
st.write("Overview content")
with tab2:
st.write("Data content")
with tab3:
st.write("Settings content")
# Expander (collapsible section)
with st.expander("Click to expand"):
st.write("Hidden content that can be expanded")
# Container
with st.container():
st.write("This is inside a container")
st.write("Another line")
# Sidebar
st.sidebar.title("Sidebar")
st.sidebar.selectbox("Choose option", ["A", "B", "C"])
st.sidebar.slider("Sidebar slider", 0, 100)
5. Status and Progress
import streamlit as st, time
# Success, info, warning, error messages
st.success("Success! Everything worked.")
st.info("This is an informational message.")
st.warning("This is a warning.")
st.error("This is an error message.")
# Progress bar
progress_bar = st.progress(0)
for i in range(100):
time.sleep(0.01)
progress_bar.progress(i + 1)
# Spinner (loading indicator)
with st.spinner("Processing..."):
time.sleep(3)
st.success("Done!")
# Balloons (celebration)
st.balloons()
# Snow (celebration)
# st.snow()
6. Caching for Performance
import streamlit as st, pandas as pd, time
# Cache data loading (persists across reruns)
@st.cache_data
def load_data():
time.sleep(2) # Simulate slow data load
return pd.read_csv('large_file.csv')
# Cache resource (connections, models)
@st.cache_resource
def load_model():
# Load ML model (expensive operation)
return load_my_model()
# Use cached data
df = load_data() # Only loads once, then cached
model = load_model() # Cached globally
st.write(f"Loaded {len(df)} rows")
7. Session State (Persistent Data)
import streamlit as st
# Initialize session state
if 'count' not in st.session_state:
st.session_state.count = 0
# Increment counter
if st.button("Increment"):
st.session_state.count += 1
st.write(f"Count: {st.session_state.count}")
# Store user data across reruns
if 'user_data' not in st.session_state:
st.session_state.user_data = {}
name = st.text_input("Name")
if name:
st.session_state.user_data['name'] = name
st.write(f"Hello, {st.session_state.user_data['name']}!")
Common Patterns
Pattern 1: Data Dashboard
import streamlit as st, pandas as pd, plotly.express as px
st.set_page_config(page_title="Sales Dashboard", layout="wide")
# Sidebar filters
st.sidebar.header("Filters")
date_range = st.sidebar.date_input("Date Range", [])
category = st.sidebar.multiselect("Category", ["A", "B", "C"])
# Load data
@st.cache_data
def load_sales_data():
return pd.read_csv('sales_data.csv')
df = load_sales_data()
# Apply filters
if date_range:
df = df[df['date'].between(date_range[0], date_range[1])]
if category:
df = df[df['category'].isin(category)]
# Metrics row
col1, col2, col3, col4 = st.columns(4)
col1.metric("Total Revenue", f"${df['revenue'].sum():,.0f}")
col2.metric("Orders", f"{len(df):,}")
col3.metric("Avg Order", f"${df['revenue'].mean():.2f}")
col4.metric("Top Product", df['product'].mode()[0])
# Charts
col1, col2 = st.columns(2)
with col1:
st.subheader("Revenue by Category")
fig = px.bar(df.groupby('category')['revenue'].sum().reset_index(),
x='category', y='revenue')
st.plotly_chart(fig, use_container_width=True)
with col2:
st.subheader("Revenue Trend")
fig = px.line(df.groupby('date')['revenue'].sum().reset_index(),
x='date', y='revenue')
st.plotly_chart(fig, use_container_width=True)
# Data table
with st.expander("View Raw Data"):
st.dataframe(df)
Pattern 2: Data Explorer
import streamlit as st, pandas as pd, plotly.express as px
st.title("📊 Data Explorer")
# File upload
uploaded_file = st.file_uploader("Upload CSV", type=['csv'])
if uploaded_file:
df = pd.read_csv(uploaded_file)
# Show basic info
st.subheader("Dataset Overview")
col1, col2, col3 = st.columns(3)
col1.metric("Rows", len(df))
col2.metric("Columns", len(df.columns))
col3.metric("Memory", f"{df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
# Column selection
st.subheader("Explore Data")
columns = st.multiselect("Select columns", df.columns.tolist(), default=df.columns.tolist()[:5])
if columns:
st.dataframe(df[columns])
# Statistics
st.subheader("Statistics")
st.write(df[columns].describe())
# Visualization
st.subheader("Visualize")
col1, col2 = st.columns(2)
with col1:
x_col = st.selectbox("X-axis", columns)
with col2:
y_col = st.selectbox("Y-axis", columns)
chart_type = st.radio("Chart Type", ["Scatter", "Line", "Bar"])
if chart_type == "Scatter":
fig = px.scatter(df, x=x_col, y=y_col)
elif chart_type == "Line":
fig = px.line(df, x=x_col, y=y_col)
else:
fig = px.bar(df, x=x_col, y=y_col)
st.plotly_chart(fig, use_container_width=True)
Pattern 3: Multi-Page App
Create a multi-page app with file structure:
app/
├── main.py
└── pages/
├── 1_📊_Dashboard.py
├── 2_📈_Analytics.py
└── 3_⚙️_Settings.py
Main page (main.py):
import streamlit as st
st.set_page_config(page_title="Multi-Page App", page_icon="🏠")
st.title("Welcome to My App")
st.sidebar.success("Select a page above.")
st.markdown("""
This is the home page. Navigate using the sidebar.
""")
Pages automatically appear in the sidebar. Each page is a separate Python file.
Form Handling
import streamlit as st
# Forms prevent rerun on every widget change
with st.form("my_form"):
st.write("Fill out the form")
name = st.text_input("Name")
age = st.number_input("Age", min_value=0, max_value=120)
favorite_color = st.selectbox("Favorite Color", ["Red", "Green", "Blue"])
# Form submit button
submitted = st.form_submit_button("Submit")
if submitted:
st.write(f"Name: {name}")
st.write(f"Age: {age}")
st.write(f"Color: {favorite_color}")
Best Practices
- Use caching - Cache expensive operations with
@st.cache_dataand@st.cache_resource - Session state for persistence - Use
st.session_stateto persist data across reruns - Organize with containers - Use columns, tabs, and expanders for clean layouts
- Forms for multiple inputs - Prevent reruns with forms when collecting multiple inputs
- Wide layout for dashboards - Use
st.set_page_config(layout="wide")for dashboards - Sidebar for controls - Put filters and settings in the sidebar
- Progress indicators - Show spinners for long operations
Common Issues
Issue: App reruns on every interaction
Use st.form() to batch inputs or st.session_state to control behavior.
Issue: Slow performance
Cache expensive operations:
@st.cache_data
def expensive_computation(param):
# Your code here
return result
Issue: State not persisting
Use session state:
if 'my_var' not in st.session_state:
st.session_state.my_var = initial_value
Resources
- references/api_reference.md: Quick reference for common Streamlit components
- Official docs: https://docs.streamlit.io/
- API reference: https://docs.streamlit.io/develop/api-reference
- Gallery: https://streamlit.io/gallery
- Community: https://discuss.streamlit.io/