AnsysLink/scripts/deployment_check.py

431 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
CAE Mesh Generator - Deployment Check Script
部署前系统检查脚本
"""
import os
import sys
import subprocess
import importlib
import json
import tempfile
from pathlib import Path
from datetime import datetime
class DeploymentChecker:
def __init__(self):
self.project_root = Path(__file__).parent.parent # 上一级目录
self.checks_passed = 0
self.checks_failed = 0
self.warnings = []
self.errors = []
def print_header(self):
"""打印检查头部信息"""
print("=" * 70)
print("🔍 CAE网格生成助手 - 部署检查")
print("=" * 70)
print(f"检查时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"项目目录: {self.project_root}")
print("=" * 70)
def check_python_environment(self):
"""检查Python环境"""
print("\n📋 检查Python环境...")
# Python版本检查
version = sys.version_info
if version.major < 3 or (version.major == 3 and version.minor < 8):
self.add_error(f"Python版本过低: {version.major}.{version.minor}.{version.micro}")
self.add_error("需要Python 3.8或更高版本")
return False
else:
print(f"✅ Python版本: {version.major}.{version.minor}.{version.micro}")
# 虚拟环境检查
if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
print("✅ 运行在虚拟环境中")
else:
self.add_warning("未使用虚拟环境,建议使用虚拟环境")
return True
def check_dependencies(self):
"""检查依赖包"""
print("\n📦 检查依赖包...")
# 读取requirements.txt
requirements_file = self.project_root / 'requirements.txt'
if not requirements_file.exists():
self.add_error("requirements.txt文件不存在")
return False
# 解析依赖
required_packages = []
try:
with open(requirements_file, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
package = line.split('==')[0].split('>=')[0].split('<=')[0]
required_packages.append(package)
except Exception as e:
self.add_error(f"读取requirements.txt失败: {e}")
return False
# 检查每个包
missing_packages = []
for package in required_packages:
try:
importlib.import_module(package.replace('-', '_'))
print(f"{package}: 已安装")
except ImportError:
print(f"{package}: 未安装")
missing_packages.append(package)
if missing_packages:
self.add_error(f"缺少依赖包: {', '.join(missing_packages)}")
self.add_error("请运行: pip install -r requirements.txt")
return False
return True
def check_project_structure(self):
"""检查项目结构"""
print("\n📁 检查项目结构...")
required_files = [
'app.py',
'config.py',
'requirements.txt',
'README.md'
]
required_dirs = [
'backend',
'backend/api',
'backend/core',
'backend/models',
'backend/utils',
'backend/pymechanical',
'templates',
'static',
'static/css',
'static/js'
]
# 检查必需文件
for file_path in required_files:
full_path = self.project_root / file_path
if full_path.exists():
print(f"{file_path}")
else:
print(f"{file_path}")
self.add_error(f"缺少必需文件: {file_path}")
# 检查必需目录
for dir_path in required_dirs:
full_path = self.project_root / dir_path
if full_path.exists() and full_path.is_dir():
print(f"{dir_path}/")
else:
print(f"{dir_path}/")
self.add_error(f"缺少必需目录: {dir_path}")
return len(self.errors) == 0
def check_configuration(self):
"""检查配置文件"""
print("\n⚙️ 检查配置...")
try:
from config import FLASK_CONFIG, ANSYS_CONFIG, ALLOWED_EXTENSIONS
# 检查Flask配置
required_flask_keys = ['MAX_CONTENT_LENGTH', 'UPLOAD_FOLDER', 'RESULT_FOLDER']
for key in required_flask_keys:
if key in FLASK_CONFIG:
print(f"✅ Flask配置 {key}: {FLASK_CONFIG[key]}")
else:
self.add_warning(f"Flask配置缺少 {key}")
# 检查ANSYS配置
if ANSYS_CONFIG:
print(f"✅ ANSYS配置已定义")
else:
self.add_warning("ANSYS配置为空将使用默认设置")
# 检查允许的文件扩展名
if ALLOWED_EXTENSIONS:
print(f"✅ 允许的文件扩展名: {ALLOWED_EXTENSIONS}")
else:
self.add_error("未定义允许的文件扩展名")
except ImportError as e:
self.add_error(f"无法导入配置: {e}")
return False
except Exception as e:
self.add_error(f"配置检查失败: {e}")
return False
return True
def check_directories(self):
"""检查运行时目录"""
print("\n📂 检查运行时目录...")
runtime_dirs = [
'uploads',
'results',
'temp',
'logs',
'static/visualizations'
]
for dir_name in runtime_dirs:
dir_path = self.project_root / dir_name
try:
dir_path.mkdir(parents=True, exist_ok=True)
if os.access(dir_path, os.W_OK):
print(f"{dir_name}/ (可写)")
else:
print(f"⚠️ {dir_name}/ (只读)")
self.add_warning(f"目录 {dir_name} 不可写")
except Exception as e:
print(f"{dir_name}/ (创建失败)")
self.add_error(f"无法创建目录 {dir_name}: {e}")
return True
def check_flask_app(self):
"""检查Flask应用"""
print("\n🌐 检查Flask应用...")
try:
# 添加项目根目录到Python路径
sys.path.insert(0, str(self.project_root))
from app import create_app
app = create_app()
print("✅ Flask应用创建成功")
# 检查路由
routes = []
for rule in app.url_map.iter_rules():
routes.append(f"{rule.methods} {rule.rule}")
print(f"✅ 注册路由数量: {len(routes)}")
# 检查关键路由
key_routes = [
'GET /',
'POST /api/upload',
'GET /api/mesh/status',
'POST /api/mesh/generate',
'GET /api/mesh/result'
]
for route in key_routes:
if any(route in r for r in routes):
print(f"✅ 关键路由: {route}")
else:
print(f"❌ 缺少路由: {route}")
self.add_error(f"缺少关键路由: {route}")
except Exception as e:
self.add_error(f"Flask应用检查失败: {e}")
return False
return True
def check_ansys_availability(self):
"""检查ANSYS可用性"""
print("\n🔧 检查ANSYS可用性...")
try:
import ansys.mechanical.core as mech
print("✅ ANSYS Mechanical Core 可用")
# 尝试获取版本信息
try:
# 这里可以添加更详细的ANSYS检查
print("✅ ANSYS集成模块正常")
except Exception as e:
self.add_warning(f"ANSYS详细检查失败: {e}")
except ImportError:
print("⚠️ ANSYS Mechanical Core 不可用")
self.add_warning("ANSYS不可用系统将在演示模式下运行")
return True
def check_port_availability(self, port=5000):
"""检查端口可用性"""
print(f"\n🌐 检查端口 {port} 可用性...")
import socket
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(1)
result = s.connect_ex(('localhost', port))
if result == 0:
print(f"⚠️ 端口 {port} 已被占用")
self.add_warning(f"端口 {port} 被占用,可能需要更改配置")
else:
print(f"✅ 端口 {port} 可用")
except Exception as e:
self.add_warning(f"端口检查失败: {e}")
return True
def check_disk_space(self):
"""检查磁盘空间"""
print("\n💾 检查磁盘空间...")
try:
import shutil
total, used, free = shutil.disk_usage(self.project_root)
free_gb = free / (1024**3)
total_gb = total / (1024**3)
print(f"✅ 总空间: {total_gb:.1f} GB")
print(f"✅ 可用空间: {free_gb:.1f} GB")
if free_gb < 1:
self.add_error("磁盘空间不足 (< 1GB)")
return False
elif free_gb < 5:
self.add_warning("磁盘空间较少 (< 5GB)")
except Exception as e:
self.add_warning(f"磁盘空间检查失败: {e}")
return True
def run_basic_tests(self):
"""运行基本测试"""
print("\n🧪 运行基本测试...")
try:
# 测试数据模型
from backend.models.data_models import UploadedFile, ProcessingStatus, MeshResult
from datetime import datetime
# 测试UploadedFile
test_file = UploadedFile(
id='test',
filename='test.step',
file_path='/tmp/test.step',
upload_time=datetime.now(),
status='UPLOADED'
)
test_dict = test_file.to_dict()
print("✅ UploadedFile模型测试通过")
# 测试ProcessingStatus
test_status = ProcessingStatus(
status='PROCESSING',
message='Test processing',
start_time=datetime.now()
)
status_dict = test_status.to_dict()
print("✅ ProcessingStatus模型测试通过")
# 测试MeshResult
test_result = MeshResult(
element_count=1000,
node_count=1500,
quality_score=85.0,
quality_status='GOOD',
generation_time=60.0
)
result_dict = test_result.to_dict()
print("✅ MeshResult模型测试通过")
except Exception as e:
self.add_error(f"基本测试失败: {e}")
return False
return True
def add_error(self, message):
"""添加错误"""
self.errors.append(message)
self.checks_failed += 1
def add_warning(self, message):
"""添加警告"""
self.warnings.append(message)
def print_summary(self):
"""打印检查总结"""
print("\n" + "=" * 70)
print("📊 检查结果总结")
print("=" * 70)
total_checks = self.checks_passed + self.checks_failed
if total_checks > 0:
success_rate = (self.checks_passed / total_checks) * 100
print(f"检查通过率: {success_rate:.1f}%")
print(f"错误数量: {len(self.errors)}")
print(f"警告数量: {len(self.warnings)}")
if self.errors:
print("\n❌ 错误列表:")
for i, error in enumerate(self.errors, 1):
print(f" {i}. {error}")
if self.warnings:
print("\n⚠️ 警告列表:")
for i, warning in enumerate(self.warnings, 1):
print(f" {i}. {warning}")
print("\n" + "=" * 70)
if len(self.errors) == 0:
print("🎉 所有检查通过!系统已准备好部署。")
return True
else:
print("❌ 存在错误,请修复后重新检查。")
return False
def run_all_checks(self):
"""运行所有检查"""
self.print_header()
checks = [
("Python环境", self.check_python_environment),
("依赖包", self.check_dependencies),
("项目结构", self.check_project_structure),
("配置文件", self.check_configuration),
("运行时目录", self.check_directories),
("Flask应用", self.check_flask_app),
("ANSYS可用性", self.check_ansys_availability),
("端口可用性", self.check_port_availability),
("磁盘空间", self.check_disk_space),
("基本测试", self.run_basic_tests)
]
for check_name, check_func in checks:
try:
if check_func():
self.checks_passed += 1
else:
self.checks_failed += 1
except Exception as e:
self.add_error(f"{check_name}检查异常: {e}")
self.checks_failed += 1
return self.print_summary()
def main():
"""主函数"""
checker = DeploymentChecker()
success = checker.run_all_checks()
return 0 if success else 1
if __name__ == '__main__':
sys.exit(main())