Files
2026-05-12 19:40:31 +09:00

53 lines
1.4 KiB
Python

import inspect
import json
import sys
from dataclasses import InitVar, asdict, dataclass, field, is_dataclass
from json import JSONEncoder
from typing import Any, Dict
from pydash.strings import snake_case
def get_annotations(obj):
if sys.version_info.minor >= 10 and hasattr(inspect, "get_annotations"):
return inspect.get_annotations(obj) # type: ignore
else:
return obj.__annotations__
class SerializeableJSONEncoder(JSONEncoder):
def default(self, o):
if is_dataclass(o):
return asdict(o)
return super().default(o)
encoder_kwargs = {}
if sys.version_info.minor >= 10:
encoder_kwargs["kw_only"] = True
encoder_kwargs["default"] = SerializeableJSONEncoder
@dataclass
class Serializeable:
encoder: InitVar[JSONEncoder] = field(**encoder_kwargs)
@classmethod
def from_dict(cls, data: Dict[str, Any]):
annotations = get_annotations(cls)
attributes = dict.keys(annotations)
snake_case_kwargs = {
snake_case(k): data.get(k) for k in data if snake_case(k) in attributes
}
snake_case_kwargs["encoder"] = snake_case_kwargs.get(
"encoder", SerializeableJSONEncoder
)
return cls(**snake_case_kwargs) # type: ignore
@property
def __dict__(self) -> Dict[str, Any]:
return asdict(self)
def to_json(self):
return json.dumps(self, cls=self.encoder) # type: ignore