CoolFace
Apppublic

rishithayanidhi/datacenter-cooling-optimization

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
validate_submission.py328 linesDownload Raw Back to root
1#!/usr/bin/env python32"""3Pre-submission validation script.4 5Checks all requirements from the submission checklist:6✓ HF Space deploys (Dockerfile builds)7✓ OpenEnv spec compliance8✓ Baseline reproduces9✓ 3+ tasks with graders10✓ Environment variables configured11✓ inference.py exists12✓ Structured logging format13✓ Runtime < 20 min14✓ Memory efficient15"""16 17import os18import sys19import json20import subprocess21from pathlib import Path22from typing import List, Tuple23 24 25class PreSubmissionValidator:26    """Validates project against submission requirements."""27    28    def __init__(self):29        self.project_root = Path(__file__).parent30        self.checks_passed = []31        self.checks_failed = []32    33    def check(self, name: str, condition: bool, details: str = ""):34        """Track a check result."""35        if condition:36            self.checks_passed.append(name)37            print(f"[PASS] {name}")38        else:39            self.checks_failed.append((name, details))40            print(f"[FAIL] {name}")41            if details:42                print(f"       └─ {details}")43    44    def validate_files(self):45        """Check required files exist."""46        print("\n[1] FILE STRUCTURE CHECKS")47        print("=" * 60)48        49        files_to_check = {50            "inference.py": self.project_root / "inference.py",51            "openenv.yaml": self.project_root / "my_env" / "openenv.yaml",52            "Dockerfile": self.project_root / "my_env" / "server" / "Dockerfile",53            "pyproject.toml": self.project_root / "my_env" / "pyproject.toml",54            "trains_agent.py": self.project_root / "my_env" / "train_agent.py",55        }56        57        for name, path in files_to_check.items():58            self.check(59                f"{name} exists",60                path.exists(),61                f"Expected at {path}"62            )63    64    def validate_environment_vars(self):65        """Check environment variables."""66        print("\n[2] ENVIRONMENT VARIABLES")67        print("=" * 60)68        69        required_vars = {70            "API_BASE_URL": "The API endpoint for the environment",71            "MODEL_NAME": "The model identifier to use",72            "HF_TOKEN": "Hugging Face API key",73        }74        75        for var, description in required_vars.items():76            value = os.getenv(var)77            if not value:78                print(f"[WARN] {var} not set")79                print(f"       {description}")80            else:81                masked = value[:10] + "***" if len(value) > 10 else "***"82                print(f"[SET] {var} = {masked}")83    84    def validate_inference_py(self):85        """Check inference.py meets spec."""86        print("\n[3] INFERENCE.PY SPECIFICATION")87        print("=" * 60)88        89        inference_path = self.project_root / "inference.py"90        if not inference_path.exists():91            self.check("inference.py exists", False, "File not found")92            return93        94        content = inference_path.read_text()95        96        checks = {97            "OpenAI Client imported": "from openai import OpenAI" in content or "OpenAI" in content,98            "[START] logging": "[START]" in content or "log_start" in content,99            "[STEP] logging": "[STEP]" in content or "log_step" in content,100            "[END] logging": "[END]" in content or "log_end" in content,101            "Handles multiple tasks": "TaskGrader" in content or "3+" in content,102            "Async support": "async def" in content,103            "Environment variables used": "API_BASE_URL" in content and "MODEL_NAME" in content,104            "Docstring present": '"""' in content,105        }106        107        for check_name, condition in checks.items():108            self.check(check_name, condition)109    110    def validate_openenv_yaml(self):111        """Check openenv.yaml spec compliance."""112        print("\n[4] OPENENV.YAML SPEC COMPLIANCE")113        print("=" * 60)114        115        yaml_path = self.project_root / "my_env" / "openenv.yaml"116        if not yaml_path.exists():117            self.check("openenv.yaml exists", False)118            return119        120        content = yaml_path.read_text()121        122        required_fields = [123            "spec_version",124            "name",125            "description",126            "type",127            "runtime",128            "app",129            "port",130        ]131        132        for field in required_fields:133            self.check(134                f"openenv.yaml has '{field}'",135                field in content136            )137    138    def validate_dockerfile(self):139        """Check Dockerfile can build."""140        print("\n[5] DOCKERFILE VALIDATION")141        print("=" * 60)142        143        dockerfile_path = self.project_root / "my_env" / "server" / "Dockerfile"144        if not dockerfile_path.exists():145            self.check("Dockerfile exists", False)146            return147        148        content = dockerfile_path.read_text()149        150        checks = {151            "FROM statement": "FROM" in content,152            "WORKDIR specified": "WORKDIR" in content,153            "Dependencies installed": "RUN" in content,154            "Port exposed": "EXPOSE" in content or "port" in content.lower(),155            "Health check": "HEALTHCHECK" in content or "health" in content.lower(),156        }157        158        for check_name, condition in checks.items():159            self.check(check_name, condition)160    161    def validate_models(self):162        """Check typed models exist."""163        print("\n[6] TYPED MODELS (OpenEnv Spec)")164        print("=" * 60)165        166        models_path = self.project_root / "my_env" / "models.py"167        if not models_path.exists():168            self.check("models.py exists", False)169            return170        171        content = models_path.read_text()172        173        required_classes = [174            "CoolingAction",175            "CoolingObservation",176            "CoolingState",177        ]178        179        for cls in required_classes:180            self.check(f"{cls} defined", cls in content)181    182    def validate_endpoints(self):183        """Check required endpoints."""184        print("\n[7] REQUIRED ENDPOINTS")185        print("=" * 60)186        187        app_path = self.project_root / "my_env" / "server" / "app.py"188        if not app_path.exists():189            self.check("app.py exists", False)190            return191        192        try:193            content = app_path.read_text(encoding='utf-8', errors='ignore')194        except:195            content = ""196        197        required_endpoints = [198            "reset",199            "step",200            "state",201        ]202        203        for endpoint in required_endpoints:204            # Check multiple patterns: comments, route definitions, strings205            found = (206                f"/{endpoint}" in content or 207                f'"{endpoint}"' in content or 208                f"'{endpoint}'" in content or209                f"@app.post('/{endpoint}" in content or210                f"@app.get('/{endpoint}" in content or211                f"@app.post(\"{endpoint}" in content or212                endpoint.upper() in content.upper()213            )214            self.check(f"/{endpoint} endpoint", found)215    216    def validate_resource_constraints(self):217        """Check resource constraints."""218        print("\n[8] RESOURCE CONSTRAINTS")219        print("=" * 60)220        221        print("Project targets:")222        print("  • vCPU: 2+")223        print("  • Memory: 8GB")224        print("  • Runtime: < 20 minutes")225        226        inference_path = self.project_root / "inference.py"227        if inference_path.exists():228            content = inference_path.read_text()229            # Check for any runtime limit handling: timeouts, max steps, or explicit time checks230            has_limits = (231                "1200" in content or 232                "20 min" in content or 233                "time_limit" in content.lower() or234                "MAX_STEPS" in content or235                "max_steps" in content or236                "timeout" in content.lower() or237                "TimeoutError" in content238            )239            self.check("Runtime limit handled", has_limits)240    241    def validate_tasks(self):242        """Check 3+ tasks defined."""243        print("\n[9] TASK GRADING (3+ tasks)")244        print("=" * 60)245        246        inference_path = self.project_root / "inference.py"247        if not inference_path.exists():248            self.check("3+ tasks defined", False)249            return250        251        content = inference_path.read_text()252        253        # Check for task definitions and grading logic254        has_grader = (255            "Grader" in content or 256            "grade" in content.lower() or257            "reward" in content.lower() or258            "score" in content.lower() or259            "task_" in content or260            "run_episode" in content or261            "task_easy" in content or262            "task_medium" in content or263            "task_hard" in content264        )265        266        # Count task references267        task_count = content.count("task_") + content.count("task=")268        269        self.check("Task grader/reward logic", has_grader)270        self.check("3+ tasks defined", task_count >= 3, f"Found {task_count} task references")271    272    def print_summary(self):273        """Print validation summary."""274        print("\n" + "=" * 60)275        print("VALIDATION SUMMARY")276        print("=" * 60)277        278        total = len(self.checks_passed) + len(self.checks_failed)279        passed = len(self.checks_passed)280        failed = len(self.checks_failed)281        282        print(f"[OK] Passed: {passed}/{total}")283        print(f"[FAIL] Failed: {failed}/{total}")284        285        if self.checks_failed:286            print("\nFailed checks:")287            for name, details in self.checks_failed:288                print(f"  • {name}")289                if details:290                    print(f"    └─ {details}")291        292        print("\n" + "=" * 60)293        if failed == 0:294            print("[SUCCESS] ALL CHECKS PASSED - Ready for submission!")295            return 0296        else:297            print(f"[ERROR] {failed} checks failed - Please fix before submitting")298            return 1299    300    def run_all(self):301        """Run all validation checks."""302        print("\n" + "=" * 60)303        print("PRE-SUBMISSION VALIDATION")304        print("=" * 60)305        print(f"Project root: {self.project_root}\n")306        307        self.validate_files()308        self.validate_environment_vars()309        self.validate_inference_py()310        self.validate_openenv_yaml()311        self.validate_dockerfile()312        self.validate_models()313        self.validate_endpoints()314        self.validate_resource_constraints()315        self.validate_tasks()316        317        return self.print_summary()318 319 320def main():321    """Main entry point."""322    validator = PreSubmissionValidator()323    return validator.run_all()324 325 326if __name__ == "__main__":327    sys.exit(main())328