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.

Files changed (58) hide show
  1. MediBot/MediBot.bat +233 -19
  2. MediBot/MediBot.py +138 -46
  3. MediBot/MediBot_Crosswalk_Library.py +127 -623
  4. MediBot/MediBot_Crosswalk_Utils.py +618 -0
  5. MediBot/MediBot_Preprocessor.py +72 -17
  6. MediBot/MediBot_Preprocessor_lib.py +470 -76
  7. MediBot/MediBot_UI.py +32 -17
  8. MediBot/MediBot_dataformat_library.py +68 -20
  9. MediBot/MediBot_docx_decoder.py +120 -19
  10. MediBot/MediBot_smart_import.py +180 -0
  11. MediBot/__init__.py +89 -0
  12. MediBot/get_medicafe_version.py +25 -0
  13. MediBot/update_json.py +35 -6
  14. MediBot/update_medicafe.py +19 -1
  15. MediCafe/MediLink_ConfigLoader.py +160 -0
  16. MediCafe/__init__.py +171 -0
  17. MediCafe/__main__.py +222 -0
  18. MediCafe/api_core.py +1098 -0
  19. MediCafe/api_core_backup.py +427 -0
  20. MediCafe/api_factory.py +306 -0
  21. MediCafe/api_utils.py +356 -0
  22. MediCafe/core_utils.py +450 -0
  23. MediCafe/graphql_utils.py +445 -0
  24. MediCafe/logging_config.py +123 -0
  25. MediCafe/logging_demo.py +61 -0
  26. MediCafe/migration_helpers.py +463 -0
  27. MediCafe/smart_import.py +436 -0
  28. MediLink/MediLink.py +66 -26
  29. MediLink/MediLink_837p_cob_library.py +28 -28
  30. MediLink/MediLink_837p_encoder.py +33 -34
  31. MediLink/MediLink_837p_encoder_library.py +243 -151
  32. MediLink/MediLink_837p_utilities.py +129 -5
  33. MediLink/MediLink_API_Generator.py +83 -60
  34. MediLink/MediLink_API_v3.py +1 -1
  35. MediLink/MediLink_ClaimStatus.py +177 -31
  36. MediLink/MediLink_DataMgmt.py +405 -72
  37. MediLink/MediLink_Decoder.py +20 -1
  38. MediLink/MediLink_Deductible.py +155 -28
  39. MediLink/MediLink_Display_Utils.py +72 -0
  40. MediLink/MediLink_Down.py +127 -5
  41. MediLink/MediLink_Gmail.py +712 -653
  42. MediLink/MediLink_PatientProcessor.py +257 -0
  43. MediLink/MediLink_UI.py +85 -61
  44. MediLink/MediLink_Up.py +28 -4
  45. MediLink/MediLink_insurance_utils.py +227 -264
  46. MediLink/MediLink_main.py +248 -0
  47. MediLink/MediLink_smart_import.py +264 -0
  48. MediLink/__init__.py +93 -0
  49. MediLink/insurance_type_integration_test.py +66 -76
  50. MediLink/test.py +1 -1
  51. MediLink/test_timing.py +59 -0
  52. {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/METADATA +1 -1
  53. medicafe-0.250805.0.dist-info/RECORD +81 -0
  54. medicafe-0.250805.0.dist-info/entry_points.txt +2 -0
  55. {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/top_level.txt +1 -0
  56. medicafe-0.250728.8.dist-info/RECORD +0 -59
  57. {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/LICENSE +0 -0
  58. {medicafe-0.250728.8.dist-info → medicafe-0.250805.0.dist-info}/WHEEL +0 -0
MediCafe/core_utils.py ADDED
@@ -0,0 +1,450 @@
1
+ # core_utils.py
2
+ """
3
+ Core utilities module for MediCafe
4
+ This module contains shared functionality between MediBot and MediLink modules
5
+ to break circular import dependencies.
6
+ """
7
+
8
+ import os, sys
9
+
10
+ # Ensure proper path setup for imports
11
+ # Get the project root directory (parent of MediCafe directory)
12
+ project_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
13
+ medilink_dir = os.path.join(project_dir, 'MediLink')
14
+ medibot_dir = os.path.join(project_dir, 'MediBot')
15
+
16
+ # Add paths in order of priority - project root first, then module directories
17
+ if project_dir not in sys.path:
18
+ sys.path.insert(0, project_dir)
19
+ if medilink_dir not in sys.path:
20
+ sys.path.insert(0, medilink_dir)
21
+ if medibot_dir not in sys.path:
22
+ sys.path.insert(0, medibot_dir)
23
+
24
+ # Common constants and configurations
25
+ DEFAULT_CONFIG_PATH = os.path.join(project_dir, 'json', 'config.json')
26
+ DEFAULT_CROSSWALK_PATH = os.path.join(project_dir, 'json', 'crosswalk.json')
27
+
28
+ def setup_project_path(file_path=None):
29
+ """
30
+ Standard project path setup function used by all entry points.
31
+
32
+ Args:
33
+ file_path: The __file__ of the calling module. If None, uses this file's directory.
34
+
35
+ Returns:
36
+ The project directory path.
37
+ """
38
+ if file_path is None:
39
+ file_path = __file__
40
+
41
+ project_dir = os.path.abspath(os.path.join(os.path.dirname(file_path), ".."))
42
+ current_dir = os.path.abspath(os.path.dirname(file_path))
43
+
44
+ if project_dir not in sys.path:
45
+ sys.path.insert(0, project_dir)
46
+ if current_dir not in sys.path:
47
+ sys.path.insert(0, current_dir)
48
+
49
+ return project_dir
50
+
51
+ def setup_module_paths(file_path):
52
+ """
53
+ Enhanced path setup for individual modules.
54
+ Sets up both project root and module directory paths.
55
+
56
+ Args:
57
+ file_path: The __file__ of the calling module
58
+
59
+ Returns:
60
+ Tuple of (project_dir, current_dir)
61
+ """
62
+ project_dir = os.path.abspath(os.path.join(os.path.dirname(file_path), ".."))
63
+ current_dir = os.path.abspath(os.path.dirname(file_path))
64
+
65
+ # Add paths in order of priority
66
+ if project_dir not in sys.path:
67
+ sys.path.insert(0, project_dir)
68
+ if current_dir not in sys.path:
69
+ sys.path.insert(0, current_dir)
70
+
71
+ return project_dir, current_dir
72
+
73
+ def safe_import_with_fallback(primary_import_path, fallback_import_path=None, function_name=None):
74
+ """
75
+ Safely import a module or function with fallback options.
76
+
77
+ Args:
78
+ primary_import_path (str): Primary import path to try
79
+ fallback_import_path (str): Fallback import path if primary fails
80
+ function_name (str): Specific function name to extract from module
81
+
82
+ Returns:
83
+ The imported module or function, or None if all imports fail
84
+ """
85
+ try:
86
+ if function_name:
87
+ module = __import__(primary_import_path, fromlist=[function_name])
88
+ return getattr(module, function_name)
89
+ else:
90
+ return __import__(primary_import_path)
91
+ except ImportError:
92
+ if fallback_import_path:
93
+ try:
94
+ if function_name:
95
+ module = __import__(fallback_import_path, fromlist=[function_name])
96
+ return getattr(module, function_name)
97
+ else:
98
+ return __import__(fallback_import_path)
99
+ except ImportError:
100
+ return None
101
+ return None
102
+
103
+ def smart_import(import_specs, default_value=None):
104
+ """
105
+ Enhanced import function that tries multiple import strategies intelligently.
106
+
107
+ Args:
108
+ import_specs (list): List of import specifications. Each can be:
109
+ - String: Direct import path
110
+ - Tuple: (import_path, function_name)
111
+ - Dict: {'path': import_path, 'function': function_name, 'fallback': fallback_path}
112
+ default_value: Value to return if all imports fail
113
+
114
+ Returns:
115
+ The imported module/function or default_value
116
+ """
117
+ for spec in import_specs:
118
+ try:
119
+ if isinstance(spec, str):
120
+ # Simple string - direct import
121
+ return __import__(spec)
122
+ elif isinstance(spec, tuple):
123
+ # Tuple - (path, function_name)
124
+ path, function_name = spec
125
+ module = __import__(path, fromlist=[function_name])
126
+ return getattr(module, function_name)
127
+ elif isinstance(spec, dict):
128
+ # Dict with fallback
129
+ path = spec['path']
130
+ function_name = spec.get('function')
131
+ fallback = spec.get('fallback')
132
+
133
+ try:
134
+ if function_name:
135
+ module = __import__(path, fromlist=[function_name])
136
+ return getattr(module, function_name)
137
+ else:
138
+ return __import__(path)
139
+ except ImportError:
140
+ if fallback:
141
+ try:
142
+ if function_name:
143
+ module = __import__(fallback, fromlist=[function_name])
144
+ return getattr(module, function_name)
145
+ else:
146
+ return __import__(fallback)
147
+ except ImportError:
148
+ continue
149
+ continue
150
+ except ImportError:
151
+ continue
152
+
153
+ return default_value
154
+
155
+ def import_medibot_module(module_name, function_name=None):
156
+ """
157
+ Centralized function to import MediBot modules with intelligent fallbacks.
158
+
159
+ Args:
160
+ module_name (str): Name of the MediBot module (e.g., 'MediBot_dataformat_library')
161
+ function_name (str): Specific function to extract (optional)
162
+
163
+ Returns:
164
+ The imported module/function or None
165
+ """
166
+ import_specs = [
167
+ # Direct import first
168
+ module_name,
169
+ # Then try with MediBot prefix
170
+ 'MediBot.{}'.format(module_name),
171
+ # Then try relative import
172
+ '.{}'.format(module_name),
173
+ # Finally try as a submodule
174
+ {'path': 'MediBot.{}'.format(module_name), 'fallback': module_name}
175
+ ]
176
+
177
+ if function_name:
178
+ # If we need a specific function, modify specs to extract it
179
+ function_specs = []
180
+ for spec in import_specs:
181
+ if isinstance(spec, str):
182
+ function_specs.append((spec, function_name))
183
+ elif isinstance(spec, dict):
184
+ function_specs.append({
185
+ 'path': spec['path'],
186
+ 'function': function_name,
187
+ 'fallback': spec.get('fallback')
188
+ })
189
+ return smart_import(function_specs)
190
+ else:
191
+ return smart_import(import_specs)
192
+
193
+ def import_medibot_module_with_debug(module_name, function_name=None):
194
+ """
195
+ Enhanced version of import_medibot_module with debugging information.
196
+
197
+ Args:
198
+ module_name (str): Name of the MediBot module
199
+ function_name (str): Specific function to extract (optional)
200
+
201
+ Returns:
202
+ The imported module/function or None
203
+ """
204
+ # Try the standard import first
205
+ result = import_medibot_module(module_name, function_name)
206
+ if result is not None:
207
+ return result
208
+
209
+ # If that fails, try additional strategies with debugging
210
+ additional_specs = [
211
+ # Try as a direct file import
212
+ '{}.py'.format(module_name),
213
+ # Try with full path resolution
214
+ 'MediBot.{}.py'.format(module_name),
215
+ # Try importing from current directory
216
+ './{}'.format(module_name),
217
+ # Try importing from parent directory
218
+ '../{}'.format(module_name)
219
+ ]
220
+
221
+ for spec in additional_specs:
222
+ try:
223
+ if function_name:
224
+ module = __import__(spec, fromlist=[function_name])
225
+ return getattr(module, function_name)
226
+ else:
227
+ return __import__(spec)
228
+ except ImportError:
229
+ continue
230
+
231
+ # If all else fails, log the failure
232
+ config_loader = get_shared_config_loader()
233
+ if config_loader:
234
+ config_loader.log("Failed to import MediBot module: {}".format(module_name), level="WARNING")
235
+ else:
236
+ print("[WARNING] Failed to import MediBot module: {}".format(module_name))
237
+
238
+ return None
239
+
240
+ def import_medilink_module(module_name, function_name=None):
241
+ """
242
+ Centralized function to import MediLink modules with intelligent fallbacks.
243
+
244
+ Args:
245
+ module_name (str): Name of the MediLink module
246
+ function_name (str): Specific function to extract (optional)
247
+
248
+ Returns:
249
+ The imported module/function or None
250
+ """
251
+ import_specs = [
252
+ # Direct import first
253
+ module_name,
254
+ # Then try with MediLink prefix
255
+ 'MediLink.{}'.format(module_name),
256
+ # Then try relative import
257
+ '.{}'.format(module_name),
258
+ # Finally try as a submodule
259
+ {'path': 'MediLink.{}'.format(module_name), 'fallback': module_name}
260
+ ]
261
+
262
+ if function_name:
263
+ # If we need a specific function, modify specs to extract it
264
+ function_specs = []
265
+ for spec in import_specs:
266
+ if isinstance(spec, str):
267
+ function_specs.append((spec, function_name))
268
+ elif isinstance(spec, dict):
269
+ function_specs.append({
270
+ 'path': spec['path'],
271
+ 'function': function_name,
272
+ 'fallback': spec.get('fallback')
273
+ })
274
+ return smart_import(function_specs)
275
+ else:
276
+ return smart_import(import_specs)
277
+
278
+ def get_shared_config_loader():
279
+ """
280
+ Returns the MediLink_ConfigLoader module using safe import patterns.
281
+ This is used by both MediBot and MediLink modules.
282
+ """
283
+ # Try multiple import strategies - now including the new MediCafe location
284
+ try:
285
+ # First try to import directly from MediCafe package
286
+ from MediCafe import MediLink_ConfigLoader
287
+ return MediLink_ConfigLoader
288
+ except ImportError:
289
+ try:
290
+ # Try direct import from MediCafe directory
291
+ import MediLink_ConfigLoader
292
+ return MediLink_ConfigLoader
293
+ except ImportError:
294
+ try:
295
+ # Try relative import from current directory
296
+ from . import MediLink_ConfigLoader
297
+ return MediLink_ConfigLoader
298
+ except ImportError:
299
+ return None
300
+
301
+ def create_fallback_logger():
302
+ """
303
+ Creates a minimal fallback logger when MediLink_ConfigLoader is unavailable.
304
+
305
+ Returns:
306
+ A simple logger object with a log method
307
+ """
308
+ class FallbackLogger:
309
+ def log(self, message, level="INFO"):
310
+ print("[{}] {}".format(level, message))
311
+
312
+ return FallbackLogger()
313
+
314
+ def get_config_loader_with_fallback():
315
+ """
316
+ Get MediLink_ConfigLoader with automatic fallback to simple logger.
317
+
318
+ Returns:
319
+ MediLink_ConfigLoader or FallbackLogger
320
+ """
321
+ config_loader = get_shared_config_loader()
322
+ if config_loader is None:
323
+ return create_fallback_logger()
324
+ return config_loader
325
+
326
+ def log_import_error(module_name, error, level="WARNING"):
327
+ """
328
+ Centralized logging for import errors.
329
+
330
+ Args:
331
+ module_name (str): Name of the module that failed to import
332
+ error (Exception): The import error that occurred
333
+ level (str): Log level (WARNING, ERROR, etc.)
334
+ """
335
+ config_loader = get_shared_config_loader()
336
+ if config_loader and hasattr(config_loader, 'log'):
337
+ config_loader.log("Failed to import {}: {}".format(module_name, error), level=level)
338
+ else:
339
+ print("[{}] Failed to import {}: {}".format(level, module_name, error))
340
+
341
+ def create_config_cache():
342
+ """
343
+ Creates a lazy configuration loading pattern for modules.
344
+ Returns a tuple of (get_config_function, cache_variables).
345
+
346
+ Usage:
347
+ _get_config, (_config_cache, _crosswalk_cache) = create_config_cache()
348
+
349
+ # Later in functions:
350
+ config, crosswalk = _get_config()
351
+ """
352
+ _config_cache = None
353
+ _crosswalk_cache = None
354
+
355
+ def _get_config():
356
+ nonlocal _config_cache, _crosswalk_cache
357
+ if _config_cache is None:
358
+ config_loader = get_shared_config_loader()
359
+ if config_loader:
360
+ _config_cache, _crosswalk_cache = config_loader.load_configuration()
361
+ else:
362
+ _config_cache, _crosswalk_cache = {}, {}
363
+ return _config_cache, _crosswalk_cache
364
+
365
+ return _get_config, (_config_cache, _crosswalk_cache)
366
+
367
+ # Common import patterns used throughout the codebase
368
+ def import_with_alternatives(import_specs):
369
+ """
370
+ Import a module using multiple alternative paths.
371
+
372
+ Args:
373
+ import_specs (list): List of tuples containing (import_path, function_name_or_None)
374
+
375
+ Returns:
376
+ The first successfully imported module or function
377
+ """
378
+ for import_path, function_name in import_specs:
379
+ result = safe_import_with_fallback(import_path, function_name=function_name)
380
+ if result is not None:
381
+ return result
382
+ return None
383
+
384
+ # API Client Factory Integration
385
+ def get_api_client_factory():
386
+ """
387
+ Get configured API client factory using shared configuration.
388
+
389
+ Returns:
390
+ APIClientFactory: Configured factory instance or None if unavailable
391
+ """
392
+ # Try multiple import paths for factory
393
+ import_specs = [
394
+ ('MediCafe.api_factory', 'APIClientFactory'),
395
+ ('MediLink.MediLink_API_Factory', 'APIClientFactory'), # Legacy fallback
396
+ ('MediLink_API_Factory', 'APIClientFactory') # Legacy fallback
397
+ ]
398
+
399
+ APIClientFactory = import_with_alternatives(import_specs)
400
+ if not APIClientFactory:
401
+ log_import_error('MediCafe.api_factory', Exception("All import paths failed"))
402
+ return None
403
+
404
+ try:
405
+ config_loader = get_shared_config_loader()
406
+ if config_loader:
407
+ try:
408
+ config, _ = config_loader.load_configuration()
409
+ factory_config = config.get('API_Factory_Config', {})
410
+ return APIClientFactory(factory_config)
411
+ except Exception:
412
+ # Fall back to default configuration
413
+ return APIClientFactory()
414
+ else:
415
+ return APIClientFactory()
416
+ except Exception as e:
417
+ # Don't log error here - just return None silently
418
+ return None
419
+
420
+ def get_api_client(**kwargs):
421
+ """
422
+ Convenience function to get API client directly.
423
+
424
+ Args:
425
+ **kwargs: Additional parameters
426
+
427
+ Returns:
428
+ APIClient: v3 API client instance or None if unavailable
429
+ """
430
+ factory = get_api_client_factory()
431
+ if factory:
432
+ return factory.get_client(**kwargs)
433
+ return None
434
+
435
+ def get_api_core_client(**kwargs):
436
+ """
437
+ Get API client from MediCafe core API module.
438
+
439
+ Args:
440
+ **kwargs: Additional parameters
441
+
442
+ Returns:
443
+ APIClient: Core API client instance or None if unavailable
444
+ """
445
+ try:
446
+ from MediCafe.api_core import APIClient
447
+ return APIClient(**kwargs)
448
+ except ImportError:
449
+ # Don't log error here - just return None silently
450
+ return None