Coverage for packages/dqm-ml/src/dqm_ml/dependency.py: 100%
45 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-21 08:27 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-21 08:27 +0000
1"""Dependency management utilities for DQM-ML v2.
3This module provides functions for handling optional dependencies,
4displaying version information, and discovering available commands.
5"""
7from collections.abc import Generator
8from contextlib import contextmanager
9import logging
10from typing import Any
12from dqm_ml_core import PluginLoadedRegistry
13from dqm_ml_core._version_ import version as core_version
15logger = logging.getLogger(__name__)
18@contextmanager
19def optional_dependencies(error: str = "ignore") -> Generator[None, None, None]:
20 """Context manager for handling optional dependencies.
22 Args:
23 error: How to handle missing optional dependencies:
24 - "ignore": Silently continue (default)
25 - "warn": Print a warning message
26 - "raise": Raise the ImportError
28 Yields:
29 None - this is a context manager that doesn't provide any value.
30 """
31 assert error in {"raise", "warn", "ignore"}
32 try:
33 yield None
34 except ImportError as e:
35 if error == "raise":
36 raise e
37 if error == "warn":
38 msg = f'Missing optional dependency "{e.name}". Use pip to install.'
39 print(f"Warning: {msg}")
42def display_version(arg_list: list[str] | None = None) -> None:
43 """Print the DQM-ML core version to stdout.
45 Args:
46 arg_list: Unused, provided for CLI compatibility.
47 """
48 print(f"DQM-ML version : {core_version}")
51def display_list_of(arg_list: list[str] | None = None) -> None:
52 """Print all registered plugins (metrics, dataloaders, output writers).
54 Args:
55 arg_list: Unused, provided for CLI compatibility.
56 """
57 # TODO : we display all but we can filter / use extra parameters
58 print("Available data metrics_registry")
59 for key, value in PluginLoadedRegistry.get_metrics_registry().items():
60 print(f"- {key} - {value}")
62 print("Available data features_registry")
63 for key, value in PluginLoadedRegistry.get_features_registry().items():
64 print(f"- {key} - {value}")
66 print("Available data gap_registry")
67 for key, value in PluginLoadedRegistry.get_gap_registry().items():
68 print(f"- {key} - {value}")
70 print("Available data loaders")
71 for key, value in PluginLoadedRegistry.get_dataloaders_registry().items():
72 print(f"- {key} - {value}")
74 print("Available outputs writers")
75 for key, value in PluginLoadedRegistry.get_outputwriter_registry().items():
76 print(f"- {key} - {value}")
79def get_available_command() -> dict[str, Any]:
80 """Build a dictionary of available CLI commands.
82 Returns:
83 Dict mapping command names to their handler functions.
84 """
85 command_list = {"version": display_version, "list": display_list_of}
86 optional_dep_mode = "warn"
88 # We import available command for dqml cli
89 with optional_dependencies(optional_dep_mode):
90 from dqm_ml_job._version_ import version as pipeline_version
91 from dqm_ml_job.cli import execute
93 logger.debug(f"Different dqm-ml-job version {pipeline_version}")
94 command_list["process"] = execute
96 return command_list