# Copyright 2025 - Oumi## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.importdataclassesimportjsonfromtypingimportAnyimportnumpyasnpimporttorchfromoumi.utils.loggingimportloggerJSON_FILE_INDENT=2
[docs]defdefault(self,obj):"""Extending python's JSON Encoder to serialize torch dtype."""ifobjisNone:return""# JSON does NOT natively support any torch types.elifisinstance(obj,torch.dtype):returnstr(obj)# JSON does NOT natively support numpy types.elifisinstance(obj,np.integer):returnint(obj)elifisinstance(obj,np.floating):returnfloat(obj)elifisinstance(obj,np.ndarray):returnobj.tolist()else:try:returnsuper().default(obj)exceptException:logger.warning(f"Non-serializable value `{obj}` of type `{type(obj)}`.")returnstr(obj)
[docs]defconvert_all_keys_to_serializable_types(dictionary:dict)->None:"""Converts all keys in a hierarchical dictionary to serializable types."""serializable_key_types={str,int,float,bool,None}non_serializable_keys=[keyforkeyindictionaryiftype(key)notinserializable_key_types]forkeyinnon_serializable_keys:dictionary[str(key)]=dictionary.pop(key)# Recursively convert all keys for nested dictionaries.forvalueindictionary.values():ifisinstance(value,dict):convert_all_keys_to_serializable_types(value)
[docs]defjson_serializer(obj:Any)->str:"""Serializes a Python obj to a JSON formatted string."""ifdataclasses.is_dataclass(obj)andnotisinstance(obj,type):dict_to_serialize=dataclasses.asdict(obj)elifisinstance(obj,dict):dict_to_serialize=objelse:raiseValueError(f"Cannot serialize object of type {type(obj)} to JSON.")# Ensure all (nested) dictionary keys are serializable.ifisinstance(dict_to_serialize,dict):convert_all_keys_to_serializable_types(dict_to_serialize)# Attempt to serialize the dictionary to JSON.try:returnjson.dumps(dict_to_serialize,cls=TorchJsonEncoder,indent=JSON_FILE_INDENT)exceptExceptionase:error_str="Non-serializable dict:\n"forkey,valueindict_to_serialize.items():error_str+=f" - {key}: {value} (type: {type(value)})\n"logger.error(error_str)raiseException(f"Failed to serialize dict to JSON: {e}")