setup_venv.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #!/usr/bin/env python
  2. """
  3. Python虚拟环境设置脚本
  4. 功能:
  5. - 创建Python虚拟环境
  6. - 安装项目依赖
  7. - 生成激活脚本
  8. 用法:
  9. python setup_venv.py # 创建venv并安装依赖
  10. python setup_venv.py --upgrade # 升级已有依赖
  11. python setup_venv.py --clean # 删除并重新创建venv
  12. """
  13. import os
  14. import sys
  15. import subprocess
  16. import argparse
  17. from pathlib import Path
  18. def run_command(cmd, cwd=None, check=True):
  19. """运行命令并显示输出"""
  20. print(f"执行: {' '.join(cmd) if isinstance(cmd, list) else cmd}")
  21. try:
  22. result = subprocess.run(
  23. cmd,
  24. cwd=cwd,
  25. check=check,
  26. capture_output=True,
  27. text=True,
  28. shell=True if isinstance(cmd, str) else False
  29. )
  30. if result.stdout:
  31. print(result.stdout)
  32. return result
  33. except subprocess.CalledProcessError as e:
  34. print(f"错误: {e}")
  35. if e.stderr:
  36. print(f"错误输出: {e.stderr}")
  37. if check:
  38. sys.exit(1)
  39. return e
  40. def check_python():
  41. """检查Python版本"""
  42. version = sys.version_info
  43. print(f"Python版本: {version.major}.{version.minor}.{version.micro}")
  44. if version.major < 3 or (version.major == 3 and version.minor < 8):
  45. print("❌ 需要Python 3.8或更高版本")
  46. sys.exit(1)
  47. print("✓ Python版本符合要求")
  48. def create_venv(venv_path, clean=False):
  49. """创建虚拟环境"""
  50. if clean and venv_path.exists():
  51. print(f"删除现有虚拟环境: {venv_path}")
  52. import shutil
  53. shutil.rmtree(venv_path)
  54. if venv_path.exists():
  55. print(f"✓ 虚拟环境已存在: {venv_path}")
  56. return
  57. print(f"创建虚拟环境: {venv_path}")
  58. run_command([sys.executable, "-m", "venv", str(venv_path)])
  59. print("✓ 虚拟环境创建成功")
  60. def get_venv_python(venv_path):
  61. """获取虚拟环境中的Python路径"""
  62. if os.name == 'nt': # Windows
  63. return venv_path / "Scripts" / "python.exe"
  64. else: # Unix/Linux/macOS
  65. return venv_path / "bin" / "python"
  66. def get_venv_pip(venv_path):
  67. """获取虚拟环境中的pip路径"""
  68. if os.name == 'nt': # Windows
  69. return venv_path / "Scripts" / "pip.exe"
  70. else: # Unix/Linux/macOS
  71. return venv_path / "bin" / "pip"
  72. def install_dependencies(venv_path, upgrade=False):
  73. """安装项目依赖"""
  74. python_path = get_venv_python(venv_path)
  75. # 升级pip (使用python -m pip方式)
  76. print("升级pip...")
  77. run_command([str(python_path), "-m", "pip", "install", "--upgrade", "pip"])
  78. # 安装依赖
  79. requirements_file = Path("requirements.txt")
  80. if not requirements_file.exists():
  81. print("❌ requirements.txt文件不存在")
  82. return
  83. print("安装项目依赖...")
  84. cmd = [str(python_path), "-m", "pip", "install", "-r", "requirements.txt"]
  85. if upgrade:
  86. cmd.append("--upgrade")
  87. run_command(cmd)
  88. print("✓ 依赖安装完成")
  89. def create_activation_scripts(venv_path):
  90. """创建激活脚本"""
  91. backend_dir = Path.cwd()
  92. # Windows批处理脚本
  93. activate_bat = backend_dir / "activate_venv.bat"
  94. with open(activate_bat, 'w', encoding='utf-8') as f:
  95. f.write(f"""@echo off
  96. echo 激活Python虚拟环境...
  97. call "{venv_path}\\Scripts\\activate.bat"
  98. echo ✓ 虚拟环境已激活
  99. echo.
  100. echo 可用命令:
  101. echo python run.py - 启动Flask应用
  102. echo python init_db.py - 初始化数据库
  103. echo celery -A celery_worker worker - 启动Celery worker
  104. echo pytest - 运行测试
  105. echo.
  106. """)
  107. # Unix/Linux shell脚本
  108. activate_sh = backend_dir / "activate_venv.sh"
  109. with open(activate_sh, 'w', encoding='utf-8') as f:
  110. f.write(f"""#!/bin/bash
  111. echo "激活Python虚拟环境..."
  112. source "{venv_path}/bin/activate"
  113. echo "✓ 虚拟环境已激活"
  114. echo ""
  115. echo "可用命令:"
  116. echo " python run.py - 启动Flask应用"
  117. echo " python init_db.py - 初始化数据库"
  118. echo " celery -A celery_worker worker - 启动Celery worker"
  119. echo " pytest - 运行测试"
  120. echo ""
  121. """)
  122. # 设置执行权限 (Unix/Linux)
  123. if os.name != 'nt':
  124. os.chmod(activate_sh, 0o755)
  125. print(f"✓ 激活脚本已创建:")
  126. print(f" Windows: {activate_bat}")
  127. print(f" Unix/Linux: {activate_sh}")
  128. def main():
  129. parser = argparse.ArgumentParser(description='Python虚拟环境设置')
  130. parser.add_argument('--upgrade', action='store_true', help='升级依赖包')
  131. parser.add_argument('--clean', action='store_true', help='删除并重新创建虚拟环境')
  132. parser.add_argument('--venv-name', default='venv', help='虚拟环境目录名 (默认: venv)')
  133. args = parser.parse_args()
  134. print(f"\n{'='*50}")
  135. print("Python虚拟环境设置")
  136. print(f"{'='*50}\n")
  137. # 检查Python版本
  138. check_python()
  139. # 虚拟环境路径
  140. venv_path = Path.cwd() / args.venv_name
  141. # 创建虚拟环境
  142. create_venv(venv_path, clean=args.clean)
  143. # 安装依赖
  144. install_dependencies(venv_path, upgrade=args.upgrade)
  145. # 创建激活脚本
  146. create_activation_scripts(venv_path)
  147. print(f"\n{'='*50}")
  148. print("✓ 虚拟环境设置完成!")
  149. print(f"{'='*50}")
  150. print(f"\n激活虚拟环境:")
  151. if os.name == 'nt': # Windows
  152. print(f" activate_venv.bat")
  153. print(f" 或者: {venv_path}\\Scripts\\activate.bat")
  154. else: # Unix/Linux
  155. print(f" source activate_venv.sh")
  156. print(f" 或者: source {venv_path}/bin/activate")
  157. print(f"\n停用虚拟环境:")
  158. print(f" deactivate")
  159. if __name__ == '__main__':
  160. main()