"""JSON Schema loading and validation.""" from __future__ import annotations import json from functools import lru_cache from importlib.resources import files from itertools import islice from jsonschema import Draft202012Validator, FormatChecker from .errors import SchemaValidationFailed @lru_cache(maxsize=8) def validator_for(schema_name: str) -> Draft202012Validator: if "/" in schema_name or "\\" in schema_name or not schema_name.endswith(".json"): raise SchemaValidationFailed(f"Target schema is unavailable: {schema_name}") resource = files("edu_crawler.schemas").joinpath(schema_name) if not resource.is_file(): raise SchemaValidationFailed(f"Target schema is unavailable: {schema_name}") schema = json.loads(resource.read_text(encoding="utf-8")) Draft202012Validator.check_schema(schema) return Draft202012Validator(schema, format_checker=FormatChecker()) def validate_record(schema_name: str, record: dict) -> None: errors = list(islice(validator_for(schema_name).iter_errors(record), 5)) if not errors: return summaries = [] for error in errors: path = ".".join(str(part) for part in error.absolute_path) or "$" summaries.append(f"{path}: {error.validator} validation failed") raise SchemaValidationFailed("; ".join(summaries))