plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
21.49k stars 2.07k forks source link

Dash 1.0.0 Series - Proposed Set of *Breaking Changes* #469

Closed chriddyp closed 5 years ago

chriddyp commented 5 years ago

Roadmap Items

React 16 support

Deferred

This is the "Proposed Breaking Changes" issue as per the "Breaking Changes" process outlined in https://github.com/plotly/dash/issues/458. The version 1.0.0 of dash, dash-renderer, dash-core-components, and dash-html-components will be compatible with each other and will contain at least one breaking change across the libraries. We will publish the breaking changes no earlier than 2 weeks after we have publicly committed to the proposal in this issue.

Proposed list of breaking changes

  1. Upgrade React.js and react-dom from v15.6.2 to v16.6.1
  2. Set serve_locally = True by default
  3. Resource integrity checks for CDN resources
  4. Hide the undo/redo buttons by default
  5. Update how the initialization callbacks work if properties aren't supplied

Breaking Change 1. Upgrade React.js (react) and react-dom from v15.6.2 to v16.6.1

Technical Background Dash's front-end is built on top of React.js. This includes:

dash-renderer provides the React libraries (as script tags) - individual component libraries do not have React.js bundled in their libraries (React is an "implicit" dependency). So, to update React, we only need to update the React and react-dom libraries provided in dash-renderer. The component authors are responsible for ensuring that their components will work in this new version of React.

Pull Requests that make these changes

Reason for Upgrade

Implications for the Dash Developer

Implications for the Dash Component Author

Implications for Documentation

Our plugin documentation and the dash-component-boilerplate will need to be updated to highlight this change.

Implications for Community Forum

The following threads mention React and will need to be updated:

I searched "React 16" and "React 15" in the community forum to find these threads.

Will this break or change in the future? If so, how can we prepare?

Yes. React 17 will come out next year with its own set of breaking changes. Component authors will need to upgrade our components to be React 17 compatible and we will need to update dash-renderer with the new version of React.

For this to be a smooth transition, we should:

Can this be done in a backwards compatible way instead?

No. There is only one React version that is included in Dash and that version needs to be upgraded.

Are there any other risks to consider?

Some Dash component authors in the community may not upgrade their components to be React 16 incompatible (because they didn't get the notifications, they don't have the time, they don't have the expertise, etc).

If certain popular components aren't updated, then the Dash dev team (or other community members) could make a (temporary) fork of the components that is compatible.

We will rely on users to report these issues via the Dash Community Forum.

Beyond the communication policy outlined in #458, are there any other ways that we can inform our users about this change?

Can we automate the upgrade process for our users?

Not really. We could make PRs into the open source libraries for certain simple, common fixes (like the proptypes import).

Is there anything to consider with respect to compatibility between components?

Yes. The "1.0" series of dash-renderer will only be compatible with the "1.0" series of the main component libraries (dash-core-components, dash-html-components). Technically, dash will not be affected and the "1.0" series of dash may be compatible with the "0" series of the other libraries and vice versa. However, this will not be guaranteed. We will gaurentee the compatibility of these packages within a major version series.

If something breaks, can we inform users through an error message in any way?

I don't think so. We will be relying on React to provide helpful error messages if a component is incompatible. Perhaps we could test this out and create community forum posts with the error messages in advance of this change.

Are there any open items?

Breaking Change 2 - Set serve_locally = True by default

Pull Requests that make these changes

https://github.com/plotly/dash/pull/722

Reason for Upgrade

By default, the JavaScript and CSS for Dash's component suites are served from the unpkg CDN (the same CDN that the React.js recommends). The user can serve these packages locally, from their Python site-packages folder (the folder that contains the installed packages for a given Python installation) by setting:

app.scripts.config.serve_locally = True
app.css.config.serve_locally = True

Serving the assets from the CDN may be faster than serving the assets from Flask (although this has not been rigorously tested). However, there are several issues:

  1. Offline Environments. Many Dash apps run in completely offline environments: airgapped corporate or offsite networks, airplanes, conferences, cafes. Unless the user sets serve_locally = True, the app will silently fail to load.
  2. It's hard to debug when it doesn't work. If the app doesn't have internet access and the app doesn't load, it's hard to know why. You have to open up the browser console and inspect the network requests. Dash is supposed to abstract away these complexities.
  3. The CDN is untrusted. Dash doesn't own the unpkg CDN and so unpkg could be hacked and could serve malicious JavaScript instead of the Dash component libraries. In https://github.com/plotly/dash/pull/442, we're adding resource integrity checks so that if unpkg serves a different JavaScript or CSS bundle than what we originally provided, the browser will reject the request. However, these resource integrity checks are not supported in IE and only partially supported in Edge.
  4. It doesn't work if the component libraries aren't published to NPM. The unpkg CDN serves files that are published to NPM. If a Dash app uses a package that hasn't been published to NPM, then the user needs to set serve_locally = True. While dash-core-components, dash-html-components, and dash-table will all be published to NPM, not all packages will be. For example, packages that are built by organizations and kept private or packages that are in development (via dash-component-boilerplate).

Implications for the Dash Developer

Implications for the Dash Component Author

Less frustration! serve_locally=True needs to be set when developing a component locally (since it isn't published to NPM while developing) and it's easy to forget this.

With serve_locally=True, Dash Component authors that publish public packages may forget to test their packages with serve_locally=False. If they follow the instructions from the boilerplate, then it "should work" but they may forget or misconfigure the necessary references to extra CSS files.

Implications for Documentation

Implications for Community Forum

Will this break or change in the future? If so, how can we prepare?

No. Once serve_locally = True should be the default for here on out.

Can this be done in a backwards compatible way instead?

No.

Are there any other risks to consider?

There is a risk that serving the JS and CSS files from site-packages doesn't work in some environments due to unknown reasons. As always, we will have to rely on user's bug reports in the community forum and GitHub.

Beyond the communication policy outlined in #458, are there any other ways that we can inform our users about this change?

No.

Can we automate the upgrade process for our users?

No.

Is there anything to consider with respect to compatibility between components?

No. All component libraries should work with serve_locally = False.

If something breaks, can we inform users through an error message in any way?

Perhaps.

Are there any open items?

Breaking Change 3 - Resource integrity checks for CDN resources

Deferred until a later release and less important since serve_locally is True by default

Pull Requests that make these changes

https://github.com/plotly/dash/pull/442

Reason for Upgrade

Currently, when serve_locally = False (the current default but soon it won't be, see above), Dash loads component's CSS and JavaScript from the unpkg CDN which is untrusted. This change would add a resource integrity check to the script tags, allowing the browser to reject the resource if it was modified in any way.

~This is a breaking change as it is uncompatible with older versions of dash-core-components. In our "1.0 Series" of Dash, we will ensure the compatibility of versions across our Dash libraries.~ No longer a breaking change since we version-lock the dash core packages.

Implications for the Dash Developer

serve_locally = False will be more secure as long as you are on a browser that supports subresource integrity checks (not supported in IE and Edge).

Implications for the Dash Component Author

Component authors will have to ensure that the files that they are uploading to NPM are unmodified before or after they publish to PyPI as the resource integrity check is computed from the local file.

Implications for Documentation

We will need to document this in our plugin guide: https://github.com/plotly/dash-component-boilerplate

Implications for Community Forum

None.

Will this break or change in the future? If so, how can we prepare?

I don't think so.

Can this be done in a backwards compatible way instead?

~No. Currently, this change breaks old versions of dash-core-components (which had files that were modified in between the NPM and PyPI publish sets) but we can't modify packages that are already published.~ Version locking has rendered this obsolete.

Are there any other risks to consider?

I don't think so.

Beyond the communication policy outlined in #458, are there any other ways that we can inform our users about this change?

I don't think so.

Can we automate the upgrade process for our users?

Perhaps the publish script in dash-component-boilerplate could ensure that the bundles aren't rebuilt between publishing to NPM and PyPI?

Is there anything to consider with respect to compatibility between components?

No

If something breaks, can we inform users through an error message in any way?

If the resource integrity check fails, the user will see an error in their browser console. Perhaps we could include this in our "Dash Debugging Guide", in particular the section about network requests.

Are there any open items?

Breaking Change 4 - Hide the undo/redo buttons by default

Pull Requests that make these changes

NA

Reason for Upgrade

Historically, the undo/redo buttons were a 'feature' that I included during the initial development of Dash. I wanted to ensure that the Dash architecture was amenable to an undo/redo functionality, similar to what's available in other BI solutions. Including them by default in Dash was for my own development sanity: is dash capable of performing undo/redo?

It's a neat feature and it demonstrated how powerful Dash's state-driven architecture was. However, it was never thoughtfully designed and in many cases, it isn't that useful for end-users. In fact, "is it possible to hide the floating toolbar" is one of the most visited community forum topics.

While it's possible to remove the buttons through CSS, it requires some googling to learn how and an extra CSS file. Dash is productive: the default behaviour shouldn't require users to create more than a single file in their project.

So, I propose that we remove them by default and we add an extra config flag to allow users to turn them back on: app = dash.Dash(__name__, show_undo_redo=True).

Implications for the Dash Developer

If users really liked this feature, then they'll have to explicitly turn it back on.

Implications for the Dash Component Author

None.

Implications for Documentation

Implications for Community Forum

Will this break or change in the future? If so, how can we prepare?

I don't think so. In the future, I could imagine that these buttons could be more configurable so that users could include them in a more thoughtful position in their app (e.g. in a centralized header or footer). Perhaps they would be dcc.Undo and dcc.Redo components. Setting show_undo_redo = False should not affect this.

Can this be done in a backwards compatible way instead?

No.

Are there any other risks to consider?

I don't think so.

Beyond the communication policy outlined in #458, are there any other ways that we can inform our users about this change?

We should create a new community forum topic outlining the change and specifying how turn this back on.

Can we automate the upgrade process for our users?

No.

Is there anything to consider with respect to compatibility between components?

No.

If something breaks, can we inform users through an error message in any way?

No.

Are there any open items?

Breaking Change 5 - Update how the initialization callbacks work if properties aren't supplied

This has been deferred until later

For more details, see https://github.com/plotly/dash/issues/468

A few technical issues need to be resolved in https://github.com/plotly/dash/issues/468 before we can consider folding this into the 1.0.0 release. If these issues can't be resolved in a timely matter, then we will likely push this fix to the 2.0.0 series.


Thanks for reading ❤️ As always, we welcome your feedback in this issue or privately via a message on the dash community forum: https://community.plot.ly/u/chriddyp/

T4rk1n commented 5 years ago

Breaking Change 3 - Resource integrity checks for CDN resources

I found the implementation I made in #442 to be a little too dangerous, requires too much attention especially considering third parties components libraries. I'd like instead to add an option in the new cli #451 to generate the hashes and include them as a field in the dist. If the component doesn't have the field we just not include it in the tag formatting. That wouldn't be breaking change.

T4rk1n commented 5 years ago

It doesn't work if the component libraries aren't published to NPM.

Just remove the external_url from the dist and it will serve it locally even if it's not set. There is a flag (publish_on_npm) in the boilerplate to include it or not. Default is True.

Also, when debug=True and dev_tools_serve_dev_bundles=True dash will serve locally by default. https://github.com/plotly/dash/blob/dcd0f41504821ab7466983b5cd00bff009ca5911/dash/dash.py#L1170-L1172

T4rk1n commented 5 years ago

If a flask route fails, then we could log it in the terminal. In dash==0.30.0, we silenced flask's route logging for 200 level requests, do we still log 4xx or 5xx errors in the terminal? Should we?

500 errors are mostly caused by users exception in routes, the stacktrace/error will still be displayed because the logging level is ERROR.

Something we could do instead of silencing the whole logging is to add a handler/filter and only emit the logs we want.

chriddyp commented 5 years ago

I think we should also consider removing animate=True from dcc.Graph in favor of the new transitions API - https://community.plot.ly/t/exploring-a-transitions-api-for-dcc-graph/15468

rmarren1 commented 5 years ago

Perhaps we can remove events here as well?

rmarren1 commented 5 years ago

https://github.com/plotly/dash/blob/5ba0bc25448227f33559a71adb4746ebb09bc349/dash/dash.py#L619-L624

Maybe we can delete this too.

ned2 commented 5 years ago

With the Dash assets machinery now in place, we could also drop the static_folder kwarg from the Dash __init__ method. It's now redundant, and if someone really needs it, they can pass in their own Flask instance configured accordingly.

PhillP commented 5 years ago

This is just to voice support for the move to react 16+. In a current project we would like to make use of some Kendo React components within dash, however the react version is currently a blocker for some of this (as at least some of the Kendo components require react 16+). I imagine this scenario could effect others doing similar things.

Is there an estimated release date for react 16 support as yet? or somewhere to track this release?

happyshows commented 5 years ago

Could you confirm the react-markdown component will be updated so that tables will be properly rendered?

Marc-Andre-Rivet commented 5 years ago

@happyshows We will bump react-markdown to 4.x

Marc-Andre-Rivet commented 5 years ago

@happyshows Fwiw, react-markdown has been bumped up to 4.x in Dash 0.40

alexcjohnson commented 5 years ago

Dash 1.0 has been released - the lead comment updated to match what we actually did and did not do of the items listed there. See https://dash.plot.ly/dash-1-0-migration or the changelog for a more complete list though, in particular the dash-table API changed substantially and this is not reflected here, also dcc.Markdown and dcc.SyntaxHighlighter were merged.