Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions dvc/commands/experiments/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ def _update_names(names, items):
def _collect_names(all_experiments, **kwargs):
metric_names = defaultdict(dict)
param_names = defaultdict(dict)
deps_names = set()

for _, experiments in all_experiments.items():
for exp_data in experiments.values():
exp = exp_data.get("data", {})
_update_names(metric_names, exp.get("metrics", {}).items())
_update_names(param_names, exp.get("params", {}).items())
for dep_name in exp.get("deps", {}):
deps_names.add(dep_name)

return metric_names, param_names
return metric_names, param_names, deps_names


experiment_types = {
Expand All @@ -64,6 +67,7 @@ def _collect_rows(
experiments,
metric_names,
param_names,
deps_names,
precision=DEFAULT_PRECISION,
sort_by=None,
sort_order=None,
Expand Down Expand Up @@ -150,7 +154,11 @@ def _collect_rows(
precision,
fill_value=fill_value,
)

for dep in deps_names:
hash_info = exp.get("deps", {}).get(dep, {}).get("hash")
if hash_info is not None:
hash_info = hash_info[:7]
row.append(hash_info or fill_value)
yield row


Expand Down Expand Up @@ -245,6 +253,7 @@ def experiments_table(
metric_names,
param_headers,
param_names,
deps_names,
sort_by=None,
sort_order=None,
precision=DEFAULT_PRECISION,
Expand All @@ -256,14 +265,16 @@ def experiments_table(
from dvc.compare import TabularData

td = TabularData(
lconcat(headers, metric_headers, param_headers), fill_value=fill_value
lconcat(headers, metric_headers, param_headers, deps_names),
fill_value=fill_value,
)
for base_rev, experiments in all_experiments.items():
rows = _collect_rows(
base_rev,
experiments,
metric_names,
param_names,
deps_names,
sort_by=sort_by,
sort_order=sort_order,
precision=precision,
Expand Down Expand Up @@ -310,7 +321,7 @@ def show_experiments(
):
from funcy.seqs import flatten as flatten_list

metric_names, param_names = _collect_names(all_experiments)
metric_names, param_names, deps_names = _collect_names(all_experiments)

headers = [
"Experiment",
Expand All @@ -335,6 +346,7 @@ def show_experiments(
metric_names,
param_headers,
param_names,
deps_names,
kwargs.get("sort_by"),
kwargs.get("sort_order"),
kwargs.get("precision"),
Expand All @@ -359,14 +371,22 @@ def show_experiments(
)
td.drop(*merge_headers[1:])

headers = {"metrics": metric_headers, "params": param_headers}
headers = {
"metrics": metric_headers,
"params": param_headers,
"deps": deps_names,
}
styles = {
"Experiment": {"no_wrap": True, "header_style": "black on grey93"},
"Created": {"header_style": "black on grey93"},
"State": {"header_style": "black on grey93"},
"Executor": {"header_style": "black on grey93"},
}
header_bg_colors = {"metrics": "cornsilk1", "params": "light_cyan1"}
header_bg_colors = {
"metrics": "cornsilk1",
"params": "light_cyan1",
"deps": "plum2",
}
styles.update(
{
header: {
Expand Down
23 changes: 23 additions & 0 deletions dvc/repo/experiments/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def _collect_experiment_commit(
running=None,
onerror: Optional[Callable] = None,
):
from dvc.dependency import ParamsDependency, RepoDependency

res: Dict[str, Optional[Any]] = defaultdict(dict)
for rev in repo.brancher(revs=[exp_rev]):
if rev == "workspace":
Expand All @@ -39,6 +41,26 @@ def _collect_experiment_commit(
if params:
res["params"] = params

res["deps"] = {
dep.def_path: {
"hash": dep.hash_info.value,
"size": dep.meta.size,
"nfiles": dep.meta.nfiles,
}
for dep in repo.index.deps
if not isinstance(dep, (ParamsDependency, RepoDependency))
}

res["outs"] = {
out.def_path: {
"hash": out.hash_info.value,
"size": out.meta.size,
"nfiles": out.meta.nfiles,
}
for out in repo.index.outs
if not (out.is_metric or out.is_plot)
}

res["queued"] = stash
if running is not None and exp_rev in running:
res["running"] = True
Expand Down Expand Up @@ -111,6 +133,7 @@ def show(
param_deps=False,
onerror: Optional[Callable] = None,
):

if onerror is None:
onerror = onerror_collect

Expand Down
88 changes: 76 additions & 12 deletions tests/func/experiments/test_show.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import os
from datetime import datetime
from unittest.mock import ANY

import pytest
from funcy import first, get_in
Expand Down Expand Up @@ -38,7 +39,15 @@ def test_show_simple(tmp_dir, scm, dvc, exp_stage):
assert dvc.experiments.show()["workspace"] == {
"baseline": {
"data": {
"deps": {
"copy.py": {
"hash": ANY,
"size": ANY,
"nfiles": None,
}
},
"metrics": {"metrics.yaml": {"data": {"foo": 1}}},
"outs": {},
"params": {"params.yaml": {"data": {"foo": 1}}},
"queued": False,
"running": False,
Expand All @@ -63,7 +72,15 @@ def test_show_experiment(tmp_dir, scm, dvc, exp_stage, workspace):

expected_baseline = {
"data": {
"deps": {
"copy.py": {
"hash": ANY,
"size": ANY,
"nfiles": None,
}
},
"metrics": {"metrics.yaml": {"data": {"foo": 1}}},
"outs": {},
"params": {"params.yaml": {"data": {"foo": 1}}},
"queued": False,
"running": False,
Expand Down Expand Up @@ -318,8 +335,16 @@ def test_show_running_workspace(tmp_dir, scm, dvc, exp_stage, capsys):
assert dvc.experiments.show()["workspace"] == {
"baseline": {
"data": {
"deps": {
"copy.py": {
"hash": ANY,
"size": ANY,
"nfiles": None,
}
},
"metrics": {"metrics.yaml": {"data": {"foo": 1}}},
"params": {"params.yaml": {"data": {"foo": 1}}},
"outs": {},
"queued": False,
"running": True,
"executor": info.location,
Expand All @@ -329,7 +354,7 @@ def test_show_running_workspace(tmp_dir, scm, dvc, exp_stage, capsys):
}

capsys.readouterr()
assert main(["exp", "show", "--no-pager"]) == 0
assert main(["exp", "show", "--csv"]) == 0
cap = capsys.readouterr()
assert "Running" in cap.out
assert info.location in cap.out
Expand Down Expand Up @@ -450,26 +475,26 @@ def _get_rev_isotimestamp(rev):
capsys.readouterr()
assert main(["exp", "show", "--csv"]) == 0
cap = capsys.readouterr()
data_dep = first(x for x in dvc.index.deps if "copy.py" in x.fspath)
data_hash = data_dep.hash_info.value[:7]
Comment on lines +478 to +479
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know how to something like the ANY usage above but for the type of assertions bellow

assert "Experiment,rev,typ,Created,parent" in cap.out
assert "metrics.yaml:foo,params.yaml:foo,copy.py" in cap.out
assert f",workspace,baseline,,,3,3,{data_hash}" in cap.out
assert (
"Experiment,rev,typ,Created,parent,metrics.yaml:foo,params.yaml:foo"
in cap.out
)
assert ",workspace,baseline,,,3,3" in cap.out
assert (
"master,{},baseline,{},,1,1".format(
baseline_rev[:7], _get_rev_isotimestamp(baseline_rev)
"master,{},baseline,{},,1,1,{}".format(
baseline_rev[:7], _get_rev_isotimestamp(baseline_rev), data_hash
)
in cap.out
)
assert (
"{},{},branch_base,{},,2,2".format(
ref_info1.name, rev1[:7], _get_rev_isotimestamp(rev1)
"{},{},branch_base,{},,2,2,{}".format(
ref_info1.name, rev1[:7], _get_rev_isotimestamp(rev1), data_hash
)
in cap.out
)
assert (
"{},{},branch_commit,{},,3,3".format(
ref_info2.name, rev2[:7], _get_rev_isotimestamp(rev2)
"{},{},branch_commit,{},,3,3,{}".format(
ref_info2.name, rev2[:7], _get_rev_isotimestamp(rev2), data_hash
)
in cap.out
)
Expand Down Expand Up @@ -596,3 +621,42 @@ def test_show_parallel_coordinates(tmp_dir, dvc, scm, mocker, capsys):
html_text = (tmp_dir / "dvc_plots" / "index.html").read_text()
assert '"label": "Created"' not in html_text
assert '"label": "foobar"' not in html_text


def test_show_outs(tmp_dir, dvc, scm):
tmp_dir.gen("copy.py", COPY_SCRIPT)
params_file = tmp_dir / "params.yaml"
params_data = {
"foo": 1,
"bar": 1,
}
(tmp_dir / params_file).dump(params_data)

dvc.run(
cmd="python copy.py params.yaml metrics.yaml && echo out > out",
metrics_no_cache=["metrics.yaml"],
params=["foo", "bar"],
name="copy-file",
deps=["copy.py"],
outs=["out"],
)
scm.add(
[
"dvc.yaml",
"dvc.lock",
"copy.py",
"params.yaml",
"metrics.yaml",
".gitignore",
]
)
scm.commit("init")

outs = dvc.experiments.show()["workspace"]["baseline"]["data"]["outs"]
assert outs == {
"out": {
"hash": ANY,
"size": ANY,
"nfiles": None,
}
}