Source code for majis.schema.schema
"""JSON schema sub-module."""
import re
from collections import UserDict
from json import loads
from pathlib import Path
from warnings import warn
from jsonschema import validate
from jsonschema.exceptions import ValidationError
SCHEMA_FOLDER = Path(__file__).parent
[docs]
class ValidationWarning(Warning):
"""Validation warning."""
[docs]
class JsonSchema(UserDict):
"""JSON schema object."""
def __init__(self, fname: str | Path):
self.fname = Path(fname)
self.data = loads(self.fname.read_text(encoding='utf-8'))
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return f'{self.__class__.__name__}> {self}'
@property
def name(self) -> str:
"""Schema file name."""
return self.fname.stem
@property
def title(self) -> str:
"""Schema title description."""
return self.data.get('title', '(undefined)')
@property
def version(self) -> int:
"""Schema version.
At the moment this value is extracted from the title property.
"""
if 'version' in self.data:
return int(self.data['version'])
for version in re.findall(r'v(\d+)', self.title):
return int(version)
return 0
[docs]
def validate(self, content: dict, raises_error: bool = True) -> None:
"""Validate content against the JSON schema.
If ``raises_error`` is set to ``False``, a ``ValidationWarning``
can be reported instead of a ``ValidationError``.
"""
try:
validate(instance=content, schema=self.data)
except ValidationError as err:
if raises_error:
raise err from None
warn(f'{self}: {err}', category=ValidationWarning, stacklevel=2)
MAJIS_SCHEMAS = {
'ITL': [
JsonSchema(SCHEMA_FOLDER / 'jsoc-itl-schema.json'),
JsonSchema(SCHEMA_FOLDER / 'majis-itl-schema.json'),
],
'OPL': [
JsonSchema(SCHEMA_FOLDER / 'jsoc-opl-schema.json'),
],
}