medicafe 0.250728.8__py3-none-any.whl → 0.250805.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 +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 +222 -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.py +66 -26
- MediLink/MediLink_837p_cob_library.py +28 -28
- MediLink/MediLink_837p_encoder.py +33 -34
- MediLink/MediLink_837p_encoder_library.py +243 -151
- 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 +405 -72
- 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 +712 -653
- MediLink/MediLink_PatientProcessor.py +257 -0
- MediLink/MediLink_UI.py +85 -61
- MediLink/MediLink_Up.py +28 -4
- MediLink/MediLink_insurance_utils.py +227 -264
- MediLink/MediLink_main.py +248 -0
- MediLink/MediLink_smart_import.py +264 -0
- MediLink/__init__.py +93 -0
- MediLink/insurance_type_integration_test.py +66 -76
- MediLink/test.py +1 -1
- MediLink/test_timing.py +59 -0
- {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/METADATA +1 -1
- medicafe-0.250805.0.dist-info/RECORD +81 -0
- medicafe-0.250805.0.dist-info/entry_points.txt +2 -0
- {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/top_level.txt +1 -0
- medicafe-0.250728.8.dist-info/RECORD +0 -59
- {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/LICENSE +0 -0
- {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/WHEEL +0 -0
|
@@ -11,6 +11,8 @@ Functions included:
|
|
|
11
11
|
- File/path handling utilities
|
|
12
12
|
- Processing utilities
|
|
13
13
|
- Validation utilities
|
|
14
|
+
- Insurance matching utilities
|
|
15
|
+
- EDI segment utilities
|
|
14
16
|
|
|
15
17
|
Import Strategy:
|
|
16
18
|
This module only imports base Python modules and MediLink_ConfigLoader to avoid
|
|
@@ -21,12 +23,11 @@ from datetime import datetime
|
|
|
21
23
|
import sys
|
|
22
24
|
import os
|
|
23
25
|
import re
|
|
26
|
+
import difflib
|
|
24
27
|
|
|
25
28
|
# Import MediLink_ConfigLoader for logging functionality
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
except ImportError:
|
|
29
|
-
import MediLink_ConfigLoader
|
|
29
|
+
from MediCafe.core_utils import get_shared_config_loader
|
|
30
|
+
MediLink_ConfigLoader = get_shared_config_loader()
|
|
30
31
|
|
|
31
32
|
# =============================================================================
|
|
32
33
|
# DATE/TIME UTILITIES
|
|
@@ -246,6 +247,126 @@ def handle_validation_errors(transaction_set_control_number, validation_errors,
|
|
|
246
247
|
MediLink_ConfigLoader.log("HALT: Processing halted at transaction set {} due to unresolved validation errors.".format(transaction_set_control_number), config, level="ERROR")
|
|
247
248
|
sys.exit() # Optionally halt further processing
|
|
248
249
|
|
|
250
|
+
# =============================================================================
|
|
251
|
+
# INSURANCE MATCHING UTILITIES
|
|
252
|
+
# =============================================================================
|
|
253
|
+
|
|
254
|
+
def find_closest_insurance_matches(insurance_name, insurance_to_id, max_matches=3):
|
|
255
|
+
"""
|
|
256
|
+
Find the closest matches for an insurance name in the MAINS data.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
insurance_name (str): The insurance name to find matches for
|
|
260
|
+
insurance_to_id (dict): Dictionary mapping insurance names to IDs from MAINS
|
|
261
|
+
max_matches (int): Maximum number of matches to return
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
list: List of tuples (insurance_name, similarity_score) sorted by similarity
|
|
265
|
+
"""
|
|
266
|
+
if not insurance_to_id:
|
|
267
|
+
return []
|
|
268
|
+
|
|
269
|
+
# Normalize the search term
|
|
270
|
+
normalized_search = insurance_name.upper().strip()
|
|
271
|
+
|
|
272
|
+
# Calculate similarity scores for all insurance names
|
|
273
|
+
matches = []
|
|
274
|
+
for mains_insurance_name in insurance_to_id.keys():
|
|
275
|
+
normalized_mains = mains_insurance_name.upper().strip()
|
|
276
|
+
|
|
277
|
+
# Use difflib for similarity scoring
|
|
278
|
+
similarity = difflib.SequenceMatcher(None, normalized_search, normalized_mains).ratio()
|
|
279
|
+
|
|
280
|
+
# Boost score for partial matches
|
|
281
|
+
if normalized_search in normalized_mains or normalized_mains in normalized_search:
|
|
282
|
+
similarity += 0.2
|
|
283
|
+
|
|
284
|
+
# Boost score for word matches
|
|
285
|
+
search_words = set(normalized_search.split())
|
|
286
|
+
mains_words = set(normalized_mains.split())
|
|
287
|
+
word_overlap = len(search_words.intersection(mains_words))
|
|
288
|
+
if word_overlap > 0:
|
|
289
|
+
similarity += 0.1 * word_overlap
|
|
290
|
+
|
|
291
|
+
matches.append((mains_insurance_name, similarity))
|
|
292
|
+
|
|
293
|
+
# Sort by similarity score (highest first) and return top matches
|
|
294
|
+
matches.sort(key=lambda x: x[1], reverse=True)
|
|
295
|
+
return matches[:max_matches]
|
|
296
|
+
|
|
297
|
+
def prompt_for_insurance_selection(insurance_name, closest_matches, config):
|
|
298
|
+
"""
|
|
299
|
+
Prompt the user to select from the closest matches or choose manual intervention.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
insurance_name (str): The original insurance name that wasn't found
|
|
303
|
+
closest_matches (list): List of tuples (insurance_name, similarity_score)
|
|
304
|
+
config (dict): Configuration object
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
str or None: Selected insurance name or None for manual intervention
|
|
308
|
+
"""
|
|
309
|
+
print("\n" + "="*60)
|
|
310
|
+
print("INSURANCE NAME NOT FOUND IN MAINS")
|
|
311
|
+
print("="*60)
|
|
312
|
+
print("Original insurance name: '{}'".format(insurance_name))
|
|
313
|
+
print("\nClosest matches found in MAINS:")
|
|
314
|
+
print("-" * 40)
|
|
315
|
+
|
|
316
|
+
for i, (match_name, similarity) in enumerate(closest_matches, 1):
|
|
317
|
+
print("{}. {} (similarity: {:.1%})".format(i, match_name, similarity))
|
|
318
|
+
|
|
319
|
+
print("\n{}. None of these - I need to fix this manually".format(len(closest_matches) + 1))
|
|
320
|
+
print("-" * 40)
|
|
321
|
+
|
|
322
|
+
while True:
|
|
323
|
+
try:
|
|
324
|
+
choice = input("\nPlease select an option (1-{}): ".format(len(closest_matches) + 1))
|
|
325
|
+
choice_num = int(choice)
|
|
326
|
+
|
|
327
|
+
if 1 <= choice_num <= len(closest_matches):
|
|
328
|
+
selected_name = closest_matches[choice_num - 1][0]
|
|
329
|
+
print("\nSelected: '{}'".format(selected_name))
|
|
330
|
+
MediLink_ConfigLoader.log("User selected insurance name '{}' for original '{}'".format(selected_name, insurance_name), config, level="INFO")
|
|
331
|
+
return selected_name
|
|
332
|
+
elif choice_num == len(closest_matches) + 1:
|
|
333
|
+
print("\n" + "="*60)
|
|
334
|
+
print("MANUAL INTERVENTION REQUIRED")
|
|
335
|
+
print("="*60)
|
|
336
|
+
print("To resolve this issue, you may need to:")
|
|
337
|
+
print("1. Check if the insurance name is spelled correctly in your source data")
|
|
338
|
+
print("2. Verify the insurance exists in MAINS with a different name")
|
|
339
|
+
print("3. Add the insurance to MAINS if it's missing")
|
|
340
|
+
print("4. Update the crosswalk with the correct payer ID mapping")
|
|
341
|
+
print("\nThe process will continue with other claims, but this claim will be skipped.")
|
|
342
|
+
print("="*60)
|
|
343
|
+
MediLink_ConfigLoader.log("User chose manual intervention for insurance name '{}'".format(insurance_name), config, level="WARNING")
|
|
344
|
+
return None
|
|
345
|
+
else:
|
|
346
|
+
print("Invalid choice. Please enter a number between 1 and {}.".format(len(closest_matches) + 1))
|
|
347
|
+
except ValueError:
|
|
348
|
+
print("Invalid input. Please enter a number.")
|
|
349
|
+
except KeyboardInterrupt:
|
|
350
|
+
print("\n\nProcess interrupted by user.")
|
|
351
|
+
return None
|
|
352
|
+
|
|
353
|
+
# =============================================================================
|
|
354
|
+
# EDI SEGMENT UTILITIES
|
|
355
|
+
# =============================================================================
|
|
356
|
+
|
|
357
|
+
def build_nm1_segment(payer_name, payer_id):
|
|
358
|
+
"""
|
|
359
|
+
Build NM1 segment using payer name and ID.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
payer_name (str): Name of the payer
|
|
363
|
+
payer_id (str): Payer ID
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
str: Formatted NM1 segment
|
|
367
|
+
"""
|
|
368
|
+
return "NM1*PR*2*{}*****PI*{}~".format(payer_name, payer_id)
|
|
369
|
+
|
|
249
370
|
# =============================================================================
|
|
250
371
|
# UTILITY FUNCTION REGISTRY
|
|
251
372
|
# =============================================================================
|
|
@@ -260,5 +381,8 @@ __all__ = [
|
|
|
260
381
|
'winscp_validate_output_directory',
|
|
261
382
|
'get_output_directory',
|
|
262
383
|
'generate_segment_counts',
|
|
263
|
-
'handle_validation_errors'
|
|
384
|
+
'handle_validation_errors',
|
|
385
|
+
'find_closest_insurance_matches',
|
|
386
|
+
'prompt_for_insurance_selection',
|
|
387
|
+
'build_nm1_segment'
|
|
264
388
|
]
|
|
@@ -1,29 +1,47 @@
|
|
|
1
1
|
# This script requires Python 3.11 and is to be used for intalling new API clients.
|
|
2
2
|
import os, time, subprocess, shutil, tempfile, shlex, re
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from watchdog.observers import Observer
|
|
5
|
-
from watchdog.events import FileSystemEventHandler
|
|
6
|
-
from MediLink_API_v3 import ConfigLoader
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
# Add workspace directory to Python path for MediCafe imports
|
|
6
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
7
|
+
workspace_dir = os.path.dirname(current_dir)
|
|
8
|
+
if workspace_dir not in sys.path:
|
|
9
|
+
sys.path.insert(0, workspace_dir)
|
|
10
|
+
|
|
11
|
+
# Safe import for watchdog with fallback
|
|
12
|
+
try:
|
|
13
|
+
from watchdog.observers import Observer
|
|
14
|
+
from watchdog.events import FileSystemEventHandler
|
|
15
|
+
WATCHDOG_AVAILABLE = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
Observer = None
|
|
18
|
+
FileSystemEventHandler = None
|
|
19
|
+
WATCHDOG_AVAILABLE = False
|
|
20
|
+
print("Warning: watchdog module not available. File monitoring functionality will be limited.")
|
|
21
|
+
|
|
22
|
+
from MediCafe.api_core import ConfigLoader
|
|
23
|
+
|
|
24
|
+
class SwaggerHandler(FileSystemEventHandler if WATCHDOG_AVAILABLE else object):
|
|
9
25
|
def __init__(self, json_folder):
|
|
26
|
+
if WATCHDOG_AVAILABLE:
|
|
27
|
+
super().__init__()
|
|
10
28
|
self.json_folder = json_folder
|
|
11
29
|
|
|
12
30
|
def on_created(self, event):
|
|
13
31
|
if event.is_directory:
|
|
14
32
|
return
|
|
15
33
|
if event.src_path.endswith('.yaml') or event.src_path.endswith('.json'):
|
|
16
|
-
print(
|
|
34
|
+
print("New file detected: {}".format(event.src_path))
|
|
17
35
|
time.sleep(2) # Add a short delay to ensure the file is ready for reading
|
|
18
36
|
self.process_swagger_file(event.src_path)
|
|
19
37
|
|
|
20
38
|
def process_swagger_file(self, file_path):
|
|
21
|
-
print(
|
|
39
|
+
print("Processing file: {}".format(file_path))
|
|
22
40
|
# Sanitize filename to replace spaces with underscores
|
|
23
41
|
sanitized_file_path = os.path.join(os.path.dirname(file_path), sanitize_filename(os.path.basename(file_path)))
|
|
24
42
|
if sanitized_file_path != file_path:
|
|
25
43
|
os.rename(file_path, sanitized_file_path)
|
|
26
|
-
print(
|
|
44
|
+
print("Renamed file to: {}".format(sanitized_file_path))
|
|
27
45
|
file_path = sanitized_file_path
|
|
28
46
|
|
|
29
47
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
@@ -35,17 +53,17 @@ class SwaggerHandler(FileSystemEventHandler):
|
|
|
35
53
|
shutil.copy(file_path, temp_file_path)
|
|
36
54
|
config_source_path = Path(__file__).parent.parent / 'json' / 'openapi_config.json'
|
|
37
55
|
shutil.copy(config_source_path, config_path)
|
|
38
|
-
print(
|
|
56
|
+
print("Copied files to: {} and {}".format(temp_file_path, config_path))
|
|
39
57
|
|
|
40
58
|
swagger_definitions = ConfigLoader.load_swagger_file(str(temp_file_path))
|
|
41
59
|
if swagger_definitions:
|
|
42
|
-
print(
|
|
60
|
+
print("Swagger definitions loaded successfully from: {}".format(temp_file_path))
|
|
43
61
|
if generate_api_client(temp_file_path, output_dir, config_path):
|
|
44
62
|
backport_code(output_dir)
|
|
45
63
|
move_generated_client(temp_dir, file_path)
|
|
46
64
|
provide_instructions(file_path)
|
|
47
65
|
else:
|
|
48
|
-
print(
|
|
66
|
+
print("Failed to load Swagger definitions from: {}".format(temp_file_path))
|
|
49
67
|
|
|
50
68
|
def sanitize_filename(filename):
|
|
51
69
|
return filename.replace(' ', '_')
|
|
@@ -76,7 +94,7 @@ def generate_api_client(swagger_path, output_path, config_path):
|
|
|
76
94
|
'-c', str(config_path)
|
|
77
95
|
]
|
|
78
96
|
|
|
79
|
-
print(
|
|
97
|
+
print("Attempting command: {}".format(' '.join(command)))
|
|
80
98
|
|
|
81
99
|
try:
|
|
82
100
|
result = subprocess.run(command, check=True, capture_output=True, text=True)
|
|
@@ -112,7 +130,7 @@ def generate_api_client(swagger_path, output_path, config_path):
|
|
|
112
130
|
'-o', shlex.quote(str(output_path)),
|
|
113
131
|
'-c', shlex.quote(str(config_path))
|
|
114
132
|
]
|
|
115
|
-
print(
|
|
133
|
+
print("Attempting quoted command: {}".format(' '.join(quoted_command)))
|
|
116
134
|
result = subprocess.run(' '.join(quoted_command), check=True, shell=True, capture_output=True, text=True)
|
|
117
135
|
print("API client generated successfully with quoted command.")
|
|
118
136
|
print(result.stdout)
|
|
@@ -126,10 +144,10 @@ def generate_api_client(swagger_path, output_path, config_path):
|
|
|
126
144
|
|
|
127
145
|
try:
|
|
128
146
|
print("Attempting with batch script.")
|
|
129
|
-
batch_script_content =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
147
|
+
batch_script_content = """
|
|
148
|
+
@echo off
|
|
149
|
+
{} generate -i "{}" -g python -o "{}" -c "{}"
|
|
150
|
+
""".format(openapi_generator_path, swagger_path, output_path, config_path)
|
|
133
151
|
batch_script_path = Path(tempfile.gettempdir()) / "generate_client.bat"
|
|
134
152
|
with open(batch_script_path, 'w') as batch_script:
|
|
135
153
|
batch_script.write(batch_script_content)
|
|
@@ -156,8 +174,8 @@ def backport_code(output_dir):
|
|
|
156
174
|
with open(file_path, 'r') as f:
|
|
157
175
|
code = f.read()
|
|
158
176
|
|
|
159
|
-
code = re.sub(r'
|
|
160
|
-
code = re.sub(r'async
|
|
177
|
+
code = re.sub(r'"(.*?)".format()', r'"\1".format', code) # Replace f-strings
|
|
178
|
+
code = re.sub(r'async de', 'def', code) # Remove async syntax
|
|
161
179
|
code = re.sub(r'await ', '', code) # Remove await syntax
|
|
162
180
|
code = re.sub(r':\s*\w+ =', '=', code) # Remove type hints in variable assignments
|
|
163
181
|
code = re.sub(r'def (\w+)\(.*?\) -> .*?:', r'def \1(', code) # Remove type hints in function definitions
|
|
@@ -166,7 +184,7 @@ def backport_code(output_dir):
|
|
|
166
184
|
|
|
167
185
|
with open(file_path, 'w') as f:
|
|
168
186
|
f.write(code)
|
|
169
|
-
print(
|
|
187
|
+
print("Backported {}".format(file_path))
|
|
170
188
|
|
|
171
189
|
def move_generated_client(temp_dir, original_file_path):
|
|
172
190
|
api_name = Path(original_file_path).stem
|
|
@@ -175,60 +193,65 @@ def move_generated_client(temp_dir, original_file_path):
|
|
|
175
193
|
shutil.rmtree(destination_dir)
|
|
176
194
|
try:
|
|
177
195
|
shutil.move(str(Path(temp_dir) / 'generated_client'), str(destination_dir))
|
|
178
|
-
print(
|
|
196
|
+
print("Moved generated client to {}".format(destination_dir))
|
|
179
197
|
except FileNotFoundError as e:
|
|
180
|
-
print(
|
|
198
|
+
print("Error moving generated client: {}".format(e))
|
|
181
199
|
except Exception as e:
|
|
182
|
-
print(
|
|
200
|
+
print("Unexpected error moving generated client: {}".format(e))
|
|
183
201
|
|
|
184
202
|
def provide_instructions(swagger_path):
|
|
185
203
|
api_name = Path(swagger_path).stem
|
|
186
|
-
instructions =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
204
|
+
instructions = """
|
|
205
|
+
API Client for {} has been generated successfully.
|
|
206
|
+
|
|
207
|
+
Integration Steps:
|
|
208
|
+
1. Locate the generated client code in the 'generated_clients/{}' directory.
|
|
209
|
+
2. Integrate the generated client code into your project by following these steps:
|
|
210
|
+
a. Copy the generated client directory to your project's client directory.
|
|
211
|
+
b. Import the client classes in your project as needed.
|
|
212
|
+
c. Ensure that the generated client adheres to the BaseAPIClient interface if integrating with the existing system.
|
|
213
|
+
3. Update your configuration to include the new API endpoint details.
|
|
214
|
+
4. Test the integration thoroughly to ensure compatibility and functionality.
|
|
215
|
+
|
|
216
|
+
Example Integration:
|
|
217
|
+
from clients.generated.{}.api_client import ApiClient as {}Client
|
|
218
|
+
|
|
219
|
+
class New{}APIClient(BaseAPIClient):
|
|
220
|
+
def __init__(self, config):
|
|
221
|
+
super().__init__(config)
|
|
222
|
+
self.generated_client = {}Client()
|
|
223
|
+
|
|
224
|
+
def get_access_token(self, endpoint_name):
|
|
225
|
+
# Implement token retrieval logic
|
|
226
|
+
pass
|
|
227
|
+
|
|
228
|
+
def make_api_call(self, endpoint_name, call_type, url_extension="", params=None, data=None):
|
|
229
|
+
# Use the generated client to make the API call
|
|
230
|
+
if call_type == 'GET':
|
|
231
|
+
response = self.generated_client.call_api(url_extension, 'GET', params=params, header_params=headers)
|
|
232
|
+
elif call_type == 'POST':
|
|
233
|
+
response = self.generated_client.call_api(url_extension, 'POST', body=data, header_params=headers)
|
|
234
|
+
elif call_type == 'DELETE':
|
|
235
|
+
response = self.generated_client.call_api(url_extension, 'DELETE', header_params=headers)
|
|
236
|
+
else:
|
|
237
|
+
raise ValueError("Unsupported call type")
|
|
238
|
+
return response
|
|
239
|
+
|
|
240
|
+
""".format(api_name, api_name, api_name, api_name, api_name, api_name)
|
|
223
241
|
print(instructions)
|
|
224
242
|
|
|
225
243
|
def main():
|
|
226
244
|
json_folder = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'json'))
|
|
245
|
+
if not WATCHDOG_AVAILABLE:
|
|
246
|
+
print("Watchdog is not available. Skipping file monitoring.")
|
|
247
|
+
print("Please ensure watchdog is installed and in your PATH.")
|
|
248
|
+
return
|
|
249
|
+
|
|
227
250
|
event_handler = SwaggerHandler(json_folder)
|
|
228
251
|
observer = Observer()
|
|
229
252
|
observer.schedule(event_handler, path=json_folder, recursive=False)
|
|
230
253
|
observer.start()
|
|
231
|
-
print(
|
|
254
|
+
print("Monitoring folder: {}".format(json_folder))
|
|
232
255
|
try:
|
|
233
256
|
while True:
|
|
234
257
|
time.sleep(1)
|
MediLink/MediLink_API_v3.py
CHANGED