项目:streamlit/streamlit | 星数:46173 | 语言:Python | 协议:Apache-2.0 | GitHub仓库
更新日期:2026-10-29 · 作者:CodeArts 编辑部
想给一个 Python 脚本配界面,传统做法要拆成前后端:写接口、写页面、处理 CORS、打包部署。Streamlit 把这一整层抹掉了——你写 Python,从上到下按顺序调用组件,页面就按顺序渲染。改一行代码保存,浏览器里立刻刷新。
46173 星、Apache-2.0,它现在最常见的用途是两类:内部数据工具(查询、报表、打标)和 AI 应用的演示界面(聊天、RAG 问答、模型对比)。
pip install streamlit streamlit run app.py
import streamlit as st
st.title('销售看板')
name = st.text_input('你的名字')
if name:
st.write(f'你好,{name}')
import pandas as pd
df = pd.DataFrame({'月份': ['1月','2月','3月'], '销售额': [120, 180, 150]})
st.dataframe(df)
st.bar_chart(df.set_index('月份'))
默认起在 8501 端口,保存文件后页面右上角出现"Rerun"提示,选 Always rerun 就是热重载。
这是理解 Streamlit 的第一把钥匙。用户点任何控件,整个脚本会从上到下重新执行一遍。所有变量重新计算,所有组件重新渲染。好处是无需管理状态,坏处是耗时操作会被反复触发——于是有了缓存。
| 装饰器 | 缓存对象 | 典型用途 |
|---|---|---|
@st.cache_data | 返回值(会序列化) | 读 DataFrame、调 API、算统计 |
@st.cache_resource | 对象本身(全局共享) | 数据库连接、模型、tokenizer |
@st.cache_data(ttl=600)
def load_orders(date):
return pd.read_sql(f"select * from orders where d='{date}'", conn)
@st.cache_resource
def get_model():
from sentence_transformers import SentenceTransformer
return SentenceTransformer('BAAI/bge-small-zh-v1.5')
最常见的坑是把模型加载放进 cache_data,每次都要序列化反序列化,反而更慢;反过来把数据库连接放进 cache_data,连接对象不可序列化会直接报错。判断标准很简单:会变的数据用 data,重对象用 resource。
聊天记录、多步表单的中间结果,都需要跨脚本重跑保留:
if 'messages' not in st.session_state:
st.session_state.messages = []
prompt = st.chat_input('说点什么')
if prompt:
st.session_state.messages.append({'role': 'user', 'content': prompt})
reply = my_llm(prompt)
st.session_state.messages.append({'role': 'assistant', 'content': reply})
for m in st.session_state.messages:
with st.chat_message(m['role']):
st.markdown(m['content'])
这就是一个流式聊天界面的骨架,十行左右。想加流式输出,把 reply = my_llm(prompt) 换成 st.write_stream(gen) 即可。
text_input、number_input、selectbox、multiselect、slider、file_uploader、date_input。st.sidebar 放筛选参数,st.columns 横向分栏,st.tabs 切页签,st.expander 折叠长内容。st.spinner 包住耗时调用,st.progress 显示进度,st.success/error/warning 给结论。表单场景用 with st.form('f'): 包起来,用户填完点提交才触发重跑,否则每改一个字段就重算一次,体验很差。
Streamlit 原生支持多页:在入口文件同目录建 pages/ 文件夹,里面的 1_数据概览.py、2_模型评测.py 会自动出现在左侧导航。文件名前缀数字控制顺序。小项目用这个就够,不需要引入额外路由库。
# 内网/自己服务器 streamlit run app.py --server.port 8501 --server.address 0.0.0.0 # 容器化 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"]
Streamlit 官方社区云可以直连 GitHub 仓库一键部署,免费额度适合演示;但如果应用涉及内部数据或 API Key,务必自托管。放在反向代理后时记得设置 --server.baseUrlPath 和 --server.enableCORS=false,否则会出现 websocket 连不上的白屏。
Streamlit 不是通用 Web 框架。需要精细 UI 设计、复杂前端交互、SEO 友好的对外站点、高并发的公共产品,它都不合适——每次交互都整脚本重跑的执行模型注定了并发能力有限。它最佳的位置是:内部工具、数据探索、模型演示、原型验证。认清这个边界,用起来会很舒服。
两者定位接近。Streamlit 更偏数据应用和仪表盘,布局能力强、表格与图表生态好;Gradio 更聚焦模型演示界面,几行代码就能暴露一个推理函数,且对 HuggingFace Spaces 集成更顺。做数据看板选 Streamlit,做模型 demo 选 Gradio。
把数据库连接或大模型放进 cache_data,对象需要序列化,会直接报错或性能骤降;把可变的 DataFrame 放进 cache_resource,多个用户会共享同一份数据并可能被互相污染。原则:会变的数据用 cache_data,重且共享的对象用 cache_resource。
不适合高并发。每个会话的交互都会触发完整脚本重跑,资源消耗与用户数成正比,免费社区云也有资源限制。内部工具几十人同时使用没问题;面向公众的高并发产品应选 FastAPI + 前端框架。