Coverage for src/blob_dict/blob/json.py: 0%

46 statements  

« prev     ^ index     » next       coverage.py v7.8.1, created at 2025-05-23 02:51 -0700

1from __future__ import annotations 

2 

3import json 

4from typing import Any, override 

5 

6import yaml 

7from pydantic import BaseModel 

8 

9from . import StrBlob 

10 

11 

12class JsonDictBlob(StrBlob): 

13 def __init__(self, blob: bytes | str | dict[str, Any]) -> None: 

14 if isinstance(blob, dict): 

15 blob = json.dumps(blob) 

16 

17 super().__init__(blob) 

18 

19 def as_dict(self) -> dict[str, Any]: 

20 return json.loads(self._blob_bytes) 

21 

22 @override 

23 def __repr__(self) -> str: 

24 return f"{self.__class__.__name__}({self.as_dict().__repr__()})" 

25 

26 

27class YamlDictBlob(StrBlob): 

28 def __init__(self, blob: bytes | str | dict[str, Any]) -> None: 

29 if isinstance(blob, dict): 

30 blob = yaml.safe_dump(blob) 

31 

32 super().__init__(blob) 

33 

34 def as_dict(self) -> dict[str, Any]: 

35 return yaml.safe_load(self._blob_bytes) 

36 

37 @override 

38 def __repr__(self) -> str: 

39 return f"{self.__class__.__name__}({self.as_dict().__repr__()})" 

40 

41 

42class JsonModelBlob(JsonDictBlob): 

43 __MISSING_MODEL_CLASS_ERROR_MESSAGE = "Must specify Pydantic model class if specified blob is not a model object" # noqa: E501 

44 __BAD_MODEL_CLASS_ERROR_MESSAGE = "Must specify Pydantic model class that inherits from `BaseModel`" # noqa: E501 

45 

46 def __init__( 

47 self, 

48 blob: bytes | str | dict[str, Any] | BaseModel, 

49 *, 

50 model_class: type[BaseModel] | None = None, 

51 ) -> None: 

52 if not isinstance(blob, BaseModel) and not model_class: 

53 raise ValueError(JsonModelBlob.__MISSING_MODEL_CLASS_ERROR_MESSAGE) 

54 

55 if model_class == BaseModel: 

56 raise ValueError(JsonModelBlob.__BAD_MODEL_CLASS_ERROR_MESSAGE) 

57 

58 self.__model_class: type[BaseModel] 

59 if isinstance(blob, BaseModel): 

60 self.__model_class = type(blob) 

61 blob = blob.model_dump_json() 

62 elif model_class: 

63 self.__model_class = model_class 

64 

65 super().__init__(blob) 

66 

67 def as_model(self) -> BaseModel: 

68 return self.__model_class.model_validate_json(self._blob_bytes) 

69 

70 @override 

71 def __repr__(self) -> str: 

72 return f"{self.__class__.__name__}({self.as_model().__repr__()})"