Skip to content

Commit dfe50f0

Browse files
committed
feat: add unified to_json() and from_json()
1 parent 143b5a3 commit dfe50f0

4 files changed

Lines changed: 229 additions & 82 deletions

File tree

‎src/oold/model/__init__.py‎

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
get_backend,
1414
get_resolver,
1515
)
16-
from oold.static import GenericLinkedBaseModel, export_jsonld, import_jsonld
16+
from oold.static import (
17+
GenericLinkedBaseModel,
18+
export_jsonld,
19+
import_json,
20+
import_jsonld,
21+
)
1722

1823
# pydantic v2
1924
_types: Dict[str, pydantic.main._model_construction.ModelMetaclass] = {}
@@ -27,7 +32,11 @@ def __new__(mcs, name, bases, namespace):
2732
if hasattr(cls, "get_cls_iri"):
2833
iri = cls.get_cls_iri()
2934
if iri is not None:
30-
_types[iri] = cls
35+
if isinstance(iri, list):
36+
for i in iri:
37+
_types[i] = cls
38+
else:
39+
_types[iri] = cls
3140
return cls
3241

3342
# override operators, see https://docs.python.org/3/library/operator.html
@@ -68,7 +77,7 @@ class LinkedBaseModel(_LinkedBaseModel):
6877
__iris__: Optional[Dict[str, Union[str, List[str]]]] = {}
6978

7079
@classmethod
71-
def get_cls_iri(cls) -> str:
80+
def get_cls_iri(cls) -> Union[str, List[str], None]:
7281
"""Return the unique IRI of the class.
7382
Overwrite this method in the subclass."""
7483
schema = {}
@@ -77,10 +86,25 @@ def get_cls_iri(cls) -> str:
7786
if "json_schema_extra" in cls.model_config:
7887
schema = cls.model_config["json_schema_extra"]
7988

80-
if "iri" in schema:
81-
return schema["iri"]
82-
else:
89+
cls_iri = []
90+
# schema annotation - should be expanded IRI
91+
if "$id" in schema:
92+
cls_iri.append(schema["$id"])
93+
elif "iri" in schema:
94+
cls_iri.append(schema["iri"])
95+
# default value of type field - may be compacted IRI
96+
type_field_name = cls.get_type_field()
97+
# pydantic v2
98+
type_field = cls.model_fields.get(type_field_name, None)
99+
if type_field is not None and type_field.default not in cls_iri:
100+
cls_iri.append(type_field.default)
101+
102+
if len(cls_iri) == 0:
83103
return None
104+
elif len(cls_iri) == 1:
105+
return cls_iri[0]
106+
else:
107+
return cls_iri
84108

85109
def get_iri(self) -> str:
86110
"""Return the unique IRI of the object.
@@ -412,6 +436,15 @@ def to_jsonld(self) -> Dict:
412436
return export_jsonld(self, BaseModel)
413437

414438
@classmethod
415-
def from_jsonld(self, jsonld: Dict) -> "LinkedBaseModel":
439+
def from_jsonld(cls, jsonld: Dict) -> "LinkedBaseModel":
416440
"""Constructs a model instance from a JSON-LD representation."""
417-
return import_jsonld(BaseModel, jsonld, _types)
441+
return import_jsonld(BaseModel, LinkedBaseModel, cls, jsonld, _types)
442+
443+
def to_json(self) -> Dict:
444+
"""Return the JSON representation of the object."""
445+
return json.loads(self.model_dump_json(exclude_none=True))
446+
447+
@classmethod
448+
def from_json(cls, data: Dict) -> "LinkedBaseModel":
449+
"""Constructs a model instance from a JSON representation."""
450+
return import_json(BaseModel, LinkedBaseModel, cls, data, _types)

‎src/oold/model/v1/__init__.py‎

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
get_backend,
1414
get_resolver,
1515
)
16-
from oold.static import GenericLinkedBaseModel, export_jsonld, import_jsonld
16+
from oold.static import (
17+
GenericLinkedBaseModel,
18+
export_jsonld,
19+
import_json,
20+
import_jsonld,
21+
)
1722

1823
if TYPE_CHECKING:
1924
from pydantic.v1.typing import AbstractSetIntStr, MappingIntStrAny
@@ -31,7 +36,11 @@ def __new__(mcs, name, bases, namespace):
3136
if hasattr(cls, "get_cls_iri"):
3237
iri = cls.get_cls_iri()
3338
if iri is not None:
34-
_types[iri] = cls
39+
if isinstance(iri, list):
40+
for i in iri:
41+
_types[i] = cls
42+
else:
43+
_types[iri] = cls
3544
return cls
3645

3746
# override operators, see https://docs.python.org/3/library/operator.html
@@ -72,18 +81,33 @@ class LinkedBaseModel(_LinkedBaseModel):
7281
__iris__: Optional[Dict[str, Union[str, List[str]]]] = PrivateAttr()
7382

7483
@classmethod
75-
def get_cls_iri(cls) -> str:
84+
def get_cls_iri(cls) -> Union[str, List[str], None]:
7685
"""Return the unique IRI of the class.
7786
Overwrite this method in the subclass."""
7887
schema = {}
88+
# pydantic v1
7989
if hasattr(cls, "__config__"):
8090
if hasattr(cls.__config__, "schema_extra"):
8191
schema = cls.__config__.schema_extra
8292

83-
if "iri" in schema:
84-
return schema["iri"]
85-
else:
93+
cls_iri = []
94+
# schema annotation - should be expanded IRI
95+
if "$id" in schema:
96+
cls_iri.append(schema["$id"])
97+
elif "iri" in schema:
98+
cls_iri.append(schema["iri"])
99+
# default value of type field - may be compacted IRI
100+
type_field_name = cls.get_type_field()
101+
# pydantic v2
102+
type_field = cls.__fields__.get(type_field_name, None)
103+
if type_field is not None:
104+
cls_iri.append(type_field.default)
105+
if len(cls_iri) == 0:
86106
return None
107+
elif len(cls_iri) == 1:
108+
return cls_iri[0]
109+
else:
110+
return cls_iri
87111

88112
def get_iri(self) -> str:
89113
"""Return the unique IRI of the object.
@@ -358,6 +382,15 @@ def to_jsonld(self) -> Dict:
358382
return export_jsonld(self, BaseModel)
359383

360384
@classmethod
361-
def from_jsonld(self, jsonld: Dict) -> "LinkedBaseModel":
385+
def from_jsonld(cls, jsonld: Dict) -> "LinkedBaseModel":
362386
"""Constructs a model instance from a JSON-LD representation."""
363-
return import_jsonld(BaseModel, jsonld, _types)
387+
return import_jsonld(BaseModel, LinkedBaseModel, cls, jsonld, _types)
388+
389+
def to_json(self) -> Dict:
390+
"""Return the JSON representation of the object as dict."""
391+
return json.loads(self.json(exclude_none=True))
392+
393+
@classmethod
394+
def from_json(cls, json_dict: Dict) -> "LinkedBaseModel":
395+
"""Constructs a model instance from a JSON representation."""
396+
return import_json(BaseModel, LinkedBaseModel, cls, json_dict, _types)

0 commit comments

Comments
 (0)