Streamlit 极速查
版本v1.54.0 更新日志2026-02-07 GitHubstreamlit/streamlit
340px

🏗️ 运行模型与骨架 >>>

理解“自上而下”重跑逻辑是入门关键
  • st.set_page_config: 必须在首行调用,配置标题、布局、侧边栏。
  • 重跑机制: 任何 widget 交互或代码保存,脚本都会从头执行。
  • st.stop(): 满足特定条件时,中断后续代码执行。
  • st.rerun(): 立刻手动触发一次脚本重跑。
import streamlit as st

# 必须放在脚本第一行
st.set_page_config(
    page_title="仪表盘",
    layout="wide",
    initial_sidebar_state="expanded"
)

🔘 输入控件 Widgets >>>

组件返回值即为当前状态值
  • 常用控件: st.button, st.checkbox, st.radio, st.selectbox, st.multiselect, st.slider, st.text_input, st.date_input, st.file_uploader
  • key=: 极其重要。用于区分同类组件,且在循环中创建组件时必须唯一。
  • on_change / on_click: 注册回调处理状态。
# 返回值为用户选择结果
genre = st.radio(
    "选择你喜欢的流派",
    ["喜剧", "剧情", "纪录片"],
    key="genre_radio"
)

if st.button("提交"):
    st.write(f"你选择了: {genre}")

📦 布局与容器 >>>

  • st.sidebar: 侧边栏,适合放全局过滤器。
  • st.columns(n): 水平分栏,支持 [1, 2, 1] 权重。
  • st.tabs(["A", "B"]): 页面内的标签切换。
  • st.expander("Label"): 可收起的详情区域。
  • st.empty(): 占位符。可后续调用 placeholder.write(...) 覆盖旧内容。
col1, col2 = st.columns([1, 2])
with col1:
    st.metric("日活", "1.2k", "12%")
with col2:
    with st.expander("查看明细"):
        st.write("表格内容...")

🧠 Session State >>>

跨重跑持久化数据的唯一途径
  • 行为类似字典: st.session_state["k"]
  • 初始化范式: 必须先检查 key 是否存在。
  • Widget 绑定: widget 的 key 会自动映射到 session_state。
  • 警告: 不能用 state 设置 button/file_uploader。
if "counter" not in st.session_state:
    st.session_state.counter = 0

def increment():
    st.session_state.counter += 1

st.button("加 1", on_click=increment)
st.write(f"当前值: {st.session_state.counter}")

⚡ 性能优化与缓存 >>>

  • @st.cache_data: 缓存数据/序列化结果。支持 ttl (过期时间), max_entries (最大条数)。
  • @st.cache_resource: 缓存单例对象 (如 DB 连接、ML 模型)。
  • 参数过滤: 前缀带下划线的参数 (如 _db) 不参与 hash 计算。
@st.cache_data(ttl=3600)
def fetch_api_data(url):
    # 昂贵操作
    return requests.get(url).json()

@st.cache_resource
def load_model():
    return pipeline("sentiment-analysis")

🤖 LLM & Chat 集成 >>>

快速构建 AI 聊天应用
  • st.chat_message("user" | "assistant"): 气泡容器。
  • st.chat_input("..."): 固定底部的输入框。
  • st.write_stream(generator): 流式输出,支持将 LLM 生成器直接渲染为打字机效果。
if prompt := st.chat_input():
    st.chat_message("user").write(prompt)
    with st.chat_message("assistant"):
        # 直接传入生成器即可流式渲染
        full_res = st.write_stream(response_gen(prompt))
        st.session_state.messages.append(full_res)

📊 数据与图表 >>>

  • st.dataframe: 交互式表格,支持排序/筛选。
  • st.data_editor: 可编辑表格,可捕获变更。
  • st.metric: 大字指标,支持增量 delta 颜色。
  • 图表事件: st.plotly_chart(..., on_select="rerun") 可返回用户选中的点。
df = pd.DataFrame({"x": [1,2], "y": [3,4]})
# 开启自动拉伸
st.dataframe(df, use_container_width=True)

# 捕获用户编辑
edited_df = st.data_editor(df)

📝 表单与提交 >>>

防止在输入参数过程中由于重跑导致的频繁计算
  • st.form("my_form"): 内部所有 widget 交互不会触发重跑。
  • st.form_submit_button: 必须存在且仅能在此组件点击时提交并触发重跑。
with st.form("settings"):
    n = st.number_input("数量", 10)
    mode = st.selectbox("模式", ["A", "B"])
    # 只有点击这里才会执行后续昂贵任务
    submitted = st.form_submit_button("开始计算")

if submitted:
    st.write(f"计算中: {n}, {mode}")

🧭 多页与导航 >>>

  • 动态定义: st.navigation([st.Page("a.py"), ...])
  • 目录模式: 自动识别项目根目录下的 pages/ 文件夹。
  • st.switch_page: 代码逻辑强制跳转页面。
  • st.page_link: 正文中插入直达链接(带图标)。
# 新版(推荐) 统一导航配置
pg = st.navigation([
    st.Page("home.py", title="首页", icon="🏠"),
    st.Page("dash.py", title="图表", icon="📊")
])
pg.run()

🔗 URL 与查询参数 >>>

让应用状态可分享(Deep Linking)
  • st.query_params: 获取或设置 URL 后的 ?k=v
  • 典型场景: 把选定的过滤器同步到 URL,刷新不丢失。
# 读取 URL 参数
region = st.query_params.get("region", "CN")

# 设置 URL 参数 (同步状态)
if st.button("切换到美国区"):
    st.query_params["region"] = "US"

💻 CLI 命令行参考 >>>

  • streamlit run app.py: 启动。
  • --server.port=8501: 指定端口。
  • --server.headless=true: 无头模式运行。
  • streamlit config show: 打印全量配置。
  • streamlit cache clear: 清理本地磁盘缓存。
# 常用启动组合
streamlit run main.py \
  --server.address=0.0.0.0 \
  --theme.primaryColor="#ff4b4b"

🔔 状态与进度反馈 >>>

  • st.spinner("..."): 临时加载动效。
  • st.status("..."): 进阶状态容器,支持逐步更新步骤。
  • 反馈: st.toast, st.balloons, st.snow
  • 警告: st.error, st.warning, st.info, st.success
with st.status("正在拉取数据...", expanded=True) as s:
    st.write("正在连接 API...")
    time.sleep(1)
    st.write("正在处理 JSON...")
    s.update(label="完成!", state="complete")