Trifecta-Lab / trifecta_bro /api /validator.py
Brettapps's picture
Upload folder using huggingface_hub (part 21)
e23172f verified
Raw History Blame Contribute Delete
2.39 kB
"""Response validation for FormFav payloads.
Guards against shape drift / missing fields. Never fabricates missing data —
it records what was present so the scoring model can degrade gracefully.
"""
from __future__ import annotations
from typing import Any
class ValidationIssue:
def __init__(self, level: str, field: str, message: str) -> None:
self.level = level # 'error' | 'warn'
self.field = field
self.message = message
def __repr__(self) -> str:
return f"[{self.level}] {self.field}: {self.message}"
def validate_meetings(payload: Any) -> list[ValidationIssue]:
issues: list[ValidationIssue] = []
if not isinstance(payload, dict):
return [ValidationIssue("error", "payload", "meetings payload is not an object")]
meetings = payload.get("meetings")
if not isinstance(meetings, list):
issues.append(ValidationIssue("error", "meetings", "missing 'meetings' array"))
return issues
for i, m in enumerate(meetings):
if not isinstance(m, dict):
issues.append(ValidationIssue("error", f"meetings[{i}]", "meeting is not an object"))
continue
if "slug" not in m and "track" not in m:
issues.append(ValidationIssue("warn", f"meetings[{i}]", "no slug/track"))
if "races" not in m:
issues.append(ValidationIssue("warn", f"meetings[{i}]", "no 'races' array"))
return issues
def validate_race_form(payload: Any) -> list[ValidationIssue]:
issues: list[ValidationIssue] = []
if not isinstance(payload, dict):
return [ValidationIssue("error", "payload", "race form payload is not an object")]
if "runners" not in payload:
issues.append(ValidationIssue("error", "runners", "missing 'runners' array"))
else:
runners = payload["runners"]
if not isinstance(runners, list):
issues.append(ValidationIssue("error", "runners", "'runners' is not a list"))
else:
for i, r in enumerate(runners):
if not isinstance(r, dict):
issues.append(ValidationIssue("error", f"runners[{i}]", "runner not an object"))
continue
if "number" not in r and "barrier" not in r:
issues.append(ValidationIssue("warn", f"runners[{i}]", "runner missing number/barrier"))
return issues