2024-11-21 17:46:43 +00:00
import csv
import os
import sys
from collections import defaultdict
2024-10-28 23:39:36 +00:00
from datetime import datetime
2024-11-21 17:46:43 +00:00
2024-10-28 23:39:36 +00:00
import boto3
from botocore . config import Config
2024-11-14 16:35:33 +00:00
from dotenv import load_dotenv
# Please see the following confluence page for instructions on loading keys into your
# `.env`:
# https://aarete.atlassian.net/wiki/spaces/DoczyAI/pages/1283751954/Using+.env+for+AWS+keys
load_dotenv ( )
2024-11-13 17:08:19 +00:00
2024-11-21 17:46:43 +00:00
2024-11-01 18:52:15 +00:00
######################################## UTILS ###################################################
2024-12-17 16:34:59 +00:00
# def check_s3_bucket_exists(s3_client, bucket_name: str):
# try:
# s3_client.head_bucket(Bucket=bucket_name)
# print(f"{bucket_name} exists")
# except s3_client.exceptions.ClientError as e:
# error_code = e.response["Error"]["Code"]
# if error_code == "404":
# print(f"{bucket_name} does not exist")
# raise
# else:
# print(f"Error {error_code}")
# raise
# except Exception as e:
# raise
# return
from botocore . exceptions import NoCredentialsError
2025-01-06 15:39:29 +00:00
2024-11-01 18:52:15 +00:00
def check_s3_bucket_exists ( s3_client , bucket_name : str ) :
try :
s3_client . head_bucket ( Bucket = bucket_name )
print ( f " { bucket_name } exists " )
2024-12-17 16:34:59 +00:00
except NoCredentialsError :
print ( " AWS credentials not found " )
return False
2024-11-01 18:52:15 +00:00
except s3_client . exceptions . ClientError as e :
2024-11-13 17:08:19 +00:00
error_code = e . response [ " Error " ] [ " Code " ]
if error_code == " 404 " :
2024-11-01 18:52:15 +00:00
print ( f " { bucket_name } does not exist " )
raise
else :
print ( f " Error { error_code } " )
raise
except Exception as e :
raise
2024-12-17 16:34:59 +00:00
return True
2024-10-28 23:39:36 +00:00
2025-08-05 20:46:19 +00:00
2024-10-28 23:39:36 +00:00
######################################## GENERAL SETTINGS ########################################
TEST = False # True to run test prompt - just for testing model connection
TODAY = datetime . now ( ) . strftime ( " % Y % m %d " )
2025-09-24 15:56:27 +00:00
MAX_CONTEXT_LENGTH = 100000
2025-08-21 17:45:18 +00:00
######################################## TRACKING ########################################
2024-11-14 22:36:09 +00:00
2025-01-10 18:19:46 +00:00
UPLOAD_FREQUENCY = 10
2024-11-21 15:19:53 +00:00
2024-10-28 23:39:36 +00:00
######################################## SYSTEM ARGUMENTS ########################################
# read_mode, run_mode, input_dir, output_dir, consolidated_output_dir
2024-11-21 17:46:43 +00:00
def get_value_from_env ( key : str , default_value : str = None ) - > str :
value = os . getenv ( key , default_value )
2024-11-14 16:35:33 +00:00
if value is not None :
return value
2024-11-21 17:46:43 +00:00
raise KeyError ( f " { key } not found in .env file " )
2024-10-28 23:39:36 +00:00
def get_arg_value ( arg_name , default ) :
args = [ item for item in sys . argv if arg_name == item . split ( " = " ) [ 0 ] ]
if len ( args ) == 0 :
return default
elif len ( args ) == 1 :
return args [ 0 ] . split ( " = " ) [ 1 ]
else :
raise Exception ( f " Too many argument values: { args } " )
# Run config args
RUN_MODE = get_arg_value ( " run_mode " , " ec2 " ) # Valid: local or ec2
2024-11-13 17:08:19 +00:00
READ_MODE = get_arg_value ( " read_mode " , " s3 " ) # Valid: local or s3
2024-10-28 23:39:36 +00:00
BATCH_ID = get_arg_value ( " batch_id " , " test_batch " )
2025-08-29 14:38:15 +00:00
# Per-file logging settings (for debugging)
ENABLE_PER_FILE_LOGGING = get_arg_value ( " enable_per_file_logging " , " False " ) == " True "
PER_FILE_LOG_LEVEL = get_arg_value (
" per_file_log_level " , " DEBUG "
) . upper ( ) # DEBUG, INFO, WARNING, ERROR
PER_FILE_LOG_DIR = get_arg_value ( " per_file_log_dir " , " logs " )
2025-07-22 20:43:13 +00:00
ENABLE_RUNTIME_ROTATION = False # Set to True to enable multi-runtime failover
2024-10-28 23:39:36 +00:00
# Field args
2025-10-13 18:54:10 +00:00
FIELDS = get_arg_value ( " fields " , " all " ) # Valid: one_to_one, one_to_n, all
2025-01-27 19:39:23 +00:00
FIELD_JSON_PATH = " src/prompts/investment_prompts.json "
2024-10-28 23:39:36 +00:00
# Client-specific args
2025-03-24 21:05:01 +00:00
STATE = [ s . strip ( ) for s in get_arg_value ( " state " , " None " ) . upper ( ) . split ( " - " ) if s ]
2025-05-19 20:04:59 +00:00
CLIENT = [ s . strip ( ) for s in get_arg_value ( " client " , " None " ) . split ( " - " ) if s ]
2024-10-28 23:39:36 +00:00
# File IO args
LOCAL_PATH = get_arg_value (
" input_dir " , " data/test "
) # Valid: any valid path that contains txt files
S3_PREFIX = get_arg_value ( " s3_prefix " , " " )
S3_BUCKET = get_arg_value ( " s3_bucket " , " " )
OUTPUT_DIRECTORY = get_arg_value (
" output_dir " , " output_individual "
) # Valid: any valid directory
TRACKING_FILE = get_arg_value ( " tracking_file " , f " { BATCH_ID } _tracking.csv " )
2024-12-17 16:34:59 +00:00
WRITE_TO_S3 = get_arg_value ( " write_to_s3 " , " True " ) == " True "
2024-11-01 18:52:15 +00:00
S3_OUTPUT_BUCKET = get_arg_value ( " s3_output_bucket " , default = " doczy-output " )
2024-10-28 23:39:36 +00:00
# Filtering args
FILTER_ALREADY_PROCESSED = (
get_arg_value ( " filter " , False ) == " True "
) # Valid: True or False
# Multithreading args
MAX_WORKERS = int ( get_arg_value ( " max_workers " , 2 ) ) # Valid: any integer
2024-11-13 17:08:19 +00:00
# default false for the regex based IRS chunking
IRS_REGEX_CHECK = get_arg_value ( " irs_regex_check " , False ) == " True "
2025-08-05 20:46:19 +00:00
# QCQA args - only need to be set when running qa_qc.py INDEPENDENTLY, not needed for at-scale runs
2024-12-06 17:27:42 +00:00
AC_DF = get_arg_value ( " ac_df " , None )
B_DF = get_arg_value ( " b_df " , None )
DF_READ_MODE = get_arg_value ( " df_read_mode " , " s3 " )
2024-10-28 23:39:36 +00:00
2024-11-21 15:19:53 +00:00
######################################## FILE LOG ########################################
FILE_LOG_FIELDS = [
2025-08-05 20:46:19 +00:00
" filename " ,
" process_type " ,
" start_time " ,
" end_time " ,
" processing_time_seconds " ,
" delta_time_hours " ,
" status " ,
" error " ,
" memory_usage_mb " ,
" cpu_percent " ,
2024-11-21 15:19:53 +00:00
]
2025-08-05 20:46:19 +00:00
FILE_LOG_NAME = f " { BATCH_ID } _filelog.csv "
2024-11-21 15:19:53 +00:00
if not os . path . exists ( FILE_LOG_NAME ) :
2025-08-05 20:46:19 +00:00
with open ( FILE_LOG_NAME , " w " , newline = " " , encoding = " utf-8 " ) as f :
2024-11-21 15:19:53 +00:00
writer = csv . DictWriter ( f , fieldnames = FILE_LOG_FIELDS )
writer . writeheader ( )
2024-10-28 23:39:36 +00:00
######################################## CLIENT SETTINGS ########################################
2025-01-30 16:30:59 +00:00
CLIENT_NAME = get_arg_value ( " client_name " , " Test-Client " )
2024-10-28 23:39:36 +00:00
PROV_TYPE = None
######################################## I/O SETTINGS ########################################
CONSOLIDATED_OUTPUT_DIRECTORY = " output_consolidated "
REPORTING_OUTPUT_DIRECTORY = " output_reports "
UNPROCESSED_RESULTS_NAME = f " { BATCH_ID } -B-Unprocessed.csv "
AC_RESULTS_NAME = f " { BATCH_ID } -AC.csv "
B_RESULTS_NAME = f " { BATCH_ID } -B.csv "
TABLE_ANALYSIS_NAME = f " { BATCH_ID } -Table-Analysis.csv "
######################################## AWS SETTINGS #########################################
2024-11-27 15:08:04 +00:00
# RUN_MODE = "local" # for testing purposes only
2024-10-28 23:39:36 +00:00
# Bedrock
if RUN_MODE == " local " :
2024-11-21 17:46:43 +00:00
AWS_ACCESS_KEY_ID = get_value_from_env ( " AWS_ACCESS_KEY_ID " )
AWS_SECRET_ACCESS_KEY = get_value_from_env ( " AWS_SECRET_ACCESS_KEY " )
AWS_SESSION_TOKEN = get_value_from_env ( " AWS_SESSION_TOKEN " )
2024-11-14 16:35:33 +00:00
2024-11-21 17:46:43 +00:00
# Bedrock
2024-10-28 23:39:36 +00:00
config = Config ( read_timeout = 2000 )
BEDROCK_RUNTIME = boto3 . client (
service_name = " bedrock-runtime " ,
region_name = " us-east-1 " ,
aws_access_key_id = AWS_ACCESS_KEY_ID ,
aws_secret_access_key = AWS_SECRET_ACCESS_KEY ,
aws_session_token = AWS_SESSION_TOKEN ,
config = config ,
)
2024-11-21 17:46:43 +00:00
# S3
S3_CLIENT = boto3 . client (
" s3 " ,
region_name = " us-east-2 " ,
aws_access_key_id = AWS_ACCESS_KEY_ID ,
aws_secret_access_key = AWS_SECRET_ACCESS_KEY ,
aws_session_token = AWS_SESSION_TOKEN ,
)
2024-10-28 23:39:36 +00:00
elif RUN_MODE == " ec2 " :
2024-11-21 17:46:43 +00:00
# Bedrock
2025-08-05 20:46:19 +00:00
config = Config (
read_timeout = 4000 , max_pool_connections = 60
) # Doubled read_timeout to 4000
2024-10-28 23:39:36 +00:00
BEDROCK_RUNTIME = boto3 . client (
service_name = " bedrock-runtime " , region_name = " us-east-1 " , config = config
)
# S3
S3_CLIENT = boto3 . client ( " s3 " , region_name = " us-east-2 " )
2024-11-01 18:52:15 +00:00
# Check that S3_OUTPUT_BUCKET exists and raise an error if not
if WRITE_TO_S3 :
check_s3_bucket_exists ( S3_CLIENT , S3_OUTPUT_BUCKET )
2024-10-28 23:39:36 +00:00
# Claude model IDs
MODEL_ID_CLAUDE3_HAIKU = " anthropic.claude-3-haiku-20240307-v1:0 "
MODEL_ID_CLAUDE35_SONNET = " anthropic.claude-3-5-sonnet-20240620-v1:0 "
MODEL_ID_CLAUDE2 = " anthropic.claude-instant-v1 "
2025-05-07 18:21:09 +00:00
MODEL_ID_CLAUDE35_SONNET_V2 = " anthropic.claude-3-5-sonnet-20241022-v2:0 "
2025-10-22 16:46:28 +00:00
MODEL_ID_CLAUDE37_SONNET = " us.anthropic.claude-3-7-sonnet-20250219-v1:0 "
2025-07-18 19:00:09 +00:00
MODEL_ID_CLAUDE4_SONNET = " us.anthropic.claude-sonnet-4-20250514-v1:0 "
2025-10-22 16:46:28 +00:00
MODEL_ID_CLAUDE45_SONNET = " us.anthropic.claude-sonnet-4-5-20250929-v1:0 "
2025-07-18 19:00:09 +00:00
# Model aliases for easy upgrades
MODEL_ALIASES = {
2025-10-22 16:46:28 +00:00
" sonnet_37 " : MODEL_ID_CLAUDE37_SONNET ,
" sonnet_4 " : MODEL_ID_CLAUDE4_SONNET ,
" sonnet_45 " : MODEL_ID_CLAUDE45_SONNET ,
2025-07-18 19:00:09 +00:00
" sonnet_latest " : MODEL_ID_CLAUDE4_SONNET ,
" haiku_latest " : MODEL_ID_CLAUDE3_HAIKU ,
" legacy_sonnet " : MODEL_ID_CLAUDE35_SONNET ,
}
2025-08-05 20:46:19 +00:00
2025-07-18 19:00:09 +00:00
def resolve_model_id ( model_identifier : str ) - > str :
"""
Resolve a model identifier to its actual model ID.
Supports both direct model IDs and aliases.
"""
return MODEL_ALIASES . get ( model_identifier , model_identifier )
2024-10-28 23:39:36 +00:00
2025-08-05 20:46:19 +00:00
2024-10-28 23:39:36 +00:00
######################################## CLAUDE AND PROMPT TRACKING ########################################
ENABLE_ANSWER_TRACKING = False
ANSWER_TRACKING_DICT = { }
######################################## POSTPROCESSING SETTINGS ########################################
FUZZY_MATCH_THRESHOLD = 0.8
2025-08-05 20:46:19 +00:00
FILE_NAME_COLUMN = " Contract Name "
2024-12-13 19:23:04 +00:00
BLANKS_THRESHOLD = 0.5
2024-10-28 23:39:36 +00:00
######################################## COMPLEX FLAG SETTINGS ########################################
COMPLEX_MAX_WORKERS = 50
RATE_THRESHOLD = 10
TABLE_THRESHOLD = 2
COMPLEX_OUTPUT_PATH = " complex_flag_output "
COMPLEX_OUTPUT_FILENAME = f " { TODAY } _complex_flag_test.csv "
2025-06-20 19:46:23 +00:00
TABLE_ROW_LIMIT = 10
2024-10-28 23:39:36 +00:00
######################################## EC2 ########################################
MODEL_STATS = defaultdict (
lambda : {
" requests " : 0 ,
" tokens_sent " : 0 ,
" tokens_received " : 0 ,
" total_time " : 0 ,
" claude2_requests " : 0 ,
" claude3_requests " : 0 ,
" claude35_requests " : 0 ,
}
)
GLOBAL_STATS = {
" total_requests " : 0 ,
" total_tokens_sent " : 0 ,
" total_tokens_received " : 0 ,
" total_time " : 0 ,
" total_claude2_requests " : 0 ,
" total_claude3_requests " : 0 ,
" total_claude35_requests " : 0 ,
}
def assume_role_and_get_runtime ( account_id , role_name ) :
sts_client = boto3 . client ( " sts " )
role_arn = f " arn:aws:iam:: { account_id } :role/ { role_name } "
assumed_role = sts_client . assume_role (
RoleArn = role_arn , RoleSessionName = f " UATLambdaSession "
)
credentials = assumed_role [ " Credentials " ]
runtime = boto3 . client (
service_name = " bedrock-runtime " ,
region_name = " us-east-1 " ,
aws_access_key_id = credentials [ " AccessKeyId " ] ,
aws_secret_access_key = credentials [ " SecretAccessKey " ] ,
aws_session_token = credentials [ " SessionToken " ] ,
config = config ,
)
return runtime
2024-11-21 17:46:43 +00:00
2024-10-28 23:39:36 +00:00
dev_account_id = " 660131068782 "
dev_role_name = " doczy-dev-bedrock-lambda-role "
prod_account_id = " 211125720533 "
prod_role_name = " doczy-prod-bedrock-lambda-role "
2025-05-07 18:21:09 +00:00
2025-08-05 20:46:19 +00:00
############## S3 BUCKETS FOR PDF FILES ##############
DOCZY_PDF_FILES_BUCKET_NAME = " doczy-pdf-files " # sample bucket name added. we can either use this or create a new one
DOCZY_PDF_FILES_BUCKET_S3_URL = f " https:// { DOCZY_PDF_FILES_BUCKET_NAME } .s3.us-east-2.amazonaws.com/ " # sample s3 url added. we can either use this or create a new one
2025-05-07 18:21:09 +00:00
############## VISION API SETTINGS ##############
2025-08-05 20:46:19 +00:00
ENABLE_VISION = get_arg_value ( " enable_vision " , " False " ) == " True " # False by default