Coverage for ml_workbench/cli_datasets.py: 19%
58 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-19 11:25 +0200
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-19 11:25 +0200
1from __future__ import annotations
3import argparse
4import json
5from pathlib import Path
6from typing import Any, Dict, Optional
8from .config import YamlConfig
9from .dataset import Dataset
12def _basic_stats_for_dataset(name: str, cfg: YamlConfig) -> dict[str, Any]:
13 """Get basic statistics for a dataset using the Dataset class.
15 Parameters
16 ----------
17 name : str
18 Dataset name
19 cfg : YamlConfig
20 Configuration object
22 Returns
23 -------
24 dict[str, Any]
25 Dictionary with dataset statistics including name, description, format,
26 type, path, num_columns, num_rows, column_names, and is_combined flag
27 """
28 try:
29 ds = Dataset(name, cfg)
31 result: dict[str, Any] = {
32 "name": name,
33 "description": ds.description,
34 "format": ds.format,
35 "type": ds.type,
36 "path": ds.path,
37 "is_combined": ds.is_combined,
38 }
40 # Try to read and get statistics
41 try:
42 stats = ds.get_statistics()
43 result.update({
44 "num_columns": stats["num_columns"],
45 "num_rows": stats["num_rows"],
46 "column_names": stats["column_names"],
47 })
48 except Exception as exc:
49 # If reading fails, still return basic info with error
50 result.update({
51 "num_columns": None,
52 "num_rows": None,
53 "column_names": None,
54 "error": str(exc),
55 })
57 return result
59 except Exception as exc:
60 # If dataset creation fails, return minimal info
61 return {
62 "name": name,
63 "error": f"Failed to create dataset: {exc}",
64 }
67def parse_kv_pairs(kv_list: list[str]) -> Dict[str, Any]:
68 variables: Dict[str, Any] = {}
69 for item in kv_list:
70 if "=" not in item:
71 raise argparse.ArgumentTypeError(
72 f"Invalid variable format {item!r}, expected key=value"
73 )
74 key, value = item.split("=", 1)
75 variables[key] = value
76 return variables
79def build_arg_parser() -> argparse.ArgumentParser:
80 parser = argparse.ArgumentParser(
81 prog="ml-workbench-datasets",
82 description="Inspect datasets from a YAML config and print basic statistics.",
83 )
84 parser.add_argument("yaml", type=Path, help="Path to YAML configuration file")
85 parser.add_argument(
86 "--var",
87 dest="vars",
88 action="append",
89 default=[],
90 metavar="key=value",
91 help="Placeholder variable override (can be used multiple times)",
92 )
93 parser.add_argument(
94 "--json",
95 action="store_true",
96 help="Output machine-readable JSON instead of pretty text",
97 )
98 return parser
101def main(argv: Optional[list[str]] = None) -> int:
102 parser = build_arg_parser()
103 args = parser.parse_args(argv)
105 variables = parse_kv_pairs(list(args.vars)) if args.vars else {}
106 cfg = YamlConfig(args.yaml, **variables)
108 # Get list of dataset names and generate statistics for each
109 dataset_names = cfg.get_datasets_list()
110 results = [_basic_stats_for_dataset(name, cfg) for name in dataset_names]
112 if args.json:
113 print(json.dumps({"datasets": results}, indent=2))
114 else:
115 for item in results:
116 print(f"- {item['name']}")
117 if "error" in item:
118 print(f" error: {item['error']}")
119 continue
121 print(f" format: {item.get('format')}")
122 print(f" type: {item.get('type')}")
123 print(f" path: {item.get('path')}")
125 if item.get("is_combined"):
126 print(" combined: true")
128 print(f" num_columns: {item.get('num_columns')}")
129 print(f" num_rows: {item.get('num_rows')}")
131 # Print column names if available
132 column_names = item.get("column_names")
133 if column_names:
134 print(f" columns: {', '.join(column_names)}")
136 return 0
139if __name__ == "__main__": # pragma: no cover
140 raise SystemExit(main())