medicafe 0.250728.9__py3-none-any.whl → 0.250805.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of medicafe might be problematic. Click here for more details.
- MediBot/MediBot.bat +233 -19
- MediBot/MediBot.py +138 -46
- MediBot/MediBot_Crosswalk_Library.py +127 -623
- MediBot/MediBot_Crosswalk_Utils.py +618 -0
- MediBot/MediBot_Preprocessor.py +72 -17
- MediBot/MediBot_Preprocessor_lib.py +470 -76
- MediBot/MediBot_UI.py +32 -17
- MediBot/MediBot_dataformat_library.py +68 -20
- MediBot/MediBot_docx_decoder.py +120 -19
- MediBot/MediBot_smart_import.py +180 -0
- MediBot/__init__.py +89 -0
- MediBot/get_medicafe_version.py +25 -0
- MediBot/update_json.py +35 -6
- MediBot/update_medicafe.py +19 -1
- MediCafe/MediLink_ConfigLoader.py +160 -0
- MediCafe/__init__.py +171 -0
- MediCafe/__main__.py +314 -0
- MediCafe/api_core.py +1098 -0
- MediCafe/api_core_backup.py +427 -0
- MediCafe/api_factory.py +306 -0
- MediCafe/api_utils.py +356 -0
- MediCafe/core_utils.py +450 -0
- MediCafe/graphql_utils.py +445 -0
- MediCafe/logging_config.py +123 -0
- MediCafe/logging_demo.py +61 -0
- MediCafe/migration_helpers.py +463 -0
- MediCafe/smart_import.py +436 -0
- MediLink/MediLink_837p_cob_library.py +28 -28
- MediLink/MediLink_837p_encoder.py +33 -34
- MediLink/MediLink_837p_encoder_library.py +226 -150
- MediLink/MediLink_837p_utilities.py +129 -5
- MediLink/MediLink_API_Generator.py +83 -60
- MediLink/MediLink_API_v3.py +1 -1
- MediLink/MediLink_ClaimStatus.py +177 -31
- MediLink/MediLink_DataMgmt.py +378 -63
- MediLink/MediLink_Decoder.py +20 -1
- MediLink/MediLink_Deductible.py +155 -28
- MediLink/MediLink_Display_Utils.py +72 -0
- MediLink/MediLink_Down.py +127 -5
- MediLink/MediLink_Gmail.py +720 -653
- MediLink/MediLink_PatientProcessor.py +257 -0
- MediLink/MediLink_UI.py +85 -71
- MediLink/MediLink_Up.py +28 -4
- MediLink/MediLink_insurance_utils.py +227 -230
- MediLink/MediLink_main.py +248 -0
- MediLink/MediLink_smart_import.py +264 -0
- MediLink/__init__.py +93 -1
- MediLink/insurance_type_integration_test.py +13 -3
- MediLink/test.py +1 -1
- MediLink/test_timing.py +59 -0
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.2.dist-info}/METADATA +1 -1
- medicafe-0.250805.2.dist-info/RECORD +81 -0
- medicafe-0.250805.2.dist-info/entry_points.txt +2 -0
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.2.dist-info}/top_level.txt +1 -0
- medicafe-0.250728.9.dist-info/RECORD +0 -59
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.2.dist-info}/LICENSE +0 -0
- {medicafe-0.250728.9.dist-info → medicafe-0.250805.2.dist-info}/WHEEL +0 -0
MediBot/MediBot_Preprocessor.py
CHANGED
|
@@ -1,32 +1,53 @@
|
|
|
1
1
|
#MediBot_Preprocessor.py
|
|
2
2
|
import os, re, sys, argparse
|
|
3
3
|
from collections import OrderedDict # so that the field_mapping stays in order.
|
|
4
|
-
import
|
|
4
|
+
import time # Added for timing instrumentation
|
|
5
5
|
|
|
6
6
|
# Add parent directory of the project to the Python path
|
|
7
7
|
project_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
8
8
|
sys.path.append(project_dir)
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
# Use core utilities for standardized imports
|
|
11
|
+
from MediCafe.core_utils import (
|
|
12
|
+
import_medibot_module,
|
|
13
|
+
get_config_loader_with_fallback
|
|
14
|
+
)
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
# Initialize configuration loader with fallback
|
|
17
|
+
MediLink_ConfigLoader = get_config_loader_with_fallback()
|
|
18
|
+
|
|
19
|
+
# Import MediBot modules using centralized import functions
|
|
20
|
+
MediBot_Crosswalk_Library = import_medibot_module('MediBot_Crosswalk_Library')
|
|
21
|
+
MediBot_Preprocessor_lib = import_medibot_module('MediBot_Preprocessor_lib')
|
|
22
|
+
|
|
23
|
+
# Initialize API client variables
|
|
24
|
+
get_api_client = None
|
|
19
25
|
|
|
20
26
|
try:
|
|
21
|
-
|
|
27
|
+
# Try to use the factory for enhanced features (circuit breakers, shared clients, etc.)
|
|
28
|
+
from MediCafe.api_factory import APIClientFactory
|
|
29
|
+
factory = APIClientFactory()
|
|
30
|
+
get_api_client = lambda: factory.get_shared_client() # Use shared client for token caching benefits
|
|
31
|
+
MediLink_ConfigLoader.log("MediBot_Preprocessor using API Factory with shared client", level="INFO")
|
|
22
32
|
except ImportError as e:
|
|
23
|
-
|
|
24
|
-
|
|
33
|
+
# Fallback to basic API client
|
|
34
|
+
try:
|
|
35
|
+
from MediCafe.core_utils import get_api_client
|
|
36
|
+
MediLink_ConfigLoader.log("MediBot_Preprocessor using fallback API client", level="WARNING")
|
|
37
|
+
except ImportError as e2:
|
|
38
|
+
# Make API client optional - don't log warning for now
|
|
39
|
+
get_api_client = None
|
|
40
|
+
|
|
41
|
+
# Configuration will be loaded when needed
|
|
42
|
+
_config_cache = None
|
|
43
|
+
_crosswalk_cache = None
|
|
25
44
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
45
|
+
def _get_config():
|
|
46
|
+
"""Get configuration, loading it if not already cached."""
|
|
47
|
+
global _config_cache, _crosswalk_cache
|
|
48
|
+
if _config_cache is None:
|
|
49
|
+
_config_cache, _crosswalk_cache = MediBot_Preprocessor_lib.get_cached_configuration()
|
|
50
|
+
return _config_cache, _crosswalk_cache
|
|
30
51
|
|
|
31
52
|
# CSV Preprocessor built for Carol
|
|
32
53
|
def preprocess_csv_data(csv_data, crosswalk):
|
|
@@ -43,8 +64,22 @@ def preprocess_csv_data(csv_data, crosswalk):
|
|
|
43
64
|
MediBot_Preprocessor_lib.filter_rows(csv_data)
|
|
44
65
|
|
|
45
66
|
# Convert 'Surgery Date' from string format to datetime objects for sorting purposes.
|
|
67
|
+
|
|
68
|
+
# TIMING: Start surgery date conversion timing (SLOW OPERATION)
|
|
69
|
+
date_start_time = time.time()
|
|
70
|
+
print("Starting surgery date conversion at: {}".format(time.strftime("%H:%M:%S")))
|
|
71
|
+
MediLink_ConfigLoader.log("Starting surgery date conversion at: {}".format(time.strftime("%H:%M:%S")), level="INFO")
|
|
72
|
+
|
|
46
73
|
MediBot_Preprocessor_lib.convert_surgery_date(csv_data)
|
|
47
74
|
|
|
75
|
+
# TIMING: End surgery date conversion timing
|
|
76
|
+
date_end_time = time.time()
|
|
77
|
+
date_duration = date_end_time - date_start_time
|
|
78
|
+
print("Surgery date conversion completed at: {} (Duration: {:.2f} seconds)".format(
|
|
79
|
+
time.strftime("%H:%M:%S"), date_duration))
|
|
80
|
+
MediLink_ConfigLoader.log("Surgery date conversion completed at: {} (Duration: {:.2f} seconds)".format(
|
|
81
|
+
time.strftime("%H:%M:%S"), date_duration), level="INFO")
|
|
82
|
+
|
|
48
83
|
# Update the CSV data to include only unique patient records.
|
|
49
84
|
# Re-sort the CSV data after deduplication to ensure the correct order.
|
|
50
85
|
# Sort the patients by 'Surgery Date' and then by 'Patient Last' name alphabetically.
|
|
@@ -71,8 +106,23 @@ def preprocess_csv_data(csv_data, crosswalk):
|
|
|
71
106
|
# Update the "Ins1 Insurance ID" column based on the crosswalk and the "Ins1 Payer ID" column for each row.
|
|
72
107
|
# If the Payer ID is not found in the crosswalk, create a placeholder entry in the crosswalk and mark the row for review.
|
|
73
108
|
MediLink_ConfigLoader.log("CSV Pre-processor: Populating 'Ins1 Insurance ID' based on Crosswalk...", level="INFO")
|
|
109
|
+
config, _ = _get_config()
|
|
110
|
+
|
|
111
|
+
# TIMING: Start insurance ID update timing (SLOWEST OPERATION)
|
|
112
|
+
insurance_start_time = time.time()
|
|
113
|
+
print("Starting insurance ID updates at: {}".format(time.strftime("%H:%M:%S")))
|
|
114
|
+
MediLink_ConfigLoader.log("Starting insurance ID updates at: {}".format(time.strftime("%H:%M:%S")), level="INFO")
|
|
115
|
+
|
|
74
116
|
MediBot_Preprocessor_lib.update_insurance_ids(csv_data, config, crosswalk)
|
|
75
117
|
|
|
118
|
+
# TIMING: End insurance ID update timing
|
|
119
|
+
insurance_end_time = time.time()
|
|
120
|
+
insurance_duration = insurance_end_time - insurance_start_time
|
|
121
|
+
print("Insurance ID updates completed at: {} (Duration: {:.2f} seconds)".format(
|
|
122
|
+
time.strftime("%H:%M:%S"), insurance_duration))
|
|
123
|
+
MediLink_ConfigLoader.log("Insurance ID updates completed at: {} (Duration: {:.2f} seconds)".format(
|
|
124
|
+
time.strftime("%H:%M:%S"), insurance_duration), level="INFO")
|
|
125
|
+
|
|
76
126
|
# Enrich the "Default Diagnosis #1" column based on the parsed docx for each row.
|
|
77
127
|
# This needs to handle the different patient dates correctly so we get the right diagnosis code assigned to the right patient on the right date of service.
|
|
78
128
|
# Currently, we've deleted all the second date entries for patients. As long as they exist in the system, they're just deleted.
|
|
@@ -124,6 +174,7 @@ def check_existing_patients(selected_patient_ids, MAPAT_MED_PATH):
|
|
|
124
174
|
def intake_scan(csv_headers, field_mapping):
|
|
125
175
|
identified_fields = OrderedDict()
|
|
126
176
|
missing_fields_warnings = []
|
|
177
|
+
config, _ = _get_config()
|
|
127
178
|
required_fields = config["required_fields"]
|
|
128
179
|
|
|
129
180
|
MediLink_ConfigLoader.log("Intake Scan - Field Mapping: {}".format(field_mapping), level="DEBUG")
|
|
@@ -209,7 +260,11 @@ def main():
|
|
|
209
260
|
|
|
210
261
|
# Initialize API client only when needed
|
|
211
262
|
if args.update_crosswalk or args.init_crosswalk:
|
|
212
|
-
|
|
263
|
+
if get_api_client is not None:
|
|
264
|
+
client = get_api_client()
|
|
265
|
+
else:
|
|
266
|
+
print("Error: No API client available")
|
|
267
|
+
client = None
|
|
213
268
|
|
|
214
269
|
if args.update_crosswalk:
|
|
215
270
|
print("Updating the crosswalk...")
|