import json import sys VARIABLE_TO_CODE_MAP = { "agg901": "00H86", "agg902": "00H86", "agg908": "00H86", "agg911": "00H86", "all231": "00ASH", "at28a": "00WR3", "at28b": "00WR3", "at36s": "00WR3", "balmag01": "00H88", "balmag02": "00H88", "balmag04": "00AI5", "bc102s": "00WR3", "bc104s": "00WR3", "bc107s": "00WR3", "bc20s": "00WR3", "bc21s": "00WR3", "bc28s": "00WR3", "bc36s": "00WR3", "bc97a": "00WR3", "bc98a": "00WR3", "bkc14": "00ASF", "bkc321": "00ASI", "bkc322": "00ASI", "bkc323": "00ASI", "bkc324": "00ASI", "bkc327": "00ASI", "bkc328": "00ASI", "bkc84": "00ASF", "br20s": "00WR3", "ct319": "00AI9", "ct320": "00AI9", "cta11": "00AI9", "cta20": "00AI9", "cta21": "00AI9", "cv13": "00V26", "cv17": "00V26", "cv21": "00V26", "cv25": "00V26", "duemag01": "00AI5", "fi21s": "00WR3", "fi34s": "00WR3", "fi35s": "00WR3", "g051s": "00WR3", "g102s": "00WR3", "g105s": "00WR3", "g106s": "00WR3", "g201a": "00WR3", "g221d": "00WR3", "g232s": "00WR3", "g242b": "00WR3", "g250a": "00WR3", "g403s": "00WR3", "g405s": "00WR3", "g408s": "00WR3", "g411s": "00WR3", "g416s": "00WR3", "g417s": "00WR3", "g960s": "00WR3", "g990s": "00WR3", "index01": "00V53", "index02": "00V53", "mnpmag03": "00AI5", "mt20s": "00WR3", "mt34s": "00WR3", "p02d": "00WBO", "p02h": "00WBO", "paymnt08": "00H91", "pb28s": "00WR3", "pb34s": "00WR3", "re102s": "00WR3", "re28s": "00WR3", "re36s": "00WR3", "ret12": "00ASF", "rev12": "00ASF", "rev13": "00ASF", "rev14": "00ASF", "rev201": "00ASG", "rev202": "00ASG", "rev203": "00ASG", "rev223": "00ASG", "rev224": "00ASG", "rev225": "00ASG", "rev231": "00ASH", "rev232": "00ASH", "rev233": "00ASH", "rev252": "00ASH", "rev253": "00ASH", "rev321": "00ASI", "rev322": "00ASI", "rev54": "00ASF", "rev84": "00ASF", "rle904": "00ASJ", "rvlr75": "00WP4", "rvlr77": "00WP4", "s004s": "00WR3", "s114s": "00WR3", "st32s": "00WR3", "trv01": "00H87", "trv02": "00H87", "us21s": "00WR3", "us34s": "00WR3", "utlmag01": "00AI5", "utlmag02": "00AI5", "utlmag03": "00AI5", "utlmag04": "00AI5", "walshr02": "00H90", } SCORE_TO_CODE_MAP = { "evtg04": "001NN", "eads66": "00WDC" } def safe_get(d, *keys): """Attempts both snake_case and camelCase keys in a dict, handles None safely.""" if not isinstance(d, dict): return {} for key in keys: if key in d: return d[key] return {} def extract_model_variables(creditBureau: dict) -> dict: if not creditBureau: return {} variable_code_map = VARIABLE_TO_CODE_MAP score_code_map = SCORE_TO_CODE_MAP # Step 0: Extract application_id extracted = {} # Step 1: Locate add-on products with fallback casing credit_bureau = safe_get(creditBureau, "creditBureau", "credit_bureau") subject_node = safe_get( safe_get( safe_get(credit_bureau, "product"), "subject" ), "subject_record", "subjectRecord" ) add_ons = safe_get(subject_node, "add_on_product", "addOnProduct") value_map = {} # Step 2: Flatten values for product in add_ons if isinstance(add_ons, list) else []: code = product.get("code") score_model = safe_get(product, "score_model", "scoreModel") # 2a. Flatten characteristics (already done) characteristics = score_model.get("characteristic", []) for char in characteristics: if isinstance(char, dict) and "id" in char and "value" in char: key = char["id"].lower() value_map[(code, key)] = char["value"] # 2b. Also capture score result if present score = safe_get(score_model, "score") if score: # Capture score result results = score.get("results") if isinstance(results, str): value_map[(code, "score")] = results # Capture top 4 score factors as list of {code, rank} raw_factors = score.get("factors", {}).get("factor", []) if not isinstance(raw_factors, list): raw_factors = [] top_factors = [ {"code": f.get("code"), "rank": f.get("rank")} for f in raw_factors[:4] if isinstance(f, dict) and "code" in f and "rank" in f ] if top_factors: value_map[(code, "factors")] = top_factors # Step 3.a: Use variable_to_code_map to fetch final vars for var, code in variable_code_map.items(): extracted[var] = value_map.get((code, var)) # Step 3.b: Use score_to_code_map to fetch score vars for key, code in SCORE_TO_CODE_MAP.items(): value = value_map.get((code, "score")) if value: extracted[key] = value.lstrip("+") # Extract factor list, if available factor_list = value_map.get((code, "factors")) if factor_list: extracted[f"{key}_factors"] = factor_list return extracted if __name__ == "__main__": for filename in sys.argv[1:]: with open(filename) as f: data = json.load(f) print(f"\n--- Extracting from: {filename} ---") result = extract_model_variables(data) for k, v in result.items(): print(f"{k}: {v}")