Streamlit 快速构建交互式页面的python库

基础介绍
streamlit 是什么
Streamlit是一个面向机器学习和数据科学团队的开源应用程序框架,通过它可以用python代码方便快捷的构建交互式前端页面。streamlit特别适合结合大模型快速的构建一些对话式的应用,可以看到一些行业内热门的使用。



项目本身也比较成熟,release版本,start数量等都表明该项目持续打磨了很长时间。

streamlit 简单示例
import streamlit as st
import numpy as np
import matplotlib.pyplot as plt
st.title('Sin')
# Get user input for frequency and amplitude
freq = st.slider('频率', min_value=1, max_value=10, value=1)
# Create x values
x = np.linspace(0, 2*np.pi, 1000)
# Create y values
y = np.sin(freq * x)
# Plot the graph
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Sine Wave')
ax.set_xlabel('X')
ax.set_ylabel('Y')
st.pyplot(fig)
运行代码
streanlit run sample_demo.py

streamlit 优缺点
streamlit优点:
- 不需要掌握前端知识就能创建web页面
- 内置很多机器学习交互的展示组件,更有利于算法工程师使用
- 开发速度快,修改方便
streamlit缺点: - 前端界面固定,开发者不能随意调整控件位置
- 只适合于少量页面的项目,不适用于复杂网页的网站前端
组件集合
streamlit 主要用于构建前端页面,有着丰富的前端组件。 streamlit 官方文档:https://docs.streamlit.io/library/get-started/main-concepts
从官方文档来看,主要的组件包括:
- 文本
- 数据表格
- 图表
- 输入组件
- 媒体组件
- 布局和容器
- 聊天框
- 状态展示
- 控制流程
下面将常见的组件拿出来,做一个集合。stremlit的一个页面叫做一个app,可以将多个页面组装起来,如下图:


文字

数据表格

输入组件

聊天

js和html 渲染
上文中已经提到streamlit的组件排列方式是从上到下逐个渲染,无法做到html那样灵活的调整组件的位置。但是stream还是提供了两个函数可以支持对页面css和js的修改。
对css的修改
streamlit中按钮是没有背景颜色的,如果想增加按钮的底色,就可以对其css修改。如下:
import streamlit as st
st.button("点击我")
hide_streamlit_style = """
<style>
.ef3psqc11 {background-color: yellowgreen}
</style>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
通过类名找到对应的按钮,然后准备好css代码,最后使用st.markdown函数将css渲染到页面上。

这时就可以通过css 隐藏属性来完成。根据按钮的id找到按钮,隐藏该组件。
hide_streamlit_style = """
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
</style>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
插入js
除了可以插入css之后,streamlit也支持插入js代码,这个功能就赋予streamlit操作html页面的能力。上面修改按钮颜色的需求通过js也能实现。首先通过js找到按钮,然后对元素的属性赋值。
import streamlit as st
import streamlit.components.v1 as components
st.button("点击我")
# hide_streamlit_style = """
# <style>
# .ef3psqc11 {background-color: yellowgreen}
# </style>
# """
# st.markdown(hide_streamlit_style, unsafe_allow_html=True)
js_btn = '''window.parent.document.getElementsByClassName("ef3psqc11")[0].style.backgroundColor = "bisque"'''
components.html(f'''<script>{js_btn}</script>''', width=0, height=0)
修改js使用的是import streamlit.components.v1 as components,和普通js不同的是需要在js前面加上window.parent,否则不能生效。
除了支持原生js之后,也支持jquery库。
组件工作原理
使用streamlit构建的页面和html构建的页面在工作方式上有很大的不同,streamlit有自己的一套工作机制,具体来说有如下两点注意:
- streamlit 根据组件在代码的位置,从上至下渲染组件
- 点击或触发某一个控件之后,代码会从上至下执行一遍
会话状态
在前文中提到streamlit中触发一个按钮会重新执行整个文件,相当于整个代码重新执行一遍,这样带来的一个副作用就是前后两次操作不能互相传递数据。比如下图中想要实现点击确定按钮,将输入的内容展示在最上面。

这个简单的需求反而不好实现,因为点击确定按钮之后,整个程序重新执行,输入的用户名和密码已经是上一次页面的数据,无法传递到下一次页面渲染中。这时就需要会话状态来解决这个问题了。
首先解释一下streamlit中的会话。在streamlit中一个tab页表示一个会话,新开tab页或者刷新页面都代表会话失效。会话机制提供了一种能力:在会话中,也就是一个tab中存在一个全局对象,支持插入、更新、删除数据,该对象在会话任何时机都可以使用。会话机制可以有效解决页面渲染前后带来的数据传递问题。
下面看看通过会话机制如何解决数据传递
import streamlit as st
msg = ""
if "name" in st.session_state:
msg = {"name": st.session_state.name, "passwd": st.session_state.passwd}
st.write(f"输入的内容是:{msg}")
name = st.text_input(label="用户名:")
passwd = st.text_input(label="密码:")
submit = st.button("确定")
if submit:
st.session_state["name"] = name
st.session_state["passwd"] = passwd
streamlit run text_input.py

st.session_state 就是会话机制的全局变量,在按钮点击之后向st.session_state中更新数据,当新一轮循环开始时判断st.session_state中是否有name属性,如果存在name数据表明会话中有数据,读取数据展示出来。
st.session_state支持即支持字典的数据管理方式,也支持属性的管理方式。也就是说获取一个数据,st.session_state["data"] 和 st.session_state.data都是支持的
避坑指南
在实际使用streamlit中也有到一些让人困惑的事情,下面列举出来避免有人同样踩坑。
不同按钮的监听方式会影响组件渲染顺序
按钮有两种监听方式,分别是监听按钮变量和绑定回调函数
# 按钮监听方法1
submit = st.button()
if submit:
pass
# 按钮监听方法2
submit = st.button(on_click=handler_click)
这两种监听方式有不同的组件渲染顺序。具体来说是:
- 使用监听按钮方式,点击按钮之后程序重新执行所有代码,执行到按钮时进入监听代码片段
- 使用回调函数,点击按钮之后先执行回调函数,再重新执行所有代码
如下获取输入框信息,就会发现获取的是button出现时input输入框的状态,而不是最新的状态
import streamlit as st
def get_username_passwd(username, password):
st.write("username:", username, "password:", password)
with st.form("登录页面"):
username = st.text_input("用户名")
password = st.text_input("密码")
# 使用on_click的方法,获取的是button出现时input输入框的状态,而不是最新的状态。逆天bug
submitted = st.form_submit_button("登录", on_click=get_username_passwd, args=(username, password))
元素没有固定ID
在streamlit中生成的页面没有固定的class name 或 id。在不同环境下可能生成不一样的class name。所以通过js或css修改页面的方法往往不能通用,因为类名会发生变化。
可靠的获取元素的方法是使用 data-testid="stFormSubmitButton"中的 data_testid。

但是如果页面中有多个相同属性的 data-testid,那么这种方式也不可靠。
使用建议
来自三体人的呐喊:
不要在大型项目中使用!
不要在大型项目中使用!
不要在大型项目中使用!
streamlit调整布局是一件痛苦的事情。个人真实感受:如果说做项目想盖房子,做普通项目是用水泥砖头盖房子,用streamlit像是用积木盖房子,感觉碰一下就倒了。

streamlit更适合用在功能单一,页面较少,没有页面跳转的项目上。各种封装好的组件能够快速实现一个最小可行性产品(MVP),避免算法工程师在前端页面花费太长时间。
Streamlit 快速构建交互式页面的python库的更多相关文章
- 通过Web Api 和 Angular.js 构建单页面的web 程序
通过Web Api 和 Angular.js 构建单页面的web 程序 在传统的web 应用程序中,浏览器端通过向服务器端发送请求,然后服务器端根据这个请求发送HTML到浏览器,这个响应将会影响整个的 ...
- selenium测瀑布流UI页面的Python代码
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdri ...
- REST-framework快速构建API--分页
分页简介 当数据量特别大的时候,我们通过API获取数据会非常慢,所以此时我们需要将数据"分批次"取出来,这里的"分批次"就是,分页! REST框架支持自定义分页 ...
- 这些Python库真的很“冷”,但是却很强大
Python是一种很棒的编程语言.事实上,它还是世界上发展最快的编程语言之一.它一次又一次证明了它在数据科学职位中的实用性.整个Python及其库的生态系统使其成为全世界用户(初学者和高级)的合适选择 ...
- 快速构建页面结构的 3D Visualization
对 Chrome 扩展功能熟悉的小伙伴,可能都有用过 Chrome 的 3D 展示页面层级关系这个功能. 可以通过 控制台 --> 右边的三个小点 --> More Tools --> ...
- 一个交互式可视化Python库——Bokeh
本篇为<Python数据可视化实战>第十篇文章,我们一起学习一个交互式可视化Python库--Bokeh. Bokeh基础 Bokeh是一个专门针对Web浏览器的呈现功能的交互式可视化Py ...
- 快速构建一个简单的单页vue应用
技术栈 vue-cli webpack vux,vux-loader less,less-loader vue-jsonp vue-scroller ES6 vue-cli:一个vue脚手架工具,利用 ...
- python抽取指定url页面的title方法
python抽取指定url页面的title方法 今天简单使用了一下python的re模块和lxml模块,分别利用的它们提供的正则表达式和xpath来解析页面源码从中提取所需的title,xpath在完 ...
- Python 库大全
作者:Lingfeng Ai链接:http://www.zhihu.com/question/24590883/answer/92420471来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...
- 哪些 Python 库让你相见恨晚?【转】
原文链接:https://www.zhihu.com/question/24590883/answer/92420471 原文链接:Python 资源大全 ---------------- 这又是一个 ...
随机推荐
- 论文解读(MCD)《Maximum Classifier Discrepancy for Unsupervised Domain Adaptation》
Note:[ wechat:Y466551 | 付费咨询,非诚勿扰 ] 论文信息 论文标题:Maximum Classifier Discrepancy for Unsupervised Domain ...
- 如何破解wifi密码?
前期准备: kali 系统 外置无线网卡 破解过程: 首先,需要登录kali系统,可以是虚拟机. 在虚拟机中设置点击 虚拟机-可移动设备-无线网卡的名称,将无线网卡绑定到kali虚拟机上. 在kali ...
- SpringCloudAlibaba框架学习
遇到问题找了各种办法都没有解决,就reload maven,再不行就重启idea,重启电脑.(有奇效,我好几次就这么解决的,可能是我电脑配置太拉了) 注册中心 - Nacos 配置文件优先级:本地配置 ...
- LeetCode952三部曲之二:小幅度优化(137ms -> 122ms,超39% -> 超51%)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<LeetCode952三部曲& ...
- 搭建 QT6+OpenCv4.7+CMake的环境
本文主要介绍如何搭建QT6+OpenCv的开发环境,基本流程如下 先安装CMake3.27.3,用来编译适用用QT的OpenCv的源码,安装完成后要配置系统的环境变量 安装Qt6的开发环境,并配置环境 ...
- Microsoft Build 2021第二天
C++20 Ranges are complete in Visual Studio 2019 version 16.10 https://devblogs.microsoft.com/cppblog ...
- 「codeforces - 1344D」Résumé Review
link. 有点狗,但还算个好题. 设定 \(f_i(x)=a_ix-x^3\),\(\Delta_i(x)=f_i(x)-f_i(x-1)\),可以洞察到 \(\Delta_i(x)\) 在正自然数 ...
- 6.2 Sunday搜索内存特征
Sunday 算法是一种字符串搜索算法,由Daniel M.Sunday于1990年开发,该算法用于在较长的字符串中查找子字符串的位置.算法通过将要搜索的模式的字符与要搜索的字符串的字符进行比较,从模 ...
- 前端三件套系例之JS——JS的BOM操作、JS的DOM操作
文章目录 1 JS的BOM操作 1.介绍 2.window对象 2-1 代码 3.window的子对象 3-1 navigator对象(了解即可) 3-2 screen对象(了解即可) 3-3 his ...
- solidity入门
1. solidity 简介 Solidity(中文名称:Solidity 语言)是一种面向智能合约(Smart Contracts)的高级编程语言,最初由以太坊(Ethereum)的团队开发并用于以 ...