From 1afc0c84737be6a12240c55c96e81ef3e08fbeb1 Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Wed, 15 May 2019 17:48:43 -0400 Subject: [PATCH 1/4] serve_locally by default --- dash/dash.py | 5 ++++- dash/resources.py | 21 +++++++++------------ tests/IntegrationTests.py | 5 ++--- tests/test_integration.py | 3 --- tests/test_resources.py | 5 ++++- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index cf6ee38e92..8a2c9a1e7f 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -1376,9 +1376,12 @@ def enable_dev_tools(self, self._watch_thread.daemon = True self._watch_thread.start() - if debug and self._dev_tools.serve_dev_bundles: + if (debug and self._dev_tools.serve_dev_bundles and + not self.scripts.config.serve_locally): # Dev bundles only works locally. self.scripts.config.serve_locally = True + print('WARNING: dev bundles requested with serve_locally=False.\n' + 'This is not supported, switching to serve_locally=True') return debug diff --git a/dash/resources.py b/dash/resources.py index 5ca7b1f70d..87cd8b3ab1 100644 --- a/dash/resources.py +++ b/dash/resources.py @@ -66,10 +66,17 @@ def get_all_resources(self, dev_bundles=False): return self._filter_resources(all_resources, dev_bundles) +# pylint: disable=too-few-public-methods +class _Config: + def __init__(self, infer_from_layout, serve_locally): + self.infer_from_layout = infer_from_layout + self.serve_locally = serve_locally + + class Css: def __init__(self, layout=None): self._resources = Resources('_css_dist', layout) - self._resources.config = self.config + self._resources.config = self.config = _Config(True, True) def _update_layout(self, layout): self._resources.layout = layout @@ -80,16 +87,11 @@ def append_css(self, stylesheet): def get_all_css(self): return self._resources.get_all_resources() - # pylint: disable=no-init, too-few-public-methods - class config: - infer_from_layout = True - serve_locally = False - class Scripts: def __init__(self, layout=None): self._resources = Resources('_js_dist', layout) - self._resources.config = self.config + self._resources.config = self.config = _Config(True, True) def _update_layout(self, layout): self._resources.layout = layout @@ -99,8 +101,3 @@ def append_script(self, script): def get_all_scripts(self, dev_bundles=False): return self._resources.get_all_resources(dev_bundles) - - # pylint: disable=no-init, too-few-public-methods - class config: - infer_from_layout = True - serve_locally = False diff --git a/tests/IntegrationTests.py b/tests/IntegrationTests.py index 13a69f1f53..be7c4bb9f3 100644 --- a/tests/IntegrationTests.py +++ b/tests/IntegrationTests.py @@ -69,10 +69,9 @@ def tearDown(s): s.server_process.terminate() time.sleep(2) - def startServer(s, dash): + def startServer(s, app): def run(): - dash.scripts.config.serve_locally = True - dash.run_server( + app.run_server( port=8050, debug=False, processes=4, diff --git a/tests/test_integration.py b/tests/test_integration.py index ab66dd0206..a8a7c91933 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -562,7 +562,6 @@ def create_layout(): def test_multi_output(self): app = Dash(__name__) - app.scripts.config.serve_locally = True app.layout = html.Div([ html.Button('OUTPUT', id='output-btn'), @@ -663,7 +662,6 @@ def overlapping_multi_output(n_clicks): def test_multi_output_no_update(self): app = Dash(__name__) - app.scripts.config.serve_locally = True app.layout = html.Div([ html.Button('B', 'btn'), @@ -696,7 +694,6 @@ def show_clicks(n): def test_no_update_chains(self): app = Dash(__name__) - app.scripts.config.serve_locally = True app.layout = html.Div([ dcc.Input(id='a_in', value='a'), diff --git a/tests/test_resources.py b/tests/test_resources.py index 38b4351f2f..3b83028300 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -48,6 +48,7 @@ def test_external(self): ) app.layout = dcc.Markdown() app.scripts.config.serve_locally = False + app.scripts.config.xxx = 123 with mock.patch('dash.dash.os.stat', return_value=StatMock()): resource = app._collect_and_register_resources( @@ -67,7 +68,9 @@ def test_internal(self): assets_ignore='load_after.+.js' ) app.layout = dcc.Markdown() - app.scripts.config.serve_locally = True + + self.assertEqual(app.scripts.config.serve_locally, True) + self.assertEqual(app.css.config.serve_locally, True) with mock.patch('dash.dash.os.stat', return_value=StatMock()): with mock.patch('dash.dash.importlib.import_module', From aba2b15e2d3dd887c36daf3989fc4e553c2e184b Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Wed, 15 May 2019 20:06:28 -0400 Subject: [PATCH 2/4] changelog for serve_locally change --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdbb1d24eb..c0a9879839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Unreleased +### Changed +- [#722](https://github.com/plotly/dash/pull/722) Assets are served locally by default. Both JS scripts and CSS files are affected. This improves robustness and flexibility in numerous situations, but in certain cases initial loading could be slowed. To restore the previous CDN serving, set `app.scripts.config.serve_locally = False` (and similarly with `app.css`, but this is generally less important). + ## [0.43.0] - 2019-04-25 ### Changed - Bumped dash-core-components version from 0.47.0 to [0.48.0](https://github.com/plotly/dash-core-components/blob/master/CHANGELOG.md#0480---2019-05-15) From cf46e6beeb3535c8e0018d34e7282656b1951dbf Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Wed, 15 May 2019 21:16:18 -0400 Subject: [PATCH 3/4] more robust test_aborted_callback --- tests/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index a8a7c91933..b49c53c7d2 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -190,7 +190,7 @@ def callback2(value): output2 = self.wait_for_element_by_id('output2') # callback1 runs 4x (initial page load and 3x through send_keys) - self.assertEqual(callback1_count.value, 4) + wait_for(lambda: callback1_count.value == 4) # callback2 is never triggered, even on initial load self.assertEqual(callback2_count.value, 0) From c096aa1c445dada79ef4d81c146328253a742390 Mon Sep 17 00:00:00 2001 From: alexcjohnson Date: Tue, 21 May 2019 13:16:10 -0400 Subject: [PATCH 4/4] wtf was config.xxx doing there? --- tests/test_resources.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_resources.py b/tests/test_resources.py index 3b83028300..62fe0aaeed 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -48,7 +48,6 @@ def test_external(self): ) app.layout = dcc.Markdown() app.scripts.config.serve_locally = False - app.scripts.config.xxx = 123 with mock.patch('dash.dash.os.stat', return_value=StatMock()): resource = app._collect_and_register_resources(