From 9a5f2bf3c420671a5b021b51ab67fe0d1bde301c Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 24 Nov 2021 09:18:02 +0100 Subject: [PATCH 1/4] chore: add reproduction test for non-deterministic html --- packages/python/plotly/plotly/tests/test_io/test_html.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/python/plotly/plotly/tests/test_io/test_html.py b/packages/python/plotly/plotly/tests/test_io/test_html.py index e2b2b976a7e..a096c63254c 100644 --- a/packages/python/plotly/plotly/tests/test_io/test_html.py +++ b/packages/python/plotly/plotly/tests/test_io/test_html.py @@ -38,3 +38,9 @@ def fig1(request): def test_versioned_cdn_included(fig1): assert plotly_cdn_url() in pio.to_html(fig1, include_plotlyjs="cdn") + + +def test_html_deterministic(fig1): + assert pio.to_html(fig1, include_plotlyjs="cdn") == pio.to_html( + fig1, include_plotlyjs="cdn" + ) From 3cd01a4a254c2703fb101bc33bff5ae97d4010ae Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 24 Nov 2021 09:18:35 +0100 Subject: [PATCH 2/4] feat: dont use random ID --- packages/python/plotly/plotly/io/_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/python/plotly/plotly/io/_html.py b/packages/python/plotly/plotly/io/_html.py index ac7a642b755..b56f8b5abad 100644 --- a/packages/python/plotly/plotly/io/_html.py +++ b/packages/python/plotly/plotly/io/_html.py @@ -135,7 +135,7 @@ def to_html( fig_dict = validate_coerce_fig_to_dict(fig, validate) # ## Generate div id ## - plotdivid = str(uuid.uuid4()) + plotdivid = "plotly-root" # ## Serialize figure ## jdata = to_json_plotly(fig_dict.get("data", [])) From bed8c1b44692e29657e6bf27254c0da04c0a6f45 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 24 Nov 2021 09:26:56 +0100 Subject: [PATCH 3/4] chore: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6129ff037b6..a8ae441841f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +### Fixed + - Fixed non-determinism in `to_html` function, resulting in unneccessary checksum differences [#3449](https://github.com/plotly/plotly.py/issues/3449) + ## [5.4.0] - 2021-11-15 ### Fixed From 3b461a7f70212e37c649b71043fbe08742437646 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 24 Nov 2021 15:47:33 +0100 Subject: [PATCH 4/4] feat: make div_id configurable implements https://github.com/plotly/plotly.py/pull/3487#issuecomment-977883165 --- packages/python/plotly/plotly/io/_html.py | 5 ++++- packages/python/plotly/plotly/tests/test_io/test_html.py | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/python/plotly/plotly/io/_html.py b/packages/python/plotly/plotly/io/_html.py index b56f8b5abad..1e2fe2db6d6 100644 --- a/packages/python/plotly/plotly/io/_html.py +++ b/packages/python/plotly/plotly/io/_html.py @@ -38,6 +38,7 @@ def to_html( default_width="100%", default_height="100%", validate=True, + div_id=None, ): """ Convert a figure to an HTML string representation. @@ -135,7 +136,7 @@ def to_html( fig_dict = validate_coerce_fig_to_dict(fig, validate) # ## Generate div id ## - plotdivid = "plotly-root" + plotdivid = div_id or str(uuid.uuid4()) # ## Serialize figure ## jdata = to_json_plotly(fig_dict.get("data", [])) @@ -391,6 +392,7 @@ def write_html( default_width="100%", default_height="100%", auto_open=False, + div_id=None, ): """ Write a figure to an HTML file representation @@ -512,6 +514,7 @@ def write_html( default_width=default_width, default_height=default_height, validate=validate, + div_id=div_id, ) # Check if file is a string diff --git a/packages/python/plotly/plotly/tests/test_io/test_html.py b/packages/python/plotly/plotly/tests/test_io/test_html.py index a096c63254c..a056fd8f872 100644 --- a/packages/python/plotly/plotly/tests/test_io/test_html.py +++ b/packages/python/plotly/plotly/tests/test_io/test_html.py @@ -41,6 +41,7 @@ def test_versioned_cdn_included(fig1): def test_html_deterministic(fig1): - assert pio.to_html(fig1, include_plotlyjs="cdn") == pio.to_html( - fig1, include_plotlyjs="cdn" + div_id = "plotly-root" + assert pio.to_html(fig1, include_plotlyjs="cdn", div_id=div_id) == pio.to_html( + fig1, include_plotlyjs="cdn", div_id=div_id )