Skip to content

base

BaseModelPlus

Bases: ParserMixin, BaseModel

Extended pydantic BaseModel with some good defaults.

Used as basis for various entities, including: * Metadata schemas * Harvester arguments

Source code in src/metador_core/schema/base.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class BaseModelPlus(ParserMixin, BaseModel, metaclass=DynEncoderModelMetaclass):
    """Extended pydantic BaseModel with some good defaults.

    Used as basis for various entities, including:
    * Metadata schemas
    * Harvester arguments
    """

    class Config:
        # keep extra fields by default
        extra = Extra.allow
        # make PrivateAttr wrappers not always needed
        underscore_attrs_are_private = True
        # serialize enums properly
        use_enum_values = True
        # when alias is set, still allow using field name
        # (we use aliases for invalid attribute names in Python)
        allow_population_by_field_name = True
        # users should jump through hoops to add invalid stuff
        validate_assignment = True
        # defaults should also be validated
        validate_all = True
        # for JSON compat
        allow_inf_nan = False
        # pydantic anystr config: non-empty, non-whitespace
        # (but we prefer NonEmptyStr anyway for inheritance)
        anystr_strip_whitespace = True
        min_anystr_length = 1

    def dict(self, *args, **kwargs):
        """Return a dict.

        Nota that this will eliminate all pydantic models,
        but might still contain complex value types.
        """
        return super().dict(*args, **_mod_def_dump_args(kwargs))

    def json(self, *args, **kwargs) -> str:
        """Return serialized JSON as string."""
        return super().json(*args, **_mod_def_dump_args(kwargs))

    def json_dict(self, **kwargs):
        """Return a JSON-compatible dict.

        Uses round-trip through JSON serialization.
        """
        return json.loads(self.json(**kwargs))

    def yaml(self, **kwargs) -> str:
        """Return serialized YAML as string."""
        # Current way: use round trip through JSON to kick out non-JSON entities
        # (more elegant: allow ruamel yaml to reuse defined custom JSON dumpers)
        # tmp = self.json_dict(**_mod_def_dump_args(kwargs))
        return to_yaml_str(self)

    @classmethod
    def parse_file(cls, path: Union[str, Path]):
        return parse_yaml_file_as(cls, path)

    @classmethod
    def parse_raw(cls, dat: Union[str, bytes], **kwargs):
        try:
            return super().parse_raw(dat, **kwargs)
        except ValidationError:
            return parse_yaml_raw_as(cls, dat)

    def __bytes__(self) -> bytes:
        """Serialize to JSON and return UTF-8 encoded bytes to be written in a file."""
        # add a newline, as otherwise behaviour with text editors will be confusing
        # (e.g. vim automatically adds a trailing newline that it hides)
        # https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline
        return (self.json() + "\n").encode(encoding="utf-8")

    def __str__(self) -> str:
        return self.json(indent=2)

dict

dict(*args, **kwargs)

Return a dict.

Nota that this will eliminate all pydantic models, but might still contain complex value types.

Source code in src/metador_core/schema/base.py
50
51
52
53
54
55
56
def dict(self, *args, **kwargs):
    """Return a dict.

    Nota that this will eliminate all pydantic models,
    but might still contain complex value types.
    """
    return super().dict(*args, **_mod_def_dump_args(kwargs))

json

json(*args, **kwargs) -> str

Return serialized JSON as string.

Source code in src/metador_core/schema/base.py
58
59
60
def json(self, *args, **kwargs) -> str:
    """Return serialized JSON as string."""
    return super().json(*args, **_mod_def_dump_args(kwargs))

json_dict

json_dict(**kwargs)

Return a JSON-compatible dict.

Uses round-trip through JSON serialization.

Source code in src/metador_core/schema/base.py
62
63
64
65
66
67
def json_dict(self, **kwargs):
    """Return a JSON-compatible dict.

    Uses round-trip through JSON serialization.
    """
    return json.loads(self.json(**kwargs))

yaml

yaml(**kwargs) -> str

Return serialized YAML as string.

Source code in src/metador_core/schema/base.py
69
70
71
72
73
74
def yaml(self, **kwargs) -> str:
    """Return serialized YAML as string."""
    # Current way: use round trip through JSON to kick out non-JSON entities
    # (more elegant: allow ruamel yaml to reuse defined custom JSON dumpers)
    # tmp = self.json_dict(**_mod_def_dump_args(kwargs))
    return to_yaml_str(self)

__bytes__

__bytes__() -> bytes

Serialize to JSON and return UTF-8 encoded bytes to be written in a file.

Source code in src/metador_core/schema/base.py
87
88
89
90
91
92
def __bytes__(self) -> bytes:
    """Serialize to JSON and return UTF-8 encoded bytes to be written in a file."""
    # add a newline, as otherwise behaviour with text editors will be confusing
    # (e.g. vim automatically adds a trailing newline that it hides)
    # https://stackoverflow.com/questions/729692/why-should-text-files-end-with-a-newline
    return (self.json() + "\n").encode(encoding="utf-8")