211 lines
5.5 KiB
Python
211 lines
5.5 KiB
Python
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}")
|