medicafe 0.240419.2__py3-none-any.whl → 0.240613.0__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 +174 -38
- MediBot/MediBot.py +80 -77
- MediBot/MediBot_Charges.py +0 -28
- MediBot/MediBot_Crosswalk_Library.py +281 -0
- MediBot/MediBot_Post.py +0 -0
- MediBot/MediBot_Preprocessor.py +138 -211
- MediBot/MediBot_Preprocessor_lib.py +496 -0
- MediBot/MediBot_UI.py +80 -35
- MediBot/MediBot_dataformat_library.py +79 -35
- MediBot/MediBot_docx_decoder.py +295 -0
- MediBot/update_medicafe.py +46 -8
- MediLink/MediLink.py +207 -108
- MediLink/MediLink_837p_encoder.py +299 -214
- MediLink/MediLink_837p_encoder_library.py +445 -245
- MediLink/MediLink_API_v2.py +174 -0
- MediLink/MediLink_APIs.py +139 -0
- MediLink/MediLink_ConfigLoader.py +44 -32
- MediLink/MediLink_DataMgmt.py +297 -89
- MediLink/MediLink_Decoder.py +63 -0
- MediLink/MediLink_Down.py +73 -102
- MediLink/MediLink_ERA_decoder.py +4 -4
- MediLink/MediLink_Gmail.py +479 -4
- MediLink/MediLink_Mailer.py +0 -0
- MediLink/MediLink_Parser.py +111 -0
- MediLink/MediLink_Scan.py +0 -0
- MediLink/MediLink_Scheduler.py +2 -131
- MediLink/MediLink_StatusCheck.py +0 -4
- MediLink/MediLink_UI.py +87 -27
- MediLink/MediLink_Up.py +301 -45
- MediLink/MediLink_batch.bat +1 -1
- MediLink/test.py +74 -0
- medicafe-0.240613.0.dist-info/METADATA +55 -0
- medicafe-0.240613.0.dist-info/RECORD +43 -0
- {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/WHEEL +5 -5
- medicafe-0.240419.2.dist-info/METADATA +0 -19
- medicafe-0.240419.2.dist-info/RECORD +0 -32
- {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/LICENSE +0 -0
- {medicafe-0.240419.2.dist-info → medicafe-0.240613.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import requests
|
|
3
|
+
|
|
4
|
+
# Importing configuration loader
|
|
5
|
+
try:
|
|
6
|
+
from MediLink import MediLink_ConfigLoader
|
|
7
|
+
except ImportError:
|
|
8
|
+
import MediLink_ConfigLoader
|
|
9
|
+
|
|
10
|
+
# Class for handling API calls
|
|
11
|
+
class APIClient:
|
|
12
|
+
def __init__(self):
|
|
13
|
+
# Load configuration
|
|
14
|
+
self.config, _ = MediLink_ConfigLoader.load_configuration()
|
|
15
|
+
# Initialize token cache
|
|
16
|
+
self.token_cache = {}
|
|
17
|
+
|
|
18
|
+
# Method to get access token
|
|
19
|
+
def get_access_token(self, endpoint_name):
|
|
20
|
+
# Retrieve endpoint configuration
|
|
21
|
+
endpoint_config = self.config['MediLink_Config']['endpoints'][endpoint_name]
|
|
22
|
+
current_time = time.time()
|
|
23
|
+
|
|
24
|
+
# Check if token is cached and still valid
|
|
25
|
+
if endpoint_name in self.token_cache:
|
|
26
|
+
cached_token = self.token_cache[endpoint_name]
|
|
27
|
+
if cached_token['expires_at'] > current_time:
|
|
28
|
+
return cached_token['access_token']
|
|
29
|
+
|
|
30
|
+
# Prepare data for token request
|
|
31
|
+
data = {
|
|
32
|
+
'grant_type': 'client_credentials',
|
|
33
|
+
'client_id': endpoint_config['client_id'],
|
|
34
|
+
'client_secret': endpoint_config['client_secret'],
|
|
35
|
+
'scope': 'hipaa'
|
|
36
|
+
}
|
|
37
|
+
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
|
|
38
|
+
|
|
39
|
+
# Request token
|
|
40
|
+
response = requests.post(endpoint_config['token_url'], headers=headers, data=data)
|
|
41
|
+
response.raise_for_status()
|
|
42
|
+
token_data = response.json()
|
|
43
|
+
access_token = token_data['access_token']
|
|
44
|
+
expires_in = token_data.get('expires_in', 3600)
|
|
45
|
+
|
|
46
|
+
# Cache token with expiration time adjusted
|
|
47
|
+
self.token_cache[endpoint_name] = {
|
|
48
|
+
'access_token': access_token,
|
|
49
|
+
'expires_at': current_time + expires_in - 120
|
|
50
|
+
}
|
|
51
|
+
return access_token
|
|
52
|
+
|
|
53
|
+
# Method for making API calls
|
|
54
|
+
def make_api_call(self, endpoint_name, call_type, url_extension="", params=None, data=None):
|
|
55
|
+
# Retrieve endpoint configuration
|
|
56
|
+
endpoint_config = self.config['MediLink_Config']['endpoints'][endpoint_name]
|
|
57
|
+
# Get access token
|
|
58
|
+
token = self.get_access_token(endpoint_name)
|
|
59
|
+
headers = {'Authorization': 'Bearer {}'.format(token), 'Accept': 'application/json'}
|
|
60
|
+
|
|
61
|
+
# Construct full URL
|
|
62
|
+
url = endpoint_config['api_url'] + url_extension
|
|
63
|
+
|
|
64
|
+
# Make appropriate type of call
|
|
65
|
+
if call_type == 'GET':
|
|
66
|
+
response = requests.get(url, headers=headers, params=params)
|
|
67
|
+
elif call_type == 'POST':
|
|
68
|
+
headers['Content-Type'] = 'application/json'
|
|
69
|
+
response = requests.post(url, headers=headers, json=data)
|
|
70
|
+
elif call_type == 'DELETE':
|
|
71
|
+
response = requests.delete(url, headers=headers)
|
|
72
|
+
else:
|
|
73
|
+
raise ValueError("Unsupported call type")
|
|
74
|
+
|
|
75
|
+
if response.status_code >= 400:
|
|
76
|
+
print("Error {}: {}".format(response.status_code, response.text))
|
|
77
|
+
response.raise_for_status()
|
|
78
|
+
|
|
79
|
+
return response.json()
|
|
80
|
+
|
|
81
|
+
# Method for creating coverage
|
|
82
|
+
def create_coverage(self, endpoint_name, patient_info):
|
|
83
|
+
return self.make_api_call(endpoint_name, 'POST', url_extension="/coverages", data=patient_info)
|
|
84
|
+
|
|
85
|
+
# Method for getting all coverages
|
|
86
|
+
def get_coverages(self, endpoint_name, params=None):
|
|
87
|
+
return self.make_api_call(endpoint_name, 'GET', url_extension="/coverages", params=params)
|
|
88
|
+
|
|
89
|
+
# Method for getting coverage by ID
|
|
90
|
+
def get_coverage_by_id(self, endpoint_name, coverage_id):
|
|
91
|
+
return self.make_api_call(endpoint_name, 'GET', url_extension="/coverages/{}".format(coverage_id))
|
|
92
|
+
|
|
93
|
+
# Method for deleting coverage by ID
|
|
94
|
+
def delete_coverage_by_id(self, endpoint_name, coverage_id):
|
|
95
|
+
return self.make_api_call(endpoint_name, 'DELETE', url_extension="/coverages/{}".format(coverage_id))
|
|
96
|
+
|
|
97
|
+
# Method for getting payer list
|
|
98
|
+
def get_payer_list(self, endpoint_name, params=None):
|
|
99
|
+
return self.make_api_call(endpoint_name, 'GET', url_extension="/availity-payer-list", params=params)
|
|
100
|
+
|
|
101
|
+
# Function to fetch payer name from API
|
|
102
|
+
def fetch_payer_name_from_api(payer_id, config, primary_endpoint='AVAILITY'):
|
|
103
|
+
client = APIClient()
|
|
104
|
+
|
|
105
|
+
# Step 1: Reload configuration for safety (This should be able to be replaced by APIClient())
|
|
106
|
+
config, _ = MediLink_ConfigLoader.load_configuration()
|
|
107
|
+
|
|
108
|
+
# Step 2: Check if the primary endpoint is specified and is valid
|
|
109
|
+
# (these validity checks will need to be incorporated into the main functionality)
|
|
110
|
+
endpoints = config['MediLink_Config']['endpoints']
|
|
111
|
+
if primary_endpoint and primary_endpoint in endpoints:
|
|
112
|
+
endpoint_order = [primary_endpoint] + [endpoint for endpoint in endpoints if endpoint != primary_endpoint]
|
|
113
|
+
else:
|
|
114
|
+
endpoint_order = list(endpoints.keys())
|
|
115
|
+
|
|
116
|
+
# Step 3: Iterate through available endpoints in specified order
|
|
117
|
+
for endpoint_name in endpoint_order:
|
|
118
|
+
endpoint_config = endpoints[endpoint_name]
|
|
119
|
+
if not all(key in endpoint_config for key in ['token_url', 'client_id', 'client_secret']):
|
|
120
|
+
MediLink_ConfigLoader.log("Skipping {} due to missing API keys.".format(endpoint_name), config, level="WARNING")
|
|
121
|
+
continue
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
response = client.get_payer_list(endpoint_name, params={'payerId': payer_id})
|
|
125
|
+
if 'payers' in response and response['payers']:
|
|
126
|
+
payer = response['payers'][0]
|
|
127
|
+
payer_name = payer.get('displayName') or payer.get('name')
|
|
128
|
+
|
|
129
|
+
MediLink_ConfigLoader.log("Successfully found payer at {} for ID {}: {}".format(endpoint_name, payer_id, payer_name), config, level="INFO")
|
|
130
|
+
return payer_name
|
|
131
|
+
else:
|
|
132
|
+
MediLink_ConfigLoader.log("No payer found at {} for ID: {}. Trying next available endpoint.".format(endpoint_name, payer_id), config, level="INFO")
|
|
133
|
+
except requests.RequestException as e:
|
|
134
|
+
MediLink_ConfigLoader.log("API call failed at {} for Payer ID '{}': {}".format(endpoint_name, payer_id, str(e)), config, level="ERROR")
|
|
135
|
+
|
|
136
|
+
error_message = "All endpoints exhausted for Payer ID {}.".format(payer_id)
|
|
137
|
+
MediLink_ConfigLoader.log(error_message, config, level="CRITICAL")
|
|
138
|
+
raise ValueError(error_message)
|
|
139
|
+
|
|
140
|
+
# Example usage
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
client = APIClient()
|
|
143
|
+
try:
|
|
144
|
+
# Fetch and print payer name
|
|
145
|
+
payer_name = fetch_payer_name_from_api("11347", 'config.yaml')
|
|
146
|
+
print("Payer Name: {}".format(payer_name))
|
|
147
|
+
|
|
148
|
+
# Example patient info
|
|
149
|
+
patient_info = {
|
|
150
|
+
"policyNumber": "12345",
|
|
151
|
+
"name": "John Doe",
|
|
152
|
+
"dob": "1980-01-01"
|
|
153
|
+
}
|
|
154
|
+
# Create coverage and print response
|
|
155
|
+
response = client.create_coverage('AVAILITY', patient_info)
|
|
156
|
+
print("Create Coverage Response: {}".format(response))
|
|
157
|
+
|
|
158
|
+
# Get all coverages and print response
|
|
159
|
+
response = client.get_coverages('AVAILITY')
|
|
160
|
+
print("All Coverages: {}".format(response))
|
|
161
|
+
|
|
162
|
+
# Example coverage ID
|
|
163
|
+
coverage_id = "some-coverage-id"
|
|
164
|
+
# Get coverage by ID and print response
|
|
165
|
+
response = client.get_coverage_by_id('AVAILITY', coverage_id)
|
|
166
|
+
print("Coverage by ID: {}".format(response))
|
|
167
|
+
|
|
168
|
+
# Delete coverage by ID and print response
|
|
169
|
+
response = client.delete_coverage_by_id('AVAILITY', coverage_id)
|
|
170
|
+
print("Delete Coverage Response: {}".format(response))
|
|
171
|
+
|
|
172
|
+
except Exception as e:
|
|
173
|
+
# Print error if any
|
|
174
|
+
print("Error: {}".format(e))
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Unused archive backup. This has been superceded by API_v2
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import requests
|
|
5
|
+
try:
|
|
6
|
+
from MediLink import MediLink_ConfigLoader
|
|
7
|
+
except ImportError:
|
|
8
|
+
import MediLink_ConfigLoader
|
|
9
|
+
|
|
10
|
+
# Fetches the payer name from API based on the payer ID.
|
|
11
|
+
def fetch_payer_name_from_api(payer_id, config, primary_endpoint='AVAILITY'):
|
|
12
|
+
"""
|
|
13
|
+
Fetches the payer name from the API using the provided payer ID.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
payer_id (str): The ID of the payer.
|
|
17
|
+
config (dict): Configuration settings.
|
|
18
|
+
primary_endpoint (str): The primary endpoint for resolving payer information.
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
ValueError: If all endpoints are exhausted without finding the payer.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
str: The fetched payer name.
|
|
25
|
+
"""
|
|
26
|
+
# Reload for safety
|
|
27
|
+
config, _ = MediLink_ConfigLoader.load_configuration()
|
|
28
|
+
|
|
29
|
+
# Step 1: Retrieve endpoint configurations
|
|
30
|
+
endpoints = config['MediLink_Config']['endpoints']
|
|
31
|
+
tried_endpoints = []
|
|
32
|
+
|
|
33
|
+
# Step 2: Check if the primary endpoint is specified and is valid
|
|
34
|
+
if primary_endpoint and primary_endpoint in endpoints:
|
|
35
|
+
endpoint_order = [primary_endpoint] + [endpoint for endpoint in endpoints if endpoint != primary_endpoint]
|
|
36
|
+
else:
|
|
37
|
+
endpoint_order = list(endpoints.keys())
|
|
38
|
+
|
|
39
|
+
# Step 3: Iterate through available endpoints in specified order
|
|
40
|
+
for endpoint_name in endpoint_order:
|
|
41
|
+
endpoint_config = endpoints[endpoint_name]
|
|
42
|
+
if not all(key in endpoint_config for key in ['token_url', 'client_id', 'client_secret']):
|
|
43
|
+
MediLink_ConfigLoader.log("Skipping {} due to missing API keys.".format(endpoint_name), config, level="WARNING")
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
# Step 4: Get access token for the endpoint
|
|
47
|
+
token = get_access_token(endpoint_config)
|
|
48
|
+
api_url = endpoint_config.get("api_url", "")
|
|
49
|
+
headers = {'Authorization': 'Bearer {}'.format(token), 'Accept': 'application/json'}
|
|
50
|
+
params = {'payerId': payer_id}
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# Step 5: Make API call to fetch payer name
|
|
54
|
+
response = requests.get(api_url, headers=headers, params=params)
|
|
55
|
+
response.raise_for_status()
|
|
56
|
+
data = response.json()
|
|
57
|
+
if 'payers' in data and data['payers']:
|
|
58
|
+
payer = data['payers'][0]
|
|
59
|
+
payer_name = payer.get('displayName') or payer.get('name')
|
|
60
|
+
|
|
61
|
+
# Log successful match
|
|
62
|
+
MediLink_ConfigLoader.log("Successfully found payer at {} for ID {}: {}".format(endpoint_name, payer_id, payer_name), config, level="INFO")
|
|
63
|
+
|
|
64
|
+
return payer_name
|
|
65
|
+
else:
|
|
66
|
+
MediLink_ConfigLoader.log("No payer found at {} for ID: {}. Trying next available endpoint.".format(endpoint_name, payer_id), config, level="INFO")
|
|
67
|
+
except requests.RequestException as e:
|
|
68
|
+
# Step 6: Log API call failure
|
|
69
|
+
MediLink_ConfigLoader.log("API call failed at {} for Payer ID '{}': {}".format(endpoint_name, payer_id, str(e)), config, level="ERROR")
|
|
70
|
+
tried_endpoints.append(endpoint_name)
|
|
71
|
+
|
|
72
|
+
# Step 7: Log all endpoints exhaustion and raise error
|
|
73
|
+
error_message = "All endpoints exhausted for Payer ID {}. Endpoints tried: {}".format(payer_id, ', '.join(tried_endpoints))
|
|
74
|
+
MediLink_ConfigLoader.log(error_message, config, level="CRITICAL")
|
|
75
|
+
raise ValueError(error_message)
|
|
76
|
+
|
|
77
|
+
# Test Case for API fetch
|
|
78
|
+
#payer_id = "11347"
|
|
79
|
+
#config = load_configuration()
|
|
80
|
+
#payer_name = fetch_payer_name_from_api(payer_id, config, endpoint='AVAILITY')
|
|
81
|
+
#print(payer_id, payer_name)
|
|
82
|
+
|
|
83
|
+
# Initialize a global dictionary to store the access token and its expiry time
|
|
84
|
+
# TODO (Low API) This will need to get setup for each endpoint separately.
|
|
85
|
+
token_cache = {
|
|
86
|
+
'access_token': None,
|
|
87
|
+
'expires_at': 0 # Timestamp of when the token expires
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
def get_access_token(endpoint_config):
|
|
91
|
+
current_time = time.time()
|
|
92
|
+
|
|
93
|
+
# Check if the cached token is still valid
|
|
94
|
+
if token_cache['access_token'] and token_cache['expires_at'] > current_time:
|
|
95
|
+
return token_cache['access_token']
|
|
96
|
+
|
|
97
|
+
# Validate endpoint configuration
|
|
98
|
+
if not endpoint_config or not all(k in endpoint_config for k in ['client_id', 'client_secret', 'token_url']):
|
|
99
|
+
raise ValueError("Endpoint configuration is incomplete or missing necessary fields.")
|
|
100
|
+
|
|
101
|
+
# Extract credentials and URL from the config
|
|
102
|
+
CLIENT_ID = endpoint_config.get("client_id")
|
|
103
|
+
CLIENT_SECRET = endpoint_config.get("client_secret")
|
|
104
|
+
url = endpoint_config.get("token_url")
|
|
105
|
+
|
|
106
|
+
# Setup the data payload and headers for the HTTP request
|
|
107
|
+
data = {
|
|
108
|
+
'grant_type': 'client_credentials',
|
|
109
|
+
'client_id': CLIENT_ID,
|
|
110
|
+
'client_secret': CLIENT_SECRET,
|
|
111
|
+
'scope': 'hipaa'
|
|
112
|
+
}
|
|
113
|
+
headers = {
|
|
114
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
# Perform the HTTP request to get the access token
|
|
119
|
+
response = requests.post(url, headers=headers, data=data)
|
|
120
|
+
response.raise_for_status() # This will raise an exception for HTTP error statuses
|
|
121
|
+
json_response = response.json()
|
|
122
|
+
access_token = json_response.get('access_token')
|
|
123
|
+
expires_in = json_response.get('expires_in', 3600) # Default to 3600 seconds if not provided
|
|
124
|
+
|
|
125
|
+
if not access_token:
|
|
126
|
+
raise ValueError("No access token returned by the server.")
|
|
127
|
+
|
|
128
|
+
# Store the access token and calculate the expiry time
|
|
129
|
+
token_cache['access_token'] = access_token
|
|
130
|
+
token_cache['expires_at'] = current_time + expires_in - 120 # Subtracting 120 seconds to provide buffer
|
|
131
|
+
|
|
132
|
+
return access_token
|
|
133
|
+
except requests.RequestException as e:
|
|
134
|
+
# Handle HTTP errors (e.g., network problems, invalid response)
|
|
135
|
+
error_msg = "Failed to retrieve access token: {0}. Response status: {1}".format(str(e), response.status_code if response else 'No response')
|
|
136
|
+
raise Exception(error_msg)
|
|
137
|
+
except ValueError as e:
|
|
138
|
+
# Handle specific errors like missing access token
|
|
139
|
+
raise Exception("Configuration or server response error: {0}".format(str(e)))
|
|
@@ -4,45 +4,28 @@ import logging
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from collections import OrderedDict
|
|
6
6
|
import sys
|
|
7
|
+
import platform
|
|
7
8
|
|
|
8
9
|
"""
|
|
9
10
|
This function should be generalizable to have a initialization script over all the Medi* functions
|
|
10
11
|
"""
|
|
11
|
-
|
|
12
|
-
# Setup basic logging.
|
|
13
|
-
# BUG Consolidate this with MediLink_837p_encoder_library.log
|
|
14
|
-
def setup_logger(local_storage_path):
|
|
15
|
-
# Define a reasonable name for the log file, e.g., "MediLink_Down_Process.log"
|
|
16
|
-
log_filename = datetime.now().strftime("MediLink_Down_Process_%m%d%Y.log")
|
|
17
|
-
log_filepath = os.path.join(local_storage_path, log_filename)
|
|
18
|
-
|
|
19
|
-
for handler in logging.root.handlers[:]:
|
|
20
|
-
logging.root.removeHandler(handler)
|
|
21
|
-
|
|
22
|
-
# Setup logging to file
|
|
23
|
-
logging.basicConfig(level=logging.INFO,
|
|
24
|
-
format='%(asctime)s - %(levelname)s - %(message)s',
|
|
25
|
-
filename=log_filepath, # Direct logging to a file in local_storage_path
|
|
26
|
-
filemode='a') # Append mode
|
|
27
|
-
|
|
28
|
-
# If you also want to see the logs in the console, add a StreamHandler
|
|
29
|
-
#console_handler = logging.StreamHandler()
|
|
30
|
-
#console_handler.setLevel(logging.INFO)
|
|
31
|
-
#formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
|
32
|
-
#console_handler.setFormatter(formatter)
|
|
33
|
-
#logging.getLogger('').addHandler(console_handler)
|
|
34
|
-
|
|
35
12
|
def load_configuration(config_path=os.path.join(os.path.dirname(__file__), '..', 'json', 'config.json'), crosswalk_path=os.path.join(os.path.dirname(__file__), '..', 'json', 'crosswalk.json')):
|
|
36
13
|
"""
|
|
37
14
|
Loads endpoint configuration, credentials, and other settings from JSON files.
|
|
38
15
|
|
|
39
16
|
Returns: A tuple containing dictionaries with configuration settings for the main config and crosswalk.
|
|
40
17
|
"""
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
18
|
+
# TODO (Low Config Upgrade) The Medicare / Private differentiator flag probably needs to be pulled or passed to this.
|
|
19
|
+
# BUG (HARDCODE) FOR NOW:
|
|
20
|
+
# Detect the operating system
|
|
21
|
+
if platform.system() == 'Windows' and platform.release() == 'XP':
|
|
22
|
+
# Use F: paths for Windows XP
|
|
23
|
+
config_path = "F:\\Medibot\\json\\config.json"
|
|
24
|
+
crosswalk_path = "F:\\Medibot\\json\\crosswalk.json"
|
|
25
|
+
else:
|
|
26
|
+
# Use G: paths for other versions of Windows
|
|
27
|
+
config_path = "G:\\My Drive\\Codes\\MediCafe\\json\\config.json"
|
|
28
|
+
crosswalk_path = "G:\\My Drive\\Codes\\MediCafe\\json\\crosswalk.json"
|
|
46
29
|
|
|
47
30
|
try:
|
|
48
31
|
with open(config_path, 'r') as config_file:
|
|
@@ -55,8 +38,11 @@ def load_configuration(config_path=os.path.join(os.path.dirname(__file__), '..',
|
|
|
55
38
|
crosswalk = json.load(crosswalk_file)
|
|
56
39
|
|
|
57
40
|
return config, crosswalk
|
|
58
|
-
except
|
|
59
|
-
|
|
41
|
+
except ValueError as e:
|
|
42
|
+
if isinstance(e, UnicodeDecodeError):
|
|
43
|
+
print("Error decoding JSON file: {}".format(e))
|
|
44
|
+
else:
|
|
45
|
+
print("Error parsing JSON file: {}".format(e))
|
|
60
46
|
sys.exit(1) # Exit the script due to a critical error in configuration loading
|
|
61
47
|
except FileNotFoundError:
|
|
62
48
|
print("One or both JSON files not found. Config: {}, Crosswalk: {}".format(config_path, crosswalk_path))
|
|
@@ -66,4 +52,30 @@ def load_configuration(config_path=os.path.join(os.path.dirname(__file__), '..',
|
|
|
66
52
|
sys.exit(1) # Exit the script due to a critical error in configuration loading
|
|
67
53
|
except Exception as e:
|
|
68
54
|
print("An unexpected error occurred while loading the configuration: {}".format(e))
|
|
69
|
-
sys.exit(1) # Exit the script due to a critical error in configuration loading
|
|
55
|
+
sys.exit(1) # Exit the script due to a critical error in configuration loading
|
|
56
|
+
|
|
57
|
+
# Logs messages with optional error type and claim data.
|
|
58
|
+
def log(message, config=None, level="INFO", error_type=None, claim=None):
|
|
59
|
+
|
|
60
|
+
# If config is not provided, load it
|
|
61
|
+
if config is None:
|
|
62
|
+
config, _ = load_configuration()
|
|
63
|
+
|
|
64
|
+
# Setup logger if not already configured
|
|
65
|
+
if not logging.root.handlers:
|
|
66
|
+
local_storage_path = config['MediLink_Config'].get('local_storage_path', '.') if isinstance(config, dict) else '.'
|
|
67
|
+
log_filename = datetime.now().strftime("Log_%m%d%Y.log")
|
|
68
|
+
log_filepath = os.path.join(local_storage_path, log_filename)
|
|
69
|
+
logging.basicConfig(level=logging.INFO,
|
|
70
|
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
|
71
|
+
filename=log_filepath,
|
|
72
|
+
filemode='a')
|
|
73
|
+
|
|
74
|
+
# Prepare log message
|
|
75
|
+
claim_data = " - Claim Data: {}".format(claim) if claim else ""
|
|
76
|
+
error_info = " - Error Type: {}".format(error_type) if error_type else ""
|
|
77
|
+
full_message = "{} {}{}".format(message, claim_data, error_info)
|
|
78
|
+
|
|
79
|
+
# Log the message
|
|
80
|
+
logger = logging.getLogger()
|
|
81
|
+
getattr(logger, level.lower())(full_message)
|