"""Validation helpers for CLI/API job inputs."""
from __future__ import annotations
from typing import Any, Dict
from pydantic import ValidationError
from .models import JobSpec, RunConfig
[docs]
def validate_job_spec(payload: Dict[str, Any]) -> JobSpec:
"""Parse and validate a raw job spec payload."""
return JobSpec.model_validate(payload)
[docs]
def validate_run_config(payload: Dict[str, Any]) -> RunConfig:
"""Parse and validate a run config payload."""
return RunConfig.model_validate(payload)
[docs]
def summarize_validation_error(exc: ValidationError) -> str:
"""Return a human-readable validation summary.
Each pydantic issue lands on its own line under an ``"Invalid job
config:"`` header so multi-issue errors stay scannable. Previously
the issues were semicolon-joined into a single dense line, which
became hard to read once nested locations appeared.
"""
parts = []
for issue in exc.errors():
loc = ".".join(str(item) for item in issue.get("loc", []))
msg = issue.get("msg", "invalid value")
parts.append(f"{loc}: {msg}" if loc else msg)
if not parts:
return "Invalid job config"
return "Invalid job config:\n - " + "\n - ".join(parts)