File size: 1,234 Bytes
313f40c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from __future__ import annotations

from typing import Any, Dict, List, Tuple

from jsonschema import Draft202012Validator, FormatChecker
from jsonschema.exceptions import ValidationError

from .jsonpath_utils import path_to_jsonpath


def _to_path_tokens(error: ValidationError) -> List[str]:
    tokens: List[str] = []
    # instance path → tokens
    for p in error.path:
        if isinstance(p, int):
            tokens.append(f"[{p}]")
        else:
            tokens.append(f".{p}")
    return tokens


def _error_to_dict(error: ValidationError) -> Dict[str, Any]:
    tokens = _to_path_tokens(error)
    return {
        "message": error.message,
        "validator": error.validator,
        "validator_value": error.validator_value,
        "jsonpath": path_to_jsonpath(tokens),
        "path_tokens": tokens,
        "schema_path": list(error.schema_path),
    }


def validate_with_jsonschema(
    schema: Dict[str, Any], payload: Any
) -> Tuple[bool, List[dict]]:
    validator = Draft202012Validator(schema, format_checker=FormatChecker())
    errors = sorted(validator.iter_errors(payload), key=lambda e: list(e.path))
    if not errors:
        return True, []
    return False, [_error_to_dict(e) for e in errors]