更新时间:2026 年 7 月 21 日
Streamlit 是一个纯 Python 的开源 Web 应用框架,让数据科学家和机器学习工程师在无需前端知识的情况下,用几十行代码就能构建交互式数据应用。相比 Flask 或 Django,Streamlit 能把开发时间从数天压缩到几小时,是 2026 年数据科学团队做快速原型、内部工具和模型演示的首选方案。本文会带你从零安装、掌握核心组件与缓存机制,最后把一个完整的机器学习应用部署到生产环境。
Streamlit 是纯 Python 数据科学 Web 应用框架。从零安装到生产部署完整实战,覆盖组件、缓存、st.fragment、机器学习模型集成,以及 Community Cloud、Docker 与 Kubernetes 部署路径。

更新时间:2026 年 7 月 21 日
Streamlit 是一个纯 Python 的开源 Web 应用框架,让数据科学家和机器学习工程师在无需前端知识的情况下,用几十行代码就能构建交互式数据应用。相比 Flask 或 Django,Streamlit 能把开发时间从数天压缩到几小时,是 2026 年数据科学团队做快速原型、内部工具和模型演示的首选方案。本文会带你从零安装、掌握核心组件与缓存机制,最后把一个完整的机器学习应用部署到生产环境。
st.fragment 局部刷新装饰器,可将不必要的整页重跑减少 60% 以上,是性能优化最重要的新特性。st.cache_data(用于返回可序列化数据的函数)与 st.cache_resource(用于返回不可序列化对象,如数据库连接、ML 模型)。st.session_state)是构建多步骤表单、聊天界面、工作流的关键,避免每次交互丢失状态。Streamlit 是一个开源的 Python Web 应用框架,专为数据科学、机器学习和数据工程场景设计。跟传统 Web 框架(Flask、Django、FastAPI)不一样,Streamlit 的核心哲学是"脚本即应用",你写的仍然是普通 Python 脚本,Streamlit 运行时会把它渲染成一个响应式 Web 界面。这套模式极大降低了数据从业者构建可视化和交互式工具的门槛。
说点背景。Streamlit 由前 Google 工程师 Adrien Treuille、Amanda Kelly 和 Thiago Teixeira 于 2019 年推出,2022 年被 Snowflake 以 8 亿美元收购。截至 2026 年 7 月,官方版本已经推进到 1.44 系列,GitHub 上 star 数超过 40k,PyPI 月下载量突破 1500 万次。它在 Kaggle、Hugging Face Spaces、内部数据仪表板等场景里占据统治地位。
老实说,Streamlit 能这么快铺开,主要是三个原因:纯 Python 编程(不用碰 HTML/CSS/JS)、响应式模型(脚本自上而下重跑,任何交互都会触发状态更新)、丰富的生态集成(原生支持 pandas、Polars、Matplotlib、Plotly、Altair、Bokeh、PyDeck 等)。对于需要在几小时内做出模型演示、A/B 结果面板、数据探索工具的团队,Streamlit 基本没什么替代品。
我自己是从 0.60 开始用的,2026 年的 Streamlit 跟当年的架构完全不是一回事:引入了 st.fragment 局部刷新、改进了 st.dialog 模态框、支持 native chat 元素、Session State API 稳定化,并且和 Polars、Arrow、DuckDB 等新数据栈的集成越来越紧密。如果你已经熟悉 Polars DataFrame 高性能数据处理,把它接入 Streamlit 前端算是水到渠成的下一步。
Streamlit 需要 Python 3.9 或更高版本(推荐 3.11 或 3.12,性能明显好于 3.9)。在虚拟环境中安装:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install streamlit==1.44.*
# 验证安装
streamlit hello
streamlit hello 会启动官方演示应用,包含图表、地图、数据帧等示例,帮助你验证环境是否就绪。默认端口是 8501,浏览器会自动打开 http://localhost:8501。
接下来创建 app.py 作为你的第一个真正应用:
import streamlit as st
import pandas as pd
import numpy as np
st.set_page_config(
page_title="我的第一个数据应用",
page_icon="📊",
layout="wide",
)
st.title("销售数据快速分析")
st.write("这是一个用 Streamlit 构建的最小可用应用。")
# 生成示例数据
rng = np.random.default_rng(42)
df = pd.DataFrame({
"日期": pd.date_range("2026-01-01", periods=30),
"销售额": rng.integers(1000, 5000, size=30),
"订单数": rng.integers(20, 100, size=30),
})
# 交互控件
threshold = st.slider("筛选阈值(销售额)", 1000, 5000, 2000)
filtered = df[df["销售额"] >= threshold]
st.metric("符合条件的天数", len(filtered), delta=len(filtered) - 15)
st.dataframe(filtered, use_container_width=True)
st.line_chart(filtered.set_index("日期")["销售额"])
用 streamlit run app.py 启动。你会立刻拥有一个带标题、滑块、指标卡、数据表和折线图的完整 Web 应用,代码量不到 25 行。这就是 Streamlit 的杀手锏。
Streamlit 提供了 40 多个内置组件(widgets),几乎覆盖了数据应用所有的交互需求。常用的输入类组件包括:
st.text_input、st.number_input、st.text_area:文本与数字输入st.selectbox、st.multiselect、st.radio:单选与多选st.slider、st.date_input、st.time_input:范围与时间选择st.file_uploader:文件上传(支持 CSV、Excel、图片等)st.button、st.form_submit_button:触发动作st.chat_input、st.chat_message:LLM 聊天界面(2024 年新增)Streamlit 支持四种主要布局容器。st.sidebar 用于左侧固定侧栏;st.columns 把主区分为水平列;st.tabs 创建标签页;st.expander 折叠区块。看个例子:
import streamlit as st
with st.sidebar:
dataset = st.selectbox("选择数据集", ["销售", "用户", "库存"])
date_range = st.date_input("日期范围", value=[])
col1, col2, col3 = st.columns(3)
col1.metric("总营收", "¥1.2M", "+12%")
col2.metric("活跃用户", "8,421", "-3%")
col3.metric("转化率", "4.5%", "+0.8%")
tab1, tab2 = st.tabs(["📈 趋势", "📋 明细"])
with tab1:
st.line_chart({"销售": [10, 20, 30, 25, 40]})
with tab2:
st.write("原始数据表")
st.session_state 是一个类似字典的对象,用来在脚本重跑之间持久化数据。这对购物车、多步骤表单、聊天历史这些场景来说,几乎是必需品:
import streamlit as st
# 初始化
if "count" not in st.session_state:
st.session_state.count = 0
if "history" not in st.session_state:
st.session_state.history = []
if st.button("增加计数"):
st.session_state.count += 1
st.session_state.history.append(st.session_state.count)
st.write(f"当前计数:{st.session_state.count}")
st.write(f"历史:{st.session_state.history}")
Streamlit 内置了一套面向数据科学的展示组件。st.dataframe 渲染出来的是可排序、可搜索、可导出 CSV 的交互式表格,底层用 Apache Arrow 传输,处理几十万行毫无压力。st.data_editor 更进一步,允许用户在浏览器里直接编辑单元格,编辑后的 DataFrame 会作为返回值传回 Python,这在标注工具、审核界面里极为实用。
import streamlit as st
import pandas as pd
df = pd.DataFrame({
"产品": ["A", "B", "C"],
"价格": [99.9, 199.0, 49.5],
"在售": [True, False, True],
})
edited = st.data_editor(
df,
column_config={
"价格": st.column_config.NumberColumn(format="¥%.2f"),
"在售": st.column_config.CheckboxColumn(),
},
num_rows="dynamic",
)
if st.button("保存修改"):
edited.to_csv("products.csv", index=False)
st.success("已保存!")
Streamlit 提供三类图表 API。原生极简图(st.line_chart、st.bar_chart、st.area_chart、st.scatter_chart)适合快速原型;专业库集成(st.plotly_chart、st.altair_chart、st.vega_lite_chart、st.pyplot、st.bokeh_chart)适合生产可视化;地图(st.map、st.pydeck_chart)则用于地理数据。
import plotly.express as px
import streamlit as st
df = px.data.gapminder().query("year == 2007")
fig = px.scatter(
df, x="gdpPercap", y="lifeExp",
size="pop", color="continent",
log_x=True, hover_name="country",
title="2007 年各国 GDP 与预期寿命",
)
st.plotly_chart(fig, use_container_width=True)
如果你的数据分析基于 Pandas 3.0 Copy-on-Write 或 DuckDB 嵌入式分析数据库,可以直接把结果 DataFrame 传给 st.dataframe 或 st.plotly_chart,Streamlit 会自动完成序列化和渲染。
Streamlit 的"脚本重跑"模型意味着每次用户交互都会重新执行整个脚本。如果不缓存耗时操作(读文件、查数据库、加载 ML 模型),用户体验会灾难性地卡顿。Streamlit 2023 年重构了缓存 API,把老式 st.cache 拆分为两个专用装饰器:
| 特性 | st.cache_data | st.cache_resource |
|---|---|---|
| 用途 | 返回可序列化数据(DataFrame、dict、list、numpy 数组) | 返回不可序列化对象(DB 连接、ML 模型、Tokenizer) |
| 存储方式 | 每次调用返回副本(安全隔离) | 全局共享单个实例 |
| 典型示例 | 读取 CSV、SQL 查询、API 请求 | 加载 PyTorch/TF 模型、创建数据库连接池 |
| TTL 支持 | 是(ttl="1h") | 是 |
| 最大条目 | 是(max_entries=100) | 是 |
| 失效方式 | .clear() 或参数变化 | .clear() 或参数变化 |
典型使用模式:
import streamlit as st
import pandas as pd
import joblib
@st.cache_data(ttl=3600, show_spinner="加载销售数据…")
def load_sales(source: str) -> pd.DataFrame:
return pd.read_parquet(source)
@st.cache_resource
def load_model(path: str):
return joblib.load(path)
df = load_sales("s3://mybucket/sales.parquet")
model = load_model("models/rf_v2.joblib")
pred = model.predict(df.drop(columns=["target"]))
把训练好的模型包装成 Streamlit 应用,是数据团队最常见的用例之一。下面这个示例展示了一个完整的鸢尾花分类应用,配合 scikit-learn 1.8 GPU 加速 训练出来的模型:
import streamlit as st
import numpy as np
import joblib
from pathlib import Path
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
MODEL_PATH = Path("iris_rf.joblib")
@st.cache_resource
def get_model() -> RandomForestClassifier:
if MODEL_PATH.exists():
return joblib.load(MODEL_PATH)
X, y = load_iris(return_X_y=True)
model = RandomForestClassifier(n_estimators=200, random_state=42)
model.fit(X, y)
joblib.dump(model, MODEL_PATH)
return model
st.title("🌸 鸢尾花分类预测")
st.caption("基于 scikit-learn RandomForest 的实时推理演示")
model = get_model()
CLASSES = ["Setosa", "Versicolor", "Virginica"]
with st.form("prediction_form"):
col1, col2 = st.columns(2)
with col1:
sepal_len = st.slider("花萼长度 (cm)", 4.0, 8.0, 5.4)
sepal_wid = st.slider("花萼宽度 (cm)", 2.0, 4.5, 3.4)
with col2:
petal_len = st.slider("花瓣长度 (cm)", 1.0, 7.0, 1.3)
petal_wid = st.slider("花瓣宽度 (cm)", 0.1, 2.5, 0.2)
submitted = st.form_submit_button("预测", type="primary")
if submitted:
X = np.array([[sepal_len, sepal_wid, petal_len, petal_wid]])
proba = model.predict_proba(X)[0]
pred_idx = int(np.argmax(proba))
st.success(f"预测类别:**{CLASSES[pred_idx]}**(置信度 {proba[pred_idx]:.1%})")
st.bar_chart({c: p for c, p in zip(CLASSES, proba)})
几个关键设计点:@st.cache_resource 确保模型只加载一次;st.form 把多个输入组合为原子事务,避免每次滑块变动都触发预测;st.form_submit_button 是唯一的触发器,能保证用户体验流畅。这套模式可以直接迁移到 XGBoost、LightGBM、PyTorch 或 Hugging Face Transformers 模型。
随着应用变复杂,把所有逻辑塞进单个 app.py 会失控。Streamlit 从 1.10 起原生支持基于文件的多页面路由:在项目根目录创建 pages/ 子目录,每个 .py 文件自动成为一个页面。1.36 之后官方推荐使用 st.navigation + st.Page 的编程式路由,灵活性更好:
import streamlit as st
pages = [
st.Page("home.py", title="首页", icon="🏠", default=True),
st.Page("dashboard.py", title="仪表板", icon="📊"),
st.Page("model.py", title="模型预测", icon="🤖"),
st.Page("settings.py", title="设置", icon="⚙️"),
]
nav = st.navigation(pages)
nav.run()
st.fragment(在 1.33 稳定)是 2024 年以来最重要的性能特性。用它装饰一个函数后,函数内部的重跑不会触发外部脚本重跑,只会刷新局部区域。这对实时更新时间戳、股票价格、聊天流响应等场景至关重要。
import streamlit as st
import time
import pandas as pd
st.title("实时监控面板(st.fragment 演示)")
# 全局筛选(触发整页重跑)
symbol = st.selectbox("股票代码", ["AAPL", "NVDA", "TSLA"])
@st.fragment(run_every=2) # 每 2 秒刷新一次此片段
def live_price(symbol: str):
price = round(150 + 10 * (time.time() % 60) / 60, 2)
st.metric(f"{symbol} 实时价格", f"${price}", f"{price - 150:+.2f}")
live_price(symbol)
# 这一部分只在 symbol 变化时才会重跑
st.subheader("历史 K 线")
st.line_chart(pd.DataFrame({"close": [148, 150, 152, 149, 151]}))
在旧版 Streamlit 里,要实现"每 2 秒更新价格"必须用 st.rerun() 或 time.sleep 循环,代价就是整页重跑。st.fragment 让局部刷新变得声明式,官方基准测试显示,对于典型 5 组件仪表板,用 fragment 后整体渲染时间下降 60% 到 75%。我自己那个跑在内网的运营看板,用了 fragment 之后从"用户拖一次滑块要卡 3 秒"变成基本无感。
2026 年 Python 数据应用框架的格局,主要由三个玩家占据。选型标准取决于用例、团队能力和目标用户:
| 维度 | Streamlit | Gradio | Dash (Plotly) |
|---|---|---|---|
| 主要定位 | 数据仪表板 / 内部工具 | ML/LLM 模型演示 | 企业级分析应用 |
| 学习曲线 | 极低(数小时上手) | 极低(数小时上手) | 中等(需了解 React 概念) |
| 响应模型 | 脚本重跑 + fragment | 事件驱动 | 回调(Callback) |
| UI 定制性 | 中等(主题 + 少量 HTML) | 低(预设组件为主) | 高(完全可定制 CSS) |
| 多页面支持 | 原生 st.navigation | Tab 或多个接口 | Dash Pages |
| 典型社区托管 | Streamlit Community Cloud | Hugging Face Spaces | Dash Enterprise(付费) |
| 2026 GitHub Star | ~40k | ~35k | ~22k |
| 最适合 | 数据探索、A/B 分析、报表 | LLM 聊天、图像生成 Demo | 金融 / 医疗 / 制造业仪表板 |
简短建议:数据科学团队做内部工具或仪表板选 Streamlit;要把模型 Demo 发到公开社区就选 Gradio;需要品牌化 UI 和复杂布局的企业应用选 Dash。三者并不是零和关系,Streamlit 和 Gradio 甚至可以嵌入到同一个 Docker 镜像里并存。
开发完成之后,Streamlit 应用有三条主要部署路径。
把代码推到 GitHub 公开仓库,在 Streamlit Community Cloud 用 GitHub 账号登录,选择仓库和入口文件,几分钟内就能拿到 https://your-app.streamlit.app 的公开 URL。适合个人项目、演示、开源工具。限制也很清楚:1GB 内存、CPU 有限、公开可访问。
企业环境通常需要私有部署。下面是一个我在多个项目里复用过的生产级 Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8501
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1
ENTRYPOINT ["streamlit", "run", "app.py", \
"--server.port=8501", \
"--server.address=0.0.0.0", \
"--server.headless=true", \
"--browser.gatherUsageStats=false"]
构建与运行:
docker build -t my-streamlit-app:latest .
docker run -p 8501:8501 --env-file .env my-streamlit-app:latest
对于需要横向扩展、灰度发布、SSO 集成的团队,Kubernetes 是标准方案。几个关键点:设置 readinessProbe 指向 /_stcore/health;用 sticky session(service.beta.kubernetes.io/aws-load-balancer-target-node-labels 或 Ingress 会话亲和性)保证同一用户始终命中同一 Pod(因为 Session State 是进程本地内存);生产上建议接入 Redis 或数据库作为共享状态后端。
不管选哪条路线,都建议开启 --server.enableCORS=false(仅内网)、通过反向代理(Nginx、Traefik)终结 HTTPS,并对 st.secrets 敏感值使用 Kubernetes Secret 而非明文。详细参数参见 Streamlit 官方部署文档 和 Streamlit GitHub Releases 更新日志。
两者都是 Python 数据应用框架,但侧重不同。Streamlit 更适合构建多页面数据仪表板、内部工具、A/B 分析面板,UI 元素丰富;Gradio 更擅长封装机器学习模型(尤其是 LLM 与图像生成),提供开箱即用的聊天界面和 Hugging Face Spaces 一键部署。数据探索选 Streamlit,模型演示选 Gradio。
最快的方式是使用 Streamlit Community Cloud:把代码推送到 GitHub 公开仓库,登录 streamlit.io/cloud 用 GitHub 授权,选择仓库和入口文件即可自动构建部署。免费版提供 1GB 内存、公开访问的子域名(*.streamlit.app)和 GitHub push 自动重新部署。
看返回值是否可以序列化。DataFrame、字典、numpy 数组、SQL 查询结果等可序列化数据用 st.cache_data(每次返回副本,多用户隔离);数据库连接、机器学习模型、Tokenizer 等不可序列化对象用 st.cache_resource(全局共享单例)。选错会导致内存暴涨或数据串扰。
Streamlit 原生支持所有主流 Python 可视化库:Matplotlib(st.pyplot)、Plotly(st.plotly_chart)、Altair(st.altair_chart)、Bokeh(st.bokeh_chart)、Vega-Lite、PyDeck(3D 地图)、Graphviz。它还提供轻量原生图表 st.line_chart、st.bar_chart、st.scatter_chart 用于快速原型。
单实例 Streamlit 依靠 Tornado 事件循环,实测在中等应用(10-20 个组件、数万行数据)下可稳定支持 20-50 个并发用户。突破此规模需要横向扩展多副本 + 会话亲和性(sticky session)+ 将 Session State 迁移到 Redis。企业场景通常在 Kubernetes 中运行 3-10 个副本。
Streamlit 1.42+ 内置了 st.experimental_user 和原生 OIDC 认证,配置 secrets.toml 中的 OAuth 提供商(Google、GitHub、Auth0 等)即可开箱即用。自托管场景推荐用反向代理层(Nginx + OAuth2 Proxy)或 streamlit-authenticator 第三方库,避免在应用层重复实现认证逻辑。