#!/usr/bin/env python3 """Comprehensive project validation script""" import os import sys from pathlib import Path print("="*70) print("COMPREHENSIVE PROJECT VALIDATION") print("="*70) issues = [] warnings = [] # 1. Check all required files exist print("\n[CHECK 1] Required Files") required_files = [ "environment/__init__.py", "environment/types.py", "environment/env.py", "environment/data_generator.py", "environment/graders.py", "app.py", "Dockerfile", "requirements.txt", "inference.py", "openenv.yaml", "README.md" ] for file in required_files: if Path(file).exists(): size = Path(file).stat().st_size print(f" [OK] {file:35} ({size:>6} bytes)") else: print(f" [ERROR] {file:35} MISSING") issues.append(f"Missing file: {file}") # 2. Check Python syntax print("\n[CHECK 2] Python Syntax") python_files = [ "environment/types.py", "environment/env.py", "environment/data_generator.py", "environment/graders.py", "app.py", "inference.py" ] for file in python_files: try: with open(file, 'r') as f: code = f.read() compile(code, file, 'exec') print(f" [OK] {file:35} syntax valid") except SyntaxError as e: print(f" [ERROR] {file:35} {e}") issues.append(f"Syntax error in {file}") # 3. Check imports print("\n[CHECK 3] Import Validation") try: from environment.types import Observation, Action, Reward, State print(f" [OK] environment.types imports") except ImportError as e: print(f" [ERROR] environment.types: {e}") issues.append(f"Import error in types") try: from environment.env import EmailTriageEnv print(f" [OK] environment.env imports") except ImportError as e: print(f" [ERROR] environment.env: {e}") issues.append(f"Import error in env") try: from environment.data_generator import DataGenerator print(f" [OK] environment.data_generator imports") except ImportError as e: print(f" [ERROR] environment.data_generator: {e}") issues.append(f"Import error in data_generator") try: from environment.graders import SpamDetectionGrader print(f" [OK] environment.graders imports") except ImportError as e: print(f" [ERROR] environment.graders: {e}") issues.append(f"Import error in graders") # 4. Check environment functionality print("\n[CHECK 4] Environment Functionality") try: from environment import EmailTriageEnv, Action, EmailCategory, Team for task in ["spam_detection", "multi_class_routing", "context_aware_triage"]: env = EmailTriageEnv(task) obs = env.reset() assert obs is not None action = Action(classification=EmailCategory.NORMAL, team=Team.SUPPORT, priority=1) obs, reward, done, info = env.step(action) assert 0 <= reward.value <= 1 print(f" [OK] {task:30} works") except Exception as e: print(f" [ERROR] {e}") issues.append(f"Environment error: {str(e)[:50]}") # 5. Check Flask app print("\n[CHECK 5] Flask App") try: from app import app print(f" [OK] Flask app loads") routes = [rule.rule for rule in app.url_map.iter_rules()] required = ['/health', '/reset', '/step', '/state', '/tasks'] for route in required: if route in routes: print(f" [OK] {route:20} endpoint") else: warnings.append(f"Missing route: {route}") except Exception as e: print(f" [ERROR] Flask: {e}") issues.append(f"Flask error") # 6. Check openenv.yaml print("\n[CHECK 6] openenv.yaml") try: import yaml with open('openenv.yaml', 'r') as f: spec = yaml.safe_load(f) if 'tasks' in spec and len(spec['tasks']) >= 3: print(f" [OK] {len(spec['tasks'])} tasks defined") else: warnings.append("Less than 3 tasks") if 'action_space' in spec: print(f" [OK] action_space defined") if 'observation_space' in spec: print(f" [OK] observation_space defined") if 'reward' in spec: print(f" [OK] reward defined") except Exception as e: print(f" [ERROR] openenv.yaml: {e}") issues.append(f"YAML error") # 7. Check inference.py format print("\n[CHECK 7] Inference Format") try: with open('inference.py', 'r') as f: code = f.read() if '[START]' in code and '[STEP]' in code and '[END]' in code: print(f" [OK] Logging format correct") if 'OpenAI' in code: print(f" [OK] Uses OpenAI client") if all(x in code for x in ['OPENAI_API_KEY', 'MODEL_NAME', 'API_BASE_URL']): print(f" [OK] All env vars handled") except Exception as e: print(f" [ERROR] inference.py: {e}") issues.append(f"Inference error") # 8. Check Dockerfile print("\n[CHECK 8] Dockerfile") try: with open('Dockerfile', 'r') as f: df = f.read() if 'python:3.11' in df: print(f" [OK] Python 3.11 base") if '7860' in df: print(f" [OK] Port 7860 exposed") if 'HEALTHCHECK' in df: print(f" [OK] Health check set") except Exception as e: print(f" [ERROR] Dockerfile: {e}") issues.append(f"Dockerfile error") # 9. Check requirements.txt print("\n[CHECK 9] requirements.txt") try: with open('requirements.txt', 'r') as f: reqs = f.read().lower() for pkg in ['pydantic', 'flask', 'openai', 'pyyaml']: if pkg in reqs: print(f" [OK] {pkg:20} listed") except Exception as e: print(f" [ERROR] requirements.txt: {e}") issues.append(f"Requirements error") # 10. Check documentation print("\n[CHECK 10] Documentation") doc_files = { "README.md": 5000, "DEPLOYMENT_CHECKLIST.md": 2000, "START_HERE.md": 1000, "SUBMISSION_CHECKLIST.md": 5000, } docs_ok = 0 for doc, min_size in doc_files.items(): if Path(doc).exists(): size = Path(doc).stat().st_size if size >= min_size: print(f" [OK] {doc:35}") docs_ok += 1 else: warnings.append(f"{doc} too small ({size} bytes)") else: warnings.append(f"Missing: {doc}") # Summary print("\n" + "="*70) print("VALIDATION RESULTS") print("="*70) print(f"\nCritical Issues: {len(issues)}") print(f"Warnings: {len(warnings)}") if issues: print(f"\nCRITICAL ISSUES TO FIX:") for issue in issues: print(f" - {issue}") sys.exit(1) else: print(f"\n[SUCCESS] All critical checks passed!") if warnings: print(f"\nMinor warnings ({len(warnings)}):") for w in warnings: print(f" - {w}") print("\n[READY] Project is ready for deployment!")