Streamlit 技巧 几个被忽视但重要的功能和机制

在使用 Streamlit 构建数据应用的过程中,我逐渐发现了一些非常有用但可能容易被忽视的功能与机制。为了更好地记录和分享这些知识,本文将详细介绍这些功能,希望能为同样使用 Streamlit 的同学们提供一些帮助。

Tabs 组件

1
2
3
4
5
6
7
8
9
10
11
12
13
import streamlit as st

tab1, tab2, tab3 = st.tabs(["Cat", "Dog", "Owl"])

with tab1:
st.header("A cat")
st.image("https://static.streamlit.io/examples/cat.jpg", width=200)
with tab2:
st.header("A dog")
st.image("https://static.streamlit.io/examples/dog.jpg", width=200)
with tab3:
st.header("An owl")
st.image("https://static.streamlit.io/examples/owl.jpg", width=200)

控件中的 key 的应用

Key 是为了区分组件的键。如果空间名称完全相同就会报错,需要用 key 进行区分。

Fragment 局部刷新

Streamlit 默认是全页刷新,通过@st. Fragment 装饰器,可以实现实现局部刷新的效果。

1
2
3
4
5
6
7
8
9
10
11
12
import streamlit as st
import time

@st.fragment
def release_the_balloons():
st.button("Release the balloons", help="Fragment rerun")
st.balloons()

with st.spinner("Inflating balloons..."):
time.sleep(5)
release_the_balloons()
st.button("Inflate more balloons", help="Full rerun")

Session State

Session State 是 Streamlit 提供的一种机制,用于在用户会话之间保持变量的状态。在 Web 应用中,通常每个用户的请求都是独立的,这意味着每次刷新页面或导航到新页面时,变量的状态都会丢失。然而,在某些情况下,我们希望某些变量的状态能够在用户的整个会话期间保持不变,这就是 Session State 发挥作用的地方。

示例 1:简单的计数器

这个示例展示了一个简单的计数器,用户每次点击按钮时,计数器的值会增加。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import streamlit as st

# 初始化 session state
if 'counter' not in st.session_state:
st.session_state.counter = 0

# 增加计数器的按钮
increment_button = st.button('Increment Counter')

if increment_button:
st.session_state.counter += 1

# 显示当前计数器的值
st.write(f'Counter: {st.session_state.counter}')

示例 2:用户登录状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import streamlit as st

# 初始化 session state
if 'logged_in' not in st.session_state:
st.session_state.logged_in = False

# 登录表单
if not st.session_state.logged_in:
username = st.text_input('Username')
password = st.text_input('Password', type='password')
login_button = st.button('Login')

if login_button:
if username == 'admin' and password == 'password':
st.session_state.logged_in = True
st.success('Logged in successfully!')
else:
st.error('Invalid credentials')

# 显示欢迎信息
if st.session_state.logged_in:
st.write(f'Welcome, {username}!')
logout_button = st.button('Logout')
if logout_button:
st.session_state.logged_in = False
st.success('Logged out successfully!')

St. Form 表单

使用 st.form 创建一个表单,需要给表单分配一个唯一的 key,这个 key 用于标识不同的表单实例。在表单内部,可以添加各种输入控件,如文本输入框、选择框等。
在表单内部,你可以像在其他地方一样添加各种输入控件。这些控件的值会被保存在一个表单状态中,直到用户点击提交按钮。
使用 st.form_submit_button 添加一个提交按钮。当用户点击这个按钮时,表单内的所有输入控件的值都会被捕获,并可以通过条件语句来处理这些值。

以下是一个完整的示例,展示了如何使用 st.form 创建一个包含多个输入控件的表单,并在用户提交表单后验证输入的有效性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
with st.form(key="form1"):
respond_info = {
"name": None,
"team": None,
"share_info": None,
"email_info": None,
"age_info": None
}

respond_info["name"] = st.text_input(label="Name")
respond_info["team"] = st.selectbox(
label="favorate team:",
options=["Arsenal", "Man City", "Man United", "Chelsea", "Liverpool"]
)
respond_info["share_info"] = st.radio(label="share my information:", options=["yes", "no"])
respond_info["email_info"] = st.checkbox(label="Receive Email notification")
respond_info["age_info"] = st.slider(label="age", min_value=0, max_value=100)
# submit button
form_submitted = st.form_submit_button(label="Submit!")

def check_form_valid():
vals = respond_info.values()
return all([True if val not in [None, ""] else False for val in vals ])

# check format
if form_submitted:
if not check_form_valid():
st.warning("Please fill in all form values!")
else:
# st.balloons()
st.write("form submitted!")


print(respond_info)
respond_info

St. Cache_data

st.cache_data 是 Streamlit 提供的一个装饰器,用于缓存函数的输出结果。它可以帮助减少数据加载或计算的时间,提高应用的响应速度。当一个带有 @st.cache_data 装饰器的函数被调用时,Streamlit 会检查函数的输入参数是否已经存在于缓存中。如果存在,则直接从缓存中读取结果;如果不存在,则执行函数并将其输出结果存储到缓存中。

使用示例

下面是一个简单的例子,展示了如何使用 st.cache_data 缓存一个模拟的耗时数据加载过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import streamlit as st
import time
import pandas as pd

# 模拟一个耗时的数据加载函数
@st.cache_data
def load_data(n_rows):
# 模拟长时间的数据加载过程
time.sleep(5) # 假设需要5秒来加载数据
data = {'column1': range(n_rows), 'column2': range(n_rows)}
return pd.DataFrame(data)

# 用户界面部分
st.title('使用 st.cache_data 加速数据加载')

# 获取用户输入
n_rows = st.number_input('请输入行数', min_value=1, value=100)

# 显示加载中的提示信息
with st.spinner('正在加载数据...'):
df = load_data(n_rows)

# 显示数据
st.write(df)
st.success('数据加载完成!')

在这个例子中,load_data 函数被 @st.cache_data 装饰器修饰。第一次加载指定数量的数据时,会实际执行 time.sleep(5) 模拟的长时间加载过程,并将结果缓存起来。当用户再次请求相同数量的数据时,Streamlit 将直接从缓存中获取结果,而不需要再次等待 5 秒。

批处理命令及开机启动

在服务器上部署 web 项目时,需要设置批处理命令,包括启动 python 环境,指定 python 文件等。
下面为一个例子。

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
rem 初始化 Conda
call "C:\Users\htwl\anaconda3\Scripts\activate"

rem 激活 Conda 环境
call conda activate streamlit_env

rem 切换到目标目录
cd /d D:\baibaoxiang

rem 运行 Streamlit 应用
call streamlit run D:\baibaoxiang\app.py
  • @echo off:关闭命令回显,使输出更干净。
  • call "C:\Users\htwl\anaconda3\Scripts\activate":调用 Conda 的激活脚本。
  • call conda activate streamlit_env:激活指定的 Conda 环境。
  • cd /d D:\baibaoxiang:切换到目标目录。
  • call streamlit run D:\baibaoxiang\app.py:运行 Streamlit 应用。

将上面内容放在. Bat 文件内,将文件复制到 windows 开始菜单的启动文件夹内。实现开机自动运行。

1
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

BY

纯个人经验,如有帮助,请收藏点赞,如需转载,请注明出处。
微信公众号:环境猫 er
CSDN : 细节处有神明
个人博客: https://maoyu92.github.io/


Streamlit 技巧 几个被忽视但重要的功能和机制
https://maoyu92.github.io/2024/11/13/04 经验分享/Streamlit 技巧 几个被忽视但重要的功能和机制/
作者
陈文茂
发布于
2024年11月13日
许可协议