From 082a7b54b32110351354bb38ca1848afeb083f16 Mon Sep 17 00:00:00 2001 From: philippe Date: Tue, 11 Aug 2026 09:29:10 -0400 Subject: [PATCH 1/3] Make plotly-cloud a default install dependency plotly-cloud is now installed by default with dash instead of only via the optional dash[cloud] extra. The extra is kept for backward compatibility. Update the plotly CLI ImportError hint to no longer point at dash[cloud]. Closes #3513 --- CHANGELOG.md | 1 + dash/_plotly_cli.py | 3 ++- requirements/install.txt | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ec0a56a44..a7d6b3d060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added +- [] Make `plotly-cloud` a default install dependency of Dash instead of an optional extra, so the `plotly` CLI and Dash's cloud integration are available out of the box. The `dash[cloud]` extra is kept for backward compatibility. Closes [#3513](https://github.com/plotly/dash/issues/3513). - [#3646](https://github.com/plotly/dash/pull/3646) Experimental support for React 19. The default is still React 18.3.1; to use React 19 set the environment variable `REACT_VERSION=19.2.4` before running your app, or call `dash._dash_renderer._set_react_version("19.2.4")` inside the app. React 19 has no official UMD builds, so Dash serves the [`umd-react`](https://www.npmjs.com/package/umd-react) package, together with a compatibility shim loaded after react-dom and before any component package. The shim keeps component libraries built against React <=18 (e.g. dash-bootstrap-components, dash-mantine-components) working under React 19: it stubs the removed `ReactCurrentOwner` internals, redirects the legacy element `$$typeof` symbol so pre-bundled React 18 jsx-runtimes produce elements React 19 accepts (error #525), and exposes a global `react/jsx-runtime` (`window.ReactJSXRuntime`) that Dash's own component bundles externalize to. Component library authors adopting this convention should copy the defensive `jsxRuntimeExternal` webpack external from `components/dash-core-components/webpack.config.js` rather than a bare `'ReactJSXRuntime'` string: it falls back to a `React.createElement`-based runtime when the global is missing, so the same build also works on Dash versions older than this release. ### Removed diff --git a/dash/_plotly_cli.py b/dash/_plotly_cli.py index 9974cd23b9..4456962746 100644 --- a/dash/_plotly_cli.py +++ b/dash/_plotly_cli.py @@ -9,7 +9,8 @@ def cli(): except ImportError: print( "Plotly cloud is not installed," - " install it with `pip install dash[cloud]` to use the plotly command", + " install it with `pip install plotly-cloud` (or reinstall dash)" + " to use the plotly command", file=sys.stderr, ) sys.exit(-1) diff --git a/requirements/install.txt b/requirements/install.txt index 176d9c8f5e..d5be51096d 100644 --- a/requirements/install.txt +++ b/requirements/install.txt @@ -1,6 +1,7 @@ Flask>=1.0.4,<3.2 Werkzeug<3.2 plotly>=5.0.0 +plotly-cloud importlib-metadata typing_extensions>=4.1.1 requests From 68c28fe9e691f660175c58c751c5388a8b4fbb6d Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 27 Aug 2026 11:23:10 -0400 Subject: [PATCH 2/3] Update CHANGELOG.md Co-authored-by: Cameron DeCoster --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0212b70dea..3c8d2bdec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added -- [] Make `plotly-cloud` a default install dependency of Dash instead of an optional extra, so the `plotly` CLI and Dash's cloud integration are available out of the box. The `dash[cloud]` extra is kept for backward compatibility. Closes [#3513](https://github.com/plotly/dash/issues/3513). +- [#3947](https://github.com/plotly/dash/pull/3947) Make `plotly-cloud` a default install dependency of Dash instead of an optional extra, so the `plotly` CLI and Dash's cloud integration are available out of the box. The `dash[cloud]` extra is kept for backward compatibility. - [#3765](https://github.com/plotly/dash/pull/3765) Add opt-in partial pattern matching for callback `Input`, `Output`, and `State` dependencies via `partial_pattern=True`. Dictionary ID patterns can now match component IDs containing additional keys, and partial patterns can be combined with `ALL` and `MATCH` wildcards. Fixes [#3764](https://github.com/plotly/dash/issues/3764). - [#3646](https://github.com/plotly/dash/pull/3646) Experimental support for React 19. The default is still React 18.3.1; to use React 19 set the environment variable `REACT_VERSION=19.2.4` before running your app, or call `dash._dash_renderer._set_react_version("19.2.4")` inside the app. React 19 has no official UMD builds, so Dash serves the [`umd-react`](https://www.npmjs.com/package/umd-react) package, together with a compatibility shim loaded after react-dom and before any component package. The shim keeps component libraries built against React <=18 (e.g. dash-bootstrap-components, dash-mantine-components) working under React 19: it stubs the removed `ReactCurrentOwner` internals, redirects the legacy element `$$typeof` symbol so pre-bundled React 18 jsx-runtimes produce elements React 19 accepts (error #525), and exposes a global `react/jsx-runtime` (`window.ReactJSXRuntime`) that Dash's own component bundles externalize to. Component library authors adopting this convention should copy the defensive `jsxRuntimeExternal` webpack external from `components/dash-core-components/webpack.config.js` rather than a bare `'ReactJSXRuntime'` string: it falls back to a `React.createElement`-based runtime when the global is missing, so the same build also works on Dash versions older than this release. - [#3925](https://github.com/plotly/dash/pull/3925) Add optional callback request payload compression for server-side callbacks via `compress_payload` and `compress_threshold` callback parameters (default threshold: 5,000 bytes). When enabled and the request body exceeds the threshold, the renderer sends gzip-compressed binary payloads with `Content-Encoding: gzip`, and Dash transparently decompresses on the server (Flask, FastAPI, and Quart). This can significantly reduce callback roundtrip times for large client-to-server payloads. Fixes [#3924](https://github.com/plotly/dash/issues/3924). From 9a0427e60cef918b4ecdfc31e57a58696243da9b Mon Sep 17 00:00:00 2001 From: philippe Date: Thu, 27 Aug 2026 12:07:29 -0400 Subject: [PATCH 3/3] Make callback-validation error assertions tolerate the injected plotly-cloud layout id plotly-cloud is now a default install dependency, and it appends a _plotly-cloud-* component to every app's layout via a dash_hooks entry point. That id showed up in the "string ids in the current layout" list of the callback-validation error message, breaking the exact-match assertions in dvcv008/dvcv009. Strip any _plotly-cloud-* id before comparing so the tests pass whether or not plotly-cloud is installed. --- tests/integration/devtools/test_callback_validation.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/integration/devtools/test_callback_validation.py b/tests/integration/devtools/test_callback_validation.py index bde59f3327..e4f89432d5 100644 --- a/tests/integration/devtools/test_callback_validation.py +++ b/tests/integration/devtools/test_callback_validation.py @@ -1,3 +1,5 @@ +import re + import flask import pytest from flaky import flaky @@ -31,6 +33,14 @@ def check_errors(dash_duo, specs): found = [] for i in range(cnt): msg = dash_duo.find_elements(".dash-fe-error__title")[i].text + # plotly-cloud (a default install dep) injects a `_plotly-cloud-*` + # component into every layout via a dash_hooks entry point, so it + # shows up in the "string ids in the current layout" list. Strip it + # so these assertions hold whether or not plotly-cloud is installed. + msg = re.sub(r"_plotly-cloud[\w-]*", "", msg) + msg = re.sub(r",\s*,", ",", msg) + msg = re.sub(r",\s*\]", "]", msg) + msg = re.sub(r"\[\s*,\s*", "[", msg) dash_duo.find_elements(".test-devtools-error-toggle")[i].click() dash_duo.wait_for_element(".dash-backend-error,.dash-fe-error__info") has_BE = dash_duo.driver.execute_script(