Framework#
Streamlit is a Python framework for machine learning and data visualization that can build a beautiful online app with just a few lines of code. For front-end beginners, there is no need to learn various difficult front-end frameworks, and using Flask to create various APIs on the back end is quite simple. However, to make the front end look more appealing, one must learn various frameworks and understand how to beautify it, which Streamlit addresses.
However, Streamlit can only be deployed on a server and accessed via a web browser, which is not suitable for industrial software. A Japanese developer has created a wrapped framework to facilitate packaging Streamlit projects as desktop applications.
Streamlit + Wasm + Electron = Desktop app
whitphx/stlite: In-browser Streamlit 🎈🚀
Environment Installation#
[!NOTE]
It is assumed that you already understand and have installed nvm and the basic node.js environment. If not, please refer to another blog post Blog Frontend Secondary Development - Saturn Ring Base.
It is also assumed that you understand how to create Python virtual environments and the basic usage of pip, which is part of Python basics.
- Following the tutorial in the Japanese developer's repository, create a new folder as the project folder and create the following
package.json
file to start a new NPM project, editing thename
field.
{
"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"
}
}
}
-
Run
npm install
At this point, you may encounter errors such as
npm error Cannot read properties of null (reading 'matches')
ornpm error RequestError: unable to verify the first certificate
. You need to delete the existingnode_modules
folder in the project folder. Set the npm proxy source and electron proxy source, and clean the npm cache.Since there is no good command method to modify the electron proxy source (the online command methods are misleading), on Windows, you need to modify the
.npmrc
file in theC:\Users\your_username
folder as follows.
registry=https://registry.npmmirror.com
strict-ssl=false
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
Then execute the following command to clear the cache, and running npm install
should work without issues.
npm cache clean --force
-
Create
app.py
and write the code for the Streamlit application.Here, because the relevant configuration items
stlite.desktop.files
andstlite.desktop.entrypoint
inpackage.json
specifyapp.py
, the file name must beapp.py
.The files and folders specified in
stlite.desktop.files
will be bundled into the desktop application, andstlite.desktop.entrypoint
specifies the entry Streamlit application.
An example is as follows:
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])),
))
For the required four packages, it is recommended to create a new virtual environment and use commands like python -m pip install altair
to install them within the virtual environment.
-
Add more files or directories
You can edit the relevant configuration item
stlite.desktop.files
inpackage.json
as follows; these directories and py files should comply with Streamlit's application rules. In simple terms, add all the files used in the Python project here.
{
// ...other fields...
"stlite": {
"desktop": {
// ...other fields...
"files": ["app.py", "pages/*.py", "assets"]
}
}
}
-
Specify package installations in the desktop application
You can edit the relevant configuration item
stlite.desktop.dependencies
inpackage.json
as follows; simply add all the packages used in the Python project.
{
// ...other fields...
"stlite": {
"desktop": {
// ...other fields...
"dependencies": ["altair", "numpy", "pandas", "streamlit"]
}
}
}
You can also edit stlite.desktop.requirementsTxtFiles
as follows; this is the standard dependency specification file for Python, where you can add a series of dependencies.
{
// ...other fields...
"stlite": {
"desktop": {
// ...other fields...
"requirementsTxtFiles": ["requirements.txt"]
}
}
}
-
Enable node worker threads
I still haven't figured out what worker threads are, but it seems that without enabling worker threads, the ability to run Python code is not available, Pyodide cannot be properly enabled, and the Streamlit application will not start.
Edit
stlite.desktop.nodeJsWorker
as follows.
{
// ...other fields...
"stlite": {
"desktop": {
"nodeJsWorker": true
}
}
}
-
Use the
npm run dump
commandThis creates the
./build
directory, which contains a lot of miscellaneous items needed for this application framework, but these are all for the development server and cannot be published as an executable program. -
Use the
npm run serve
commandThis command is just a wrapper for the
electron
command, which you can find out inpackage.json
. It will startelectron
and begin the application./build/electron/main.js
, which is specified in the"main"
field ofpackage.json
. This will start a de facto development server and open a preview of the desktop window. -
Use the
npm run app:dist
commandThis is also a wrapped
electron
command that will combine the miscellaneous items in the./build
directory into an installation package, placed in the./dist
folder. electron-builder has more detailed documentation. -
The more suitable command is
npm run app:dir
, which will generate a portable application in the./build
directory.
Postscript#
This framework cannot create simple local applications and requires a complete server back-end support. In my conception, I abandoned the use of local loopback addresses for socketio communication.
According to the Japanese developer's statement Electron security best practices by whitphx · #445 · whitphx/stlite, this does not comply with Electron's best security practices.
Additionally, his wrapper actually uses the specified Python version to download the packages specified in our package.json for sandbox execution, while our industrial desktop applications need to support 32-bit systems. Moreover, Streamlit's development plan does not support 32-bit systems and can only use the old version 0.62.0. Therefore, the entire framework has been abandoned for research.
This article is synchronized and updated by Mix Space to xLog. The original link is https://www.yono233.cn/posts/shoot/25_1_15_Streamlit_desktop