When working with Streamlit web apps, data dashboards, ML/AI app UIs, interactive Python visualizations, or building data science applications with Python
Comprehensive assistance with Streamlit development, generated from official documentation covering 317 pages of content including API reference, tutorials, deployment guides, and best practices.
This skill should be triggered when:
Script-based execution: Streamlit apps run as Python scripts that rerun from top to bottom on every user interaction. This makes development simple but requires understanding state management.
Session State: Persistent data storage across reruns using st.session_state. Essential for maintaining user data, form inputs, and application state.
Caching: Use @st.cache_data for data operations and @st.cache_resource for expensive resources like ML models or database connections.
Magic commands: Write variables or strings standalone to display them automatically (when magicEnabled is True).
Widget callbacks: Functions that run when widget values change, useful for complex interactions and state updates.
Fragments: Isolated portions of your app that can rerun independently with @st.fragment, improving performance for partial updates.
import streamlit as st
# Simple text display
st.title("My First Streamlit App")
st.header("Welcome to Data Science")
st.write("Hello, World!")
# Magic command (displays automatically)
"This is magic!"
# Display data
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
st.dataframe(df)
import streamlit as st
# Initialize session state
if 'count' not in st.session_state:
st.session_state.count = 0
# Button with callback
def increment():
st.session_state.count += 1
st.button('Increment', on_click=increment)
st.write(f'Count: {st.session_state.count}')
# Various input widgets
name = st.text_input("Enter your name")
age = st.slider("Select age", 0, 100, 25)
option = st.selectbox("Choose option", ['A', 'B', 'C'])
uploaded_file = st.file_uploader("Upload CSV")
import streamlit as st
import pandas as pd
import numpy as np
# Sample data
data = pd.DataFrame({
'date': pd.date_range('2024-01-01', periods=30),
'values': np.random.randn(30).cumsum()
})
# Built-in charts
st.line_chart(data.set_index('date'))
st.area_chart(data.set_index('date'))
st.bar_chart(data.set_index('date'))
# Map visualization
map_data = pd.DataFrame({
'lat': [37.76, 37.77, 37.78],
'lon': [-122.4, -122.41, -122.42]
})
st.map(map_data)
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.button("Click me")
with col3:
st.header("Column 3")
st.checkbox("Check me")
# Sidebar
with st.sidebar:
st.header("Sidebar")
filter_val = st.slider("Filter", 0, 100)
# Tabs
tab1, tab2 = st.tabs(["Data", "Charts"])
with tab1:
st.write("Your data here")
with tab2:
st.line_chart([1, 2, 3, 4, 5])
# Expander
with st.expander("Click to expand"):
st.write("Hidden content revealed!")
import streamlit as st
# Form prevents rerun on every input change
with st.form("my_form"):
st.write("User Registration")
name = st.text_input("Name")
email = st.text_input("Email")
age = st.number_input("Age", min_value=0, max_value=120)
# Form submit button
submitted = st.form_submit_button("Submit")
if submitted:
st.success(f"Welcome {name}!")
st.session_state.user_data = {
'name': name,
'email': email,
'age': age
}
import streamlit as st
import pandas as pd
import time
# Cache data loading (recomputes when inputs change)
@st.cache_data
def load_data(file_path):
time.sleep(2) # Simulate expensive operation
return pd.read_csv(file_path)
# Cache ML models/resources (persists across reruns)
@st.cache_resource
def load_model():
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
# Load trained model...
return model
# Use cached functions
data = load_data("data.csv")
model = load_model()
st.write(data)
import streamlit as st
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat messages
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.write(message["content"])
# Chat input
if prompt := st.chat_input("What would you like to know?"):
# Add user message
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.write(prompt)
# Generate and display assistant response
response = f"Echo: {prompt}" # Replace with actual LLM call
st.session_state.messages.append({"role": "assistant", "content": response})
with st.chat_message("assistant"):
st.write(response)
# app.py
import streamlit as st
st.session_state.beans = st.session_state.get("beans", 0)
st.title("Bean counter")
addend = st.number_input("Beans to add", 0, 10)
if st.button("Add"):
st.session_state.beans += addend
st.markdown(f"Beans counted: {st.session_state.beans}")
# tests/test_app.py
from streamlit.testing.v1 import AppTest
def test_increment_and_add():
"""Test that incrementing and adding works"""
at = AppTest.from_file("app.py").run()
at.number_input[0].increment().run()
at.button[0].click().run()
assert at.markdown[0].value == "Beans counted: 1"
import streamlit as st
# Check authentication status
if not st.user.is_logged_in:
if st.button("Log in"):
st.login()
else:
st.write(f"Hello, {st.user.name}!")
st.write(f"Email: {st.user.email}")
if st.button("Log out"):
st.logout()
# Configuration in .streamlit/secrets.toml:
# [auth]
# redirect_uri = "http://localhost:8501/oauth2callback"
# cookie_secret = "your-secret-key"
# client_id = "your-client-id"
# client_secret = "your-client-secret"
# server_metadata_url = "https://accounts.google.com/.well-known/openid-configuration"
# .streamlit/config.toml
[theme]
primaryColor = "#F63366"
backgroundColor = "#FFFFFF"
secondaryBackgroundColor = "#F0F2F6"
textColor = "#262730"
font = "sans-serif"
[server]
port = 8501
enableCORS = false
maxUploadSize = 200
[client]
showErrorDetails = true
toolbarMode = "auto"
This skill includes comprehensive documentation organized into focused categories:
Complete API reference covering all Streamlit commands:
st.write, st.markdown, st.title, st.header, st.text, st.code, st.latexst.dataframe, st.table, st.metric, st.json, st.data_editorst.line_chart, st.area_chart, st.bar_chart, st.map, st.plotly_chart, st.altair_chartst.button, st.checkbox, st.radio, st.selectbox, st.slider, st.text_input, st.file_uploaderst.image, st.audio, st.video, st.camera_inputst.columns, st.tabs, st.expander, st.container, st.sidebarst.chat_message, st.chat_inputst.progress, st.spinner, st.success, st.error, st.warningst.stop, st.rerun, st.form, st.dialog, @st.fragmentst.session_state, st.query_params@st.cache_data, @st.cache_resourcest.connection, database integrationsst.login, st.logout, st.userst.set_page_config, config.toml optionsStep-by-step guides and practical examples:
Deep dives into Streamlit architecture and advanced concepts:
@st.cache_data vs @st.cache_resource, cache invalidationComprehensive deployment and hosting guidance:
Beginner-friendly introduction to Streamlit:
Common questions, troubleshooting, and solutions:
Miscellaneous topics and utilities not fitting other categories
getting_started.md for foundational conceptsst.<widget_name>@st.cache_data for data loading and transformations@st.cache_resource for ML models and database connections@st.fragment for partial updates in large appskey parameter to sync with session statest.form to batch related inputs and reduce rerunsst.progress, st.spinner) for long operations.streamlit/config.toml for local configuration.streamlit/secrets.toml (never commit to git)runOnSave in config for auto-reload during developmentimport streamlit as st
import pandas as pd
# Page config
st.set_page_config(page_title="My Data App", layout="wide")
# Load data (cached)
@st.cache_data
def load_data():
return pd.read_csv("data.csv")
# Sidebar filters
with st.sidebar:
st.header("Filters")
category = st.selectbox("Category", options=['All', 'A', 'B', 'C'])
# Main content
st.title("My Data App")
data = load_data()
# Apply filters
if category != 'All':
data = data[data['category'] == category]
# Display
col1, col2 = st.columns(2)
with col1:
st.dataframe(data)
with col2:
st.line_chart(data.set_index('date'))
See Quick Reference #7 for complete chat interface implementation.