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