Coverage for src/dirschema/json/handler_pydantic.py: 100%
23 statements
« prev ^ index » next coverage.py v7.2.5, created at 2023-05-08 15:24 +0000
« prev ^ index » next coverage.py v7.2.5, created at 2023-05-08 15:24 +0000
1"""Minimal handler for using Pydantic models."""
3from typing import Any, Dict, List, Optional, Type
5from pydantic import BaseModel, ValidationError
7from .handler import ValidationHandler
10class PydanticHandler(ValidationHandler):
11 """Validation handler using `parse_obj` of pydantic models instead of JSON Schema.
13 Can serve as a simple template for other handlers, or be subclassed
14 to properly register your own models and used from your unique entry-point.
16 In principle, you can also override/add to the `MODELS` of this class
17 programmatically, but then you must accept the following disadvantages:
19 * your dirschema using this handler cannot be checked from the CLI
20 * your models are registered "globally", which might lead to collisions
21 """
23 MODELS: Dict[str, Type[BaseModel]] = {}
25 @classmethod
26 def validate_json(cls, metadata: Any, args: str) -> Dict[str, List[str]]:
27 """See [dirschema.json.handler.ValidationHandler.validate_json][]."""
28 model: Optional[Type[BaseModel]] = cls.MODELS.get(args)
29 if model is None:
30 raise ValueError(f"Unknown pydantic model: '{args}'")
31 if not issubclass(model, BaseModel):
32 raise ValueError(f"Invalid pydantic model: '{args}'")
33 try:
34 model.parse_obj(metadata)
35 except ValidationError as e:
36 errs: Dict[str, List[str]] = {}
37 for verr in e.errors():
38 key = "/" + "/".join(map(str, verr["loc"]))
39 if key not in errs:
40 errs[key] = []
41 errs[key].append(verr["msg"])
42 return errs
43 return {}