From f964a44e7c1d4fb29bcb2cd6835c00fcc693422a Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 20 Oct 2021 07:19:57 +0200 Subject: [PATCH] Exp show md (#6799) * Added `--md`/`--show-md` option to `exp show`. * Added test_show_experiments_md * Fixed re-defining all_experiments * Fixed all_experiments * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added dest markdown * Added textwrap.dedent * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update experiments.py * Apply suggestions from code review Co-authored-by: Saugat Pachhai * Update tests/unit/command/test_compat_flag.py Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Saugat Pachhai --- dvc/command/experiments.py | 17 +- tests/unit/command/test_compat_flag.py | 1 + tests/unit/command/test_experiments.py | 229 +++++++++++++++---------- 3 files changed, 156 insertions(+), 91 deletions(-) diff --git a/dvc/command/experiments.py b/dvc/command/experiments.py index 143637345..b2616d881 100644 --- a/dvc/command/experiments.py +++ b/dvc/command/experiments.py @@ -382,7 +382,12 @@ def baseline_styler(typ): def show_experiments( - all_experiments, pager=True, no_timestamp=False, csv=False, **kwargs + all_experiments, + pager=True, + no_timestamp=False, + csv=False, + markdown=False, + **kwargs, ): from funcy.seqs import flatten as flatten_list @@ -473,6 +478,7 @@ def show_experiments( header_styles=styles, row_styles=row_styles, csv=csv, + markdown=markdown, ) @@ -530,6 +536,7 @@ class CmdExperimentsShow(CmdBase): iso=iso, pager=not self.args.no_pager, csv=self.args.csv, + markdown=self.args.markdown, ) return 0 @@ -991,6 +998,14 @@ def add_parser(subparsers, parent_parser): default=False, help="Print output in csv format instead of a human-readable table.", ) + experiments_show_parser.add_argument( + "--md", + "--show-md", + action="store_true", + default=False, + dest="markdown", + help="Show tabulated output in the Markdown format (GFM).", + ) experiments_show_parser.add_argument( "--precision", type=int, diff --git a/tests/unit/command/test_compat_flag.py b/tests/unit/command/test_compat_flag.py index 1c559a017..e01469078 100644 --- a/tests/unit/command/test_compat_flag.py +++ b/tests/unit/command/test_compat_flag.py @@ -20,6 +20,7 @@ def _id_gen(val) -> str: (["experiments", "diff", "--show-md"], "markdown"), (["experiments", "show", "--show-json"], "json"), (["experiments", "show", "--show-csv"], "csv"), + (["experiments", "show", "--show-md"], "markdown"), (["ls", "--show-json", "."], "json"), (["metrics", "diff", "--show-json"], "json"), (["metrics", "diff", "--show-md"], "markdown"), diff --git a/tests/unit/command/test_experiments.py b/tests/unit/command/test_experiments.py index 7278d8bc9..3b00c4716 100644 --- a/tests/unit/command/test_experiments.py +++ b/tests/unit/command/test_experiments.py @@ -1,4 +1,5 @@ import csv +import textwrap from datetime import datetime import pytest @@ -283,104 +284,121 @@ def test_experiments_remove(dvc, scm, mocker, queue, clear_all, remote): ) -all_experiments = { - "workspace": { - "baseline": { - "data": { - "timestamp": None, - "params": { - "params.yaml": { - "data": { - "featurize": {"max_features": 3000, "ngrams": 1}, - "parent": 20170428, - "train": { - "n_est": 100, - "min_split": 36, - }, +def test_show_experiments_csv(capsys): + all_experiments = { + "workspace": { + "baseline": { + "data": { + "timestamp": None, + "params": { + "params.yaml": { + "data": { + "featurize": { + "max_features": 3000, + "ngrams": 1, + }, + "parent": 20170428, + "train": { + "n_est": 100, + "min_split": 36, + }, + } } - } - }, - "queued": False, - "running": False, - "executor": None, - "metrics": { - "scores.json": { - "data": { - "featurize": {"max_features": 3000, "ngrams": 1}, - "avg_prec": 0.5843640011189556, - "roc_auc": 0.9544670443829399, + }, + "queued": False, + "running": False, + "executor": None, + "metrics": { + "scores.json": { + "data": { + "featurize": { + "max_features": 3000, + "ngrams": 1, + }, + "avg_prec": 0.5843640011189556, + "roc_auc": 0.9544670443829399, + } } - } - }, - } - } - }, - "b05eecc666734e899f79af228ff49a7ae5a18cc0": { - "baseline": { - "data": { - "timestamp": datetime(2021, 8, 2, 16, 48, 14), - "params": { - "params.yaml": { - "data": { - "featurize": {"max_features": 3000, "ngrams": 1}, - "parent": 20170428, - "train": { - "n_est": 100, - "min_split": 2, - }, - } - } - }, - "queued": False, - "running": False, - "executor": None, - "metrics": { - "scores.json": { - "data": { - "featurize": {"max_features": 3000, "ngrams": 1}, - "avg_prec": 0.5325162867864254, - "roc_auc": 0.9106964878520005, - } - } - }, - "name": "master", + }, + } } }, - "ae99936461d6c3092934160f8beafe66a294f98d": { - "data": { - "timestamp": datetime(2021, 8, 31, 14, 56, 55), - "params": { - "params.yaml": { - "data": { - "featurize": {"max_features": 3000, "ngrams": 1}, - "parent": 20170428, - "train": { - "n_est": 100, - "min_split": 36, - }, + "b05eecc666734e899f79af228ff49a7ae5a18cc0": { + "baseline": { + "data": { + "timestamp": datetime(2021, 8, 2, 16, 48, 14), + "params": { + "params.yaml": { + "data": { + "featurize": { + "max_features": 3000, + "ngrams": 1, + }, + "parent": 20170428, + "train": { + "n_est": 100, + "min_split": 2, + }, + } } - } - }, - "queued": True, - "running": True, - "executor": None, - "metrics": { - "scores.json": { - "data": { - "featurize": {"max_features": 3000, "ngrams": 1}, - "avg_prec": 0.5843640011189556, - "roc_auc": 0.9544670443829399, + }, + "queued": False, + "running": False, + "executor": None, + "metrics": { + "scores.json": { + "data": { + "featurize": { + "max_features": 3000, + "ngrams": 1, + }, + "avg_prec": 0.5325162867864254, + "roc_auc": 0.9106964878520005, + } } - } - }, - "name": "exp-44136", - } + }, + "name": "master", + } + }, + "ae99936461d6c3092934160f8beafe66a294f98d": { + "data": { + "timestamp": datetime(2021, 8, 31, 14, 56, 55), + "params": { + "params.yaml": { + "data": { + "featurize": { + "max_features": 3000, + "ngrams": 1, + }, + "parent": 20170428, + "train": { + "n_est": 100, + "min_split": 36, + }, + } + } + }, + "queued": True, + "running": True, + "executor": None, + "metrics": { + "scores.json": { + "data": { + "featurize": { + "max_features": 3000, + "ngrams": 1, + }, + "avg_prec": 0.5843640011189556, + "roc_auc": 0.9544670443829399, + } + } + }, + "name": "exp-44136", + } + }, }, - }, -} + } - -def test_show_experiments(capsys): show_experiments( all_experiments, precision=None, fill_value="", iso=True, csv=True ) @@ -408,6 +426,37 @@ def test_show_experiments(capsys): ) +def test_show_experiments_md(capsys): + all_experiments = { + "workspace": { + "baseline": { + "data": { + "timestamp": None, + "params": {"params.yaml": {"data": {"foo": 1}}}, + "queued": False, + "running": False, + "executor": None, + "metrics": { + "scores.json": {"data": {"bar": 0.9544670443829399}} + }, + } + } + }, + } + show_experiments( + all_experiments, precision=None, fill_value="", iso=True, markdown=True + ) + cap = capsys.readouterr() + + assert cap.out == textwrap.dedent( + """\ + | Experiment | Created | bar | foo | + |--------------|-----------|--------------------|-------| + | workspace | | 0.9544670443829399 | 1 |\n + """ + ) + + @pytest.mark.parametrize("sort_order", ["asc", "desc"]) def test_show_experiments_sort_by(capsys, sort_order): sort_experiments = {