Streamlit应用打包发布
前言
好久没有冒个泡泡了,最近也是非常忙碌。搞事情还是非常累的,那么这里的话就简单更新一下使用实用一点的文章。这也是在实际过程当中遇到了很多问题,最终才解决之后的一篇经验文吧。
打包准备
这里我使用到的打包软件还是Pyinstaller ,通过这个来对其进行打包,软件本体大概是长这个样子:
这是一个视频编辑器,页面是使用streamlit来进行编写的(当然也后悔了,早知道直接使用qt或者vue来写的)那么众所周知,streamlit写出来的界面本身是需要这个玩意来独立启动的。因此打包的时候有很多细节。
载入streamlit
这里我们需要单独指定一下streamlit。这里我们需要编写一下hook,让pyinstaller来处理。
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata("streamlit")
创建启动脚本
这里我们的程序入口虽然是main.py 但是,由于我们需要
streamlit run main.py
才能启动,所以的话我们只能写一个运行脚本。之后对这个脚本进行打包,得到执行文件。
之后打包之后,需要将这个文件放到打包好 的执行文件的同级目录下
。
"""
@FileName:run_app.py.py
@Author:Huterox
@Description:Go For It
@Time:2024/6/11 11:42
@Copyright:©2018-2024 awesome!
"""
from main import *
def resolve_path(path):
resolved_path = os.path.abspath(os.path.join(os.getcwd(), path))
return resolved_path
if __name__ == "__main__":
sys.argv = [
"streamlit",
"run",
resolve_path("main.py"),
"--global.developmentMode=false",
]
sys.exit(stcli.main())
创建指令
之后的话,我们需要来创建我们的指令: 这里我展示一下我的指令:
pyinstaller --add-data ".streamlit:.streamlit" --add-data "resource:resource" --add-data "doc:doc" --add-data "assert:assert" --additional-hooks-dir=./hooks --icon=tubiao.ico run_app.py
当然实际上,我们之所以使用这个指令的目的还是为了生成spec文件,你当然可以直接创建这个文件。下面是我的参考文件。
# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.utils.hooks import collect_data_files
from PyInstaller.utils.hooks import copy_metadata
datas = [("C:/Anaconda3/envs/MixedVideo/Lib/site-packages/streamlit/runtime","./streamlit/runtime"),('.streamlit', '.streamlit'), ('resource', 'resource'), ('doc', 'doc'), ('assert', 'assert')]
datas += collect_data_files("streamlit")
datas += copy_metadata("streamlit")
block_cipher = None
a = Analysis(
['run_app.py'],
pathex=[],
binaries=[],
datas=datas,
hiddenimports=[],
hookspath=['./hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='run_app',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['tubiao.ico'],
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='run_app',
)
你可以直接按照这个来进行修改。之后
pyinstaller your_spec.spec --clean
这样一来就可以完成打包了,但是这里有几个点需要特别注意:
Q&A
虽然通过上面的方法我们可以打包好我们的程序,但是这里还是有很多问题。这里我遇到的,包括我查找相关资料的时候看到的最多的问题就是,关于依赖的问题。
依赖未找到
这里原因其实就只有一个,那就是Pyinstaller打包的时候,没有找到依赖,我们来看到这个代码。
from main import *
def resolve_path(path):
resolved_path = os.path.abspath(os.path.join(os.getcwd(), path))
return resolved_path
if __name__ == "__main__":
sys.argv = [
"streamlit",
"run",
resolve_path("main.py"),
"--global.developmentMode=false",
]
sys.exit(stcli.main())
我在这里特意:
from main import *
其目的就是为了,让Pyinstaller知道,我导入了先前程序的main文件,之后去解析里面的依赖然后自动打包。这样就解决了依赖问题,注意哪怕是你自己写的包,他也会自动解析的。如果没有,只有两个问题:
- 你的Python包没有
__init__.py
- 缺少某些dll,依赖模型(因为我这个是深度学习项目,有一些特殊格式的文件是不会被自动打包进去的)
那么解决办法很简单:
- 加入初始化文件
- 填写模块名字(第三方或自己的包名)
- 缺少某些媒体,资源文件,那就直接找打对应文件copy过去就好了。以我的程序为例,有3G的模型文件不会自动打包进去的,只能自己手动导入。
总结
以上就是全部内容了~
转载自:https://juejin.cn/post/7379092280575868965