Streamlit Cheat Sheet
Overview
Streamlit is an open-source Python framework for building interactive web applications for data science and machine learning. It turns Python scripts into shareable web apps with minimal code — no frontend experience required. Streamlit provides a rich set of widgets (sliders, buttons, file uploaders, charts), automatic re-execution on code changes, built-in caching, and native support for dataframes, charts, and media.
The framework is widely used for ML demos, data dashboards, internal tools, and LLM-powered applications. Streamlit Cloud offers free hosting for public apps, and Streamlit integrates seamlessly with pandas, plotly, matplotlib, scikit-learn, and LLM libraries.
Installation
pip install streamlit
# Verify
streamlit hello
# Create and run app
echo 'import streamlit as st; st.write("Hello!")' > app.py
streamlit run app.py
# Opens at http://localhost:8501
Core Elements
Text and Display
import streamlit as st
st.title("My App")
st.header("Section Header")
st.subheader("Subsection")
st.text("Fixed-width text")
st.markdown("**Bold** and *italic* with [links](https://example.com)")
st.latex(r"\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}")
st.code("print('hello')", language="python")
st.divider()
# Metrics
st.metric(label="Revenue", value="$42K", delta="+12%")
# JSON
st.json({"key": "value", "nested": {"a": 1}})
# Status elements
st.success("Operation completed!")
st.info("This is informational")
st.warning("Be careful!")
st.error("Something went wrong")
st.exception(ValueError("Example error"))
Input Widgets
import streamlit as st
# Text input
name = st.text_input("Your name", value="Alice")
bio = st.text_area("Bio", height=100)
password = st.text_input("Password", type="password")
# Numeric
age = st.number_input("Age", min_value=0, max_value=150, value=25)
rating = st.slider("Rating", 0, 10, 5)
range_val = st.slider("Range", 0.0, 100.0, (25.0, 75.0))
# Selection
choice = st.selectbox("Choose one", ["A", "B", "C"])
multi = st.multiselect("Choose many", ["Python", "JavaScript", "Go"])
radio = st.radio("Pick", ["Small", "Medium", "Large"])
# Boolean
agree = st.checkbox("I agree")
toggle = st.toggle("Enable feature")
# Date/Time
date = st.date_input("Date")
time = st.time_input("Time")
# File
uploaded = st.file_uploader("Upload CSV", type=["csv", "xlsx"])
if uploaded:
import pandas as pd
df = pd.read_csv(uploaded)
st.dataframe(df)
# Button
if st.button("Submit"):
st.write(f"Hello, {name}!")
# Download
st.download_button("Download data", data="col1,col2\n1,2\n3,4", file_name="data.csv")
Data Display
import streamlit as st
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(50, 3), columns=["A", "B", "C"])
# Interactive dataframe
st.dataframe(df, use_container_width=True)
# Static table
st.table(df.head())
# Editable dataframe
edited = st.data_editor(df, num_rows="dynamic")
# Column configuration
st.dataframe(df, column_config={
"A": st.column_config.NumberColumn("Column A", format="%.2f"),
"B": st.column_config.ProgressColumn("Progress", min_value=-3, max_value=3),
})
Charts
import streamlit as st
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(20, 3), columns=["a", "b", "c"])
# Built-in charts
st.line_chart(df)
st.area_chart(df)
st.bar_chart(df)
st.scatter_chart(df, x="a", y="b")
# Map
map_data = pd.DataFrame(
np.random.randn(100, 2) / [50, 50] + [37.76, -122.4],
columns=["lat", "lon"]
)
st.map(map_data)
# Plotly
import plotly.express as px
fig = px.scatter(df, x="a", y="b", color="c")
st.plotly_chart(fig, use_container_width=True)
# Matplotlib
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.hist(df["a"], bins=20)
st.pyplot(fig)
Layout
import streamlit as st
# Columns
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Users", "1,234")
with col2:
st.metric("Revenue", "$56K")
with col3:
st.metric("Growth", "+12%")
# Sidebar
with st.sidebar:
st.title("Settings")
model = st.selectbox("Model", ["GPT-4o", "Claude", "Llama"])
temp = st.slider("Temperature", 0.0, 2.0, 0.7)
# Tabs
tab1, tab2, tab3 = st.tabs(["Data", "Charts", "Settings"])
with tab1:
st.write("Data content")
with tab2:
st.write("Chart content")
# Expander
with st.expander("Advanced Options"):
st.write("Hidden content here")
# Container
with st.container(border=True):
st.write("Bordered container")
# Empty placeholder
placeholder = st.empty()
placeholder.text("Loading...")
placeholder.text("Done!")
# Popover
with st.popover("Click me"):
st.write("Popover content")
State Management
import streamlit as st
# Session state (persists across reruns)
if "counter" not in st.session_state:
st.session_state.counter = 0
if st.button("Increment"):
st.session_state.counter += 1
st.write(f"Count: {st.session_state.counter}")
# Callback functions
def on_change():
st.session_state.result = st.session_state.query.upper()
st.text_input("Query", key="query", on_change=on_change)
if "result" in st.session_state:
st.write(st.session_state.result)
# Forms (batch input)
with st.form("my_form"):
name = st.text_input("Name")
email = st.text_input("Email")
submitted = st.form_submit_button("Submit")
if submitted:
st.write(f"Submitted: {name}, {email}")
Caching
import streamlit as st
import pandas as pd
# Cache data loading
@st.cache_data
def load_data(url):
return pd.read_csv(url)
# Cache ML model (non-serializable)
@st.cache_resource
def load_model():
from transformers import pipeline
return pipeline("sentiment-analysis")
# Cache with TTL
@st.cache_data(ttl=3600) # Expires after 1 hour
def fetch_api_data():
import requests
return requests.get("https://api.example.com/data").json()
# Clear cache
# st.cache_data.clear()
Configuration
.streamlit/config.toml
[server]
port = 8501
headless = true
maxUploadSize = 200
enableCORS = false
[theme]
primaryColor = "#FF4B4B"
backgroundColor = "#FFFFFF"
secondaryBackgroundColor = "#F0F2F6"
textColor = "#262730"
font = "sans serif"
[browser]
gatherUsageStats = false
[runner]
magicEnabled = true
Secrets Management
# .streamlit/secrets.toml
OPENAI_API_KEY = "sk-..."
DATABASE_URL = "postgresql://user:pass@host/db"
[database]
host = "localhost"
port = 5432
# Access secrets
api_key = st.secrets["OPENAI_API_KEY"]
db_host = st.secrets["database"]["host"]
Advanced Usage
Chat Interface
import streamlit as st
from openai import OpenAI
st.title("Chat Assistant")
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
if "messages" not in st.session_state:
st.session_state.messages = []
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"])
if prompt := st.chat_input("Ask me anything"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
stream = client.chat.completions.create(
model="gpt-4o",
messages=st.session_state.messages,
stream=True
)
response = st.write_stream(stream)
st.session_state.messages.append({"role": "assistant", "content": response})
Multi-Page App
my_app/
├── app.py # Main entry point
├── pages/
│ ├── 1_Dashboard.py
│ ├── 2_Analysis.py
│ └── 3_Settings.py
└── .streamlit/
└── config.toml
Deployment
# Streamlit Community Cloud (free for public repos)
# 1. Push to GitHub
# 2. Go to share.streamlit.io
# 3. Connect repo and deploy
# Docker deployment
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "app.py", "--server.address", "0.0.0.0"]
Troubleshooting
| Issue | Solution |
|---|---|
| App not reloading | Check file is saved, enable runOnSave in config |
| Widget state lost | Use st.session_state with key parameter |
| Slow data loading | Use @st.cache_data or @st.cache_resource |
| File upload size limit | Set maxUploadSize in config.toml |
| Port already in use | Use --server.port 8502 flag |
| CORS errors | Set enableCORS = false in config |
| Secrets not found | Create .streamlit/secrets.toml file |
| Memory issues | Clear cache: st.cache_data.clear() |
# Debug mode
streamlit run app.py --logger.level debug
# Custom port
streamlit run app.py --server.port 8502
# Headless mode (no browser auto-open)
streamlit run app.py --server.headless true