mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
committed by
Mr. Outis
parent
e0e02a9f6b
commit
8ae01de0eb
@@ -35,13 +35,11 @@ def show_metrics(metrics, all_branches=False, all_tags=False):
|
||||
|
||||
class CmdMetricsShow(CmdBase):
|
||||
def run(self):
|
||||
typ = self.args.type
|
||||
xpath = self.args.xpath
|
||||
try:
|
||||
metrics = self.repo.metrics.show(
|
||||
self.args.path,
|
||||
typ=typ,
|
||||
xpath=xpath,
|
||||
self.args.targets,
|
||||
typ=self.args.type,
|
||||
xpath=self.args.xpath,
|
||||
all_branches=self.args.all_branches,
|
||||
all_tags=self.args.all_tags,
|
||||
recursive=self.args.recursive,
|
||||
@@ -121,7 +119,10 @@ def add_parser(subparsers, parent_parser):
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
metrics_show_parser.add_argument(
|
||||
"path", nargs="?", help="Path to a metric file or a directory."
|
||||
"targets",
|
||||
nargs="*",
|
||||
help="Metric files or directories (see -R) to show "
|
||||
"(leave empty to display all)",
|
||||
)
|
||||
metrics_show_parser.add_argument(
|
||||
"-t",
|
||||
@@ -155,8 +156,8 @@ def add_parser(subparsers, parent_parser):
|
||||
action="store_true",
|
||||
default=False,
|
||||
help=(
|
||||
"If path is a directory, recursively search and process metric "
|
||||
"files in path."
|
||||
"If any target is a directory, recursively search and process "
|
||||
"metric files."
|
||||
),
|
||||
)
|
||||
metrics_show_parser.set_defaults(func=CmdMetricsShow)
|
||||
|
||||
+4
-3
@@ -196,10 +196,11 @@ class ReproductionError(DvcException):
|
||||
|
||||
|
||||
class BadMetricError(DvcException):
|
||||
def __init__(self, path):
|
||||
def __init__(self, paths):
|
||||
super(BadMetricError, self).__init__(
|
||||
"'{}' does not exist, not a metric or is malformed".format(
|
||||
relpath(path)
|
||||
"the following outputs do not exist, are not a metric file "
|
||||
"or are malformed: {paths}".format(
|
||||
paths=", ".join(relpath(path) for path in paths)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+22
-18
@@ -152,15 +152,16 @@ def _read_metric(fd, typ=None, xpath=None, fname=None, branch=None):
|
||||
return None
|
||||
|
||||
|
||||
def _collect_metrics(repo, path, recursive, typ, xpath, branch):
|
||||
def _collect_metrics(repo, targets, recursive, typ, xpath, branch):
|
||||
"""Gather all the metric outputs.
|
||||
|
||||
Args:
|
||||
path (str): Path to a metric file or a directory.
|
||||
targets (list): List of paths to metric files or directories.
|
||||
If there's no target, collect all metrics.
|
||||
recursive (bool): If path is a directory, do a recursive search for
|
||||
metrics on the given path.
|
||||
typ (str): The type of metric to search for, could be one of the
|
||||
following (raw|json|tsv|htsv|csv|hcsv).
|
||||
typ (str): The type that will be used to interpret the metric file,
|
||||
one of the followings - (raw|json|tsv|htsv|csv|hcsv).
|
||||
xpath (str): Path to search for.
|
||||
branch (str): Branch to look up for metrics.
|
||||
|
||||
@@ -171,20 +172,21 @@ def _collect_metrics(repo, path, recursive, typ, xpath, branch):
|
||||
- xpath:
|
||||
"""
|
||||
outs = [out for stage in repo.stages() for out in stage.outs]
|
||||
found = []
|
||||
|
||||
if path:
|
||||
try:
|
||||
outs = repo.find_outs_by_path(path, outs=outs, recursive=recursive)
|
||||
except OutputNotFoundError:
|
||||
logger.debug(
|
||||
"DVC-file not for found for '{}' in branch '{}'".format(
|
||||
path, branch
|
||||
if targets:
|
||||
for target in targets:
|
||||
try:
|
||||
found += repo.find_outs_by_path(
|
||||
target, outs=outs, recursive=recursive
|
||||
)
|
||||
)
|
||||
return []
|
||||
except OutputNotFoundError:
|
||||
pass
|
||||
else:
|
||||
found = outs
|
||||
|
||||
res = []
|
||||
for o in outs:
|
||||
for o in found:
|
||||
if not o.metric:
|
||||
continue
|
||||
|
||||
@@ -259,7 +261,7 @@ def _read_metrics(repo, metrics, branch):
|
||||
|
||||
def show(
|
||||
repo,
|
||||
path=None,
|
||||
targets=None,
|
||||
typ=None,
|
||||
xpath=None,
|
||||
all_branches=False,
|
||||
@@ -269,14 +271,16 @@ def show(
|
||||
res = {}
|
||||
|
||||
for branch in repo.brancher(all_branches=all_branches, all_tags=all_tags):
|
||||
entries = _collect_metrics(repo, path, recursive, typ, xpath, branch)
|
||||
entries = _collect_metrics(
|
||||
repo, targets, recursive, typ, xpath, branch
|
||||
)
|
||||
metrics = _read_metrics(repo, entries, branch)
|
||||
if metrics:
|
||||
res[branch] = metrics
|
||||
|
||||
if not res:
|
||||
if path:
|
||||
raise BadMetricError(path)
|
||||
if targets:
|
||||
raise BadMetricError(targets)
|
||||
raise NoMetricsError()
|
||||
|
||||
return res
|
||||
|
||||
+40
-20
@@ -85,14 +85,14 @@ class TestMetricsBase(TestDvcGit):
|
||||
|
||||
class TestMetrics(TestMetricsBase):
|
||||
def test_show(self):
|
||||
ret = self.dvc.metrics.show("metric", all_branches=True)
|
||||
ret = self.dvc.metrics.show(["metric"], all_branches=True)
|
||||
self.assertEqual(len(ret), 3)
|
||||
self.assertEqual(ret["foo"]["metric"], "foo")
|
||||
self.assertEqual(ret["bar"]["metric"], "bar")
|
||||
self.assertEqual(ret["baz"]["metric"], "baz")
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_json", typ="json", xpath="branch", all_branches=True
|
||||
["metric_json"], typ="json", xpath="branch", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
self.assertSequenceEqual(ret["foo"]["metric_json"], ["foo"])
|
||||
@@ -100,7 +100,7 @@ class TestMetrics(TestMetricsBase):
|
||||
self.assertSequenceEqual(ret["baz"]["metric_json"], ["baz"])
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_tsv", typ="tsv", xpath="0,0", all_branches=True
|
||||
["metric_tsv"], typ="tsv", xpath="0,0", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
self.assertSequenceEqual(ret["foo"]["metric_tsv"], ["foo"])
|
||||
@@ -108,7 +108,7 @@ class TestMetrics(TestMetricsBase):
|
||||
self.assertSequenceEqual(ret["baz"]["metric_tsv"], ["baz"])
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_htsv", typ="htsv", xpath="0,branch", all_branches=True
|
||||
["metric_htsv"], typ="htsv", xpath="0,branch", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
self.assertSequenceEqual(ret["foo"]["metric_htsv"], ["foo"])
|
||||
@@ -116,7 +116,7 @@ class TestMetrics(TestMetricsBase):
|
||||
self.assertSequenceEqual(ret["baz"]["metric_htsv"], ["baz"])
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_csv", typ="csv", xpath="0,0", all_branches=True
|
||||
["metric_csv"], typ="csv", xpath="0,0", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
self.assertSequenceEqual(ret["foo"]["metric_csv"], ["foo"])
|
||||
@@ -124,7 +124,7 @@ class TestMetrics(TestMetricsBase):
|
||||
self.assertSequenceEqual(ret["baz"]["metric_csv"], ["baz"])
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_hcsv", typ="hcsv", xpath="0,branch", all_branches=True
|
||||
["metric_hcsv"], typ="hcsv", xpath="0,branch", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
self.assertSequenceEqual(ret["foo"]["metric_hcsv"], ["foo"])
|
||||
@@ -132,7 +132,7 @@ class TestMetrics(TestMetricsBase):
|
||||
self.assertSequenceEqual(ret["baz"]["metric_hcsv"], ["baz"])
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_json_ext",
|
||||
["metric_json_ext"],
|
||||
typ="json",
|
||||
xpath="$.metrics[?(@.deviation_mse<0.30) & (@.value_mse>0.4)]",
|
||||
all_branches=True,
|
||||
@@ -153,7 +153,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_unknown_type_ignored(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_hcsv", typ="unknown", xpath="0,branch", all_branches=True
|
||||
["metric_hcsv"], typ="unknown", xpath="0,branch", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -161,7 +161,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_type_case_normalized(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_hcsv", typ=" hCSV ", xpath="0,branch", all_branches=True
|
||||
["metric_hcsv"], typ=" hCSV ", xpath="0,branch", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -169,7 +169,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_xpath_is_empty(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_json", typ="json", xpath="", all_branches=True
|
||||
["metric_json"], typ="json", xpath="", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -177,7 +177,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_xpath_is_none(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_json", typ="json", xpath=None, all_branches=True
|
||||
["metric_json"], typ="json", xpath=None, all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -185,7 +185,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_xpath_all_columns(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_hcsv", typ="hcsv ", xpath="0,", all_branches=True
|
||||
["metric_hcsv"], typ="hcsv ", xpath="0,", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -193,7 +193,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_xpath_all_rows(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_csv", typ="csv", xpath=",0", all_branches=True
|
||||
["metric_csv"], typ="csv", xpath=",0", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -201,7 +201,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_xpath_all(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_csv", typ="csv", xpath=",", all_branches=True
|
||||
["metric_csv"], typ="csv", xpath=",", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -209,7 +209,7 @@ class TestMetrics(TestMetricsBase):
|
||||
|
||||
def test_xpath_all_with_header(self):
|
||||
ret = self.dvc.metrics.show(
|
||||
"metric_hcsv", typ="hcsv", xpath=",", all_branches=True
|
||||
["metric_hcsv"], typ="hcsv", xpath=",", all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for b in ["foo", "bar", "baz"]:
|
||||
@@ -413,10 +413,12 @@ class TestMetricsRecursive(TestDvcGit):
|
||||
|
||||
def test(self):
|
||||
with self.assertRaises(BadMetricError):
|
||||
self.dvc.metrics.show("nested", all_branches=True, recursive=False)
|
||||
self.dvc.metrics.show(
|
||||
["nested"], all_branches=True, recursive=False
|
||||
)
|
||||
|
||||
ret = self.dvc.metrics.show(
|
||||
"nested", all_branches=True, recursive=True
|
||||
["nested"], all_branches=True, recursive=True
|
||||
)
|
||||
self.assertEqual(len(ret), 1)
|
||||
self.assertEqual(
|
||||
@@ -697,7 +699,7 @@ class TestCachedMetrics(TestDvcGit):
|
||||
self.dvc = DvcRepo(".")
|
||||
|
||||
res = self.dvc.metrics.show(
|
||||
"metrics.json", all_branches=True, typ="json", xpath="metrics"
|
||||
["metrics.json"], all_branches=True, typ="json", xpath="metrics"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
@@ -711,7 +713,7 @@ class TestCachedMetrics(TestDvcGit):
|
||||
)
|
||||
|
||||
res = self.dvc.metrics.show(
|
||||
"", all_branches=True, typ="json", xpath="metrics"
|
||||
all_branches=True, typ="json", xpath="metrics"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
@@ -777,7 +779,9 @@ class TestMetricsType(TestDvcGit):
|
||||
self._do_show(file_name, xpath)
|
||||
|
||||
def _do_show(self, file_name, xpath):
|
||||
ret = self.dvc.metrics.show(file_name, xpath=xpath, all_branches=True)
|
||||
ret = self.dvc.metrics.show(
|
||||
[file_name], xpath=xpath, all_branches=True
|
||||
)
|
||||
self.assertEqual(len(ret), 3)
|
||||
for branch in self.branches:
|
||||
if isinstance(ret[branch][file_name], list):
|
||||
@@ -844,3 +848,19 @@ def test_show_xpath_should_override_stage_xpath(dvc_repo):
|
||||
|
||||
result = dvc_repo.metrics.show(xpath="m1")
|
||||
assert result == {"": {metric_file: [0.1]}}
|
||||
|
||||
|
||||
def test_show_multiple_outputs(dvc_repo, caplog):
|
||||
with open("1.json", "w") as fobj:
|
||||
json.dump({"AUC": 1}, fobj)
|
||||
|
||||
with open("2.json", "w") as fobj:
|
||||
json.dump({"AUC": 2}, fobj)
|
||||
|
||||
dvc_repo.run(cmd="", overwrite=True, metrics=["1.json"])
|
||||
dvc_repo.run(cmd="", overwrite=True, metrics=["2.json"])
|
||||
|
||||
with caplog.at_level(logging.INFO, logger="dvc"):
|
||||
assert 0 == main(["metrics", "show", "1.json", "2.json"])
|
||||
assert '1.json: {"AUC": 1}' in caplog.text
|
||||
assert '2.json: {"AUC": 2}' in caplog.text
|
||||
|
||||
Reference in New Issue
Block a user