"""
JSON Transform tool
This tool can be used to create classes from a JSON file template. (<file>.json)
Classes for elements in the JSON will be created in a file. The file <file>.py will be created
Sub-elements in your JSON will be created in its own class in a <element_name>.py file
To use the tools, run this file. You need to define your working directory in the root folder of your repos.
The parameter isd the file location of your JSON you want to create your classes from.
The created file is added in the same directory of your JSON file
WARNING:
For your parameter file, make sure to specify your path with "/" and not "\"
The target file is overwritten if already existing
"""
import json
import sys
from datetime import date, datetime
[docs]
def name_to_field(name_in: str):
name_in = name_in.replace("GUID", "_guid")
ret = ""
for i in range(len(name_in)):
if name_in[i].isupper():
if i != 0:
ret += "_"
ret += name_in[i].lower()
else:
ret += name_in[i]
return ret
[docs]
def get_class_name(class_name: str):
return class_name[0].upper() + class_name[1:]
[docs]
def is_not_empty_list(json_entity, element):
return isinstance(json_entity.get(element), list) and json_entity.get(element)
[docs]
def is_dict(json_entity, element):
return isinstance(json_entity.get(element), dict) \
and element != "fieldList" \
and element != "calculatedValuesList" \
and element != "multiFieldList"
[docs]
def to_dict(obj):
if isinstance(obj, dict):
return {k: to_dict(v) for k, v in obj.items()}
elif hasattr(obj, "__dict__"):
return {k: to_dict(v) for k, v in vars(obj).items() if not k.startswith("_")}
elif isinstance(obj, (list, tuple, set)):
return [to_dict(v) for v in obj]
elif isinstance(obj, (date, datetime)):
return obj.isoformat()
else:
return obj
[docs]
def create_class(class_name: str, pack_name: str, out_path: str, json_entity: dict):
imports = ""
def_init = ""
fields = ""
def_from_json = ""
for element in json_entity:
modified_name = name_to_field(element)
new_class_name = get_class_name(element)
if not is_not_empty_list(json_entity, element) and not is_dict(json_entity, element):
def_init += "\t\t\t" + modified_name + ": " + type(json_entity.get(element)).__name__ + " = None,\n"
def_from_json += "\t\tself." + modified_name + " = element_param.get(\"" + element + "\")\n"
else:
if is_not_empty_list(json_entity, element):
create_class(element, pack_name, out_path, json_entity.get(element)[0])
def_init += "\t\t\t" + modified_name + ": list = [],\n"
def_from_json += "\t\tfor list_element in element_param.get(\"" + element + "\"):\n"
def_from_json += "\t\t\tobj_to_add = " + new_class_name + "()\n"
def_from_json += "\t\t\tobj_to_add.from_json(list_element)\n"
def_from_json += "\t\t\tself." + modified_name + ".append(obj_to_add)\n"
else:
create_class(element, pack_name, out_path, json_entity.get(element))
def_init += "\t\t\t" + modified_name + ": " + new_class_name + " = " + new_class_name + "(),\n"
def_from_json += "\t\tself." + modified_name + " = " + "self." + modified_name + \
".from_json(element_param.get(\"" + element + "\"))\n"
imports += "from " + pack_name + "." + modified_name + " import " + new_class_name + "\n"
fields += "\t\tself." + modified_name + " = " + modified_name + "\n"
file_name = out_path + "/" + name_to_field(class_name) + ".py"
print(file_name)
file_out = open(file_name, "w")
if imports != "":
file_out.write(imports + "\n\n")
file_out.write("class " + get_class_name(class_name) + ":\n")
file_out.write("\tdef __init__(\n\t\t\tself,\n" + def_init + "\n\t):\n")
file_out.write(fields + "\n")
file_out.write("\tdef from_json(self, element_param: dict):\n" + def_from_json + "\t\treturn self\n")
file_out.close()
[docs]
def get_class_part(path: str):
parts = path.split("/")
return parts[len(parts)-1].split(".")[0]
[docs]
def get_package(path: str, separator: str):
parts = path.split("/")
package = ""
i = 0
while i < len(parts)-1:
package += parts[i] + separator
i += 1
return package[:len(package)-1]
if __name__ == "__main__":
file = sys.argv[1]
create_class(get_class_part(file), get_package(file, "."), get_package(file, "/"), json.load(open(file)))