medicafe 0.250810.5__tar.gz → 0.250810.6__tar.gz
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.
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot.bat +6 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/__main__.py +21 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/core_utils.py +116 -12
- {medicafe-0.250810.5/medicafe.egg-info → medicafe-0.250810.6}/PKG-INFO +1 -1
- {medicafe-0.250810.5 → medicafe-0.250810.6/medicafe.egg-info}/PKG-INFO +1 -1
- {medicafe-0.250810.5 → medicafe-0.250810.6}/setup.py +1 -1
- {medicafe-0.250810.5 → medicafe-0.250810.6}/LICENSE +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MANIFEST.in +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_Charges.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_Crosswalk_Library.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_Crosswalk_Utils.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_Post.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_Preprocessor.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_Preprocessor_lib.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_UI.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_dataformat_library.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_docx_decoder.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/MediBot_smart_import.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/__init__.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/get_medicafe_version.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/update_json.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediBot/update_medicafe.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/MediLink_ConfigLoader.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/__init__.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/api_core.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/api_core_backup.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/api_factory.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/api_utils.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/graphql_utils.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/logging_config.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/logging_demo.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/migration_helpers.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediCafe/smart_import.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_837p_cob_library.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_837p_encoder.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_837p_encoder_library.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_837p_utilities.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_API_Generator.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Azure.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_ClaimStatus.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_DataMgmt.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Decoder.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Deductible.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Deductible_Validator.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Display_Utils.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Down.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Gmail.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Mailer.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Parser.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_PatientProcessor.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Scan.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Scheduler.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_UI.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_Up.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_insurance_utils.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_main.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/MediLink_smart_import.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/Soumit_api.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/__init__.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/insurance_type_integration_test.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/openssl.cnf +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/test.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/test_cob_library.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/test_timing.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/test_validation.py +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/MediLink/webapp.html +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/medicafe.egg-info/SOURCES.txt +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/medicafe.egg-info/dependency_links.txt +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/medicafe.egg-info/entry_points.txt +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/medicafe.egg-info/not-zip-safe +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/medicafe.egg-info/requires.txt +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/medicafe.egg-info/top_level.txt +0 -0
- {medicafe-0.250810.5 → medicafe-0.250810.6}/setup.cfg +0 -0
@@ -25,6 +25,8 @@ echo ========================================
|
|
25
25
|
echo DEBUG MODE (INTERACTIVE)
|
26
26
|
echo ========================================
|
27
27
|
echo Running full diagnostic suite...
|
28
|
+
set "MEDICAFE_IMPORT_DEBUG=1"
|
29
|
+
set "MEDICAFE_IMPORT_STRICT=0"
|
28
30
|
echo.
|
29
31
|
set "SKIP_CLS_AFTER_DEBUG=1"
|
30
32
|
call "%~dp0full_debug_suite.bat" /interactive
|
@@ -37,6 +39,8 @@ echo ========================================
|
|
37
39
|
echo DEBUG MODE (NON-INTERACTIVE)
|
38
40
|
echo ========================================
|
39
41
|
echo Running full diagnostic suite...
|
42
|
+
set "MEDICAFE_IMPORT_DEBUG=1"
|
43
|
+
set "MEDICAFE_IMPORT_STRICT=0"
|
40
44
|
echo.
|
41
45
|
set "SKIP_CLS_AFTER_DEBUG=1"
|
42
46
|
call "%~dp0full_debug_suite.bat"
|
@@ -45,6 +49,8 @@ goto normal_mode
|
|
45
49
|
|
46
50
|
:start_normal_mode
|
47
51
|
echo Starting Normal Mode...
|
52
|
+
set "MEDICAFE_IMPORT_DEBUG=0"
|
53
|
+
set "MEDICAFE_IMPORT_STRICT=1"
|
48
54
|
goto normal_mode
|
49
55
|
|
50
56
|
:normal_mode
|
@@ -25,6 +25,7 @@ import sys
|
|
25
25
|
import os
|
26
26
|
import argparse
|
27
27
|
import subprocess
|
28
|
+
from MediCafe.core_utils import import_medilink_module, require_functions, print_import_diagnostics
|
28
29
|
|
29
30
|
# Set up module paths for proper imports
|
30
31
|
def setup_entry_point_paths():
|
@@ -44,6 +45,21 @@ def setup_entry_point_paths():
|
|
44
45
|
while pkg_dir in sys.path:
|
45
46
|
sys.path.remove(pkg_dir)
|
46
47
|
|
48
|
+
def validate_critical_imports():
|
49
|
+
"""Validate key modules and capabilities before launching subprocesses.
|
50
|
+
- Ensures we resolve the in-repo MediLink_DataMgmt and it exposes required functions.
|
51
|
+
Behavior depends on env flags handled inside core_utils.require_functions.
|
52
|
+
"""
|
53
|
+
try:
|
54
|
+
datamgmt = import_medilink_module('MediLink_DataMgmt')
|
55
|
+
if datamgmt is not None:
|
56
|
+
print_import_diagnostics('MediLink_DataMgmt', datamgmt)
|
57
|
+
# These are used by both MediBot and MediLink flows
|
58
|
+
require_functions(datamgmt, ['read_general_fixed_width_data', 'read_fixed_width_data', 'parse_fixed_width_data'])
|
59
|
+
except Exception as e:
|
60
|
+
# Fail fast only if strict mode is enabled (exception originates from require_functions)
|
61
|
+
print("Import validation warning: {}".format(e))
|
62
|
+
|
47
63
|
def run_medibot(config_file=None):
|
48
64
|
"""Run MediBot application"""
|
49
65
|
try:
|
@@ -58,6 +74,9 @@ def run_medibot(config_file=None):
|
|
58
74
|
print("Error: MediBot.py not found at {}".format(medibot_path))
|
59
75
|
return 1
|
60
76
|
|
77
|
+
# Pre-flight import validation (no-op unless strict/debug enabled)
|
78
|
+
validate_critical_imports()
|
79
|
+
|
61
80
|
# Build subprocess arguments
|
62
81
|
args = [sys.executable, medibot_path]
|
63
82
|
if config_file:
|
@@ -83,6 +102,8 @@ def run_medilink():
|
|
83
102
|
"""Run MediLink application"""
|
84
103
|
try:
|
85
104
|
print("Starting MediLink...")
|
105
|
+
# Pre-flight import validation (no-op unless strict/debug enabled)
|
106
|
+
validate_critical_imports()
|
86
107
|
# Use subprocess.call for Python 3.4.4 compatibility
|
87
108
|
|
88
109
|
# Get the path to MediLink_main.py
|
@@ -29,6 +29,62 @@ for _p in list(sys.path):
|
|
29
29
|
DEFAULT_CONFIG_PATH = os.path.join(project_dir, 'json', 'config.json')
|
30
30
|
DEFAULT_CROSSWALK_PATH = os.path.join(project_dir, 'json', 'crosswalk.json')
|
31
31
|
|
32
|
+
# Environment flags controlling import behavior
|
33
|
+
_STRICT_IMPORT = os.environ.get('MEDICAFE_IMPORT_STRICT', '0').strip().lower() in ('1', 'true', 'yes', 'y')
|
34
|
+
_DEBUG_IMPORT = os.environ.get('MEDICAFE_IMPORT_DEBUG', '0').strip().lower() in ('1', 'true', 'yes', 'y')
|
35
|
+
|
36
|
+
# Simple memoization cache for resolved imports
|
37
|
+
_IMPORT_CACHE = {}
|
38
|
+
|
39
|
+
def _cache_get(key):
|
40
|
+
try:
|
41
|
+
return _IMPORT_CACHE.get(key)
|
42
|
+
except Exception:
|
43
|
+
return None
|
44
|
+
|
45
|
+
def _cache_set(key, value):
|
46
|
+
try:
|
47
|
+
_IMPORT_CACHE[key] = value
|
48
|
+
except Exception:
|
49
|
+
pass
|
50
|
+
|
51
|
+
def _module_provenance_ok(module):
|
52
|
+
"""Return True if module appears to come from this workspace."""
|
53
|
+
try:
|
54
|
+
module_file = getattr(module, '__file__', '') or ''
|
55
|
+
return os.path.abspath(project_dir) in os.path.abspath(module_file)
|
56
|
+
except Exception:
|
57
|
+
return False
|
58
|
+
|
59
|
+
def require_functions(module, names):
|
60
|
+
"""Ensure the module exposes all required attributes; raise RuntimeError on failure in strict mode; return bool otherwise."""
|
61
|
+
missing = [name for name in names if not hasattr(module, name)]
|
62
|
+
if missing:
|
63
|
+
message = "Missing required symbols {} in module {}".format(missing, getattr(module, '__name__', 'unknown'))
|
64
|
+
if _STRICT_IMPORT:
|
65
|
+
raise RuntimeError(message)
|
66
|
+
if _DEBUG_IMPORT:
|
67
|
+
try:
|
68
|
+
print("[IMPORT DIAG] {} (file: {})".format(message, getattr(module, '__file__', 'unknown')))
|
69
|
+
except Exception:
|
70
|
+
pass
|
71
|
+
return False
|
72
|
+
return True
|
73
|
+
|
74
|
+
def print_import_diagnostics(label, module):
|
75
|
+
"""Print a single-line diagnostic about a resolved module (debug only)."""
|
76
|
+
if not _DEBUG_IMPORT:
|
77
|
+
return
|
78
|
+
try:
|
79
|
+
print("[IMPORT DIAG] {} -> name={} file={} workspace_provenance={}".format(
|
80
|
+
label,
|
81
|
+
getattr(module, '__name__', 'unknown'),
|
82
|
+
getattr(module, '__file__', 'unknown'),
|
83
|
+
_module_provenance_ok(module)
|
84
|
+
))
|
85
|
+
except Exception:
|
86
|
+
pass
|
87
|
+
|
32
88
|
def setup_project_path(file_path=None):
|
33
89
|
"""
|
34
90
|
Standard project path setup function used by all entry points.
|
@@ -122,12 +178,26 @@ def smart_import(import_specs, default_value=None):
|
|
122
178
|
try:
|
123
179
|
if isinstance(spec, str):
|
124
180
|
# Simple string - direct import
|
125
|
-
|
181
|
+
# If dotted path, ensure we get the submodule, not just the top-level package
|
182
|
+
cached = _cache_get(('str', spec))
|
183
|
+
if cached is not None:
|
184
|
+
return cached
|
185
|
+
if '.' in spec:
|
186
|
+
result = __import__(spec, fromlist=['*'])
|
187
|
+
else:
|
188
|
+
result = __import__(spec)
|
189
|
+
_cache_set(('str', spec), result)
|
190
|
+
return result
|
126
191
|
elif isinstance(spec, tuple):
|
127
192
|
# Tuple - (path, function_name)
|
128
193
|
path, function_name = spec
|
194
|
+
cached = _cache_get(('tuple', path, function_name))
|
195
|
+
if cached is not None:
|
196
|
+
return cached
|
129
197
|
module = __import__(path, fromlist=[function_name])
|
130
|
-
|
198
|
+
result = getattr(module, function_name)
|
199
|
+
_cache_set(('tuple', path, function_name), result)
|
200
|
+
return result
|
131
201
|
elif isinstance(spec, dict):
|
132
202
|
# Dict with fallback
|
133
203
|
path = spec['path']
|
@@ -135,19 +205,38 @@ def smart_import(import_specs, default_value=None):
|
|
135
205
|
fallback = spec.get('fallback')
|
136
206
|
|
137
207
|
try:
|
208
|
+
cache_key = ('dict', path, function_name)
|
209
|
+
cached = _cache_get(cache_key)
|
210
|
+
if cached is not None:
|
211
|
+
return cached
|
138
212
|
if function_name:
|
139
213
|
module = __import__(path, fromlist=[function_name])
|
140
|
-
|
214
|
+
result = getattr(module, function_name)
|
141
215
|
else:
|
142
|
-
return
|
216
|
+
# If dotted, use fromlist to return the submodule
|
217
|
+
if '.' in path:
|
218
|
+
result = __import__(path, fromlist=['*'])
|
219
|
+
else:
|
220
|
+
result = __import__(path)
|
221
|
+
_cache_set(cache_key, result)
|
222
|
+
return result
|
143
223
|
except ImportError:
|
144
224
|
if fallback:
|
145
225
|
try:
|
226
|
+
cache_key = ('dict_fallback', fallback, function_name)
|
227
|
+
cached = _cache_get(cache_key)
|
228
|
+
if cached is not None:
|
229
|
+
return cached
|
146
230
|
if function_name:
|
147
231
|
module = __import__(fallback, fromlist=[function_name])
|
148
|
-
|
232
|
+
result = getattr(module, function_name)
|
149
233
|
else:
|
150
|
-
|
234
|
+
if '.' in fallback:
|
235
|
+
result = __import__(fallback, fromlist=['*'])
|
236
|
+
else:
|
237
|
+
result = __import__(fallback)
|
238
|
+
_cache_set(cache_key, result)
|
239
|
+
return result
|
151
240
|
except ImportError:
|
152
241
|
continue
|
153
242
|
continue
|
@@ -252,14 +341,16 @@ def import_medilink_module(module_name, function_name=None):
|
|
252
341
|
Returns:
|
253
342
|
The imported module/function or None
|
254
343
|
"""
|
344
|
+
# Prefer importing from the in-repo MediLink package first to avoid
|
345
|
+
# accidentally picking up a similarly named top-level/site-packages module.
|
255
346
|
import_specs = [
|
256
|
-
#
|
257
|
-
module_name,
|
258
|
-
# Then try with MediLink prefix
|
347
|
+
# Prefer package-qualified import first (local codebase)
|
259
348
|
'MediLink.{}'.format(module_name),
|
349
|
+
# Then try direct import (legacy/installed module)
|
350
|
+
module_name,
|
260
351
|
# Then try relative import
|
261
352
|
'.{}'.format(module_name),
|
262
|
-
# Finally try as a submodule
|
353
|
+
# Finally try as a submodule with fallback
|
263
354
|
{'path': 'MediLink.{}'.format(module_name), 'fallback': module_name}
|
264
355
|
]
|
265
356
|
|
@@ -275,9 +366,22 @@ def import_medilink_module(module_name, function_name=None):
|
|
275
366
|
'function': function_name,
|
276
367
|
'fallback': spec.get('fallback')
|
277
368
|
})
|
278
|
-
|
369
|
+
result = smart_import(function_specs)
|
370
|
+
if result is not None and _DEBUG_IMPORT:
|
371
|
+
try:
|
372
|
+
print_import_diagnostics('import_medilink_module:{}:function'.format(module_name), result)
|
373
|
+
except Exception:
|
374
|
+
pass
|
375
|
+
return result
|
279
376
|
else:
|
280
|
-
|
377
|
+
result = smart_import(import_specs)
|
378
|
+
if result is not None:
|
379
|
+
# In strict mode, verify provenance and capabilities if demanded by callers
|
380
|
+
if _STRICT_IMPORT and not _module_provenance_ok(result):
|
381
|
+
raise RuntimeError("Imported module '{}' from outside workspace: {}".format(
|
382
|
+
module_name, getattr(result, '__file__', 'unknown')))
|
383
|
+
print_import_diagnostics('import_medilink_module:{}'.format(module_name), result)
|
384
|
+
return result
|
281
385
|
|
282
386
|
def get_shared_config_loader():
|
283
387
|
"""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|