11from dataclasses import dataclass
22from datetime import datetime
33from os import path
4- from typing import cast , TypeVar , Generic
4+ from typing import Any , cast , TypeVar , Generic
55
66from jsons import (
7+ dump ,
78 dumps ,
89 NoneType ,
10+ load ,
911 loads ,
1012 JsonsError ,
1113 set_deserializer ,
2224READ : str = "r"
2325JSON_PARSE_ERROR = '{"error": "Object could not be parsed due to json issue"}'
2426# TODO Issue #??: Jsons library incorrectly dumps class method
25- FROM_JSON_FILE = '"from_json_file": {}, '
27+ KEYS_TO_REMOVE = [ "from_json" , "from_json_file" , "from_json_object" ]
2628
2729
2830@dataclass
@@ -33,18 +35,19 @@ class Serializable(Generic[T]):
3335
3436 def to_json (self , strip_privates : bool = True ) -> str :
3537 """
36- Serialize to json
38+ Serialize to json string
39+ :param strip_privates: strip private variables
40+ :return: the json string representation of this object
41+ """
42+ return write_json (self , strip_privates )
43+
44+ def to_json_object (self , strip_privates : bool = True ) -> Any :
45+ """
46+ Serialize to json object
3747 :param strip_privates: strip private variables
3848 :return: the json representation of this object
3949 """
40- set_serializers ()
41- suppress_warnings ()
42- try :
43- return cast (
44- str , dumps (self , strip_privates = strip_privates , strip_nulls = True )
45- ).replace (FROM_JSON_FILE , "" )
46- except JsonsError :
47- return JSON_PARSE_ERROR
50+ return write_json_object (self , strip_privates )
4851
4952 def to_json_file (
5053 self , file_name : str , file_path : str = "" , strip_privates : bool = True
@@ -55,35 +58,115 @@ def to_json_file(
5558 :param file_path: File path
5659 :param strip_privates: Strip private variables
5760 """
58- write_json_file (self .to_json (strip_privates ), file_name , file_path )
61+ write_json_file (self , file_name , file_path , strip_privates )
62+
63+ @classmethod
64+ def from_json (cls , data : str ) -> T :
65+ """
66+ Deserialize the provided data string into the specified instance
67+ :param data: JSON string
68+ """
69+ set_deserializers ()
70+ return cast (T , loads (data , cls ))
71+
72+ @classmethod
73+ def from_json_object (cls , data : object ) -> T :
74+ """
75+ Deserialize the provided data object into the specified instance
76+ :param data: JSON object
77+ """
78+ set_deserializers ()
79+ return cast (T , load (data , cls ))
5980
6081 @classmethod
6182 def from_json_file (cls , file_name : str , file_path : str = "" ) -> T :
6283 """
6384 Deserialize the provided file into the specified instance
85+ :param file_name: File name
86+ :param file_path: File path
6487 """
6588 json_file_path : str = path .join (file_path , file_name + JSON_FILE_EXTENSION )
6689 with open (json_file_path , READ ) as json_file :
6790 data = json_file .read ()
6891 target = cls .from_json (data )
6992 return target
7093
71- @classmethod
72- def from_json (cls , data : str ) -> T :
73- """
74- Deserialize the provided data string into the specified instance
75- """
76- set_deserializers ()
77- return cast (T , loads (data , cls ))
78-
7994
80- def write_json_file (json_data : str , file_name : str , file_path : str = "" ) -> None :
95+ def _remove_key (obj : Any , key_to_remove : str ) -> Any :
96+ """
97+ Remove key from object recursively
98+ :param obj: Any object
99+ :param key_to_remove: key to remove
100+ """
101+ if isinstance (obj , dict ):
102+ for key in list (obj .keys ()):
103+ if key == key_to_remove :
104+ del obj [key ]
105+ else :
106+ _remove_key (obj [key ], key_to_remove )
107+ elif isinstance (obj , list ):
108+ for i in reversed (range (len (obj ))):
109+ if obj [i ] == key_to_remove :
110+ del obj [i ]
111+ else :
112+ _remove_key (obj [i ], key_to_remove )
113+
114+
115+ def write_json (object_to_write : object , strip_privates : bool = True ) -> str :
116+ """
117+ Serialize to json string
118+ :param object_to_write: object to write to json
119+ :param strip_privates: strip private variables
120+ :return: the json string representation of this object
121+ """
122+ set_serializers ()
123+ suppress_warnings ()
124+ try :
125+ json_object = write_json_object (object_to_write , strip_privates )
126+ json_string = cast (
127+ str , dumps (json_object , strip_privates = strip_privates , strip_nulls = True )
128+ )
129+ return json_string
130+ except JsonsError :
131+ return JSON_PARSE_ERROR
132+
133+
134+ def write_json_object (object_to_write : object , strip_privates : bool = True ) -> object :
135+ """
136+ Serialize to json object
137+ :param object_to_write: object to write to json
138+ :param strip_privates: strip private variables
139+ :return: the json representation of this object
140+ """
141+ set_serializers ()
142+ suppress_warnings ()
143+ try :
144+ json_object = dump (
145+ object_to_write , strip_privates = strip_privates , strip_nulls = True
146+ )
147+ for key in KEYS_TO_REMOVE :
148+ _remove_key (json_object , key )
149+ return json_object
150+ except JsonsError :
151+ return JSON_PARSE_ERROR
152+
153+
154+ def write_json_file (
155+ object_to_write : object ,
156+ file_name : str ,
157+ file_path : str = "" ,
158+ strip_privates : bool = True ,
159+ ) -> None :
81160 """
82- Write json data string to json file
161+ Serialize json data string to json file
162+ :param object_to_write: object to write to json
163+ :param file_name: File name
164+ :param file_path: File path
165+ :param strip_privates: strip private variables
83166 """
84167 json_file_path : str = path .join (file_path , file_name + JSON_FILE_EXTENSION )
85168 with open (json_file_path , WRITE ) as json_file :
86- json_file .write (json_data )
169+ json_file .write (write_json ( object_to_write , strip_privates ) )
87170
88171
89172def set_serializers () -> None :
0 commit comments