Merged in feature/field_type_config (pull request #731)

Feature/field type config

* Added field type procesing conditional logic

* Updated field type naming convention in config.py; Updated date_postprocessing to avoid column key missing issue

* Cleaned up code; Move merging functionality to one to one processing block

* Merged main into feature/field_type_config


Approved-by: Katon Minhas
This commit is contained in:
Sha Brown
2025-10-13 18:54:10 +00:00
committed by Katon Minhas
parent a7090c8327
commit c56270c951
3 changed files with 75 additions and 46 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ PER_FILE_LOG_DIR = get_arg_value("per_file_log_dir", "logs")
ENABLE_RUNTIME_ROTATION = False # Set to True to enable multi-runtime failover ENABLE_RUNTIME_ROTATION = False # Set to True to enable multi-runtime failover
# Field args # Field args
FIELDS = get_arg_value("fields", "abc") # Valid: ac, b, abc FIELDS = get_arg_value("fields", "all") # Valid: one_to_one, one_to_n, all
FIELD_JSON_PATH = "src/prompts/investment_prompts.json" FIELD_JSON_PATH = "src/prompts/investment_prompts.json"
# Client-specific args # Client-specific args
@@ -36,49 +36,71 @@ def process_file(file_object, constants: Constants, run_timestamp):
text_dict = preprocess.clean_tables( text_dict = preprocess.clean_tables(
text_dict, constants.EXHIBIT_HEADER_MARKERS, filename text_dict, constants.EXHIBIT_HEADER_MARKERS, filename
) )
exhibit_dict, all_exhibit_headers = preprocess.one_to_n_exhibit_chunking(
text_dict, constants.EXHIBIT_HEADER_MARKERS, filename
)
logging.info(f"{datetime_str()} Preprocessing Complete - {filename}")
################## ONE TO N ################## # Set default values
if string_utils.contains_reimbursement(contract_text): dynamic_one_to_one_fields = FieldSet()
one_to_n_results, dynamic_one_to_one_fields = run_one_to_n_prompts(
filename, exhibit_dict, all_exhibit_headers, constants process_one_to_n = config.FIELDS in ['all', 'one_to_n']
) # Return df process_one_to_one = config.FIELDS in ['all', 'one_to_one']
one_to_n_results["FILE_NAME"] = filename
one_to_n_results = postprocessing_funcs.generate_reimb_ids( # Initialize default fallback for final results
one_to_n_results final_results = pd.DataFrame([{"FILE_NAME": filename}])
) # Add reimb_id
logging.info(f"{datetime_str()} One to N Complete - {filename}") # ONE TO N PROCESSING
if process_one_to_n:
exhibit_dict, all_exhibit_headers = preprocess.one_to_n_exhibit_chunking(
text_dict, constants.EXHIBIT_HEADER_MARKERS, filename
)
logging.info(f"{datetime_str()} Preprocessing Complete - {filename}")
one_to_n_results = pd.DataFrame([{"FILE_NAME": filename}]) # Initialize here
if string_utils.contains_reimbursement(contract_text):
one_to_n_results, dynamic_one_to_one_fields = run_one_to_n_prompts(
filename, exhibit_dict, all_exhibit_headers, constants
)
one_to_n_results["FILE_NAME"] = filename
one_to_n_results = postprocessing_funcs.generate_reimb_ids(one_to_n_results)
logging.info(f"{datetime_str()} One to N Complete - {filename}")
else:
logging.info(f"{datetime_str()} No Reimbursement Found, Skipping - {filename}")
final_results = one_to_n_results # Set as final results
else: else:
one_to_n_results = pd.DataFrame([{"FILE_NAME": filename}]) logging.info(f"{datetime_str()} Fields not configured for One to N, Skipping - {filename}")
dynamic_one_to_one_fields = FieldSet()
logging.info(f"{datetime_str()} No One to N Found, Skipping - {filename}")
################## ONE TO ONE ################## # ONE TO ONE PROCESSING
one_to_one_results = run_one_to_one_prompts( if process_one_to_one:
filename, one_to_one_results = run_one_to_one_prompts(
contract_text, filename,
text_dict, contract_text,
top_sheet_dict, text_dict,
dynamic_one_to_one_fields, top_sheet_dict,
constants, dynamic_one_to_one_fields,
) # Return dict constants,
one_to_one_results["FILE_NAME"] = filename )
logging.info(f"{datetime_str()} One to One Complete - {filename}") one_to_one_results["FILE_NAME"] = filename
logging.info(f"{datetime_str()} One to One Complete - {filename}")
# Decide how to handle one_to_one results
if process_one_to_n:
# BOTH processed - merge into one_to_n
final_results = row_funcs.merge_one_to_one_into_one_to_n(
one_to_n_results, one_to_one_results, constants
)
else:
# ONLY one_to_one processed - convert dict to DataFrame
final_results = pd.DataFrame([one_to_one_results])
else:
logging.info(f"{datetime_str()} Fields not configured for One to One, Skipping - {filename}")
################## MERGE ################## # APPLY CODES IF ONE_TO_N WAS PROCESSED
merged_results = row_funcs.merge_one_to_one_into_one_to_n( if process_one_to_n:
one_to_n_results, one_to_one_results, constants results_with_code = code_funcs.code_breakout(final_results, constants)
) final_results = code_funcs.grouper_breakout(results_with_code)
logging.info(f"{datetime_str()} Codes Complete - {filename}")
################## CODES ################## # POSTPROCESS
results_with_code = code_funcs.code_breakout(merged_results, constants)
final_results = code_funcs.grouper_breakout(results_with_code)
logging.info(f"{datetime_str()} Codes Complete - {filename}")
################## POSTPROCESS ##################
final_df = postprocess.postprocess(final_results, constants) final_df = postprocess.postprocess(final_results, constants)
logging.info(f"{datetime_str()} Postprocessing Complete - {filename}") logging.info(f"{datetime_str()} Postprocessing Complete - {filename}")
@@ -173,14 +173,21 @@ def date_postprocess(df, field_json_path):
if field.field_name in df.columns: if field.field_name in df.columns:
df[field.field_name] = list(map(date_postprocessing, df[field.field_name])) df[field.field_name] = list(map(date_postprocessing, df[field.field_name]))
# Derived termination date # Check if required columns exist when creating "AARETE_DERIVED_TERMINATION_DT"
df["AARETE_DERIVED_TERMINATION_DT"] = list( # Avoid error in "one_to_n" processing
map( required_cols = ["AARETE_DERIVED_EFFECTIVE_DT", "TERMINATION_DT"]
invoke_derived_term_date, if all(col in df.columns for col in required_cols):
df["AARETE_DERIVED_EFFECTIVE_DT"], df["AARETE_DERIVED_TERMINATION_DT"] = list(
df["TERMINATION_DT"], map(
invoke_derived_term_date,
df["AARETE_DERIVED_EFFECTIVE_DT"],
df["TERMINATION_DT"],
)
) )
) else:
missing = [col for col in required_cols if col not in df.columns]
logging.info(f"Skipping AARETE_DERIVED_TERMINATION_DT creation. Missing: {missing}")
df["AARETE_DERIVED_TERMINATION_DT"] = pd.NA
return df return df