18 from typing 
import Any, Optional, Type, Dict, Tuple
 
   19 from typing_extensions 
import Self
 
   20 from datetime 
import datetime
 
   26 from .descriptor 
import KeyDescriptor
 
   27 from ..utils.date 
import DATE_FORMAT, decodeDate
 
   33         Class whose subclasses can be serialized/deserialized into/from a JSON format object 
   37     def _keyDescriptors(cls) -> Dict[str, KeyDescriptor]:
 
   39             Defines a custom mapping for python objects to json field 
   40             Key of the dictionary represents a name of the field in python 
   41             Value of the dictionary represents how should the object be serialized/deserialized 
   45             Dict[str, KeyDescriptor] -> Dictionary of objects describing translation 
   51     def __keyDescriptorByJsonName(cls, jsonName: str) -> Tuple[Optional[str], Optional[KeyDescriptor]]:
 
   53             if value.jsonName == jsonName:
 
   59     def __keyDescriptorByPythonName(cls, pythonName: str) -> Optional[KeyDescriptor]:
 
   67     def __encodeKey(self, key: str) -> str:
 
   68         descriptor = self.__class__.__keyDescriptorByPythonName(key)
 
   70         if descriptor 
is None or descriptor.jsonName 
is None:
 
   71             return inflection.underscore(key)
 
   73         return descriptor.jsonName
 
   75     def _encodeValue(self, key: str, value: Any) -> Any:
 
   77             Encodes python value into a json property 
   78             Custom field serialization can be implemented by overriding this method 
   83                 python object variable name 
   85                 json object represented as an object from standard python library 
   89             Any -> encoded value of the object 
   92         descriptor = self.__class__.__keyDescriptorByPythonName(key)
 
   94         if descriptor 
is None or descriptor.pythonType 
is None:
 
   97         if issubclass(descriptor.pythonType, Enum):
 
   98             if descriptor.isList():
 
   99                 return [element.value 
for element 
in value]
 
  103         if issubclass(descriptor.pythonType, UUID):
 
  104             if descriptor.isList():
 
  105                 return [str(element) 
for element 
in value]
 
  109         if issubclass(descriptor.pythonType, Codable):
 
  110             if descriptor.isList():
 
  111                 return [descriptor.pythonType.encode(element) 
for element 
in value]
 
  113             return descriptor.pythonType.encode(value)
 
  115         if issubclass(descriptor.pythonType, datetime):
 
  116             if descriptor.isList():
 
  117                 return [element.strftime(DATE_FORMAT) 
for element 
in value]
 
  119             return value.strftime(DATE_FORMAT)
 
  125             Encodes python object into dictionary which contains 
  126             only values representable by standard python library/types 
  130             Dict[str, Any] -> encoded object which can be serialized into json string 
  133         encodedObject: Dict[str, Any] = {}
 
  135         for key, value 
in self.__dict__.items():
 
  136             descriptor = self.__class__.__keyDescriptorByPythonName(key)
 
  139             if descriptor 
is not None and not descriptor.isEncodable:
 
  144             encodedValue = self.
_encodeValue_encodeValue(key, value)
 
  146             encodedObject[encodedKey] = encodedValue
 
  153     def __decodeKey(cls, key: str) -> str:
 
  156         if descriptorKey 
is None:
 
  157             return inflection.camelize(key, 
False)
 
  162     def _decodeValue(cls, key: str, value: Any) -> Any:
 
  164             Decodes a value of a single json field 
  165             Custom logic can be implemented by overriding this method 
  170                 name of the json field 
  172                 value of the json field 
  176             Any -> decoded value of the json field 
  181         if descriptor 
is None or descriptor.pythonType 
is None:
 
  184         if issubclass(descriptor.pythonType, Enum):
 
  185             if descriptor.isList() 
and descriptor.collectionType 
is not None:
 
  186                 return descriptor.collectionType([descriptor.pythonType(element) 
for element 
in value])
 
  188             return descriptor.pythonType(value)
 
  190         if issubclass(descriptor.pythonType, UUID):
 
  191             if descriptor.isList() 
and descriptor.collectionType 
is not None:
 
  192                 return descriptor.collectionType([descriptor.pythonType(element) 
for element 
in value])
 
  194             return descriptor.pythonType(value)
 
  196         if issubclass(descriptor.pythonType, Codable):
 
  197             if descriptor.isList() 
and descriptor.collectionType 
is not None:
 
  198                 return descriptor.collectionType([descriptor.pythonType.decode(element) 
for element 
in value])
 
  200             return descriptor.pythonType.decode(value)
 
  202         if issubclass(descriptor.pythonType, datetime):
 
  203             if descriptor.isList() 
and descriptor.collectionType 
is not None:
 
  204                 return descriptor.collectionType([decodeDate(element) 
for element 
in value])
 
  206             return decodeDate(value)
 
  210     def _updateFields(self, encodedObject: Dict[str, Any]) -> 
None:
 
  212             Updates the properties of object with new values 
  216             encodedObject : Dict[str, Any] 
  220         for key, value 
in encodedObject.items():
 
  221             _, descriptor = self.__class__.__keyDescriptorByJsonName(key)
 
  224             if descriptor 
is not None and not descriptor.isDecodable:
 
  229             self.__dict__[decodedKey] = self.
_decodeValue_decodeValue(key, value)
 
  233             Callback which is called once the object has been decoded 
  239     def decode(cls, encodedObject: Dict[str, Any]) -> Self:
 
  241             Decodes the json object into a python object 
  245             encodedObject : Dict[str, Any] 
  250             Self -> Decoded python object 
  254         obj._updateFields(encodedObject)
 
Dict[str, KeyDescriptor] _keyDescriptors(cls)
 
Dict[str, Any] encode(self)
 
Any _encodeValue(self, str key, Any value)
 
str __decodeKey(cls, str key)
 
Self decode(cls, Dict[str, Any] encodedObject)
 
Tuple[Optional[str], Optional[KeyDescriptor]] __keyDescriptorByJsonName(cls, str jsonName)
 
Any _decodeValue(cls, str key, Any value)
 
str __encodeKey(self, str key)