Coverage for python/diagnostic_and_simulation_base/utility/make_settings_json.py: 14%

29 statements  

« prev     ^ index     » next       coverage.py v7.15.0, created at 2026-07-07 13:12 +0000

1import json 

2import typing 

3 

4import numpy as np 

5 

6 

7def make_settings_json(data: dict[str, typing.Any], json_indent: int = 2) -> str: 

8 """ 

9 Function to make a Python dictionary into JSON string. 

10 The purpose of this function is for serialising the "settings.json" files prior to storing in the database. 

11 The format of the string is (note the escape characters in the new lines and open/close quotes): 

12 ``` 

13 results = '{ 

14 "settings_file_1.json": "{\n \"json_content\": \"value\"}", 

15 "settings_file_2.json": "{\n \"json_content\": 123.4}", 

16 "settings_file_3.csv": "123.4, 456.7, 789.0\n 0.1, 0.2, 0.3" 

17 }' 

18 ``` 

19 

20 The reason for this format is so that files with different formats (e.g. JSON, CSV, namelists, or binary) can all be stored 

21 

22 :param data: the dictionary containing the settings files to be made into a JSON string. 

23 :param json_indent: the indentation of the JSON string. 

24 :return json_string: the JSON string. 

25 """ 

26 

27 def convert_dict_with_numpy_to_dict_no_numpy(data: typing.Any) -> typing.Any: 

28 """ 

29 Recursively searches through nested dictionaries and converts any numpy 

30 objects to fundamental python objects, which are JSON serializable. 

31 

32 :param data: input data which might contain numpy objects 

33 :return data: data with numpy objects converted to fundamental python objects 

34 """ 

35 # TODO: change this to a for loop instead of recursion 

36 if isinstance(data, dict): 

37 return_dict_data = dict() 

38 for key, value in data.items(): 

39 return_dict_data[key] = convert_dict_with_numpy_to_dict_no_numpy(value) 

40 return return_dict_data 

41 elif isinstance(data, list): 

42 return_list_data = [] 

43 for item in data: 

44 return_list_data.append(convert_dict_with_numpy_to_dict_no_numpy(item)) 

45 return return_list_data 

46 elif isinstance(data, np.ndarray): 

47 return data.tolist() 

48 elif isinstance(data, np.generic): 

49 return data.item() 

50 else: 

51 return data 

52 

53 dict_no_numpy = convert_dict_with_numpy_to_dict_no_numpy(data) 

54 

55 if np.all([isinstance(value, dict) for value in dict_no_numpy.values()]): 

56 new_dict = dict() 

57 for key in dict_no_numpy.keys(): 

58 json_internal_content = json.dumps( 

59 dict_no_numpy[key], 

60 indent=json_indent, 

61 sort_keys=True, 

62 ) 

63 new_dict[key] = json_internal_content 

64 else: 

65 new_dict = dict_no_numpy 

66 

67 json_string = json.dumps(obj=new_dict, indent=json_indent, sort_keys=True) 

68 

69 return json_string