Spaces:
Running
Running
File size: 5,863 Bytes
fb7643a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
#!/usr/bin/env python3
"""
Comprehensive startup validation script for Web3 Research Co-Pilot
Validates syntax, imports, and configurations before application startup
"""
import ast
import sys
import os
import json
import importlib.util
from pathlib import Path
from typing import List, Dict, Any, Tuple
def validate_python_syntax(file_path: str) -> Tuple[bool, str]:
"""Validate Python file syntax."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
source = f.read()
ast.parse(source)
return True, "OK"
except SyntaxError as e:
return False, f"Syntax error at line {e.lineno}: {e.msg}"
except Exception as e:
return False, f"Parse error: {str(e)}"
def validate_imports(file_path: str) -> Tuple[bool, List[str]]:
"""Validate that all imports in a Python file can be resolved."""
issues = []
try:
with open(file_path, 'r', encoding='utf-8') as f:
source = f.read()
tree = ast.parse(source)
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
try:
importlib.import_module(alias.name)
except ImportError:
issues.append(f"Cannot import: {alias.name}")
elif isinstance(node, ast.ImportFrom):
if node.module:
try:
importlib.import_module(node.module)
except ImportError:
issues.append(f"Cannot import module: {node.module}")
return len(issues) == 0, issues
except Exception as e:
return False, [f"Import validation error: {str(e)}"]
def validate_json_files() -> Tuple[bool, List[str]]:
"""Validate JSON configuration files."""
issues = []
json_files = [
"pyproject.toml", # Will skip if not JSON
"app_config.yaml" # Will skip if not JSON
]
for file_path in json_files:
if os.path.exists(file_path) and file_path.endswith('.json'):
try:
with open(file_path, 'r') as f:
json.load(f)
except json.JSONDecodeError as e:
issues.append(f"Invalid JSON in {file_path}: {str(e)}")
except Exception as e:
issues.append(f"Error reading {file_path}: {str(e)}")
return len(issues) == 0, issues
def validate_environment_variables() -> Tuple[bool, List[str]]:
"""Validate required environment variables."""
issues = []
optional_vars = [
"CRYPTOCOMPARE_API_KEY",
"ETHERSCAN_API_KEY",
"COINGECKO_API_KEY"
]
for var in optional_vars:
if not os.getenv(var):
issues.append(f"Optional environment variable {var} not set (will use free tier)")
return True, issues # All env vars are optional
def main():
"""Run comprehensive startup validation."""
print("π Starting comprehensive validation...")
# Get all Python files
python_files = []
for root, dirs, files in os.walk("."):
# Skip __pycache__ directories
dirs[:] = [d for d in dirs if d != "__pycache__"]
for file in files:
if file.endswith(".py"):
python_files.append(os.path.join(root, file))
print(f"π Found {len(python_files)} Python files to validate")
all_valid = True
# 1. Syntax validation
print("\n1οΈβ£ Validating Python syntax...")
syntax_issues = []
for file_path in python_files:
is_valid, message = validate_python_syntax(file_path)
if not is_valid:
syntax_issues.append(f"{file_path}: {message}")
all_valid = False
else:
print(f" β
{file_path}")
if syntax_issues:
print("β Syntax Issues Found:")
for issue in syntax_issues:
print(f" - {issue}")
# 2. Critical imports validation (only for main files)
print("\n2οΈβ£ Validating critical imports...")
critical_files = ["app.py", "src/agent/research_agent.py"]
import_issues = []
for file_path in critical_files:
if os.path.exists(file_path):
is_valid, issues = validate_imports(file_path)
if not is_valid:
for issue in issues:
import_issues.append(f"{file_path}: {issue}")
else:
print(f" β
{file_path}")
# Show non-critical import issues as warnings
if import_issues:
print("β οΈ Import Warnings (may use fallbacks):")
for issue in import_issues:
print(f" - {issue}")
# 3. JSON validation
print("\n3οΈβ£ Validating configuration files...")
json_valid, json_issues = validate_json_files()
if not json_valid:
print("β Configuration Issues:")
for issue in json_issues:
print(f" - {issue}")
all_valid = False
else:
print(" β
Configuration files valid")
# 4. Environment validation
print("\n4οΈβ£ Validating environment...")
env_valid, env_issues = validate_environment_variables()
if env_issues:
print("βΉοΈ Environment Info:")
for issue in env_issues:
print(f" - {issue}")
else:
print(" β
Environment configured")
# Final result
print(f"\n{'π' if all_valid else 'β'} Validation {'PASSED' if all_valid else 'FAILED'}")
if not all_valid:
print("\nπ οΈ Please fix the issues above before starting the application")
sys.exit(1)
else:
print("\nβ
All critical validations passed - ready to start!")
sys.exit(0)
if __name__ == "__main__":
main()
|