13
13
import json
14
14
import typing
15
15
16
+ from dataclasses import asdict , is_dataclass
17
+
16
18
def try_import_pydantic_base_model ():
17
19
"""
18
20
Try to import PydanticBaseModel from Pydantic.
@@ -26,7 +28,39 @@ class Dummy: # pylint: disable=too-few-public-methods
26
28
27
29
return Dummy
28
30
31
+ def try_import_from_dacite ():
32
+ """
33
+ Try to import from_dict from dacite.
34
+ """
35
+ try :
36
+ from dacite import from_dict # type: ignore # pylint: disable=import-outside-toplevel
37
+
38
+ return asdict , from_dict
39
+
40
+ except ImportError :
41
+
42
+ def to_dict (obj ):
43
+ """a dummy function when dacite is not available"""
44
+ raise RuntimeError ("Trying to deserialize into a @dataclass." \
45
+ "Please add the optional dependencies needed." \
46
+ "use pip install restate-sdk[serde] "
47
+ "or" \
48
+ " pip install restate-sdk[all] to install all dependencies." )
49
+
50
+
51
+ def from_dict (a ,b ): # pylint: disable=too-few-public-methods,unused-argument
52
+ """a dummy function when dacite is not available"""
53
+
54
+ raise RuntimeError ("Trying to deserialize into a @dataclass." \
55
+ "Please add the optional dependencies needed." \
56
+ "use pip install restate-sdk[serde] "
57
+ "or" \
58
+ " pip install restate-sdk[all] to install all dependencies." )
59
+
60
+ return to_dict , from_dict
61
+
29
62
PydanticBaseModel = try_import_pydantic_base_model ()
63
+ DaciteToDict , DaciteFromDict = try_import_from_dacite ()
30
64
31
65
T = typing .TypeVar ('T' )
32
66
I = typing .TypeVar ('I' )
@@ -170,6 +204,9 @@ def deserialize(self, buf: bytes) -> typing.Optional[I]:
170
204
return None
171
205
if is_pydantic (self .type_hint ):
172
206
return self .type_hint .model_validate_json (buf ) # type: ignore
207
+ if is_dataclass (self .type_hint ):
208
+ data = json .loads (buf )
209
+ return DaciteFromDict (self .type_hint , data )
173
210
return json .loads (buf )
174
211
175
212
def serialize (self , obj : typing .Optional [I ]) -> bytes :
@@ -183,13 +220,13 @@ def serialize(self, obj: typing.Optional[I]) -> bytes:
183
220
Returns:
184
221
bytes: The serialized byte array.
185
222
"""
186
-
187
223
if obj is None :
188
224
return bytes ()
189
-
190
225
if is_pydantic (self .type_hint ):
191
226
return obj .model_dump_json ().encode ("utf-8" ) # type: ignore[attr-defined]
192
-
227
+ if is_dataclass (obj ):
228
+ data = DaciteToDict (obj ) # type: ignore
229
+ return json .dumps (data ).encode ("utf-8" )
193
230
return json .dumps (obj ).encode ("utf-8" )
194
231
195
232
0 commit comments