lionagi 0.17.8__py3-none-any.whl → 0.17.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,105 @@
1
- from pydantic import BaseModel
1
+ from typing import Literal
2
+
3
+ import orjson
4
+ from pydantic import BaseModel, ConfigDict
2
5
  from typing_extensions import Self
3
6
 
4
- from lionagi.utils import UNDEFINED, hash_dict
7
+ from .. import ln
8
+
9
+ _DEFAULT_HASHABLE_SERIALIZER = None
10
+
11
+ ConversionMode = Literal["python", "json", "db"]
12
+
13
+
14
+ __all__ = (
15
+ "HashableModel",
16
+ "ConversionMode",
17
+ )
5
18
 
6
19
 
7
20
  class HashableModel(BaseModel):
8
- def to_dict(self, **kwargs) -> dict:
9
- """provides interface, specific methods need to be implemented in subclass kwargs for pydantic model_dump"""
10
- return {
11
- k: v
12
- for k, v in self.model_dump(**kwargs).items()
13
- if v is not UNDEFINED
14
- }
21
+ """Used as base class for models that need to be hashable."""
22
+
23
+ model_config = ConfigDict(
24
+ populate_by_name=True,
25
+ validate_assignment=True,
26
+ extra="forbid",
27
+ arbitrary_types_allowed=True,
28
+ use_enum_values=True,
29
+ validate_default=True,
30
+ )
31
+
32
+ def _to_dict(self, **kw) -> dict:
33
+ dict_ = self.model_dump(**kw)
34
+ return {k: v for k, v in dict_.items() if ln.not_sentinel(v)}
35
+
36
+ def to_dict(self, mode: ConversionMode = "python", **kw) -> dict:
37
+ """Converts this Element to a dictionary."""
38
+ match mode:
39
+ case "python":
40
+ return self._to_dict(**kw)
41
+ case "json":
42
+ return orjson.loads(self.to_json(decode=False))
43
+ case "db":
44
+ dict_ = orjson.loads(self.to_json(decode=False))
45
+ if "metadata" in dict_:
46
+ dict_["node_metadata"] = dict_.pop("metadata", {})
47
+ return dict_
48
+ case _:
49
+ raise ValueError(f"Unsupported mode: {mode}")
15
50
 
16
51
  @classmethod
17
- def from_dict(cls, data: dict, **kwargs) -> Self:
18
- """provides interface, specific methods need to be implemented in subclass kwargs for pydantic model_validate"""
19
- return cls.model_validate(data, **kwargs)
52
+ def from_dict(
53
+ cls, data: dict, mode: ConversionMode = "python", **kw
54
+ ) -> Self:
55
+ match mode:
56
+ case "python":
57
+ return cls.model_validate(data, **kw)
58
+ case "json":
59
+ return cls.model_validate(orjson.loads(data), **kw)
60
+ case "db":
61
+ if "node_metadata" in data:
62
+ data["metadata"] = data.pop("node_metadata")
63
+ return cls.model_validate(data, **kw)
64
+ case _:
65
+ raise ValueError(f"Unsupported mode: {mode}")
66
+
67
+ def to_json(self, decode: bool = True, **kw) -> bytes | str:
68
+ """Converts this Element to a JSON string."""
69
+
70
+ dict_ = self._to_dict(**kw)
71
+ b_ = ln.json_dumpb(
72
+ dict_,
73
+ sort_keys=True,
74
+ deterministic_sets=True,
75
+ naive_utc=True,
76
+ default=_get_default_hashable_serializer(),
77
+ )
78
+ if decode:
79
+ return b_.decode("utf-8")
80
+ return b_
81
+
82
+ def from_json(
83
+ cls, data: bytes | str, mode: ConversionMode = "json", **kwargs
84
+ ) -> Self:
85
+ """Creates an instance of this class from a JSON string."""
86
+ return cls.from_dict(orjson.loads(data), mode=mode, **kwargs)
20
87
 
21
88
  def __hash__(self):
22
- # Convert kwargs to a hashable format by serializing unhashable types
23
- return hash_dict(self.to_dict())
89
+ return ln.hash_dict(self.to_dict())
90
+
91
+
92
+ def _get_default_hashable_serializer():
93
+ global _DEFAULT_HASHABLE_SERIALIZER
94
+ if _DEFAULT_HASHABLE_SERIALIZER is None:
95
+ from lionagi.protocols.ids import Element, IDType
96
+
97
+ _DEFAULT_HASHABLE_SERIALIZER = ln.get_orjson_default(
98
+ order=[IDType, Element, BaseModel],
99
+ additional={
100
+ IDType: lambda o: str(o),
101
+ Element: lambda o: o.to_dict(),
102
+ BaseModel: lambda o: o.model_dump(mode="json"),
103
+ },
104
+ )
105
+ return _DEFAULT_HASHABLE_SERIALIZER