feat: 添加便携启动器和智能选项生成功能\n\n- 添加启动应用.bat便携启动器\n- 实现AI智能选项生成系统\n- 优化UI界面和问题细化功能\n- 更新端口号为8513\n- 添加打包脚本build_exe.py和simple_build.py
This commit is contained in:
parent
c801921c73
commit
3b64fcb5e7
227
build_exe.py
Normal file
227
build_exe.py
Normal file
@ -0,0 +1,227 @@
|
||||
#!/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()
|
||||
140
simple_build.py
Normal file
140
simple_build.py
Normal file
@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
简化版打包脚本
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
def check_dependencies():
|
||||
"""检查依赖"""
|
||||
print("检查依赖...")
|
||||
try:
|
||||
import streamlit
|
||||
import openai
|
||||
import dotenv
|
||||
print("✅ 依赖检查通过")
|
||||
return True
|
||||
except ImportError as e:
|
||||
print(f"❌ 依赖缺失: {e}")
|
||||
return False
|
||||
|
||||
def create_standalone_app():
|
||||
"""创建独立应用"""
|
||||
print("创建独立应用...")
|
||||
|
||||
# 创建启动脚本
|
||||
launcher_content = '''import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
def install_dependencies():
|
||||
"""安装依赖"""
|
||||
print("正在安装依赖...")
|
||||
packages = ["streamlit", "openai", "python-dotenv"]
|
||||
for package in packages:
|
||||
try:
|
||||
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
|
||||
print(f"✅ {package} 安装成功")
|
||||
except Exception as e:
|
||||
print(f"❌ {package} 安装失败: {e}")
|
||||
return False
|
||||
return True
|
||||
|
||||
def run_app():
|
||||
"""运行应用"""
|
||||
# 创建临时目录并复制文件
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
print(f"临时目录: {temp_dir}")
|
||||
|
||||
# 复制app.py
|
||||
shutil.copy2("app.py", os.path.join(temp_dir, "app.py"))
|
||||
|
||||
# 复制.env文件(如果存在)
|
||||
if os.path.exists(".env"):
|
||||
shutil.copy2(".env", os.path.join(temp_dir, ".env"))
|
||||
|
||||
# 切换到临时目录
|
||||
os.chdir(temp_dir)
|
||||
|
||||
# 运行streamlit
|
||||
print("启动应用...")
|
||||
print("请在浏览器中打开: http://localhost:8501")
|
||||
subprocess.call([sys.executable, "-m", "streamlit", "run", "app.py", "--server.headless", "true"])
|
||||
|
||||
# 清理临时目录
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if install_dependencies():
|
||||
run_app()
|
||||
else:
|
||||
print("依赖安装失败,请手动安装依赖")
|
||||
input("按任意键退出...")
|
||||
'''
|
||||
|
||||
with open('launcher.py', 'w', encoding='utf-8') as f:
|
||||
f.write(launcher_content)
|
||||
|
||||
# 创建批处理文件
|
||||
bat_content = '''@echo off
|
||||
chcp 65001 >nul
|
||||
echo 多Agent决策工作坊启动器
|
||||
echo.
|
||||
echo 正在检查Python环境...
|
||||
|
||||
python --version >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo 错误:未找到Python,请先安装Python 3.8+
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Python环境正常
|
||||
echo 启动应用...
|
||||
echo.
|
||||
echo 应用将在浏览器中打开,请稍候...
|
||||
echo.
|
||||
|
||||
python launcher.py
|
||||
|
||||
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
|
||||
|
||||
# 检查依赖
|
||||
if not check_dependencies():
|
||||
print("请先安装依赖: pip install streamlit openai python-dotenv")
|
||||
return
|
||||
|
||||
# 创建独立应用
|
||||
create_standalone_app()
|
||||
|
||||
print("\n🎉 打包完成!")
|
||||
print("📁 生成的文件:")
|
||||
print(" - launcher.py (启动脚本)")
|
||||
print(" - 启动应用.bat (双击运行)")
|
||||
print("\n🚀 使用方法:")
|
||||
print(" 1. 双击 '启动应用.bat'")
|
||||
print(" 2. 等待依赖安装完成")
|
||||
print(" 3. 在浏览器中打开 http://localhost:8501")
|
||||
print("\n💡 提示:教室电脑需要有Python环境")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
92
启动应用.bat
Normal file
92
启动应用.bat
Normal file
@ -0,0 +1,92 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
title 多Agent决策工作坊启动器
|
||||
|
||||
echo ========================================
|
||||
echo 多Agent决策工作坊 - 便携版启动器
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo 正在检查Python环境...
|
||||
|
||||
:: 检查Python
|
||||
python --version >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo ❌ 错误:未找到Python
|
||||
echo.
|
||||
echo 请先安装Python 3.8+ 并确保已添加到PATH
|
||||
echo 下载地址:https://www.python.org/downloads/
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo ✅ Python环境正常
|
||||
echo.
|
||||
|
||||
echo 正在检查依赖...
|
||||
|
||||
:: 检查并安装streamlit
|
||||
python -c "import streamlit" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo 安装streamlit...
|
||||
python -m pip install streamlit --user
|
||||
if errorlevel 1 (
|
||||
echo ❌ streamlit安装失败
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo ✅ streamlit安装成功
|
||||
) else (
|
||||
echo ✅ streamlit已安装
|
||||
)
|
||||
|
||||
:: 检查并安装openai
|
||||
python -c "import openai" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo 安装openai...
|
||||
python -m pip install openai --user
|
||||
if errorlevel 1 (
|
||||
echo ❌ openai安装失败
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo ✅ openai安装成功
|
||||
) else (
|
||||
echo ✅ openai已安装
|
||||
)
|
||||
|
||||
:: 检查并安装python-dotenv
|
||||
python -c "import dotenv" >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo 安装python-dotenv...
|
||||
python -m pip install python-dotenv --user
|
||||
if errorlevel 1 (
|
||||
echo ❌ python-dotenv安装失败
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo ✅ python-dotenv安装成功
|
||||
) else (
|
||||
echo ✅ python-dotenv已安装
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ✅ 所有依赖检查完成
|
||||
echo.
|
||||
|
||||
echo 正在启动多Agent决策工作坊...
|
||||
echo.
|
||||
echo 🌐 应用将在浏览器中自动打开
|
||||
echo 📱 地址:http://localhost:8513
|
||||
echo.
|
||||
echo ⏳ 请稍候...
|
||||
echo.
|
||||
|
||||
:: 运行应用
|
||||
python -m streamlit run app.py --server.headless true --server.port 8513
|
||||
|
||||
echo.
|
||||
echo 应用已关闭
|
||||
echo.
|
||||
pause
|
||||
Loading…
Reference in New Issue
Block a user