Source code for create_param_json

import argparse

[docs] opn = "{\n"
[docs] cls = "}\n"
[docs] clsc = "},\n"
[docs] parser = argparse.ArgumentParser( description="Parse a python file to produce a skeleton param json file for auror" )
parser.add_argument("python_file", type=str, help="Python file to be parsed") parser.add_argument("json_file", type=str, help="Name of the output json file") parser.add_argument( "-l", "--tab_length", type=int, default=4, required=False, help="Name of the output json file", ) parser.add_argument( "-s", "--strong_typed", type=bool, default=True, required=False, help="Functions are strongly typed", )
[docs] args = parser.parse_args()
[docs] def edit_list_entry(key, lista, replacement): if key in lista: lista[lista.index(key)] = replacement
[docs] def is_list_in(lista): count = 0 for item in lista: if "List" in item: return count count += 1 else: return -1
[docs] class Param:
[docs] missing = "_###MISSING###_"
def __init__(self, paramstr, header=None): param_wrds = paramstr.split("=")
[docs] self.required = len(param_wrds) == 1
if header is None: self.name, self.types = param_wrds[0].split(":") else: self.name = param_wrds[0].strip() self.types = None self._build_dict(header) return def _build_dict(self, header): self.dicio = { "allowed": self.missing, "nullable": self.missing, "required": self.required, } if header is None: if "Union" in self.types: typestr = self.types.replace("Union[", "")[:-2].replace(" ", "") types = typestr.split(",") else: types = [self.types.strip()] else: typstr = "" for line in header: if f":type {self.name}:" in line: typstr = line.replace("\n", "").strip() break types = [] if typstr != "": delimiters = [" ", "or", ",", "optional"] types = typstr.split(":")[2] for delimiter in delimiters: types = " ".join(types.split(delimiter)) types = types.split() edit_list_entry("bool", types, "boolean") edit_list_entry("str", types, "string") edit_list_entry("numpy.ndarray", types, "ndarray") if "dtype" in types: types.remove("dtype") list_in = is_list_in(types) if list_in > -1 or "Array" in types: self.dicio["struct_type"] = [] self.dicio["minlength"] = self.missing self.dicio["maxlength"] = self.missing if list_in > -1: liststr = types[list_in] self.dicio["struct_type"] = liststr.split("[")[1].strip("]").split(",") types[list_in] = "list" if "Array" in types: self.dicio["struct_type"] = ["int", "float"] edit_list_entry("Array", types, "ndarray, list") if len(types) == 0: self.dicio["type"] = self.missing else: self.dicio["type"] = types if "int" in types or "float" in types: self.dicio["min"] = self.missing self.dicio["max"] = self.missing
[docs] def export_to_json(self, lvl, spc, op, clc): outstr = f'{lvl*spc}"{self.name}":{op}' for key in self.dicio.keys(): outstr += self._write_key(key, lvl + 1, spc) outstr = outstr[:-2] + "\n" outstr += f"{lvl*spc}{clc}" return outstr
def _write_key(self, key, lvl, spc): value = self.dicio[key] base = f'{lvl*spc}"{key}":' if isinstance(value, list): extra = "[" for ival in range(len(value)): extra += f'"{value[ival]}"' if ival != len(value) - 1: extra += ", " extra += "]" return base + f" {extra},\n" if isinstance(value, bool): return base + f" {str(value).lower()},\n" else: return base + f' "{value}",\n'
[docs] class Function: def __init__(self, name, header, strong=True):
[docs] self.param_list = []
[docs] self.name = name
[docs] self.header = header
[docs] self.strong = strong
self._build_param_list() return def _build_param_list(self): lestr = "" for line in self.header: lestr += "|" + line.strip().strip(",") if ")" in line: break param_str = lestr.split("(")[1].split(")")[0] if self.strong: param_str_list = param_str.split("|") else: param_str_list = param_str.replace("\n", "").split(",") for parstr in param_str_list: if "self" in parstr or parstr == "": continue else: if self.strong: self.param_list.append(Param(parstr)) else: self.param_list.append(Param(parstr, header=self.header))
[docs] def export_to_json(self, lvl, spc, op, clc): outstr = f'{lvl*spc}"{self.name}":{op}' for param in self.param_list: outstr += param.export_to_json(lvl + 1, spc, op, clc) outstr += f"{spc}{clc}" return outstr
[docs] class PythonFile: def __init__(self, file_name):
[docs] self.file_name = file_name
[docs] self.function_list = []
self._parse() def _parse(self): with open(self.file_name, "r") as pyfile: function_head = [] in_function = False n_3quotes = 0 func_name = "" for line in pyfile: if in_function: if '"""' in line or "'''" in line: n_3quotes += 1 function_head.append(line) if n_3quotes >= 2: in_function = False n_3quotes = 0 self.function_list.append(Function(func_name, function_head)) function_head = [] else: wrds = line.split() if len(wrds) > 0: if wrds[0] == "def": func_name = wrds[1].replace("(", "") if func_name[0] == "_": continue in_function = True function_head.append(line)
[docs] def export_to_json(self, json_file, spc, op, cl, clc): with open(json_file, "w") as outfile: outfile.write(op) for func in self.function_list: outfile.write(func.export_to_json(1, spc, op, clc)) outfile.write(cl)
[docs] mypyfile = PythonFile(args.python_file)
mypyfile.export_to_json(args.json_file, args.tab_length * " ", opn, cls, clsc)