框架#
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