框架#
Streamlit 是一个用于机器学习、数据可视化的 Python 框架,它能几行代码就构建出一个精美的在线 app 应用。对于前端小白来说是可以完全不用学习各种困难的前端框架,后端使用 flask 创建各种 api 是相当简单的,而前端想要弄得美观一些则必须学习各种框架并且懂得如何美化,Streamlit 解决了这个痛点。
但是 Streamlit 原生只能部署在服务器上,使用网页端进行浏览,这对于工业软件来说是不行的,有一个日本哥们构建了一个包装后的框架以便于 Streamlit 项目包装成桌面应用。
Streamlit + Wasm + Electron = Desktop app
whitphx/stlite: In-browser Streamlit 🎈🚀
环境安装#
[!NOTE]
默认已经了解并安装了 nvm 以及基础的 node.js 环境,没安装的请看另一篇博文 博客前端的二次开发 - 土星环的基地 。
默认已经了解了 python 的虚拟环境创建以及 pip 基本用法,这部分是 python 基础。
- 依据日本哥们仓库里的教程,新建一个文件夹作为项目文件夹,创建以下
package.json文件开始一个新的 NPM 项目,编辑name字段。
{
"name": "xxx",
"version": "0.1.0",
"main": "./build/electron/main.js",
"scripts": {
"dump": "dump-stlite-desktop-artifacts",
"serve": "cross-env NODE_ENV=production electron .",
"app:dir": "electron-builder --dir",
"app:dist": "electron-builder",
"postinstall": "electron-builder install-app-deps"
},
"build": {
"files": ["build/**/*"],
"directories": {
"buildResources": "assets"
}
},
"devDependencies": {
"@stlite/desktop": "^0.69.2",
"cross-env": "^7.0.3",
"electron": "33.3.1",
"electron-builder": "^25.1.7"
},
"stlite": {
"desktop": {
"files": ["app.py"],
"entrypoint": "app.py"
}
}
}
-
运行
npm install这个时候会有报错
npm error Cannot read properties of null (reading 'matches')或者npm error RequestError: unable to verify the first certificate这些。需要删除项目文件夹中原有的 node_modules 文件夹。设置 npm 代理源以及 electron 代理源,清理 npm 缓存。因为并没有很好的指令方法修改 electron 代理源 (网上的指令方法都是胡说八道的),在 windows 下,需要修改 C:\Users\ 你的用户名 文件夹下的 .npmrc 文件为如下。
registry=https://registry.npmmirror.com
strict-ssl=false
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
然后执行以下指令清除缓存,再运行 npm install 就没问题了。
npm cache clean --force
-
创建
app.py并编写 Streamlit 应用程序的代码。这里因为
package.json中相关配置项stlite.desktop.files以及stlite.desktop.entrypoint指定是app.py命名,所以必须是app.py文件名。其中
stlite.desktop.files指定的文件和文件夹复制捆绑到桌面应用上,stlite.desktop.entrypoint指定入口 Streamlit 应用程序。
一个示例如下
import altair as alt
import numpy as np
import pandas as pd
import streamlit as st
"""
# Welcome to Streamlit!
Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
forums](https://discuss.streamlit.io).
In the meantime, below is an example of what you can do with just a few lines of code:
"""
num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
indices = np.linspace(0, 1, num_points)
theta = 2 * np.pi * num_turns * indices
radius = indices
x = radius * np.cos(theta)
y = radius * np.sin(theta)
df = pd.DataFrame({
"x": x,
"y": y,
"idx": indices,
"rand": np.random.randn(num_points),
})
st.altair_chart(alt.Chart(df, height=700, width=700)
.mark_point(filled=True)
.encode(
x=alt.X("x", axis=None),
y=alt.Y("y", axis=None),
color=alt.Color("idx", legend=None, scale=alt.Scale()),
size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
))
其中需要的 4 个软件包,建议创建一个新的虚拟环境,并且在虚拟环境中使用类似 python -m pip install altair 的指令进行安装。
-
增加更多的文件或者目录
可以编辑
package.json中相关配置项stlite.desktop.files类似如下,这些目录和 py 文件都应该符合 Streamlit 的应用规则,简单来说就是 python 项目里用到哪些文件这里就统统添加进去。
{
// ...other fields...
"stlite": {
"desktop": {
// ...other fields...
"files": ["app.py", "pages/*.py", "assets"]
}
}
}
-
指定软件包安装在桌面应用程序里
可以编辑
package.json中相关配置项stlite.desktop.dependencies类似如下,简单来说就是 python 项目里用到哪些包就统统添加进去。
{
// ...other fields...
"stlite": {
"desktop": {
// ...other fields...
"dependencies": ["altair", "numpy", "pandas", "streamlit"]
}
}
}
也可以编辑 stlite.desktop.requirementsTxtFiles 类似如下,这是 python 的标准依赖指定文件,可以添加一系列依赖指定。
{
// ...other fields...
"stlite": {
"desktop": {
// ...other fields...
"requirementsTxtFiles": ["requirements.txt"]
}
}
}
-
开启 node worker 线程
所谓的 worker 线程是什么我也还没弄清楚,现象上来看不开启 worker 线程就不具备 python 代码的运行能力,Pyodide 无法正常启用,Streamlit 应用会无法开启。
编辑
stlite.desktop.nodeJsWorker类似如下。
{
// ...other fields...
"stlite": {
"desktop": {
"nodeJsWorker": true
}
}
}
-
使用
npm run dump指令创建了
./build目录,包含一大堆杂七杂八的东西,都是这个应用框架所需要的,但是这些都是服务于了后面的开发服务器,而不能发布为可执行程序。 -
使用
npm run serve指令这个命令只是一个包装的
electron命令你可以在package.json中了解到真实指令。它将启动electron并开始应用程序./build/electron/main.js,这是指定的"main"域中的package.json。将会开启一个事实上的开发服务器,并且打开桌面窗口的预览。 -
使用
npm run app:dist指令这同样是一个包装的
electron命令,将使用./build目录中杂七杂八的东西组合成一个安装包,放在./dist文件夹下, electron-builder 有更详细的说明。 -
而更合适的是
npm run app:dir指令,这将会在./build目录生成一个免安装的应用程序
后记#
这个框架不能进行简单的本地应用,而需要完善的服务器后端支持。在我的构想中因为不能使用本地环回地址进行 socketio 的通信,而放弃使用了。
依据日本老哥的说法 Electron security best practices by whitphx · #445 · whitphx/stlite,这不符合 Electron 安全最佳做法。
另外他的包装事实上是使用他所指定的 python 版本下载我们 package.json 中指定的包进行沙盒运行,而我们工业界的桌面应用需要支持 32 位系统,同时 Streamlit 发展计划上也不支持 32 位系统,而只能使用 0.62.0 的老版本。所以整个框架都放弃研究。
此文由 Mix Space 同步更新至 xLog
原始链接为 https://www.yono233.cn/posts/shoot/25_1_15_Streamlit_desktop