ins-pricing 0.4.4__py3-none-any.whl → 0.5.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.
Files changed (96) hide show
  1. ins_pricing/README.md +74 -56
  2. ins_pricing/__init__.py +142 -90
  3. ins_pricing/cli/BayesOpt_entry.py +52 -50
  4. ins_pricing/cli/BayesOpt_incremental.py +832 -898
  5. ins_pricing/cli/Explain_Run.py +31 -23
  6. ins_pricing/cli/Explain_entry.py +532 -579
  7. ins_pricing/cli/Pricing_Run.py +31 -23
  8. ins_pricing/cli/bayesopt_entry_runner.py +1440 -1438
  9. ins_pricing/cli/utils/cli_common.py +256 -256
  10. ins_pricing/cli/utils/cli_config.py +375 -375
  11. ins_pricing/cli/utils/import_resolver.py +382 -365
  12. ins_pricing/cli/utils/notebook_utils.py +340 -340
  13. ins_pricing/cli/watchdog_run.py +209 -201
  14. ins_pricing/frontend/README.md +573 -419
  15. ins_pricing/frontend/__init__.py +10 -10
  16. ins_pricing/frontend/config_builder.py +1 -0
  17. ins_pricing/frontend/example_workflows.py +1 -1
  18. ins_pricing/governance/__init__.py +20 -20
  19. ins_pricing/governance/release.py +159 -159
  20. ins_pricing/modelling/README.md +67 -0
  21. ins_pricing/modelling/__init__.py +147 -92
  22. ins_pricing/modelling/bayesopt/README.md +59 -0
  23. ins_pricing/modelling/{core/bayesopt → bayesopt}/__init__.py +64 -102
  24. ins_pricing/modelling/{core/bayesopt → bayesopt}/config_preprocess.py +562 -550
  25. ins_pricing/modelling/{core/bayesopt → bayesopt}/core.py +965 -962
  26. ins_pricing/modelling/{core/bayesopt → bayesopt}/model_explain_mixin.py +296 -296
  27. ins_pricing/modelling/{core/bayesopt → bayesopt}/model_plotting_mixin.py +482 -548
  28. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/__init__.py +27 -27
  29. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_ft_trainer.py +915 -913
  30. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_gnn.py +788 -785
  31. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_resn.py +448 -446
  32. ins_pricing/modelling/bayesopt/trainers/__init__.py +19 -0
  33. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_base.py +1308 -1308
  34. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_ft.py +3 -3
  35. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_glm.py +197 -198
  36. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_gnn.py +344 -344
  37. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_resn.py +283 -283
  38. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_xgb.py +346 -347
  39. ins_pricing/modelling/bayesopt/utils/__init__.py +67 -0
  40. ins_pricing/modelling/bayesopt/utils/constants.py +21 -0
  41. ins_pricing/modelling/bayesopt/utils/io_utils.py +7 -0
  42. ins_pricing/modelling/bayesopt/utils/losses.py +27 -0
  43. ins_pricing/modelling/bayesopt/utils/metrics_and_devices.py +17 -0
  44. ins_pricing/modelling/{core/bayesopt → bayesopt}/utils/torch_trainer_mixin.py +623 -623
  45. ins_pricing/modelling/{core/evaluation.py → evaluation.py} +113 -104
  46. ins_pricing/modelling/explain/__init__.py +55 -55
  47. ins_pricing/modelling/explain/metrics.py +27 -174
  48. ins_pricing/modelling/explain/permutation.py +237 -237
  49. ins_pricing/modelling/plotting/__init__.py +40 -36
  50. ins_pricing/modelling/plotting/compat.py +228 -0
  51. ins_pricing/modelling/plotting/curves.py +572 -572
  52. ins_pricing/modelling/plotting/diagnostics.py +163 -163
  53. ins_pricing/modelling/plotting/geo.py +362 -362
  54. ins_pricing/modelling/plotting/importance.py +121 -121
  55. ins_pricing/pricing/__init__.py +27 -27
  56. ins_pricing/production/__init__.py +35 -25
  57. ins_pricing/production/{predict.py → inference.py} +140 -57
  58. ins_pricing/production/monitoring.py +8 -21
  59. ins_pricing/reporting/__init__.py +11 -11
  60. ins_pricing/setup.py +1 -1
  61. ins_pricing/tests/production/test_inference.py +90 -0
  62. ins_pricing/utils/__init__.py +116 -83
  63. ins_pricing/utils/device.py +255 -255
  64. ins_pricing/utils/features.py +53 -0
  65. ins_pricing/utils/io.py +72 -0
  66. ins_pricing/{modelling/core/bayesopt/utils → utils}/losses.py +125 -129
  67. ins_pricing/utils/metrics.py +158 -24
  68. ins_pricing/utils/numerics.py +76 -0
  69. ins_pricing/utils/paths.py +9 -1
  70. {ins_pricing-0.4.4.dist-info → ins_pricing-0.5.0.dist-info}/METADATA +55 -35
  71. ins_pricing-0.5.0.dist-info/RECORD +131 -0
  72. ins_pricing/CHANGELOG.md +0 -272
  73. ins_pricing/RELEASE_NOTES_0.2.8.md +0 -344
  74. ins_pricing/docs/LOSS_FUNCTIONS.md +0 -78
  75. ins_pricing/docs/modelling/BayesOpt_USAGE.md +0 -945
  76. ins_pricing/docs/modelling/README.md +0 -34
  77. ins_pricing/frontend/QUICKSTART.md +0 -152
  78. ins_pricing/modelling/core/BayesOpt.py +0 -146
  79. ins_pricing/modelling/core/__init__.py +0 -1
  80. ins_pricing/modelling/core/bayesopt/PHASE2_REFACTORING_SUMMARY.md +0 -449
  81. ins_pricing/modelling/core/bayesopt/PHASE3_REFACTORING_SUMMARY.md +0 -406
  82. ins_pricing/modelling/core/bayesopt/REFACTORING_SUMMARY.md +0 -247
  83. ins_pricing/modelling/core/bayesopt/trainers/__init__.py +0 -19
  84. ins_pricing/modelling/core/bayesopt/utils/__init__.py +0 -86
  85. ins_pricing/modelling/core/bayesopt/utils/constants.py +0 -183
  86. ins_pricing/modelling/core/bayesopt/utils/io_utils.py +0 -126
  87. ins_pricing/modelling/core/bayesopt/utils/metrics_and_devices.py +0 -555
  88. ins_pricing/modelling/core/bayesopt/utils.py +0 -105
  89. ins_pricing/modelling/core/bayesopt/utils_backup.py +0 -1503
  90. ins_pricing/tests/production/test_predict.py +0 -233
  91. ins_pricing-0.4.4.dist-info/RECORD +0 -137
  92. /ins_pricing/modelling/{core/bayesopt → bayesopt}/config_components.py +0 -0
  93. /ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_ft_components.py +0 -0
  94. /ins_pricing/modelling/{core/bayesopt → bayesopt}/utils/distributed_utils.py +0 -0
  95. {ins_pricing-0.4.4.dist-info → ins_pricing-0.5.0.dist-info}/WHEEL +0 -0
  96. {ins_pricing-0.4.4.dist-info → ins_pricing-0.5.0.dist-info}/top_level.txt +0 -0
@@ -1,376 +1,393 @@
1
- """Unified import resolver for CLI modules.
2
-
3
- This module provides a single source of truth for all import fallback chains,
4
- eliminating the need for nested try/except blocks in multiple CLI files.
5
-
6
- Usage:
7
- from ins_pricing.cli.utils.import_resolver import resolve_imports
8
- imports = resolve_imports()
9
- ropt = imports.bayesopt
10
- PLOT_MODEL_LABELS = imports.PLOT_MODEL_LABELS
11
- """
12
-
13
- from __future__ import annotations
14
-
15
- import importlib
16
- import os
17
- import sys
18
- from dataclasses import dataclass, field
19
- from pathlib import Path
20
- from typing import Any, Callable, Dict, List, Optional, Tuple, Type
21
-
22
-
23
- @dataclass
24
- class ResolvedImports:
25
- """Container for resolved imports from the bayesopt ecosystem."""
26
-
27
- # Core bayesopt module
28
- bayesopt: Any = None
29
-
30
- # CLI common utilities
31
- PLOT_MODEL_LABELS: Dict[str, Tuple[str, str]] = field(default_factory=dict)
32
- PYTORCH_TRAINERS: List[str] = field(default_factory=list)
33
- build_model_names: Optional[Callable] = None
34
- dedupe_preserve_order: Optional[Callable] = None
35
- load_dataset: Optional[Callable] = None
36
- parse_model_pairs: Optional[Callable] = None
37
- resolve_data_path: Optional[Callable] = None
38
- resolve_path: Optional[Callable] = None
39
- fingerprint_file: Optional[Callable] = None
40
- coerce_dataset_types: Optional[Callable] = None
41
- split_train_test: Optional[Callable] = None
42
-
43
- # CLI config utilities
44
- add_config_json_arg: Optional[Callable] = None
45
- add_output_dir_arg: Optional[Callable] = None
46
- resolve_and_load_config: Optional[Callable] = None
47
- resolve_data_config: Optional[Callable] = None
48
- resolve_report_config: Optional[Callable] = None
49
- resolve_split_config: Optional[Callable] = None
50
- resolve_runtime_config: Optional[Callable] = None
51
- resolve_output_dirs: Optional[Callable] = None
52
-
53
- # Evaluation utilities
54
- bootstrap_ci: Optional[Callable] = None
55
- calibrate_predictions: Optional[Callable] = None
56
- metrics_report: Optional[Callable] = None
57
- select_threshold: Optional[Callable] = None
58
-
59
- # Governance and reporting
60
- ModelArtifact: Optional[Type] = None
61
- ModelRegistry: Optional[Type] = None
62
- drift_psi_report: Optional[Callable] = None
63
- group_metrics: Optional[Callable] = None
64
- ReportPayload: Optional[Type] = None
65
- write_report: Optional[Callable] = None
66
-
67
- # Logging
68
- configure_run_logging: Optional[Callable] = None
69
-
70
- # Plotting
71
- plot_loss_curve: Optional[Callable] = None
72
-
73
-
74
- def _debug_imports_enabled() -> bool:
75
- value = os.environ.get("BAYESOPT_DEBUG_IMPORTS")
76
- if value is None:
77
- return False
78
- return str(value).strip().lower() in {"1", "true", "yes", "y", "on"}
79
-
80
-
81
- def _try_import(module_path: str, attr_name: Optional[str] = None) -> Optional[Any]:
82
- """Attempt to import a module or attribute, returning None on failure."""
83
- try:
84
- module = importlib.import_module(module_path)
85
- if attr_name:
86
- result = getattr(module, attr_name, None)
87
- else:
88
- result = module
89
- if _debug_imports_enabled():
90
- origin = getattr(module, "__file__", None)
91
- origin = origin or getattr(module, "__path__", None)
92
- print(
93
- f"[BAYESOPT_DEBUG_IMPORTS] imported {module_path}"
94
- f"{'::' + attr_name if attr_name else ''} from {origin}",
95
- file=sys.stderr,
96
- flush=True,
97
- )
98
- return result
99
- except Exception as exc:
100
- if _debug_imports_enabled():
101
- print(
102
- f"[BAYESOPT_DEBUG_IMPORTS] failed import {module_path}"
103
- f"{'::' + attr_name if attr_name else ''}: {exc.__class__.__name__}: {exc}",
104
- file=sys.stderr,
105
- flush=True,
106
- )
107
- return None
108
-
109
-
110
- def _try_import_from_paths(
111
- paths: List[str],
112
- attr_name: Optional[str] = None
113
- ) -> Optional[Any]:
114
- """Try importing from multiple module paths, return first success."""
115
- for path in paths:
116
- result = _try_import(path, attr_name)
117
- if result is not None:
118
- return result
119
- return None
120
-
121
-
1
+ """Unified import resolver for CLI modules.
2
+
3
+ This module provides a single source of truth for all import fallback chains,
4
+ eliminating the need for nested try/except blocks in multiple CLI files.
5
+
6
+ Usage:
7
+ from ins_pricing.cli.utils.import_resolver import resolve_imports
8
+ imports = resolve_imports()
9
+ ropt = imports.bayesopt
10
+ PLOT_MODEL_LABELS = imports.PLOT_MODEL_LABELS
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import importlib
16
+ import os
17
+ import sys
18
+ from dataclasses import dataclass, field
19
+ from pathlib import Path
20
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Type
21
+
22
+
23
+ @dataclass
24
+ class ResolvedImports:
25
+ """Container for resolved imports from the bayesopt ecosystem."""
26
+
27
+ # Core bayesopt module
28
+ bayesopt: Any = None
29
+
30
+ # CLI common utilities
31
+ PLOT_MODEL_LABELS: Dict[str, Tuple[str, str]] = field(default_factory=dict)
32
+ PYTORCH_TRAINERS: List[str] = field(default_factory=list)
33
+ build_model_names: Optional[Callable] = None
34
+ dedupe_preserve_order: Optional[Callable] = None
35
+ load_dataset: Optional[Callable] = None
36
+ parse_model_pairs: Optional[Callable] = None
37
+ resolve_data_path: Optional[Callable] = None
38
+ resolve_path: Optional[Callable] = None
39
+ fingerprint_file: Optional[Callable] = None
40
+ coerce_dataset_types: Optional[Callable] = None
41
+ split_train_test: Optional[Callable] = None
42
+
43
+ # CLI config utilities
44
+ add_config_json_arg: Optional[Callable] = None
45
+ add_output_dir_arg: Optional[Callable] = None
46
+ resolve_and_load_config: Optional[Callable] = None
47
+ resolve_data_config: Optional[Callable] = None
48
+ resolve_report_config: Optional[Callable] = None
49
+ resolve_explain_save_root: Optional[Callable] = None
50
+ resolve_explain_save_dir: Optional[Callable] = None
51
+ resolve_explain_output_overrides: Optional[Callable] = None
52
+ resolve_model_path_value: Optional[Callable] = None
53
+ resolve_split_config: Optional[Callable] = None
54
+ resolve_runtime_config: Optional[Callable] = None
55
+ resolve_output_dirs: Optional[Callable] = None
56
+
57
+ # Evaluation utilities
58
+ bootstrap_ci: Optional[Callable] = None
59
+ calibrate_predictions: Optional[Callable] = None
60
+ metrics_report: Optional[Callable] = None
61
+ select_threshold: Optional[Callable] = None
62
+
63
+ # Governance and reporting
64
+ ModelArtifact: Optional[Type] = None
65
+ ModelRegistry: Optional[Type] = None
66
+ drift_psi_report: Optional[Callable] = None
67
+ group_metrics: Optional[Callable] = None
68
+ ReportPayload: Optional[Type] = None
69
+ write_report: Optional[Callable] = None
70
+
71
+ # Logging
72
+ configure_run_logging: Optional[Callable] = None
73
+
74
+ # Plotting
75
+ plot_loss_curve: Optional[Callable] = None
76
+
77
+
78
+ def _debug_imports_enabled() -> bool:
79
+ value = os.environ.get("BAYESOPT_DEBUG_IMPORTS")
80
+ if value is None:
81
+ return False
82
+ return str(value).strip().lower() in {"1", "true", "yes", "y", "on"}
83
+
84
+
85
+ def _try_import(module_path: str, attr_name: Optional[str] = None) -> Optional[Any]:
86
+ """Attempt to import a module or attribute, returning None on failure."""
87
+ try:
88
+ module = importlib.import_module(module_path)
89
+ if attr_name:
90
+ result = getattr(module, attr_name, None)
91
+ else:
92
+ result = module
93
+ if _debug_imports_enabled():
94
+ origin = getattr(module, "__file__", None)
95
+ origin = origin or getattr(module, "__path__", None)
96
+ print(
97
+ f"[BAYESOPT_DEBUG_IMPORTS] imported {module_path}"
98
+ f"{'::' + attr_name if attr_name else ''} from {origin}",
99
+ file=sys.stderr,
100
+ flush=True,
101
+ )
102
+ return result
103
+ except Exception as exc:
104
+ if _debug_imports_enabled():
105
+ print(
106
+ f"[BAYESOPT_DEBUG_IMPORTS] failed import {module_path}"
107
+ f"{'::' + attr_name if attr_name else ''}: {exc.__class__.__name__}: {exc}",
108
+ file=sys.stderr,
109
+ flush=True,
110
+ )
111
+ return None
112
+
113
+
114
+ def _try_import_from_paths(
115
+ paths: List[str],
116
+ attr_name: Optional[str] = None
117
+ ) -> Optional[Any]:
118
+ """Try importing from multiple module paths, return first success."""
119
+ for path in paths:
120
+ result = _try_import(path, attr_name)
121
+ if result is not None:
122
+ return result
123
+ return None
124
+
125
+
122
126
  def _resolve_bayesopt() -> Optional[Any]:
123
127
  """Resolve the bayesopt module from multiple possible locations."""
124
128
  paths = [
125
- "ins_pricing.modelling.core.bayesopt",
129
+ "ins_pricing.modelling.bayesopt",
126
130
  "bayesopt",
127
131
  "BayesOpt",
128
132
  ]
129
- return _try_import_from_paths(paths)
130
-
131
-
132
- def _resolve_cli_common() -> Dict[str, Any]:
133
- """Resolve CLI common utilities."""
134
- paths = [
135
- "ins_pricing.cli.utils.cli_common",
136
- "cli.utils.cli_common",
137
- "utils.cli_common",
138
- ]
139
-
140
- attrs = [
141
- "PLOT_MODEL_LABELS",
142
- "PYTORCH_TRAINERS",
143
- "build_model_names",
144
- "dedupe_preserve_order",
145
- "load_dataset",
146
- "parse_model_pairs",
147
- "resolve_data_path",
148
- "resolve_path",
149
- "fingerprint_file",
150
- "coerce_dataset_types",
151
- "split_train_test",
152
- ]
153
-
154
- results = {}
155
- for path in paths:
156
- module = _try_import(path)
157
- if module is not None:
158
- for attr in attrs:
159
- if attr not in results or results[attr] is None:
160
- results[attr] = getattr(module, attr, None)
161
- # If we got most attributes, break
162
- if sum(1 for v in results.values() if v is not None) >= len(attrs) // 2:
163
- break
164
-
165
- return results
166
-
167
-
168
- def _resolve_cli_config() -> Dict[str, Any]:
169
- """Resolve CLI config utilities."""
170
- paths = [
171
- "ins_pricing.cli.utils.cli_config",
172
- "cli.utils.cli_config",
173
- "utils.cli_config",
174
- ]
175
-
176
- attrs = [
177
- "add_config_json_arg",
178
- "add_output_dir_arg",
179
- "resolve_and_load_config",
180
- "resolve_data_config",
181
- "resolve_report_config",
182
- "resolve_split_config",
183
- "resolve_runtime_config",
184
- "resolve_output_dirs",
185
- ]
186
-
187
- results = {}
188
- for path in paths:
189
- module = _try_import(path)
190
- if module is not None:
191
- for attr in attrs:
192
- if attr not in results or results[attr] is None:
193
- results[attr] = getattr(module, attr, None)
194
- if sum(1 for v in results.values() if v is not None) >= len(attrs) // 2:
195
- break
196
-
197
- return results
198
-
199
-
133
+ return _try_import_from_paths(paths)
134
+
135
+
136
+ def _resolve_cli_common() -> Dict[str, Any]:
137
+ """Resolve CLI common utilities."""
138
+ paths = [
139
+ "ins_pricing.cli.utils.cli_common",
140
+ "cli.utils.cli_common",
141
+ "utils.cli_common",
142
+ ]
143
+
144
+ attrs = [
145
+ "PLOT_MODEL_LABELS",
146
+ "PYTORCH_TRAINERS",
147
+ "build_model_names",
148
+ "dedupe_preserve_order",
149
+ "load_dataset",
150
+ "parse_model_pairs",
151
+ "resolve_data_path",
152
+ "resolve_path",
153
+ "fingerprint_file",
154
+ "coerce_dataset_types",
155
+ "split_train_test",
156
+ ]
157
+
158
+ results = {}
159
+ for path in paths:
160
+ module = _try_import(path)
161
+ if module is not None:
162
+ for attr in attrs:
163
+ if attr not in results or results[attr] is None:
164
+ results[attr] = getattr(module, attr, None)
165
+ # If we got most attributes, break
166
+ if sum(1 for v in results.values() if v is not None) >= len(attrs) // 2:
167
+ break
168
+
169
+ return results
170
+
171
+
172
+ def _resolve_cli_config() -> Dict[str, Any]:
173
+ """Resolve CLI config utilities."""
174
+ paths = [
175
+ "ins_pricing.cli.utils.cli_config",
176
+ "cli.utils.cli_config",
177
+ "utils.cli_config",
178
+ ]
179
+
180
+ attrs = [
181
+ "add_config_json_arg",
182
+ "add_output_dir_arg",
183
+ "resolve_and_load_config",
184
+ "resolve_data_config",
185
+ "resolve_report_config",
186
+ "resolve_explain_save_root",
187
+ "resolve_explain_save_dir",
188
+ "resolve_explain_output_overrides",
189
+ "resolve_model_path_value",
190
+ "resolve_split_config",
191
+ "resolve_runtime_config",
192
+ "resolve_output_dirs",
193
+ ]
194
+
195
+ results = {}
196
+ for path in paths:
197
+ module = _try_import(path)
198
+ if module is not None:
199
+ for attr in attrs:
200
+ if attr not in results or results[attr] is None:
201
+ results[attr] = getattr(module, attr, None)
202
+ if sum(1 for v in results.values() if v is not None) >= len(attrs) // 2:
203
+ break
204
+
205
+ return results
206
+
207
+
200
208
  def _resolve_evaluation() -> Dict[str, Any]:
201
209
  """Resolve evaluation utilities."""
202
210
  paths = [
203
- "ins_pricing.modelling.core.evaluation",
211
+ "ins_pricing.modelling.evaluation",
204
212
  "evaluation",
205
213
  ]
206
-
207
- results = {}
208
- for path in paths:
209
- module = _try_import(path)
210
- if module is not None:
211
- results["bootstrap_ci"] = getattr(module, "bootstrap_ci", None)
212
- results["calibrate_predictions"] = getattr(module, "calibrate_predictions", None)
213
- results["metrics_report"] = getattr(module, "metrics_report", None)
214
- results["select_threshold"] = getattr(module, "select_threshold", None)
215
- if any(v is not None for v in results.values()):
216
- break
217
-
218
- return results
219
-
220
-
221
- def _resolve_governance() -> Dict[str, Any]:
222
- """Resolve governance and reporting utilities."""
223
- results = {}
224
-
225
- # ModelRegistry and ModelArtifact
226
- registry_paths = [
227
- "ins_pricing.governance.registry",
228
- ]
229
- for path in registry_paths:
230
- module = _try_import(path)
231
- if module is not None:
232
- results["ModelArtifact"] = getattr(module, "ModelArtifact", None)
233
- results["ModelRegistry"] = getattr(module, "ModelRegistry", None)
234
- break
235
-
236
- # PSI report
237
- psi_paths = [
238
- "ins_pricing.production",
239
- ]
240
- for path in psi_paths:
241
- module = _try_import(path)
242
- if module is not None:
243
- results["drift_psi_report"] = getattr(module, "psi_report", None)
244
- break
245
-
246
- # Group metrics
247
- monitoring_paths = [
248
- "ins_pricing.production.monitoring",
249
- ]
250
- for path in monitoring_paths:
251
- module = _try_import(path)
252
- if module is not None:
253
- results["group_metrics"] = getattr(module, "group_metrics", None)
254
- break
255
-
256
- # Report builder
257
- report_paths = [
258
- "ins_pricing.reporting.report_builder",
259
- ]
260
- for path in report_paths:
261
- module = _try_import(path)
262
- if module is not None:
263
- results["ReportPayload"] = getattr(module, "ReportPayload", None)
264
- results["write_report"] = getattr(module, "write_report", None)
265
- break
266
-
267
- return results
268
-
269
-
270
- def _resolve_logging() -> Dict[str, Any]:
271
- """Resolve logging utilities."""
272
- paths = [
273
- "ins_pricing.cli.utils.run_logging",
274
- "cli.utils.run_logging",
275
- "utils.run_logging",
276
- ]
277
-
278
- results = {}
279
- for path in paths:
280
- module = _try_import(path)
281
- if module is not None:
282
- results["configure_run_logging"] = getattr(module, "configure_run_logging", None)
283
- break
284
-
285
- return results
286
-
287
-
288
- def _resolve_plotting() -> Dict[str, Any]:
289
- """Resolve plotting utilities."""
290
- paths = [
291
- "ins_pricing.modelling.plotting.diagnostics",
292
- "ins_pricing.plotting.diagnostics",
293
- ]
294
-
295
- results = {}
296
- for path in paths:
297
- module = _try_import(path)
298
- if module is not None:
299
- results["plot_loss_curve"] = getattr(module, "plot_loss_curve", None)
300
- break
301
-
302
- return results
303
-
304
-
305
- def resolve_imports() -> ResolvedImports:
306
- """Resolve all imports from the bayesopt ecosystem.
307
-
308
- This function attempts to import modules from multiple possible locations,
309
- handling the various ways the package might be installed or run.
310
-
311
- Returns:
312
- ResolvedImports object containing all resolved imports.
313
- """
314
- imports = ResolvedImports()
315
-
316
- # Resolve bayesopt core
317
- imports.bayesopt = _resolve_bayesopt()
318
-
319
- # Resolve CLI common utilities
320
- cli_common = _resolve_cli_common()
321
- imports.PLOT_MODEL_LABELS = cli_common.get("PLOT_MODEL_LABELS", {})
322
- imports.PYTORCH_TRAINERS = cli_common.get("PYTORCH_TRAINERS", [])
323
- imports.build_model_names = cli_common.get("build_model_names")
324
- imports.dedupe_preserve_order = cli_common.get("dedupe_preserve_order")
325
- imports.load_dataset = cli_common.get("load_dataset")
326
- imports.parse_model_pairs = cli_common.get("parse_model_pairs")
327
- imports.resolve_data_path = cli_common.get("resolve_data_path")
328
- imports.resolve_path = cli_common.get("resolve_path")
329
- imports.fingerprint_file = cli_common.get("fingerprint_file")
330
- imports.coerce_dataset_types = cli_common.get("coerce_dataset_types")
331
- imports.split_train_test = cli_common.get("split_train_test")
332
-
333
- # Resolve CLI config utilities
334
- cli_config = _resolve_cli_config()
335
- imports.add_config_json_arg = cli_config.get("add_config_json_arg")
336
- imports.add_output_dir_arg = cli_config.get("add_output_dir_arg")
337
- imports.resolve_and_load_config = cli_config.get("resolve_and_load_config")
338
- imports.resolve_data_config = cli_config.get("resolve_data_config")
339
- imports.resolve_report_config = cli_config.get("resolve_report_config")
340
- imports.resolve_split_config = cli_config.get("resolve_split_config")
341
- imports.resolve_runtime_config = cli_config.get("resolve_runtime_config")
342
- imports.resolve_output_dirs = cli_config.get("resolve_output_dirs")
343
-
344
- # Resolve evaluation utilities
345
- evaluation = _resolve_evaluation()
346
- imports.bootstrap_ci = evaluation.get("bootstrap_ci")
347
- imports.calibrate_predictions = evaluation.get("calibrate_predictions")
348
- imports.metrics_report = evaluation.get("metrics_report")
349
- imports.select_threshold = evaluation.get("select_threshold")
350
-
351
- # Resolve governance and reporting
352
- governance = _resolve_governance()
353
- imports.ModelArtifact = governance.get("ModelArtifact")
354
- imports.ModelRegistry = governance.get("ModelRegistry")
355
- imports.drift_psi_report = governance.get("drift_psi_report")
356
- imports.group_metrics = governance.get("group_metrics")
357
- imports.ReportPayload = governance.get("ReportPayload")
358
- imports.write_report = governance.get("write_report")
359
-
360
- # Resolve logging
361
- logging_utils = _resolve_logging()
362
- imports.configure_run_logging = logging_utils.get("configure_run_logging")
363
-
364
- # Resolve plotting
365
- plotting = _resolve_plotting()
366
- imports.plot_loss_curve = plotting.get("plot_loss_curve")
367
-
368
- return imports
369
-
370
-
371
- # Convenience function for backward compatibility
372
- def setup_sys_path() -> None:
373
- """Ensure the repository root is in sys.path for imports."""
374
- repo_root = Path(__file__).resolve().parents[3]
375
- if str(repo_root) not in sys.path:
376
- sys.path.insert(0, str(repo_root))
214
+
215
+ results = {}
216
+ for path in paths:
217
+ module = _try_import(path)
218
+ if module is not None:
219
+ results["bootstrap_ci"] = getattr(module, "bootstrap_ci", None)
220
+ results["calibrate_predictions"] = getattr(module, "calibrate_predictions", None)
221
+ results["metrics_report"] = getattr(module, "metrics_report", None)
222
+ results["select_threshold"] = getattr(module, "select_threshold", None)
223
+ if any(v is not None for v in results.values()):
224
+ break
225
+
226
+ return results
227
+
228
+
229
+ def _resolve_governance() -> Dict[str, Any]:
230
+ """Resolve governance and reporting utilities."""
231
+ results = {}
232
+
233
+ # ModelRegistry and ModelArtifact
234
+ registry_paths = [
235
+ "ins_pricing.governance.registry",
236
+ ]
237
+ for path in registry_paths:
238
+ module = _try_import(path)
239
+ if module is not None:
240
+ results["ModelArtifact"] = getattr(module, "ModelArtifact", None)
241
+ results["ModelRegistry"] = getattr(module, "ModelRegistry", None)
242
+ break
243
+
244
+ # PSI report
245
+ psi_paths = [
246
+ "ins_pricing.production",
247
+ ]
248
+ for path in psi_paths:
249
+ module = _try_import(path)
250
+ if module is not None:
251
+ results["drift_psi_report"] = getattr(module, "psi_report", None)
252
+ break
253
+
254
+ # Group metrics
255
+ monitoring_paths = [
256
+ "ins_pricing.production.monitoring",
257
+ ]
258
+ for path in monitoring_paths:
259
+ module = _try_import(path)
260
+ if module is not None:
261
+ results["group_metrics"] = getattr(module, "group_metrics", None)
262
+ break
263
+
264
+ # Report builder
265
+ report_paths = [
266
+ "ins_pricing.reporting.report_builder",
267
+ ]
268
+ for path in report_paths:
269
+ module = _try_import(path)
270
+ if module is not None:
271
+ results["ReportPayload"] = getattr(module, "ReportPayload", None)
272
+ results["write_report"] = getattr(module, "write_report", None)
273
+ break
274
+
275
+ return results
276
+
277
+
278
+ def _resolve_logging() -> Dict[str, Any]:
279
+ """Resolve logging utilities."""
280
+ paths = [
281
+ "ins_pricing.cli.utils.run_logging",
282
+ "cli.utils.run_logging",
283
+ "utils.run_logging",
284
+ ]
285
+
286
+ results = {}
287
+ for path in paths:
288
+ module = _try_import(path)
289
+ if module is not None:
290
+ results["configure_run_logging"] = getattr(module, "configure_run_logging", None)
291
+ break
292
+
293
+ return results
294
+
295
+
296
+ def _resolve_plotting() -> Dict[str, Any]:
297
+ """Resolve plotting utilities."""
298
+ paths = [
299
+ "ins_pricing.modelling.plotting.diagnostics",
300
+ "ins_pricing.plotting.diagnostics",
301
+ ]
302
+
303
+ results = {}
304
+ for path in paths:
305
+ module = _try_import(path)
306
+ if module is not None:
307
+ results["plot_loss_curve"] = getattr(module, "plot_loss_curve", None)
308
+ break
309
+
310
+ return results
311
+
312
+
313
+ def resolve_imports() -> ResolvedImports:
314
+ """Resolve all imports from the bayesopt ecosystem.
315
+
316
+ This function attempts to import modules from multiple possible locations,
317
+ handling the various ways the package might be installed or run.
318
+
319
+ Returns:
320
+ ResolvedImports object containing all resolved imports.
321
+ """
322
+ imports = ResolvedImports()
323
+
324
+ # Resolve bayesopt core
325
+ imports.bayesopt = _resolve_bayesopt()
326
+
327
+ # Resolve CLI common utilities
328
+ cli_common = _resolve_cli_common()
329
+ imports.PLOT_MODEL_LABELS = cli_common.get("PLOT_MODEL_LABELS", {})
330
+ imports.PYTORCH_TRAINERS = cli_common.get("PYTORCH_TRAINERS", [])
331
+ imports.build_model_names = cli_common.get("build_model_names")
332
+ imports.dedupe_preserve_order = cli_common.get("dedupe_preserve_order")
333
+ imports.load_dataset = cli_common.get("load_dataset")
334
+ imports.parse_model_pairs = cli_common.get("parse_model_pairs")
335
+ imports.resolve_data_path = cli_common.get("resolve_data_path")
336
+ imports.resolve_path = cli_common.get("resolve_path")
337
+ imports.fingerprint_file = cli_common.get("fingerprint_file")
338
+ imports.coerce_dataset_types = cli_common.get("coerce_dataset_types")
339
+ imports.split_train_test = cli_common.get("split_train_test")
340
+
341
+ # Resolve CLI config utilities
342
+ cli_config = _resolve_cli_config()
343
+ imports.add_config_json_arg = cli_config.get("add_config_json_arg")
344
+ imports.add_output_dir_arg = cli_config.get("add_output_dir_arg")
345
+ imports.resolve_and_load_config = cli_config.get("resolve_and_load_config")
346
+ imports.resolve_data_config = cli_config.get("resolve_data_config")
347
+ imports.resolve_report_config = cli_config.get("resolve_report_config")
348
+ imports.resolve_explain_save_root = cli_config.get("resolve_explain_save_root")
349
+ imports.resolve_explain_save_dir = cli_config.get("resolve_explain_save_dir")
350
+ imports.resolve_explain_output_overrides = cli_config.get("resolve_explain_output_overrides")
351
+ imports.resolve_model_path_value = cli_config.get("resolve_model_path_value")
352
+ imports.resolve_split_config = cli_config.get("resolve_split_config")
353
+ imports.resolve_runtime_config = cli_config.get("resolve_runtime_config")
354
+ imports.resolve_output_dirs = cli_config.get("resolve_output_dirs")
355
+
356
+ # Resolve evaluation utilities
357
+ evaluation = _resolve_evaluation()
358
+ imports.bootstrap_ci = evaluation.get("bootstrap_ci")
359
+ imports.calibrate_predictions = evaluation.get("calibrate_predictions")
360
+ imports.metrics_report = evaluation.get("metrics_report")
361
+ imports.select_threshold = evaluation.get("select_threshold")
362
+
363
+ # Resolve governance and reporting
364
+ governance = _resolve_governance()
365
+ imports.ModelArtifact = governance.get("ModelArtifact")
366
+ imports.ModelRegistry = governance.get("ModelRegistry")
367
+ imports.drift_psi_report = governance.get("drift_psi_report")
368
+ imports.group_metrics = governance.get("group_metrics")
369
+ imports.ReportPayload = governance.get("ReportPayload")
370
+ imports.write_report = governance.get("write_report")
371
+
372
+ # Resolve logging
373
+ logging_utils = _resolve_logging()
374
+ imports.configure_run_logging = logging_utils.get("configure_run_logging")
375
+
376
+ # Resolve plotting
377
+ plotting = _resolve_plotting()
378
+ imports.plot_loss_curve = plotting.get("plot_loss_curve")
379
+
380
+ return imports
381
+
382
+
383
+ # Convenience function for backward compatibility
384
+ def setup_sys_path() -> None:
385
+ """Ensure the repository root is in sys.path for imports."""
386
+ try:
387
+ if importlib.util.find_spec("ins_pricing") is not None:
388
+ return
389
+ except Exception:
390
+ pass
391
+ repo_root = Path(__file__).resolve().parents[3]
392
+ if str(repo_root) not in sys.path:
393
+ sys.path.insert(0, str(repo_root))