BULAK/build_exe.py

227 lines
6.4 KiB
Python

#!/usr/bin/env python3
"""
打包脚本 - 将Streamlit应用打包成exe文件
"""
import os
import sys
import subprocess
import shutil
def install_pyinstaller():
"""安装PyInstaller"""
print("正在安装PyInstaller...")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "pyinstaller"])
print("✅ PyInstaller安装成功")
return True
except subprocess.CalledProcessError as e:
print(f"❌ PyInstaller安装失败: {e}")
return False
def create_spec_file():
"""创建PyInstaller spec文件"""
spec_content = '''# -*- mode: python ; coding: utf-8 -*-
import sys
from PyInstaller.utils.hooks import collect_data_files, collect_submodules
block_cipher = None
a = Analysis(
['app.py'],
pathex=[],
binaries=[],
datas=[
*collect_data_files('streamlit'),
*collect_data_files('streamlit_ace'),
*collect_data_files('streamlit_option_menu'),
('.env', '.')
],
hiddenimports=[
'streamlit',
'streamlit.web.cli',
'streamlit.runtime.scriptrunner',
'streamlit.proto',
'streamlit.config',
'streamlit.logger',
'streamlit.caching',
'streamlit.elements',
'streamlit.components',
'streamlit.server',
'streamlit.runtime',
'streamlit.delta_generator',
'streamlit.elements.lib.mutable_status_container',
'streamlit.elements.lib.dialog',
'streamlit.elements.lib.column_config',
'streamlit.elements.lib.metrics',
'streamlit.elements.lib.toast',
'streamlit.elements.lib.chat_message',
'streamlit.elements.lib.experimental_connection',
'streamlit.elements.lib.experimental_data_editor',
'streamlit.elements.lib.experimental_fragment',
'streamlit.elements.lib.experimental_get_query_params',
'streamlit.elements.lib.experimental_set_query_params',
'streamlit.elements.lib.experimental_user',
'streamlit.elements.lib.form_submit_button',
'streamlit.elements.lib.media',
'streamlit.elements.lib.progress',
'streamlit.elements.lib.snow',
'streamlit.elements.lib.spinner',
'streamlit.elements.lib.status',
'streamlit.elements.lib.tabs',
'streamlit.elements.lib.toast',
'streamlit.elements.lib.toggle',
'streamlit.elements.lib.tooltip',
'streamlit.elements.lib.widgets',
'openai',
'dotenv',
'requests',
'urllib3',
'certifi',
'charset_normalizer',
'idna',
'yaml',
'toml',
'PIL',
'numpy',
'pandas',
'altair',
'plotly',
'pydeck',
'bokeh',
'graphviz',
'keras',
'seaborn',
'sympy',
'streamlit_ace',
'streamlit_option_menu'
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='multi_agent_decision_workshop',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False, # 设置为False以隐藏控制台窗口
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
'''
with open('app.spec', 'w', encoding='utf-8') as f:
f.write(spec_content)
print("✅ spec文件创建成功")
def build_exe():
"""构建exe文件"""
print("开始构建exe文件...")
try:
# 使用spec文件构建
subprocess.check_call([sys.executable, "-m", "PyInstaller", "app.spec", "--clean"])
print("✅ exe文件构建成功")
# 检查生成的文件
dist_dir = "dist"
if os.path.exists(dist_dir):
exe_path = os.path.join(dist_dir, "multi_agent_decision_workshop.exe")
if os.path.exists(exe_path):
file_size = os.path.getsize(exe_path) / (1024 * 1024) # MB
print(f"📦 生成的exe文件: {exe_path}")
print(f"📊 文件大小: {file_size:.2f} MB")
return True
print("❌ exe文件生成失败")
return False
except subprocess.CalledProcessError as e:
print(f"❌ 构建失败: {e}")
return False
def create_launcher_bat():
"""创建启动批处理文件"""
bat_content = '''@echo off
echo 正在启动多Agent决策工作坊...
echo.
cd /d "%~dp0"
if exist "multi_agent_decision_workshop.exe" (
echo 启动应用程序...
start "" "multi_agent_decision_workshop.exe"
echo 应用程序已启动,请在浏览器中打开 http://localhost:8501
echo 按任意键退出...
pause >nul
) else (
echo 错误:未找到 multi_agent_decision_workshop.exe
echo 请确保此文件与exe文件在同一目录
pause
)
'''
with open('启动程序.bat', 'w', encoding='gbk') as f:
f.write(bat_content)
print("✅ 启动批处理文件创建成功")
def main():
"""主函数"""
print("🚀 开始打包多Agent决策工作坊应用...")
print("=" * 50)
# 检查当前目录
if not os.path.exists('app.py'):
print("❌ 错误:请在项目根目录运行此脚本")
return
# 安装PyInstaller
if not install_pyinstaller():
return
# 创建spec文件
create_spec_file()
# 构建exe
if build_exe():
# 复制必要的文件到dist目录
dist_dir = "dist"
if os.path.exists(dist_dir):
# 复制.env文件
if os.path.exists('.env'):
shutil.copy2('.env', os.path.join(dist_dir, '.env'))
# 创建启动批处理文件
os.chdir(dist_dir)
create_launcher_bat()
print("\n🎉 打包完成!")
print("📁 生成的文件在 'dist' 目录中")
print("🚀 双击 '启动程序.bat' 即可运行应用")
print("🌐 然后在浏览器中打开 http://localhost:8501")
else:
print("❌ dist目录不存在")
else:
print("❌ 打包失败")
if __name__ == "__main__":
main()