| from __future__ import annotations |
|
|
| import argparse |
| import json |
| import os |
| import sys |
| from pathlib import Path |
|
|
| from src.hackathon.validation import ( |
| MODEL_REGISTRY_ENV, |
| STIMULI_CATALOG_ENV, |
| load_model_registry, |
| load_stimuli_catalog, |
| validate_blue_submission, |
| validate_red_submission, |
| ) |
|
|
|
|
| def _load_payload(path: str) -> dict: |
| if path == "-": |
| raw = sys.stdin.read() |
| source = "stdin" |
| else: |
| source = path |
| try: |
| raw = Path(path).read_text() |
| except FileNotFoundError as exc: |
| raise ValueError(f"File not found: {path}") from exc |
|
|
| try: |
| data = json.loads(raw) |
| except json.JSONDecodeError as exc: |
| raise ValueError(f"Invalid JSON in {source}: {exc}") from exc |
|
|
| if not isinstance(data, dict): |
| raise ValueError("Submission JSON must be an object.") |
| return data |
|
|
|
|
| def main() -> int: |
| parser = argparse.ArgumentParser(description="Validate blue/red submission JSON against the contract.") |
| parser.add_argument("payload", help="Path to submission JSON or '-' for stdin.") |
| parser.add_argument("--team", choices=["blue", "red"], required=True, help="Submission team to validate.") |
| parser.add_argument( |
| "--model-registry", |
| default=os.environ.get(MODEL_REGISTRY_ENV, ""), |
| help=f"Model registry JSON path (defaults to ${MODEL_REGISTRY_ENV}).", |
| ) |
| parser.add_argument( |
| "--stimuli-catalog", |
| default=os.environ.get(STIMULI_CATALOG_ENV, ""), |
| help=f"Stimuli catalog JSON/JSONL path (defaults to ${STIMULI_CATALOG_ENV}).", |
| ) |
|
|
| args = parser.parse_args() |
| payload = _load_payload(args.payload) |
|
|
| if args.team == "blue": |
| registry = load_model_registry(args.model_registry or None) |
| models = validate_blue_submission(payload, model_registry=registry) |
| print(f"OK: blue submission validated ({len(models)} models).") |
| else: |
| catalog = load_stimuli_catalog(args.stimuli_catalog or None) |
| stimuli = validate_red_submission(payload, stimuli_catalog=catalog) |
| print(f"OK: red submission validated ({len(stimuli)} stimuli).") |
|
|
| return 0 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |
|
|