From e5cf9b203df01f13e5568c745906d74bc131235c Mon Sep 17 00:00:00 2001 From: David de la Iglesia Castro Date: Wed, 1 Sep 2021 11:17:23 +0200 Subject: [PATCH] Add auto-refresh option to html (#6400) * Added refresh tag * Formatted * Added refresh_seconds to live * Added refresh test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add refresh_seconds to render * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update html.py Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- dvc/render/html.py | 20 +++++++++++++++++--- dvc/render/utils.py | 15 +++++++++++++-- dvc/repo/live.py | 4 +++- tests/func/test_live.py | 3 +++ tests/unit/render/test_html.py | 6 +++++- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/dvc/render/html.py b/dvc/render/html.py index ec3cc5f5b..e5b650bef 100644 --- a/dvc/render/html.py +++ b/dvc/render/html.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: PAGE_HTML = """ + {refresh_tag} DVC Plot @@ -30,14 +31,23 @@ class MissingPlaceholderError(DvcException): class HTML: PLACEHOLDER = "plot_divs" PLACEHOLDER_FORMAT_STR = f"{{{PLACEHOLDER}}}" + REFRESH_PLACEHOLDER = "refresh_tag" + REFRESH_TAG = '' - def __init__(self, template: str = None): + def __init__( + self, + template: Optional[str] = None, + refresh_seconds: Optional[int] = None, + ): template = template or PAGE_HTML if self.PLACEHOLDER_FORMAT_STR not in template: raise MissingPlaceholderError(self.PLACEHOLDER_FORMAT_STR) self.template = template self.elements: List[str] = [] + self.refresh_tag = "" + if refresh_seconds is not None: + self.refresh_tag = self.REFRESH_TAG.format(refresh_seconds) def with_metrics(self, metrics: Dict[str, Dict]) -> "HTML": import tabulate @@ -60,7 +70,10 @@ class HTML: return self def embed(self) -> str: - kwargs = {self.PLACEHOLDER: "\n".join(self.elements)} + kwargs = { + self.PLACEHOLDER: "\n".join(self.elements), + self.REFRESH_PLACEHOLDER: self.refresh_tag, + } return self.template.format(**kwargs) @@ -69,6 +82,7 @@ def write( renderers: List["Renderer"], metrics: Optional[Dict[str, Dict]] = None, template_path: Optional["StrPath"] = None, + refresh_seconds: Optional[int] = None, ): os.makedirs(path, exist_ok=True) @@ -78,7 +92,7 @@ def write( with open(template_path) as fobj: page_html = fobj.read() - document = HTML(page_html) + document = HTML(page_html, refresh_seconds=refresh_seconds) if metrics: document.with_metrics(metrics) document.with_element("
") diff --git a/dvc/render/utils.py b/dvc/render/utils.py index 2b0d56752..c9f227c79 100644 --- a/dvc/render/utils.py +++ b/dvc/render/utils.py @@ -63,7 +63,14 @@ def match_renderers(plots_data, templates): return renderers -def render(repo, plots_data, metrics=None, path=None, html_template_path=None): +def render( + repo, + plots_data, + metrics=None, + path=None, + html_template_path=None, + refresh_seconds=None, +): # TODO we could probably remove repo usages (here and in VegaRenderer) renderers = match_renderers(plots_data, repo.plots.templates) if not html_template_path: @@ -76,5 +83,9 @@ def render(repo, plots_data, metrics=None, path=None, html_template_path=None): from dvc.render.html import write return write( - path, renderers, metrics=metrics, template_path=html_template_path + path, + renderers, + metrics=metrics, + template_path=html_template_path, + refresh_seconds=refresh_seconds, ) diff --git a/dvc/repo/live.py b/dvc/repo/live.py index df52279fe..f53007e89 100644 --- a/dvc/repo/live.py +++ b/dvc/repo/live.py @@ -19,7 +19,9 @@ def create_summary(out): html_path = out.path_info.fspath + "_dvc_plots" - index_path = render(out.repo, plots, metrics=metrics, path=html_path) + index_path = render( + out.repo, plots, metrics=metrics, path=html_path, refresh_seconds=5 + ) logger.info(f"\nfile://{os.path.abspath(index_path)}") diff --git a/tests/func/test_live.py b/tests/func/test_live.py index d259c11d4..9995309f3 100644 --- a/tests/func/test_live.py +++ b/tests/func/test_live.py @@ -160,6 +160,9 @@ def test_live_html(tmp_dir, dvc, live_stage, html): live_stage(html=html, live="logs") assert (tmp_dir / "logs_dvc_plots" / "index.html").is_file() == html + if html: + html_text = (tmp_dir / "logs_dvc_plots" / "index.html").read_text() + assert 'http-equiv="refresh"' in html_text @pytest.fixture diff --git a/tests/unit/render/test_html.py b/tests/unit/render/test_html.py index 56ebe6323..5b4648a1a 100644 --- a/tests/unit/render/test_html.py +++ b/tests/unit/render/test_html.py @@ -19,7 +19,11 @@ CUSTOM_PAGE_HTML = """ @pytest.mark.parametrize( "template,page_elements,expected_page", [ - (None, ["content"], PAGE_HTML.format(plot_divs="content")), + ( + None, + ["content"], + PAGE_HTML.format(plot_divs="content", refresh_tag=""), + ), ( CUSTOM_PAGE_HTML, ["content"],