quantum_circuit_optimizer / validate_deployment.py
poseidon666's picture
Upload folder using huggingface_hub
18e3b27 verified
Raw
History Blame Contribute Delete
8.37 kB
#!/usr/bin/env python3
"""
Pre-Deployment Validation Script
Run this before deploying to HuggingFace Spaces to ensure everything is ready.
"""
import os
import sys
import yaml
import json
from pathlib import Path
def check_file_exists(filepath, description):
"""Check if a required file exists."""
if Path(filepath).exists():
print(f" ✓ {description}: {filepath}")
return True
else:
print(f" ✗ {description} MISSING: {filepath}")
return False
def validate_openenv_yaml():
"""Validate openenv.yaml structure."""
print("\n" + "="*60)
print("Validating openenv.yaml")
print("="*60)
if not Path("openenv.yaml").exists():
print(" ✗ openenv.yaml not found!")
return False
with open("openenv.yaml", "r") as f:
config = yaml.safe_load(f)
required = ["spec_version", "name", "type", "runtime", "app", "port", "tasks", "action_schema", "observation_schema"]
all_ok = True
for field in required:
if field in config:
print(f" ✓ {field}: present")
else:
print(f" ✗ {field}: MISSING")
all_ok = False
# Check tasks
if "tasks" in config:
task_count = len(config["tasks"])
if task_count >= 3:
print(f" ✓ Tasks: {task_count} defined (>= 3 required)")
else:
print(f" ✗ Tasks: only {task_count} defined (need >= 3)")
all_ok = False
return all_ok
def validate_dockerfile():
"""Validate Dockerfile."""
print("\n" + "="*60)
print("Validating Dockerfile")
print("="*60)
if not Path("Dockerfile").exists():
print(" ✗ Dockerfile not found!")
return False
with open("Dockerfile", "r") as f:
content = f.read()
checks = [
("EXPOSE 7860", "Port 7860 exposed"),
("HEALTHCHECK", "Health check configured"),
("CMD", "CMD instruction present"),
("uvicorn", "Uvicorn server command"),
]
all_ok = True
for pattern, description in checks:
if pattern in content:
print(f" ✓ {description}")
else:
print(f" ✗ {description} MISSING")
all_ok = False
return all_ok
def validate_project_structure():
"""Validate project structure."""
print("\n" + "="*60)
print("Validating Project Structure")
print("="*60)
required_files = [
("pyproject.toml", "Project configuration"),
("README.md", "Documentation"),
("inference.py", "Inference script"),
("models.py", "Data models"),
("client.py", "Client implementation"),
("server/app.py", "FastAPI application"),
("server/my_env_environment.py", "Environment implementation"),
("server/tasks.py", "Task definitions"),
("graders/__init__.py", "Graders module"),
]
all_ok = True
for filepath, description in required_files:
if not check_file_exists(filepath, description):
all_ok = False
return all_ok
def validate_environment_interface():
"""Validate environment implements required interface."""
print("\n" + "="*60)
print("Validating Environment Interface")
print("="*60)
try:
from server.my_env_environment import QuantumCircuitEnvironment
from models import QuantumAction, QuantumObservation, ActionType, GateType
env = QuantumCircuitEnvironment(seed=42)
# Test reset
obs = env.reset(config={"task_id": "easy"})
assert isinstance(obs, QuantumObservation), "reset() must return QuantumObservation"
print(" ✓ reset(config) returns QuantumObservation")
# Test step
action = QuantumAction(action_type=ActionType.ADD, gate=GateType.H, qubits=[0])
obs = env.step(action)
assert isinstance(obs, QuantumObservation), "step() must return QuantumObservation"
assert hasattr(obs, 'reward'), "Observation must have reward"
assert hasattr(obs, 'done'), "Observation must have done"
print(" ✓ step(action) returns QuantumObservation with reward and done")
# Test state
state = env.state
assert state is not None, "state property must return State"
print(" ✓ state property returns State")
# Test score range
assert 0.0 <= obs.score <= 1.0, f"Score out of range: {obs.score}"
print(f" ✓ Score in valid range: {obs.score:.4f}")
return True
except Exception as e:
print(f" ✗ Environment validation failed: {e}")
return False
def validate_tasks():
"""Validate all tasks are accessible."""
print("\n" + "="*60)
print("Validating Tasks")
print("="*60)
try:
from server.my_env_environment import QuantumCircuitEnvironment
env = QuantumCircuitEnvironment(seed=42)
tasks = ["easy", "medium", "hard", "efficient", "noisy", "budget", "approx"]
for task_id in tasks:
obs = env.reset(config={"task_id": task_id})
assert obs.task_id == task_id, f"Task ID mismatch: {obs.task_id} != {task_id}"
print(f" ✓ Task '{task_id}': accessible")
print(f" ✓ All {len(tasks)} tasks validated")
return True
except Exception as e:
print(f" ✗ Task validation failed: {e}")
return False
def validate_inference_script():
"""Validate inference script structure."""
print("\n" + "="*60)
print("Validating Inference Script")
print("="*60)
if not Path("inference.py").exists():
print(" ✗ inference.py not found!")
return False
with open("inference.py", "r") as f:
content = f.read()
checks = [
("from openai import OpenAI", "OpenAI client import"),
("API_BASE_URL", "API_BASE_URL variable"),
("MODEL_NAME", "MODEL_NAME variable"),
("HF_TOKEN", "HF_TOKEN variable"),
("[START]", "START log format"),
("[STEP]", "STEP log format"),
("[END]", "END log format"),
("async def main", "Async main function"),
]
all_ok = True
for pattern, description in checks:
if pattern in content:
print(f" ✓ {description}")
else:
print(f" ✗ {description} MISSING")
all_ok = False
return all_ok
def main():
"""Run all validation checks."""
print("\n" + "="*60)
print("PRE-DEPLOYMENT VALIDATION")
print("="*60)
checks = [
("Project Structure", validate_project_structure),
("openenv.yaml", validate_openenv_yaml),
("Dockerfile", validate_dockerfile),
("Environment Interface", validate_environment_interface),
("Tasks", validate_tasks),
("Inference Script", validate_inference_script),
]
results = []
for name, check_func in checks:
try:
result = check_func()
results.append((name, result))
except Exception as e:
print(f"\n ✗ {name} validation failed with exception: {e}")
results.append((name, False))
# Summary
print("\n" + "="*60)
print("VALIDATION SUMMARY")
print("="*60)
passed = sum(1 for _, r in results if r)
total = len(results)
for name, result in results:
status = "✓ PASS" if result else "✗ FAIL"
print(f" {status}: {name}")
print(f"\nTotal: {passed}/{total} checks passed")
if passed == total:
print("\n" + "="*60)
print("🎉 READY FOR DEPLOYMENT!")
print("="*60)
print("\nNext steps:")
print(" 1. Build Docker image: docker build -t quantum-circuit-opt:latest .")
print(" 2. Test locally: docker run -p 7860:7860 quantum-circuit-opt:latest")
print(" 3. Deploy to HF Spaces: openenv push")
print("\nSee QUICK_DEPLOY.md for detailed instructions.")
return 0
else:
print("\n" + "="*60)
print(f"❌ {total - passed} check(s) failed")
print("="*60)
print("\nPlease fix the issues above before deploying.")
return 1
if __name__ == "__main__":
sys.exit(main())