Files
doczyai-pipelines/archive/ops_scripts/generic/excel_s3_diff.py
T
Katon Minhas afb6d5185d Merged in feature/lesser-table-caching-refactor-hybrid (pull request #847)
Feature/lesser table caching refactor hybrid

* chore: Remove unused duplicate main.py from shared pipeline

* fix: Correct crosswalk paths in aarete_derived.py

* chore: Remove unused documentation files from fieldExtraction

* docs: Add documentation files to documentation folder

* docs: Update README with uv setup, expanded project structure, and branching conventions

* docs: Add uv installation steps with Ubuntu/WSL emphasis

* Enable prompt caching for all remaining LLM calls

- Add _INSTRUCTION() functions for: EXHIBIT_HEADER, EXHIBIT_LINKAGE,
  EXHIBIT_TITLE_MATCH, DATE_FIX, DERIVED_TERM_DATE, CHECK_PROVIDER_NAME_MATCH,
  SPECIAL_CASE_ASSIGNMENT
- Update all invoke_claude() calls in saas and clover pipelines to use
  cache=True with corresponding _INSTRUCTION() functions
- Add new instructions to get_cacheable_instructions() for cache warming
- Update tests for new instruction functions

Functions now using caching:
- prompt_exhibit_level
- prompt_exhibit_lesser (EXHIBIT_LEVEL_LESSER_OF)
- prompt_fee_schedule_breakout
- prompt_grouper_breakout
- prompt_special_case_assignment
- prompt_exhibit_linkage
- prompt_exhibit_header
- prompt_smart_chunked (ONE_TO_ONE templates)
- prompt_date_fix
- prompt_derived_term_date
- prompt_exhibit_title_match
- provider_name_match_check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Reorder

* feat: Add bcbs_promise client pipeline with OFFSET_TERM extraction

- Add new bcbs_promise client with HSC-based OFFSET_TERM field extraction
- Extract full paragraph text of offset/recoupment provisions from contracts
- Derive OFFSET_INDICATOR (Y/N) from OFFSET_TERM presence
- Fix reorder_columns to preserve extra columns not in COLUMN_ORDER
- Update QC/QA output path to outputs/qc_qa/

* fix: Update dev deps and test assertions for QC/QA output path

- Add pytest/pytest-mock to dev dependencies for mypy type checking
- Update test assertions to expect outputs/qc_qa instead of qa_qc_output

* style: Apply black formatting to prompt_templates.py

* Merge main, move scripts

* Archive some scripts

* update py version

* remove .py version file

* Remove ASCII characters

* Restore testbed code

* restore tracking

* Update testbed metrics

* Enable prompt caching for CODE_LAST_CHECK, FILL_BILL_TYPE, DUAL_LOB_CHECK, and GROUPER_BREAKOUT

- Add CODE_LAST_CHECK_INSTRUCTION() for service specificity classification
- Add FILL_BILL_TYPE_INSTRUCTION() for bill type code determination
- Add DUAL_LOB_CHECK_INSTRUCTION() for Medicare/Medicaid classification
- Update code_funcs.py to use caching for CODE_LAST_CHECK, FILL_BILL_TYPE, GROUPER_BREAKOUT
- Update postprocessing_funcs.py to use caching for DUAL_LOB_CHECK
- Add new instructions to get_cacheable_instructions() for cache warming
- Add unit tests for new instruction functions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix postprocessing_funcs to remove invalid columns

* Merge branch 'main' into feature/lesser-table-caching-refactor-hybrid

* Revert prompt caching changes from aed1b73c

* update formatting

* Update imports


Approved-by: Sha Brown
Approved-by: Praneel Panchigar
2026-01-26 16:52:55 +00:00

84 lines
4.1 KiB
Python

import boto3
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
import os
import math
import csv
"""
This scirpt compares the file names in an Excel file (Batch excel files that MCS usually provides) with the file names in an S3 bucket.
The Excel file must contain a column with the file names to search for.
This is used mainly to find files that are missing in the batch staging files and cannot be located in the s3 bucket.
The output of this script can be then used with t_drive_search.py to find the missing files in the T drive.
Note: This script outputs both a CSV and an Excel file with the missing files and encoding issues.
We use the output excel file with the tdrive search script to find the missing files in the T drive.
"""
# Function to list S3 objects and normalize the filenames
def list_s3_files(bucket_name, prefix, s3_client):
normalized_s3_files = []
paginator = s3_client.get_paginator('list_objects_v2')
for page in paginator.paginate(Bucket=bucket_name, Prefix=prefix):
if 'Contents' in page:
for obj in page['Contents']:
key = obj['Key']
# Extract and normalize the filename (remove prefix and extension)
# filename = key.split('/')[-1] # Take the file name from the key
filename = os.path.basename(key) # Remove any directory path
if len(filename) > 4:
normalized_filename = filename[:-4] # Remove the last 4 characters (file extension)
normalized_s3_files.append(normalized_filename)
return set(normalized_s3_files)
# Main function for processing
def find_missing_files(input_excel, bucket_name, prefix, output_csv, max_workers=10):
# Initialize boto3 session and S3 client
session = boto3.Session(profile_name='doczy_uat')
s3_client = session.client('s3')
# Read the Excel file with header=1
excel_df = pd.read_excel(input_excel, header=1, sheet_name='Sheet1')
excel_filenames = excel_df['File Name'] # Remove extensions if present
excel_filenames_set = set(excel_filenames)
# Get the normalized S3 filenames
normalized_s3_files = list_s3_files(bucket_name, prefix, s3_client)
# Find files that are in Excel but not in S3
missing_files = excel_filenames_set - normalized_s3_files
print(f"Type of missing_files: {type(missing_files)}")
print(f"Type of normalized_files: {type(normalized_s3_files)}")
print(f"Type of excel_filenames_set: {type(excel_filenames_set)}")
# Identify files that may have encoding differences, ensuring only strings are processed
missing_files_list = [file for file in missing_files if isinstance(file, str) and not (isinstance(file, float) and math.isnan(file))]
non_encoded_issues = [file for file in missing_files_list if all(ord(char) < 128 for char in file)]
output_df = pd.DataFrame({
'Missing File Name': missing_files_list,
'Encoding Check': ['No Encoding Issue' if file in non_encoded_issues else 'Encoding Issue' for file in missing_files_list]
})
output_df.to_csv(output_csv, index=False, encoding='utf-8', quoting=csv.QUOTE_ALL)
# Saving output as excel file
output_df.to_excel(output_csv[:-4] + '.xlsx', index=False)
# Write the missing files and non-encoded issue files to the output CSV
# with open(output_csv, mode='w', newline='', encoding='utf-8') as csvfile:
# csvfile.write('Missing File Name,Encoding Check\n')
# for file in missing_files_list:
# encoding_status = 'No Encoding Issue' if file in non_encoded_issues else 'Encoding Issue'
# csvfile.write(f"{file},{encoding_status}\n")
if __name__ == "__main__":
input_excel = 'C:\\Doczy\\National contracting\\Allbatches\\batch_files\\updated_batches_102424\\first_batch\\Batch 14_10222024.xlsx' # Path to your input Excel file
bucket_name = 'centene-national-contracting-files' # Your S3 bucket name
prefix = 'batch_14_priority_files/TXT_FILES/' # Your S3 prefix
output_csv = 'C:\\Doczy\\National contracting\\Allbatches\\diff_batch14_2.csv' # This will also save as xls
find_missing_files(input_excel, bucket_name, prefix, output_csv)