expops 0.1.13.dev0__tar.gz → 0.1.15.dev0__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.
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/PKG-INFO +1 -1
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops.egg-info/PKG-INFO +1 -1
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/_version.py +3 -3
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/custom/custom_adapter.py +0 -4
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/executor_worker.py +0 -26
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/venv_manager.py +0 -14
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/main.py +9 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/managers/reproducibility_manager.py +0 -23
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/platform.py +0 -2
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/.github/workflows/ci.yml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/.github/workflows/release.yml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/.gitignore +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/LICENSE +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/README.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/advanced/backends.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/caching.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/data-parallelism.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/distributed.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/environments.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/pipelines.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/reporting.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/features/seed-parallelism.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/getting-started/creating-a-project.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/getting-started/quick-start.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/index.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/project-structure/charts.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/project-structure/configuration.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/project-structure/model-code.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/project-structure/overview.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/requirements.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/templates/premier-league.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/templates/sklearn-basic.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/docs/web-ui/local-ui.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/pyproject.toml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/setup.cfg +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/__main__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/core/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/main.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/reporting/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/reporting/context.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/reporting/registry.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/web/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops/web/server.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops.egg-info/SOURCES.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops.egg-info/dependency_links.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops.egg-info/entry_points.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops.egg-info/requires.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/expops.egg-info/top_level.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/__main__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/base.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/config_schema.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/custom/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/plugin_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/sklearn/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/adapters/sklearn/adapter.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/cluster/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/cluster/controller.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/cluster/process_runner.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/cluster/providers.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/compute_config.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/custom_model_base.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/dask_networkx_executor.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/data_hashing.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/graph_expansion.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/graph_types.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/networkx_parser.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/payload_spill.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/pipeline_tree.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/pipeline_utils.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/probe_path_selectors.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/process_hashing.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/step_state_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/step_system.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/core/workspace.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/base.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/conda_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/factory.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/pyenv_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/setup_env.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/system_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/environment/utils.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/managers/project_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/reporting/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/reporting/context.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/reporting/entrypoint.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/reporting/kv_utils.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/reporting/registry.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/runtime/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/runtime/context.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/runtime/env_export.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/adapters/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/adapters/gcp_kv_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/adapters/gcs_object_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/adapters/memory_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/adapters/redis_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/adapters/sqlite_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/factory.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/interfaces/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/interfaces/kv_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/storage/path_utils.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/charts/plot_metrics.js +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/charts/plot_metrics.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/charts/requirements.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/configs/compute_config.yaml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/configs/project_config.yaml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/data/England CSV.csv +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/models/premier_league_model.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/requirements.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/README.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/charts/plot_metrics.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/charts/requirements.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/configs/compute_config.yaml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/configs/project_config.yaml +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/data/train.csv +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/models/model.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/requirements.txt +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/web/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/web/server.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/web/ui/index.html +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/web/ui/mlops-charts.js +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/web/ui/script.js +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/web/ui/styles.css +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/conftest.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/testing-plan.md +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_dask_networkx_executor.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_data_hashing.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_executor_worker.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_graph_expansion.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_networkx_parser.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_payload_spill.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_prepare_runner_kwargs.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_process_hashing.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_step_state_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_step_system.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_managers/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_managers/test_reproducibility_manager.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_storage/__init__.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_storage/test_factory.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_storage/test_gcp_kv_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_storage/test_gcs_object_store.py +0 -0
- {expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_storage/test_sqlite_store.py +0 -0
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.15.dev0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 15, 'dev0')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g40e2f0532'
|
|
@@ -272,10 +272,6 @@ class CustomModelAdapter(ModelAdapter):
|
|
|
272
272
|
self.step_registry = get_step_registry()
|
|
273
273
|
try:
|
|
274
274
|
step_names = list(getattr(self.step_registry, "_steps", {}).keys())
|
|
275
|
-
if not step_names:
|
|
276
|
-
self.logger.warning("No steps found in registry. Ensure your model uses @step decorators.")
|
|
277
|
-
else:
|
|
278
|
-
self.logger.info(f"Found {len(step_names)} registered step(s)")
|
|
279
275
|
except Exception:
|
|
280
276
|
pass
|
|
281
277
|
|
|
@@ -1505,8 +1505,6 @@ def _run_chart_process_on_worker(ctx: Any, proc_payload: Dict[str, Any], run_id:
|
|
|
1505
1505
|
project_id = getattr(ctx, 'project_id', None) or os.environ.get('MLOPS_PROJECT_ID') or 'default'
|
|
1506
1506
|
rid = run_id or getattr(ctx, 'run_id', None) or os.environ.get('MLOPS_RUN_ID') or 'default'
|
|
1507
1507
|
|
|
1508
|
-
logger.info(f"[Charts] Starting chart '{name}' for run {rid}, project {project_id}")
|
|
1509
|
-
|
|
1510
1508
|
# Safeguard: mark process as running when the chart actually begins execution
|
|
1511
1509
|
try:
|
|
1512
1510
|
from .step_system import get_state_manager as _get_sm
|
|
@@ -1536,7 +1534,6 @@ def _run_chart_process_on_worker(ctx: Any, proc_payload: Dict[str, Any], run_id:
|
|
|
1536
1534
|
function_hash=fh,
|
|
1537
1535
|
started_at=time.time(),
|
|
1538
1536
|
)
|
|
1539
|
-
logger.debug(f"[Charts] Marked '{name}' running for run {rid}")
|
|
1540
1537
|
except Exception:
|
|
1541
1538
|
pass
|
|
1542
1539
|
|
|
@@ -1592,7 +1589,6 @@ def _run_chart_process_on_worker(ctx: Any, proc_payload: Dict[str, Any], run_id:
|
|
|
1592
1589
|
ep = resolve_relative_path(entrypoint, project_root=project_root, workspace_root=workspace_root)
|
|
1593
1590
|
# Set import path for user's chart script
|
|
1594
1591
|
env['MLOPS_CHART_IMPORT_FILES'] = str(ep)
|
|
1595
|
-
logger.info(f"[Charts] Will import user script: {ep}")
|
|
1596
1592
|
|
|
1597
1593
|
# Build command - always use framework entrypoint as module
|
|
1598
1594
|
py = reporting_python or os.environ.get('MLOPS_RUNTIME_PYTHON') or 'python'
|
|
@@ -1612,13 +1608,6 @@ def _run_chart_process_on_worker(ctx: Any, proc_payload: Dict[str, Any], run_id:
|
|
|
1612
1608
|
stdout_log = out_dir / 'stdout.log'
|
|
1613
1609
|
stderr_log = out_dir / 'stderr.log'
|
|
1614
1610
|
|
|
1615
|
-
logger.info(f"[Charts] Executing chart '{name}': {' '.join(cmd)}")
|
|
1616
|
-
logger.info(f"[Charts] Output directory: {out_dir}")
|
|
1617
|
-
logger.info(f"[Charts] Python interpreter: {py}")
|
|
1618
|
-
logger.info(f"[Charts] Entrypoint: {entrypoint}")
|
|
1619
|
-
logger.info(f"[Charts] MLOPS_CHART_NAME env: {env.get('MLOPS_CHART_NAME')}")
|
|
1620
|
-
logger.info(f"[Charts] MLOPS_OUTPUT_DIR env: {env.get('MLOPS_OUTPUT_DIR')}")
|
|
1621
|
-
|
|
1622
1611
|
with open(stdout_log, 'w', buffering=1) as out_f, open(stderr_log, 'w', buffering=1) as err_f:
|
|
1623
1612
|
# Write diagnostic info
|
|
1624
1613
|
err_f.write(f"=== Chart Execution Diagnostics ===\n")
|
|
@@ -1636,11 +1625,9 @@ def _run_chart_process_on_worker(ctx: Any, proc_payload: Dict[str, Any], run_id:
|
|
|
1636
1625
|
returncode = int(getattr(result, "returncode", 0) or 0)
|
|
1637
1626
|
except Exception:
|
|
1638
1627
|
returncode = 0
|
|
1639
|
-
logger.info(f"[Charts] Chart '{name}' execution completed with return code: {returncode}")
|
|
1640
1628
|
|
|
1641
1629
|
# Check if any PNGs were created
|
|
1642
1630
|
png_count = len(list(out_dir.rglob('*.png')))
|
|
1643
|
-
logger.info(f"[Charts] Found {png_count} PNG file(s) in {out_dir}")
|
|
1644
1631
|
|
|
1645
1632
|
# Upload/record artifacts (best-effort).
|
|
1646
1633
|
try:
|
|
@@ -1658,7 +1645,6 @@ def _run_chart_process_on_worker(ctx: Any, proc_payload: Dict[str, Any], run_id:
|
|
|
1658
1645
|
logger.warning("[Charts] No state manager available - artifacts not recorded")
|
|
1659
1646
|
|
|
1660
1647
|
final_count = len(list(out_dir.rglob('*.png')))
|
|
1661
|
-
logger.info(f"[Charts] Chart '{name}' complete. Output dir: {out_dir}, PNG count: {final_count}")
|
|
1662
1648
|
|
|
1663
1649
|
return {
|
|
1664
1650
|
'output_dir': str(out_dir),
|
|
@@ -2066,10 +2052,6 @@ def _maybe_init_worker_state_manager(global_config: Any, project_id: Optional[st
|
|
|
2066
2052
|
logger = _logging.getLogger(__name__)
|
|
2067
2053
|
gcp_creds = _os.getenv('GOOGLE_APPLICATION_CREDENTIALS')
|
|
2068
2054
|
gcp_project = _os.getenv('GOOGLE_CLOUD_PROJECT')
|
|
2069
|
-
logger.info(
|
|
2070
|
-
f"[Worker] Initializing state manager with GOOGLE_APPLICATION_CREDENTIALS={'SET' if gcp_creds else 'UNSET'}, "
|
|
2071
|
-
f"GOOGLE_CLOUD_PROJECT={gcp_project or 'UNSET'}"
|
|
2072
|
-
)
|
|
2073
2055
|
# Prefer top-level cache; fallback to nested experiment.parameters.cache when using full config
|
|
2074
2056
|
cache_cfg = (global_config.get('cache') or {}) if isinstance(global_config, dict) else {}
|
|
2075
2057
|
if not cache_cfg and isinstance(global_config, dict):
|
|
@@ -2094,10 +2076,6 @@ def _maybe_init_worker_state_manager(global_config: Any, project_id: Optional[st
|
|
|
2094
2076
|
pass
|
|
2095
2077
|
pid_effective = project_id or _os.getenv('MLOPS_PROJECT_ID') or 'default'
|
|
2096
2078
|
backend_type = (backend_cfg.get('type') if isinstance(backend_cfg, dict) else None) or _os.getenv('MLOPS_KV_BACKEND') or 'local'
|
|
2097
|
-
logger.info(
|
|
2098
|
-
f"[Worker] KV backend selection -> MLOPS_KV_BACKEND={_os.getenv('MLOPS_KV_BACKEND') or 'unset'}, "
|
|
2099
|
-
f"resolved={backend_type}, project_ns={pid_effective}"
|
|
2100
|
-
)
|
|
2101
2079
|
try:
|
|
2102
2080
|
from mlops.storage.factory import create_kv_store as _create_kv_store, create_object_store as _create_obj_store
|
|
2103
2081
|
ws_root = get_workspace_root()
|
|
@@ -2124,10 +2102,6 @@ def _maybe_init_worker_state_manager(global_config: Any, project_id: Optional[st
|
|
|
2124
2102
|
except Exception:
|
|
2125
2103
|
ttl_val = 24
|
|
2126
2104
|
sm_new = _SSM(cache_dir=cache_dir, kv_store=kv_store, logger=logging.getLogger(__name__), cache_ttl_hours=ttl_val, object_store=obj_store, object_prefix=obj_prefix)
|
|
2127
|
-
logger.info(
|
|
2128
|
-
f"[Worker] StateManager created -> kv_store={type(kv_store).__name__ if kv_store else 'None'}, "
|
|
2129
|
-
f"object_store={type(obj_store).__name__ if obj_store else 'None'}"
|
|
2130
|
-
)
|
|
2131
2105
|
_set_sm(sm_new)
|
|
2132
2106
|
except Exception:
|
|
2133
2107
|
return
|
|
@@ -69,7 +69,6 @@ class VenvEnvironmentManager(EnvironmentManager):
|
|
|
69
69
|
|
|
70
70
|
def setup_environment(self) -> None:
|
|
71
71
|
"""Set up the virtual environment based on configuration."""
|
|
72
|
-
print(f"[VenvEnvironmentManager] Starting venv environment setup for '{self.environment_name}'...")
|
|
73
72
|
|
|
74
73
|
if not self.environment_exists():
|
|
75
74
|
print(f"[VenvEnvironmentManager] Environment '{self.environment_name}' not found. Creating it...")
|
|
@@ -78,16 +77,12 @@ class VenvEnvironmentManager(EnvironmentManager):
|
|
|
78
77
|
|
|
79
78
|
try:
|
|
80
79
|
subprocess.run([sys.executable, "-m", "venv", str(self.venv_path)], check=True)
|
|
81
|
-
print(f"[VenvEnvironmentManager] Environment '{self.environment_name}' created successfully.")
|
|
82
80
|
except subprocess.CalledProcessError as e:
|
|
83
81
|
# One more fallback: use virtualenv if available
|
|
84
82
|
try:
|
|
85
83
|
subprocess.run([sys.executable, "-m", "virtualenv", str(self.venv_path)], check=True)
|
|
86
|
-
print(f"[VenvEnvironmentManager] Environment '{self.environment_name}' created via virtualenv.")
|
|
87
84
|
except Exception:
|
|
88
85
|
raise RuntimeError(f"Failed to create virtual environment '{self.environment_name}': {e}")
|
|
89
|
-
else:
|
|
90
|
-
print(f"[VenvEnvironmentManager] Using existing environment: '{self.environment_name}'")
|
|
91
86
|
|
|
92
87
|
self.python_interpreter = str(self._python_path(self.venv_path))
|
|
93
88
|
|
|
@@ -95,30 +90,22 @@ class VenvEnvironmentManager(EnvironmentManager):
|
|
|
95
90
|
raise FileNotFoundError(f"Python interpreter not found in environment '{self.environment_name}' at expected path: {self.python_interpreter}")
|
|
96
91
|
|
|
97
92
|
if self.requirements:
|
|
98
|
-
print(f"[VenvEnvironmentManager] Installing requirements...")
|
|
99
93
|
try:
|
|
100
94
|
# Ensure modern build tooling to prefer wheels over source builds
|
|
101
95
|
subprocess.run([self.python_interpreter, "-m", "pip", "install", "--quiet", "--upgrade", "pip", "setuptools", "wheel"], check=True)
|
|
102
96
|
pip_install_cmd = [self.python_interpreter, "-m", "pip", "install", "--quiet", "--no-cache-dir"] + self.requirements
|
|
103
97
|
subprocess.run(pip_install_cmd, check=True)
|
|
104
|
-
print(f"[VenvEnvironmentManager] Requirements installed successfully.")
|
|
105
98
|
except subprocess.CalledProcessError as e:
|
|
106
99
|
raise RuntimeError(f"Failed to install requirements: {e}")
|
|
107
100
|
|
|
108
|
-
print(f"[VenvEnvironmentManager] Python interpreter: {self.python_interpreter}")
|
|
109
|
-
print(f"[VenvEnvironmentManager] Environment setup completed for '{self.environment_name}'.")
|
|
110
|
-
|
|
111
101
|
def verify_environment(self) -> bool:
|
|
112
102
|
"""Verify that the environment is properly configured."""
|
|
113
103
|
if not self.python_interpreter:
|
|
114
104
|
print("[VenvEnvironmentManager] Python interpreter not set. Cannot verify environment.")
|
|
115
105
|
return False
|
|
116
106
|
|
|
117
|
-
print(f"[VenvEnvironmentManager] Verifying environment '{self.environment_name}'...")
|
|
118
|
-
|
|
119
107
|
try:
|
|
120
108
|
python_version_output = subprocess.check_output([self.python_interpreter, '--version'], text=True, stderr=subprocess.STDOUT).strip()
|
|
121
|
-
print(f"[VenvEnvironmentManager] Python interpreter is working: {python_version_output}")
|
|
122
109
|
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
|
123
110
|
print(f"[VenvEnvironmentManager] Python interpreter '{self.python_interpreter}' is not working: {e}")
|
|
124
111
|
return False
|
|
@@ -130,5 +117,4 @@ class VenvEnvironmentManager(EnvironmentManager):
|
|
|
130
117
|
print(f"[VenvEnvironmentManager] Environment verification failed for '{self.environment_name}'.")
|
|
131
118
|
return False
|
|
132
119
|
|
|
133
|
-
print(f"[VenvEnvironmentManager] Environment verification successful for '{self.environment_name}'.")
|
|
134
120
|
return True
|
|
@@ -259,6 +259,15 @@ def _prepare_and_reexec_under_project_interpreter_if_needed(
|
|
|
259
259
|
if local_flag:
|
|
260
260
|
cmd.append("--local")
|
|
261
261
|
os.environ[ENV_ENV_READY] = "1"
|
|
262
|
+
if source_root and (source_root / "src").exists():
|
|
263
|
+
repo_src = str((source_root / "src").resolve())
|
|
264
|
+
pp = os.environ.get("PYTHONPATH", "")
|
|
265
|
+
parts = [p for p in pp.split(os.pathsep) if p.strip()]
|
|
266
|
+
parts = [p for p in parts if Path(p).resolve() != Path(repo_src).resolve()]
|
|
267
|
+
if parts:
|
|
268
|
+
os.environ["PYTHONPATH"] = os.pathsep.join(parts)
|
|
269
|
+
elif "PYTHONPATH" in os.environ:
|
|
270
|
+
os.environ["PYTHONPATH"] = ""
|
|
262
271
|
os.execv(cmd[0], cmd)
|
|
263
272
|
except Exception as e:
|
|
264
273
|
_append_to_log_file(log_file, f"Environment setup failed: {e}\n")
|
|
@@ -24,8 +24,6 @@ class ReproducibilityManager:
|
|
|
24
24
|
self.default_environment_name: Optional[str] = None
|
|
25
25
|
self._environment_python_map: Dict[str, str] = {}
|
|
26
26
|
|
|
27
|
-
if self.project_path:
|
|
28
|
-
print(f"[ReproducibilityManager] Using project path: {self.project_path}")
|
|
29
27
|
|
|
30
28
|
@property
|
|
31
29
|
def environment_name(self) -> Optional[str]:
|
|
@@ -55,14 +53,6 @@ class ReproducibilityManager:
|
|
|
55
53
|
|
|
56
54
|
if not isinstance(random_seed_config, int):
|
|
57
55
|
random_seed_config = 42
|
|
58
|
-
if self.config.get("reproducibility", {}).get("random_seed") is None:
|
|
59
|
-
print(f"[ReproducibilityManager] random_seed not specified, using default {random_seed_config}.")
|
|
60
|
-
else:
|
|
61
|
-
print(
|
|
62
|
-
f"[ReproducibilityManager] Invalid random_seed "
|
|
63
|
-
f"'{self.config.get('reproducibility', {}).get('random_seed')}', "
|
|
64
|
-
f"using default {random_seed_config}."
|
|
65
|
-
)
|
|
66
56
|
|
|
67
57
|
seed = int(random_seed_config)
|
|
68
58
|
|
|
@@ -73,7 +63,6 @@ class ReproducibilityManager:
|
|
|
73
63
|
print(f"[ReproducibilityManager] Failed to seed Python random: {e}")
|
|
74
64
|
try:
|
|
75
65
|
np.random.seed(seed)
|
|
76
|
-
print(f"[ReproducibilityManager] Global seeds set (python, numpy): {seed}")
|
|
77
66
|
except Exception as e:
|
|
78
67
|
print(f"[ReproducibilityManager] Failed to seed NumPy: {e}")
|
|
79
68
|
|
|
@@ -101,8 +90,6 @@ class ReproducibilityManager:
|
|
|
101
90
|
except Exception:
|
|
102
91
|
pass
|
|
103
92
|
|
|
104
|
-
print(f"[ReproducibilityManager] Reproducibility setup completed with seed {seed}.")
|
|
105
|
-
|
|
106
93
|
def _seed_pytorch_if_available(self, seed: int) -> None:
|
|
107
94
|
try:
|
|
108
95
|
import torch
|
|
@@ -126,7 +113,6 @@ class ReproducibilityManager:
|
|
|
126
113
|
pass
|
|
127
114
|
except Exception:
|
|
128
115
|
pass
|
|
129
|
-
print("[ReproducibilityManager] PyTorch seed applied.")
|
|
130
116
|
except Exception:
|
|
131
117
|
# PyTorch not installed or failed to import; ignore silently
|
|
132
118
|
pass
|
|
@@ -136,7 +122,6 @@ class ReproducibilityManager:
|
|
|
136
122
|
import tensorflow as tf
|
|
137
123
|
try:
|
|
138
124
|
tf.random.set_seed(seed)
|
|
139
|
-
print("[ReproducibilityManager] TensorFlow seed applied.")
|
|
140
125
|
except Exception:
|
|
141
126
|
pass
|
|
142
127
|
except Exception:
|
|
@@ -151,7 +136,6 @@ class ReproducibilityManager:
|
|
|
151
136
|
|
|
152
137
|
def setup_environment(self) -> None:
|
|
153
138
|
"""Set up the environment based on configuration."""
|
|
154
|
-
print("[ReproducibilityManager] Starting environment setup...")
|
|
155
139
|
self.environment_managers, self.default_environment_name = create_environment_managers(self.config)
|
|
156
140
|
if self.default_environment_name and self.default_environment_name in self.environment_managers:
|
|
157
141
|
self.environment_manager = self.environment_managers[self.default_environment_name]
|
|
@@ -174,13 +158,6 @@ class ReproducibilityManager:
|
|
|
174
158
|
self._environment_python_map[env_name] = py_exec
|
|
175
159
|
except Exception:
|
|
176
160
|
py_exec = None
|
|
177
|
-
try:
|
|
178
|
-
print(f"[ReproducibilityManager] Environment '{env_name}' setup completed.")
|
|
179
|
-
print(f"[ReproducibilityManager] Environment type: {manager.get_environment_type()}")
|
|
180
|
-
if py_exec:
|
|
181
|
-
print(f"[ReproducibilityManager] Python interpreter: {py_exec}")
|
|
182
|
-
except Exception:
|
|
183
|
-
pass
|
|
184
161
|
|
|
185
162
|
# Ensure chart/reporting environments can import the platform.
|
|
186
163
|
try:
|
|
@@ -365,10 +365,8 @@ class MLPlatform:
|
|
|
365
365
|
is_distributed = self._in_distributed_mode()
|
|
366
366
|
|
|
367
367
|
if is_distributed:
|
|
368
|
-
logger.info("Detected distributed mode - will submit dynamic charts as cluster jobs")
|
|
369
368
|
return self._start_dynamic_charts_distributed(adapter, platform_config, run_id)
|
|
370
369
|
else:
|
|
371
|
-
logger.info("Local mode - will run dynamic charts as background processes")
|
|
372
370
|
return self._start_dynamic_charts_local(adapter, platform_config, run_id)
|
|
373
371
|
|
|
374
372
|
def _start_dynamic_charts_local(self, adapter: Any, platform_config: Dict[str, Any], run_id: str) -> list:
|
|
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
|
|
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
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/charts/plot_metrics.js
RENAMED
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/charts/plot_metrics.py
RENAMED
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/charts/requirements.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/data/England CSV.csv
RENAMED
|
File without changes
|
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/premier-league/requirements.txt
RENAMED
|
File without changes
|
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/charts/plot_metrics.py
RENAMED
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/charts/requirements.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/src/mlops/templates/sklearn-basic/requirements.txt
RENAMED
|
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
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_dask_networkx_executor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_core/test_prepare_runner_kwargs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{expops-0.1.13.dev0 → expops-0.1.15.dev0}/tests/unit/test_managers/test_reproducibility_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|