#!/usr/bin/env python3 """ 一键环境设置脚本 自动配置和初始化AI执行平台环境 """ import os import sys import json import subprocess import shutil from pathlib import Path from typing import Dict, List, Optional class EnvironmentSetup: def __init__(self): self.base_dir = Path(__file__).parent.parent self.config = {} def log_info(self, message: str): print(f"ℹ️ {message}") def log_success(self, message: str): print(f"✅ {message}") def log_warning(self, message: str): print(f"⚠️ {message}") def log_error(self, message: str): print(f"❌ {message}") def create_directory_structure(self): """创建完整的目录结构""" self.log_info("创建目录结构...") directories = [ "tools", "tools/requirements-engine", "tools/task-generator", "tools/execution-engine", "tools/validators", "tools/pipeline", "tools/web", "utils", "prompts", "docs", "docs/process", "docs/engine", "docs/api", "requirements", "requirements/raw", "requirements/parsed", "development", "development/tasks", "reports", "results", "tests", "e2e-tests", "config", "scripts", "static", "logs", "migrations" ] for directory in directories: dir_path = self.base_dir / directory dir_path.mkdir(parents=True, exist_ok=True) self.log_success(f"目录已创建: {directory}") def create_config_files(self): """创建配置文件""" self.log_info("创建配置文件...") # .env.example env_example = """# Claude API配置 CLAUDE_API_KEY=your_claude_api_key_here CLAUDE_API_URL=https://api.anthropic.com # 数据库配置 DATABASE_URL=postgresql+asyncpg://username:password@localhost:5432/ai_execution_platform DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_NAME=ai_execution_platform DATABASE_USER=username DATABASE_PASSWORD=password # Redis配置 REDIS_URL=redis://localhost:6379/0 REDIS_HOST=localhost REDIS_PORT=6379 REDIS_DB=0 # JWT配置 JWT_SECRET_KEY=your_jwt_secret_key_here JWT_ALGORITHM=HS256 JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30 JWT_REFRESH_TOKEN_EXPIRE_DAYS=7 # 应用配置 DEBUG=false LOG_LEVEL=INFO MAX_CONCURRENT_TASKS=3 TASK_TIMEOUT_MINUTES=60 # 安全配置 CORS_ORIGINS=["http://localhost:3000", "http://localhost:8080"] ALLOWED_HOSTS=["localhost", "127.0.0.1"] """ env_file = self.base_dir / ".env.example" with open(env_file, 'w', encoding='utf-8') as f: f.write(env_example) self.log_success("已创建: .env.example") # requirements.txt requirements = """# 核心依赖 fastapi>=0.104.0 uvicorn[standard]>=0.24.0 sqlalchemy[asyncio]>=2.0.0 alembic>=1.12.0 redis>=5.0.0 pydantic>=2.5.0 pydantic-settings>=2.1.0 click>=8.1.0 pyyaml>=6.0.1 jinja2>=3.1.2 python-multipart>=0.0.6 # 数据库驱动 asyncpg>=0.29.0 psycopg2-binary>=2.9.0 # HTTP客户端 httpx>=0.25.0 aiohttp>=3.9.0 # 认证和安全 python-jose[cryptography]>=3.3.0 passlib[bcrypt]>=1.7.4 python-multipart>=0.0.6 # 开发工具 pytest>=7.4.0 pytest-asyncio>=0.21.0 pytest-cov>=4.1.0 black>=23.0.0 ruff>=0.1.0 mypy>=1.7.0 bandit>=1.7.0 # 数据分析 pandas>=2.1.0 numpy>=1.24.0 # 工具库 python-dotenv>=1.0.0 rich>=13.6.0 typer>=0.9.0 """ req_file = self.base_dir / "requirements.txt" with open(req_file, 'w', encoding='utf-8') as f: f.write(requirements) self.log_success("已创建: requirements.txt") # pyproject.toml pyproject_toml = """[build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "ai-execution-platform" version = "2.0.0" description = "AI驱动的代码执行平台" authors = [{name = "LJWX-Stock Team"}] license = {text = "MIT"} readme = "README.md" requires-python = ">=3.11" classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", ] [project.scripts] ai-platform = "scripts.main:main" [tool.ruff] target-version = "py311" line-length = 88 select = ["E", "F", "W", "C", "I", "N", "UP", "YTT", "S", "BLE", "FBT", "B", "A", "COM", "C4", "DTZ", "T10", "EM", "FA", "ISC", "ICN", "G", "INP", "PIE", "T20", "PYI", "PT", "Q", "RSE", "RET", "SLF", "SLOT", "SIM", "TID", "TCH", "ARG", "PTH", "ERA", "PGH", "PL", "TRY", "FLY", "NPY", "AIR", "PERF", "RUF"] ignore = ["E501"] [tool.ruff.per-file-ignores] "tests/*" = ["S101", "S311"] "__init__.py" = ["F401"] [tool.mypy] python_version = "3.11" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true disallow_incomplete_defs = true check_untyped_defs = true disallow_untyped_decorators = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true warn_unreachable = true strict_equality = true [tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py", "*_test.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "--cov=src", "--cov-report=term-missing", "--cov-report=html", "--cov-report=xml", "-v" ] asyncio_mode = "auto" [tool.bandit] exclude_dirs = ["tests", "test_*"] skips = ["B101", "B601"] """ pyproject_file = self.base_dir / "pyproject.toml" with open(pyproject_file, 'w', encoding='utf-8') as f: f.write(pyproject_toml) self.log_success("已创建: pyproject.toml") # .gitignore gitignore = """# Python __pycache__/ *.py[cod] *$py.class *.so .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv Pipfile.lock # poetry poetry.lock # celery beat schedule file celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ # IDE .vscode/ .idea/ *.swp *.swo *~ # OS .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes ehthumbs.db Thumbs.db # Project specific logs/ reports/ results/ development/tasks/ requirements/parsed/ *.db *.sqlite *.sqlite3 # AI/ML models/ checkpoints/ *.pkl *.joblib # Docker .dockerignore docker-compose.override.yml """ gitignore_file = self.base_dir / ".gitignore" with open(gitignore_file, 'w', encoding='utf-8') as f: f.write(gitignore) self.log_success("已创建: .gitignore") def create_sample_requirements(self): """创建示例需求文件""" self.log_info("创建示例需求文件...") sample_req = """requirement: id: REQ-2025-001 title: 用户登录与权限管理 priority: P0 source: type: meeting stakeholder: "产品经理-张三" date: "2025-01-29" raw_content: | 用户需要通过手机号登录系统,登录后根据用户角色显示不同的功能权限。 普通用户只能查看自己的数据,管理员可以查看所有用户数据并进行管理操作。 需要支持验证码登录和密码登录两种方式。 业务规则: 1. 验证码有效期为5分钟 2. 登录失败次数限制为5次 3. 会话有效期为7天 4. 支持多设备同时登录 constraints: - 响应时间 < 200ms - 支持并发用户数 > 1000 - 安全等级: 高 acceptance_criteria: - 用户可以通过手机验证码登录 - 用户可以通过密码登录 - 登录失败次数限制 - 会话管理(7天有效期) - 权限控制正确 """ sample_file = self.base_dir / "requirements" / "raw" / "sample-requirement.yaml" with open(sample_file, 'w', encoding='utf-8') as f: f.write(sample_req) self.log_success("已创建示例需求: requirements/raw/sample-requirement.yaml") def create_git_repo(self): """初始化Git仓库""" self.log_info("初始化Git仓库...") if not (self.base_dir / ".git").exists(): try: subprocess.run(["git", "init"], cwd=self.base_dir, check=True, capture_output=True) subprocess.run(["git", "add", "."], cwd=self.base_dir, check=True, capture_output=True) subprocess.run(["git", "commit", "-m", "Initial commit: AI执行平台初始化"], cwd=self.base_dir, check=True, capture_output=True) self.log_success("Git仓库初始化完成") except subprocess.CalledProcessError as e: self.log_warning(f"Git初始化失败: {e}") else: self.log_info("Git仓库已存在") def setup_python_environment(self): """设置Python环境""" self.log_info("设置Python环境...") # 检查是否有虚拟环境 venv_path = self.base_dir / "venv" if not venv_path.exists(): try: subprocess.run([sys.executable, "-m", "venv", "venv"], cwd=self.base_dir, check=True, capture_output=True) self.log_success("虚拟环境创建完成") except subprocess.CalledProcessError as e: self.log_error(f"虚拟环境创建失败: {e}") return False # 安装依赖 if sys.prefix == sys.base_prefix: # 不在虚拟环境中,提示激活 self.log_warning("请先激活虚拟环境:") if os.name == 'nt': # Windows print(f" venv\\Scripts\\activate") else: # Unix-like print(f" source venv/bin/activate") return False try: subprocess.run([sys.executable, "-m", "pip", "install", "--upgrade", "pip"], cwd=self.base_dir, check=True, capture_output=True) subprocess.run([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], cwd=self.base_dir, check=True, capture_output=True) self.log_success("依赖包安装完成") return True except subprocess.CalledProcessError as e: self.log_error(f"依赖包安装失败: {e}") return False def run_initial_verification(self): """运行初始验证""" self.log_info("运行初始验证...") verify_script = self.base_dir / "scripts" / "verify_setup.py" if verify_script.exists(): try: result = subprocess.run([sys.executable, str(verify_script)], cwd=self.base_dir, capture_output=True, text=True) if result.returncode == 0: self.log_success("环境验证通过") else: self.log_warning(f"环境验证发现问题: {result.stderr}") except Exception as e: self.log_warning(f"无法运行验证脚本: {e}") else: self.log_warning("验证脚本不存在") def generate_setup_summary(self): """生成设置总结""" self.log_info("生成设置总结...") summary = { "setup_completed": True, "timestamp": "2025-01-29T10:30:00Z", "python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", "platform": sys.platform, "base_directory": str(self.base_dir), "next_steps": [ "1. 激活虚拟环境: source venv/bin/activate", "2. 配置环境变量: cp .env.example .env", "3. 编辑 .env 文件,配置API密钥和数据库连接", "4. 启动Redis服务: docker run -d --name redis -p 6379:6379 redis:alpine", "5. 运行验证: python scripts/verify_setup.py", "6. 开始使用: python tools/pipeline/pipeline_orchestrator.py --help" ], "important_files": [ ".env.example - 环境变量模板", "requirements.txt - Python依赖", "README.md - 项目文档", "requirements/raw/sample-requirement.yaml - 示例需求" ], "useful_commands": [ "python scripts/verify_setup.py - 验证环境设置", "python tools/pipeline/pipeline_orchestrator.py --help - 查看流水线帮助", "python utils/generate_execution_contract.py --help - 查看契约生成器帮助", "open tools/web/execution_dashboard.html - 打开监控面板" ] } summary_file = self.base_dir / "reports" / "setup-summary.json" summary_file.parent.mkdir(exist_ok=True) with open(summary_file, 'w', encoding='utf-8') as f: json.dump(summary, f, ensure_ascii=False, indent=2) return summary def main(): """主函数""" print("🚀 LJWX-Stock AI执行平台 - 一键环境设置") print("=" * 60) setup = EnvironmentSetup() try: # 创建目录结构 setup.create_directory_structure() # 创建配置文件 setup.create_config_files() # 创建示例文件 setup.create_sample_requirements() # 设置Python环境 if not setup.setup_python_environment(): print("\n⚠️ Python环境设置未完成,请手动完成后再继续") # 初始化Git仓库 setup.create_git_repo() # 运行初始验证 setup.run_initial_verification() # 生成总结 summary = setup.generate_setup_summary() print("\n" + "=" * 60) print("🎉 环境设置完成!") print("=" * 60) print("\n📋 下一步操作:") for step in summary["next_steps"]: print(f" {step}") print(f"\n📁 重要文件:") for file in summary["important_files"]: print(f" - {file}") print(f"\n🛠️ 常用命令:") for cmd in summary["useful_commands"]: print(f" - {cmd}") print(f"\n📊 设置总结已保存: {setup.base_dir}/reports/setup-summary.json") print("\n📖 详细文档请查看: README.md") except KeyboardInterrupt: print("\n\n⏹️ 设置被用户中断") sys.exit(130) except Exception as e: print(f"\n\n💥 设置过程中发生异常: {e}") sys.exit(1) if __name__ == "__main__": main()