ins-pricing 0.4.5__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 (84) hide show
  1. ins_pricing/README.md +48 -22
  2. ins_pricing/__init__.py +142 -90
  3. ins_pricing/cli/BayesOpt_entry.py +52 -50
  4. ins_pricing/cli/BayesOpt_incremental.py +39 -105
  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 +11 -9
  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/__init__.py +10 -10
  15. ins_pricing/frontend/example_workflows.py +1 -1
  16. ins_pricing/governance/__init__.py +20 -20
  17. ins_pricing/governance/release.py +159 -159
  18. ins_pricing/modelling/__init__.py +147 -92
  19. ins_pricing/modelling/{core/bayesopt → bayesopt}/README.md +2 -2
  20. ins_pricing/modelling/{core/bayesopt → bayesopt}/__init__.py +64 -102
  21. ins_pricing/modelling/{core/bayesopt → bayesopt}/config_preprocess.py +562 -562
  22. ins_pricing/modelling/{core/bayesopt → bayesopt}/core.py +965 -964
  23. ins_pricing/modelling/{core/bayesopt → bayesopt}/model_explain_mixin.py +296 -296
  24. ins_pricing/modelling/{core/bayesopt → bayesopt}/model_plotting_mixin.py +482 -548
  25. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/__init__.py +27 -27
  26. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_ft_trainer.py +915 -913
  27. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_gnn.py +788 -785
  28. ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_resn.py +448 -446
  29. ins_pricing/modelling/bayesopt/trainers/__init__.py +19 -0
  30. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_base.py +1308 -1308
  31. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_ft.py +3 -3
  32. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_glm.py +197 -198
  33. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_gnn.py +344 -344
  34. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_resn.py +283 -283
  35. ins_pricing/modelling/{core/bayesopt → bayesopt}/trainers/trainer_xgb.py +346 -347
  36. ins_pricing/modelling/bayesopt/utils/__init__.py +67 -0
  37. ins_pricing/modelling/bayesopt/utils/constants.py +21 -0
  38. ins_pricing/modelling/bayesopt/utils/io_utils.py +7 -0
  39. ins_pricing/modelling/bayesopt/utils/losses.py +27 -0
  40. ins_pricing/modelling/bayesopt/utils/metrics_and_devices.py +17 -0
  41. ins_pricing/modelling/{core/bayesopt → bayesopt}/utils/torch_trainer_mixin.py +623 -623
  42. ins_pricing/modelling/{core/evaluation.py → evaluation.py} +113 -104
  43. ins_pricing/modelling/explain/__init__.py +55 -55
  44. ins_pricing/modelling/explain/metrics.py +27 -174
  45. ins_pricing/modelling/explain/permutation.py +237 -237
  46. ins_pricing/modelling/plotting/__init__.py +40 -36
  47. ins_pricing/modelling/plotting/compat.py +228 -0
  48. ins_pricing/modelling/plotting/curves.py +572 -572
  49. ins_pricing/modelling/plotting/diagnostics.py +163 -163
  50. ins_pricing/modelling/plotting/geo.py +362 -362
  51. ins_pricing/modelling/plotting/importance.py +121 -121
  52. ins_pricing/pricing/__init__.py +27 -27
  53. ins_pricing/production/__init__.py +35 -25
  54. ins_pricing/production/{predict.py → inference.py} +140 -57
  55. ins_pricing/production/monitoring.py +8 -21
  56. ins_pricing/reporting/__init__.py +11 -11
  57. ins_pricing/setup.py +1 -1
  58. ins_pricing/tests/production/test_inference.py +90 -0
  59. ins_pricing/utils/__init__.py +116 -83
  60. ins_pricing/utils/device.py +255 -255
  61. ins_pricing/utils/features.py +53 -0
  62. ins_pricing/utils/io.py +72 -0
  63. ins_pricing/{modelling/core/bayesopt/utils → utils}/losses.py +125 -129
  64. ins_pricing/utils/metrics.py +158 -24
  65. ins_pricing/utils/numerics.py +76 -0
  66. ins_pricing/utils/paths.py +9 -1
  67. {ins_pricing-0.4.5.dist-info → ins_pricing-0.5.0.dist-info}/METADATA +182 -182
  68. ins_pricing-0.5.0.dist-info/RECORD +131 -0
  69. ins_pricing/modelling/core/BayesOpt.py +0 -146
  70. ins_pricing/modelling/core/__init__.py +0 -1
  71. ins_pricing/modelling/core/bayesopt/trainers/__init__.py +0 -19
  72. ins_pricing/modelling/core/bayesopt/utils/__init__.py +0 -86
  73. ins_pricing/modelling/core/bayesopt/utils/constants.py +0 -183
  74. ins_pricing/modelling/core/bayesopt/utils/io_utils.py +0 -126
  75. ins_pricing/modelling/core/bayesopt/utils/metrics_and_devices.py +0 -555
  76. ins_pricing/modelling/core/bayesopt/utils.py +0 -105
  77. ins_pricing/modelling/core/bayesopt/utils_backup.py +0 -1503
  78. ins_pricing/tests/production/test_predict.py +0 -233
  79. ins_pricing-0.4.5.dist-info/RECORD +0 -130
  80. /ins_pricing/modelling/{core/bayesopt → bayesopt}/config_components.py +0 -0
  81. /ins_pricing/modelling/{core/bayesopt → bayesopt}/models/model_ft_components.py +0 -0
  82. /ins_pricing/modelling/{core/bayesopt → bayesopt}/utils/distributed_utils.py +0 -0
  83. {ins_pricing-0.4.5.dist-info → ins_pricing-0.5.0.dist-info}/WHEEL +0 -0
  84. {ins_pricing-0.4.5.dist-info → ins_pricing-0.5.0.dist-info}/top_level.txt +0 -0
ins_pricing/README.md CHANGED
@@ -7,12 +7,13 @@ between modelling, production, governance, and reporting.
7
7
 
8
8
  ## Architecture
9
9
 
10
- - `cli/`: CLI entry points and shared utilities.
11
- - `modelling/`
12
- - `core/`: BayesOpt training core (GLM / XGB / ResNet / FT / GNN).
13
- - `plotting/`: model-agnostic curves and geo visualizations.
14
- - `explain/`: permutation, gradients, and SHAP helpers.
15
- - `examples/`: demo configs and notebooks (repo only; not packaged).
10
+ - `cli/`: CLI entry points and shared utilities.
11
+ - `modelling/`
12
+ - `bayesopt/`: BayesOpt training core (GLM / XGB / ResNet / FT / GNN).
13
+ - `plotting/`: model-agnostic curves and geo visualizations.
14
+ - `explain/`: permutation, gradients, and SHAP helpers.
15
+ - `evaluation.py`: calibration, metrics, and evaluation utilities.
16
+ - `examples/`: demo configs and notebooks (repo only; not packaged).
16
17
  - `pricing/`: factor tables, calibration, exposure, monitoring.
17
18
  - `production/`: scoring, metrics, drift/PSI.
18
19
  - `governance/`: registry, approval, audit workflows.
@@ -31,29 +32,54 @@ between modelling, production, governance, and reporting.
31
32
  - `from ins_pricing.explain import permutation_importance, integrated_gradients_torch`
32
33
  4. Pricing loop
33
34
  - `from ins_pricing.pricing import build_factor_table, rate_premium`
34
- 5. Production and governance
35
- - `from ins_pricing.production import batch_score, psi_report`
36
- - `from ins_pricing.governance import ModelRegistry, ReleaseManager`
35
+ 5. Production and governance
36
+ - `from ins_pricing.production import batch_score, psi_report`
37
+ - Inference: `from ins_pricing.production import load_predictor_from_config`
38
+ - `from ins_pricing.governance import ModelRegistry, ReleaseManager`
37
39
  6. Reporting
38
40
  - `from ins_pricing.reporting import build_report, write_report, schedule_daily`
39
41
 
40
- ## Import notes
41
-
42
- - `ins_pricing` exposes lightweight lazy imports so that pricing/production/governance
43
- can be used without installing heavy ML dependencies.
42
+ ## Import notes
43
+
44
+ - `ins_pricing` exposes lightweight lazy imports so that pricing/production/governance
45
+ can be used without installing heavy ML dependencies.
44
46
  - Demo notebooks/configs live in the repo under `examples/` and are not shipped
45
47
  in the PyPI package.
46
- - Heavy dependencies are only required when you import or use the related modules:
47
- - BayesOpt: `torch`, `optuna`, `xgboost`, etc.
48
- - Explain: `torch` (gradients), `shap` (SHAP).
49
- - Geo plotting on basemap: `contextily`.
50
- - Plotting: `matplotlib`.
48
+ - Heavy dependencies are only required when you import or use the related modules:
49
+ - BayesOpt: `torch`, `optuna`, `xgboost`, etc.
50
+ - Explain: `torch` (gradients), `shap` (SHAP).
51
+ - Geo plotting on basemap: `contextily`.
52
+ - Plotting: `matplotlib`.
53
+ - Inference: `torch` only when loading FT/ResNet/GNN models.
54
+
55
+ ## Inference interface (new)
56
+
57
+ - `production.inference` provides a small registry-based interface so inference
58
+ does not hard-code model loaders:
59
+ - `ModelSpec` describes the saved model location and config.
60
+ - `PredictorRegistry` lets you plug in custom model loaders.
61
+ - `load_predictor_from_config` remains backward compatible.
62
+
63
+ Example:
64
+
65
+ ```
66
+ from ins_pricing.production import load_predictor_from_config
67
+
68
+ predictor = load_predictor_from_config(
69
+ "config.json",
70
+ "resn",
71
+ device="cuda", # or "mps"/"cpu"
72
+ )
73
+ preds = predictor.predict(df)
74
+ ```
51
75
 
52
- ## Multi-platform and GPU notes
76
+ ## Multi-platform and GPU notes
53
77
 
54
- - Install the correct PyTorch build for your platform/GPU before installing extras.
55
- - Torch Geometric requires platform-specific wheels; follow the official PyG install guide.
56
- - Multi-GPU uses DDP or DataParallel where supported; Windows disables CUDA DDP.
78
+ - Install the correct PyTorch build for your platform/GPU before installing extras.
79
+ - Torch Geometric requires platform-specific wheels; follow the official PyG install guide.
80
+ - Multi-GPU uses DDP or DataParallel where supported; Windows disables CUDA DDP.
81
+ CLI usage prefers `python -m ins_pricing.cli.BayesOpt_entry ...` but the
82
+ direct script path (`python ins_pricing/cli/BayesOpt_entry.py ...`) still works.
57
83
 
58
84
  ## Backward-compatible imports
59
85
 
ins_pricing/__init__.py CHANGED
@@ -1,94 +1,146 @@
1
- from __future__ import annotations
2
-
3
- from importlib import import_module
4
- from pathlib import Path
5
- import sys
6
- import types
7
-
8
- _ROOT_SUBPACKAGES = {
9
- "modelling": "ins_pricing.modelling",
10
- "pricing": "ins_pricing.pricing",
11
- "production": "ins_pricing.production",
12
- "governance": "ins_pricing.governance",
13
- "reporting": "ins_pricing.reporting",
14
- }
15
-
16
- _MODELLING_EXPORTS = {
17
- "BayesOptConfig",
18
- "BayesOptModel",
19
- "IOUtils",
20
- "TrainingUtils",
21
- "free_cuda",
22
- }
23
-
1
+ from __future__ import annotations
2
+
3
+ from importlib import import_module
4
+ from pathlib import Path
5
+ import sys
6
+ import types
7
+
8
+ _ROOT_SUBPACKAGES = {
9
+ "modelling": "ins_pricing.modelling",
10
+ "pricing": "ins_pricing.pricing",
11
+ "production": "ins_pricing.production",
12
+ "governance": "ins_pricing.governance",
13
+ "reporting": "ins_pricing.reporting",
14
+ }
15
+
16
+ _MODELLING_EXPORTS = {
17
+ "BayesOptConfig",
18
+ "BayesOptModel",
19
+ }
20
+
21
+ _BAYESOPT_EXPORTS = {
22
+ "BayesOptConfig",
23
+ "DatasetPreprocessor",
24
+ "OutputManager",
25
+ "VersionManager",
26
+ "BayesOptModel",
27
+ "FeatureTokenizer",
28
+ "FTTransformerCore",
29
+ "FTTransformerSklearn",
30
+ "GraphNeuralNetSklearn",
31
+ "MaskedTabularDataset",
32
+ "ResBlock",
33
+ "ResNetSequential",
34
+ "ResNetSklearn",
35
+ "ScaledTransformerEncoderLayer",
36
+ "SimpleGraphLayer",
37
+ "SimpleGNN",
38
+ "TabularDataset",
39
+ "FTTrainer",
40
+ "GLMTrainer",
41
+ "GNNTrainer",
42
+ "ResNetTrainer",
43
+ "TrainerBase",
44
+ "XGBTrainer",
45
+ "_xgb_cuda_available",
46
+ }
47
+
48
+ _LEGACY_EXPORTS = {
49
+ "IOUtils": "ins_pricing.utils",
50
+ "DeviceManager": "ins_pricing.utils",
51
+ "GPUMemoryManager": "ins_pricing.utils",
52
+ "MetricFactory": "ins_pricing.utils",
53
+ "EPS": "ins_pricing.utils",
54
+ "set_global_seed": "ins_pricing.utils",
55
+ "compute_batch_size": "ins_pricing.utils",
56
+ "tweedie_loss": "ins_pricing.utils",
57
+ "infer_factor_and_cate_list": "ins_pricing.utils",
58
+ "DistributedUtils": "ins_pricing.modelling.bayesopt.utils",
59
+ "TrainingUtils": "ins_pricing.modelling.bayesopt.utils",
60
+ "free_cuda": "ins_pricing.modelling.bayesopt.utils",
61
+ "TorchTrainerMixin": "ins_pricing.modelling.bayesopt.utils",
62
+ }
63
+
24
64
  _LAZY_SUBMODULES = {
25
- "bayesopt": "ins_pricing.modelling.core.bayesopt",
65
+ "bayesopt": "ins_pricing.modelling.bayesopt",
26
66
  "plotting": "ins_pricing.modelling.plotting",
27
67
  "explain": "ins_pricing.modelling.explain",
28
- "BayesOpt": "ins_pricing.modelling.core.BayesOpt",
29
- }
30
-
31
- _PACKAGE_PATHS = {
32
- "bayesopt": Path(__file__).resolve().parent / "modelling" / "core" / "bayesopt",
33
- "plotting": Path(__file__).resolve().parent / "modelling" / "plotting",
34
- "explain": Path(__file__).resolve().parent / "modelling" / "explain",
35
68
  }
36
-
37
- __all__ = sorted(
38
- set(_ROOT_SUBPACKAGES)
39
- | set(_MODELLING_EXPORTS)
40
- | set(_LAZY_SUBMODULES)
41
- )
42
-
43
-
44
- def _lazy_module(name: str, target: str, package_path: Path | None = None) -> types.ModuleType:
45
- proxy = types.ModuleType(name)
46
- if package_path is not None:
47
- proxy.__path__ = [str(package_path)]
48
-
49
- def _load():
50
- module = import_module(target)
51
- sys.modules[name] = module
52
- return module
53
-
54
- def __getattr__(attr: str):
55
- module = _load()
56
- return getattr(module, attr)
57
-
58
- def __dir__() -> list[str]:
59
- module = _load()
60
- return sorted(set(dir(module)))
61
-
62
- proxy.__getattr__ = __getattr__ # type: ignore[attr-defined]
63
- proxy.__dir__ = __dir__ # type: ignore[attr-defined]
64
- return proxy
65
-
66
-
67
- def _install_proxy(alias: str, target: str) -> None:
68
- module_name = f"{__name__}.{alias}"
69
- if module_name in sys.modules:
70
- return
71
- proxy = _lazy_module(module_name, target, _PACKAGE_PATHS.get(alias))
72
- sys.modules[module_name] = proxy
73
- globals()[alias] = proxy
74
-
75
-
76
- for _alias, _target in _LAZY_SUBMODULES.items():
77
- _install_proxy(_alias, _target)
78
-
79
-
80
- def __getattr__(name: str):
81
- if name in _ROOT_SUBPACKAGES:
82
- module = import_module(_ROOT_SUBPACKAGES[name])
83
- globals()[name] = module
84
- return module
85
- if name in _MODELLING_EXPORTS:
86
- module = import_module("ins_pricing.modelling")
87
- value = getattr(module, name)
88
- globals()[name] = value
89
- return value
90
- raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
91
-
92
-
93
- def __dir__() -> list[str]:
94
- return sorted(set(__all__) | set(globals().keys()))
69
+
70
+ _PACKAGE_PATHS = {
71
+ "bayesopt": Path(__file__).resolve().parent / "modelling" / "bayesopt",
72
+ "plotting": Path(__file__).resolve().parent / "modelling" / "plotting",
73
+ "explain": Path(__file__).resolve().parent / "modelling" / "explain",
74
+ }
75
+
76
+ __all__ = sorted(
77
+ set(_ROOT_SUBPACKAGES)
78
+ | set(_MODELLING_EXPORTS)
79
+ | set(_BAYESOPT_EXPORTS)
80
+ | set(_LEGACY_EXPORTS)
81
+ | set(_LAZY_SUBMODULES)
82
+ )
83
+
84
+
85
+ def _lazy_module(name: str, target: str, package_path: Path | None = None) -> types.ModuleType:
86
+ proxy = types.ModuleType(name)
87
+ if package_path is not None:
88
+ proxy.__path__ = [str(package_path)]
89
+
90
+ def _load():
91
+ module = import_module(target)
92
+ sys.modules[name] = module
93
+ return module
94
+
95
+ def __getattr__(attr: str):
96
+ module = _load()
97
+ return getattr(module, attr)
98
+
99
+ def __dir__() -> list[str]:
100
+ module = _load()
101
+ return sorted(set(dir(module)))
102
+
103
+ proxy.__getattr__ = __getattr__ # type: ignore[attr-defined]
104
+ proxy.__dir__ = __dir__ # type: ignore[attr-defined]
105
+ return proxy
106
+
107
+
108
+ def _install_proxy(alias: str, target: str) -> None:
109
+ module_name = f"{__name__}.{alias}"
110
+ if module_name in sys.modules:
111
+ return
112
+ proxy = _lazy_module(module_name, target, _PACKAGE_PATHS.get(alias))
113
+ sys.modules[module_name] = proxy
114
+ globals()[alias] = proxy
115
+
116
+
117
+ for _alias, _target in _LAZY_SUBMODULES.items():
118
+ _install_proxy(_alias, _target)
119
+
120
+
121
+ def __getattr__(name: str):
122
+ if name in _ROOT_SUBPACKAGES:
123
+ module = import_module(_ROOT_SUBPACKAGES[name])
124
+ globals()[name] = module
125
+ return module
126
+ if name in _MODELLING_EXPORTS:
127
+ module = import_module("ins_pricing.modelling")
128
+ value = getattr(module, name)
129
+ globals()[name] = value
130
+ return value
131
+ if name in _BAYESOPT_EXPORTS:
132
+ module = import_module("ins_pricing.modelling.bayesopt")
133
+ value = getattr(module, name)
134
+ globals()[name] = value
135
+ return value
136
+ legacy_module = _LEGACY_EXPORTS.get(name)
137
+ if legacy_module:
138
+ module = import_module(legacy_module)
139
+ value = getattr(module, name)
140
+ globals()[name] = value
141
+ return value
142
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
143
+
144
+
145
+ def __dir__() -> list[str]:
146
+ return sorted(set(__all__) | set(globals().keys()))
@@ -1,56 +1,58 @@
1
- """Thin wrapper for the BayesOpt CLI entry point.
2
-
3
- The main implementation lives in bayesopt_entry_runner.py.
4
- """
5
-
6
- from __future__ import annotations
7
-
1
+ """Thin wrapper for the BayesOpt CLI entry point.
2
+
3
+ The main implementation lives in bayesopt_entry_runner.py.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
8
  from pathlib import Path
9
+ import importlib.util
9
10
  import json
10
11
  import os
11
12
  import sys
12
13
 
13
14
  if __package__ in {None, ""}:
14
- repo_root = Path(__file__).resolve().parents[2]
15
- if str(repo_root) not in sys.path:
16
- sys.path.insert(0, str(repo_root))
17
-
18
- def _apply_env_from_config(argv: list[str]) -> None:
19
- if "--config-json" not in argv:
20
- return
21
- idx = argv.index("--config-json")
22
- if idx + 1 >= len(argv):
23
- return
24
- raw_path = argv[idx + 1]
25
- try:
26
- cfg_path = Path(raw_path).expanduser()
27
- if not cfg_path.is_absolute():
28
- cfg_path = cfg_path.resolve()
29
- if not cfg_path.exists():
30
- script_dir = Path(__file__).resolve().parents[1]
31
- candidate = (script_dir / raw_path).resolve()
32
- if candidate.exists():
33
- cfg_path = candidate
34
- if not cfg_path.exists():
35
- return
36
- cfg = json.loads(cfg_path.read_text(encoding="utf-8", errors="replace"))
37
- env = cfg.get("env", {})
38
- if isinstance(env, dict):
39
- for key, value in env.items():
40
- if key is None:
41
- continue
42
- os.environ.setdefault(str(key), str(value))
43
- except Exception:
44
- return
45
-
46
- _apply_env_from_config(sys.argv)
47
-
48
- try:
49
- from .bayesopt_entry_runner import main
50
- except Exception: # pragma: no cover
51
- from ins_pricing.cli.bayesopt_entry_runner import main
52
-
53
- __all__ = ["main"]
54
-
55
- if __name__ == "__main__":
56
- main()
15
+ if importlib.util.find_spec("ins_pricing") is None:
16
+ repo_root = Path(__file__).resolve().parents[2]
17
+ if str(repo_root) not in sys.path:
18
+ sys.path.insert(0, str(repo_root))
19
+
20
+ def _apply_env_from_config(argv: list[str]) -> None:
21
+ if "--config-json" not in argv:
22
+ return
23
+ idx = argv.index("--config-json")
24
+ if idx + 1 >= len(argv):
25
+ return
26
+ raw_path = argv[idx + 1]
27
+ try:
28
+ cfg_path = Path(raw_path).expanduser()
29
+ if not cfg_path.is_absolute():
30
+ cfg_path = cfg_path.resolve()
31
+ if not cfg_path.exists():
32
+ script_dir = Path(__file__).resolve().parents[1]
33
+ candidate = (script_dir / raw_path).resolve()
34
+ if candidate.exists():
35
+ cfg_path = candidate
36
+ if not cfg_path.exists():
37
+ return
38
+ cfg = json.loads(cfg_path.read_text(encoding="utf-8", errors="replace"))
39
+ env = cfg.get("env", {})
40
+ if isinstance(env, dict):
41
+ for key, value in env.items():
42
+ if key is None:
43
+ continue
44
+ os.environ.setdefault(str(key), str(value))
45
+ except Exception:
46
+ return
47
+
48
+ _apply_env_from_config(sys.argv)
49
+
50
+ try:
51
+ from ins_pricing.cli.bayesopt_entry_runner import main
52
+ except Exception: # pragma: no cover
53
+ from ins_pricing.cli.bayesopt_entry_runner import main
54
+
55
+ __all__ = ["main"]
56
+
57
+ if __name__ == "__main__":
58
+ main()
@@ -1,5 +1,4 @@
1
- """Incremental training harness built on top of ``ins_pricing.bayesopt``
2
- (compat via ``BayesOpt.py``).
1
+ """Incremental training harness built on top of ``ins_pricing.bayesopt``.
3
2
 
4
3
  This utility lets you append new observations to an existing dataset,
5
4
  reuse previously tuned hyperparameters and retrain a subset of models
@@ -17,13 +16,15 @@ Example:
17
16
 
18
17
  from __future__ import annotations
19
18
 
20
- from pathlib import Path
21
- import sys
22
-
23
- if __package__ in {None, ""}:
24
- repo_root = Path(__file__).resolve().parents[2]
25
- if str(repo_root) not in sys.path:
26
- sys.path.insert(0, str(repo_root))
19
+ from pathlib import Path
20
+ import importlib.util
21
+ import sys
22
+
23
+ if __package__ in {None, ""}:
24
+ if importlib.util.find_spec("ins_pricing") is None:
25
+ repo_root = Path(__file__).resolve().parents[2]
26
+ if str(repo_root) not in sys.path:
27
+ sys.path.insert(0, str(repo_root))
27
28
 
28
29
  import argparse
29
30
  import json
@@ -31,102 +32,35 @@ from dataclasses import asdict
31
32
  from datetime import datetime
32
33
  from typing import Any, Dict, List, Optional, Sequence, Tuple
33
34
 
34
- import pandas as pd
35
-
36
- try:
37
- from .. import bayesopt as ropt # type: ignore
38
- from .utils.cli_common import ( # type: ignore
39
- PLOT_MODEL_LABELS,
40
- PYTORCH_TRAINERS,
41
- build_model_names,
42
- dedupe_preserve_order,
43
- load_dataset,
44
- parse_model_pairs,
45
- resolve_data_path,
46
- resolve_path,
47
- split_train_test,
48
- )
49
- from .utils.cli_config import ( # type: ignore
50
- add_config_json_arg,
51
- resolve_and_load_config,
52
- resolve_data_config,
53
- resolve_split_config,
54
- resolve_runtime_config,
55
- resolve_output_dirs,
56
- )
57
- except Exception: # pragma: no cover
58
- try:
59
- import bayesopt as ropt # type: ignore
60
- from utils.cli_common import ( # type: ignore
61
- PLOT_MODEL_LABELS,
62
- PYTORCH_TRAINERS,
63
- build_model_names,
64
- dedupe_preserve_order,
65
- load_dataset,
66
- parse_model_pairs,
67
- resolve_data_path,
68
- resolve_path,
69
- split_train_test,
70
- )
71
- from utils.cli_config import ( # type: ignore
72
- add_config_json_arg,
73
- resolve_and_load_config,
74
- resolve_data_config,
75
- resolve_split_config,
76
- resolve_runtime_config,
77
- resolve_output_dirs,
78
- )
79
- except Exception:
80
- try:
81
- import ins_pricing.modelling.core.bayesopt as ropt # type: ignore
82
- from ins_pricing.cli.utils.cli_common import ( # type: ignore
83
- PLOT_MODEL_LABELS,
84
- PYTORCH_TRAINERS,
85
- build_model_names,
86
- dedupe_preserve_order,
87
- load_dataset,
88
- parse_model_pairs,
89
- resolve_data_path,
90
- resolve_path,
91
- split_train_test,
92
- )
93
- from ins_pricing.cli.utils.cli_config import ( # type: ignore
94
- add_config_json_arg,
95
- resolve_and_load_config,
96
- resolve_data_config,
97
- resolve_split_config,
98
- resolve_runtime_config,
99
- resolve_output_dirs,
100
- )
101
- except Exception:
102
- import BayesOpt as ropt # type: ignore
103
- from utils.cli_common import ( # type: ignore
104
- PLOT_MODEL_LABELS,
105
- PYTORCH_TRAINERS,
106
- build_model_names,
107
- dedupe_preserve_order,
108
- load_dataset,
109
- parse_model_pairs,
110
- resolve_data_path,
111
- resolve_path,
112
- split_train_test,
113
- )
114
- from utils.cli_config import ( # type: ignore
115
- add_config_json_arg,
116
- resolve_and_load_config,
117
- resolve_data_config,
118
- resolve_split_config,
119
- resolve_runtime_config,
120
- resolve_output_dirs,
121
- )
122
-
123
- try:
124
- from .utils.run_logging import configure_run_logging # type: ignore
125
- except Exception: # pragma: no cover
126
- try:
127
- from utils.run_logging import configure_run_logging # type: ignore
128
- except Exception: # pragma: no cover
129
- configure_run_logging = None # type: ignore
35
+ import pandas as pd
36
+
37
+ from ins_pricing.cli.utils.import_resolver import resolve_imports, setup_sys_path
38
+
39
+ setup_sys_path()
40
+ _imports = resolve_imports()
41
+
42
+ ropt = _imports.bayesopt
43
+ if ropt is None: # pragma: no cover
44
+ raise ImportError("Failed to resolve ins_pricing.bayesopt for incremental CLI.")
45
+
46
+ PLOT_MODEL_LABELS = _imports.PLOT_MODEL_LABELS
47
+ PYTORCH_TRAINERS = _imports.PYTORCH_TRAINERS
48
+ build_model_names = _imports.build_model_names
49
+ dedupe_preserve_order = _imports.dedupe_preserve_order
50
+ load_dataset = _imports.load_dataset
51
+ parse_model_pairs = _imports.parse_model_pairs
52
+ resolve_data_path = _imports.resolve_data_path
53
+ resolve_path = _imports.resolve_path
54
+ split_train_test = _imports.split_train_test
55
+
56
+ add_config_json_arg = _imports.add_config_json_arg
57
+ resolve_and_load_config = _imports.resolve_and_load_config
58
+ resolve_data_config = _imports.resolve_data_config
59
+ resolve_split_config = _imports.resolve_split_config
60
+ resolve_runtime_config = _imports.resolve_runtime_config
61
+ resolve_output_dirs = _imports.resolve_output_dirs
62
+
63
+ configure_run_logging = _imports.configure_run_logging
130
64
 
131
65
 
132
66
  def _log(message: str) -> None:
@@ -1,25 +1,33 @@
1
- from __future__ import annotations
2
-
1
+ from __future__ import annotations
2
+
3
3
  from pathlib import Path
4
4
  from typing import Optional
5
-
6
- try:
7
- from .utils.notebook_utils import run_from_config, run_from_config_cli # type: ignore
8
- except Exception: # pragma: no cover
9
- from utils.notebook_utils import run_from_config, run_from_config_cli # type: ignore
10
-
11
-
12
- def run(config_json: str | Path) -> None:
13
- """Run explain by config.json (runner.mode=explain)."""
14
- run_from_config(config_json)
15
-
16
-
17
- def main(argv: Optional[list[str]] = None) -> None:
18
- run_from_config_cli(
19
- "Explain_Run: run explain by config.json (runner.mode=explain).",
20
- argv,
21
- )
22
-
23
-
24
- if __name__ == "__main__":
25
- main()
5
+ import importlib.util
6
+ import sys
7
+
8
+ if __package__ in {None, ""}:
9
+ if importlib.util.find_spec("ins_pricing") is None:
10
+ repo_root = Path(__file__).resolve().parents[2]
11
+ if str(repo_root) not in sys.path:
12
+ sys.path.insert(0, str(repo_root))
13
+
14
+ try:
15
+ from ins_pricing.cli.utils.notebook_utils import run_from_config, run_from_config_cli # type: ignore
16
+ except Exception: # pragma: no cover
17
+ from utils.notebook_utils import run_from_config, run_from_config_cli # type: ignore
18
+
19
+
20
+ def run(config_json: str | Path) -> None:
21
+ """Run explain by config.json (runner.mode=explain)."""
22
+ run_from_config(config_json)
23
+
24
+
25
+ def main(argv: Optional[list[str]] = None) -> None:
26
+ run_from_config_cli(
27
+ "Explain_Run: run explain by config.json (runner.mode=explain).",
28
+ argv,
29
+ )
30
+
31
+
32
+ if __name__ == "__main__":
33
+ main()