From e0390b723f491af95cd01745b578d92955a14529 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Tue, 4 Sep 2018 12:16:23 -0400 Subject: [PATCH 01/13] Add dev_bundle resources support. --- dash/dash.py | 11 ++++++++--- dash/resources.py | 14 +++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index 9e32383597..1b1e29b3d7 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -86,6 +86,7 @@ def __init__( external_scripts=None, external_stylesheets=None, suppress_callback_exceptions=None, + serve_dev_bundles=False, components_cache_max_age=None, **kwargs): @@ -221,6 +222,7 @@ def add_url(name, view_func, methods=('GET',)): self._layout = None self._cached_layout = None self.routes = [] + self._serve_dev_bundle = serve_dev_bundles # add a handler for components suites errors to return 404 self.server.errorhandler(exceptions.InvalidResourceError)( @@ -373,11 +375,14 @@ def _generate_scripts_html(self): # pylint: disable=protected-access srcs = self._collect_and_register_resources( self.scripts._resources._filter_resources( - dash_renderer._js_dist_dependencies + dash_renderer._js_dist_dependencies, + dev_bundles=self._serve_dev_bundle )) + self._external_scripts + self._collect_and_register_resources( - self.scripts.get_all_scripts() + + self.scripts.get_all_scripts( + dev_bundles=self._serve_dev_bundle) + self.scripts._resources._filter_resources( - dash_renderer._js_dist + dash_renderer._js_dist, + dev_bundles=self._serve_dev_bundle )) return '\n'.join([ diff --git a/dash/resources.py b/dash/resources.py index c594864d64..aa1ce871d9 100644 --- a/dash/resources.py +++ b/dash/resources.py @@ -16,7 +16,7 @@ def __init__(self, resource_name, layout): def append_resource(self, resource): self._resources.append(resource) - def _filter_resources(self, all_resources): + def _filter_resources(self, all_resources, dev_bundles=False): filtered_resources = [] for s in all_resources: filtered_resource = {} @@ -24,6 +24,10 @@ def _filter_resources(self, all_resources): filtered_resource['namespace'] = s['namespace'] if 'external_url' in s and not self.config.serve_locally: filtered_resource['external_url'] = s['external_url'] + elif 'dev_package_path' in s and dev_bundles: + filtered_resource['relative_package_path'] = ( + s['dev_package_path'] + ) elif 'relative_package_path' in s: filtered_resource['relative_package_path'] = ( s['relative_package_path'] @@ -54,7 +58,7 @@ def _filter_resources(self, all_resources): return filtered_resources - def get_all_resources(self): + def get_all_resources(self, dev_bundles=False): all_resources = [] if self.config.infer_from_layout: all_resources = ( @@ -63,7 +67,7 @@ def get_all_resources(self): else: all_resources = self._resources - return self._filter_resources(all_resources) + return self._filter_resources(all_resources, dev_bundles) def get_inferred_resources(self): namespaces = [] @@ -127,8 +131,8 @@ def _update_layout(self, layout): def append_script(self, script): self._resources.append_resource(script) - def get_all_scripts(self): - return self._resources.get_all_resources() + def get_all_scripts(self, dev_bundles=False): + return self._resources.get_all_resources(dev_bundles) def get_inferred_scripts(self): return self._resources.get_inferred_resources() From 28f749eefc55e15dddc907981f02a4d905105a3e Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Fri, 7 Sep 2018 14:17:28 -0400 Subject: [PATCH 02/13] Activate the dev tools in `run_server`. --- dash/dash.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index 1b1e29b3d7..dc659c46a0 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -86,7 +86,6 @@ def __init__( external_scripts=None, external_stylesheets=None, suppress_callback_exceptions=None, - serve_dev_bundles=False, components_cache_max_age=None, **kwargs): @@ -222,7 +221,7 @@ def add_url(name, view_func, methods=('GET',)): self._layout = None self._cached_layout = None self.routes = [] - self._serve_dev_bundle = serve_dev_bundles + self._serve_dev_bundle = False # add a handler for components suites errors to return 404 self.server.errorhandler(exceptions.InvalidResourceError)( @@ -987,5 +986,25 @@ def get_asset_url(self, path): def run_server(self, port=8050, debug=False, + dev_tools=True, + dev_tools_bundles=False, **flask_run_options): - self.server.run(port=port, debug=debug, **flask_run_options) + """ + Start the flask server in local mode, you should not run this on a + production server and use gunicorn/waitress instead. By default will + activate the dev tools (dev bundles). + + :param port: Port the application + :type port: int + :param debug: Set the debug mode of flask. + :type debug: bool + :param dev_tools: Activate all the dev tools. + :type dev_tools: bool + :param dev_tools_bundles: Serve the dev bundles of component libs. + :type dev_tools_bundles: bool + :param flask_run_options: Given to `Flask.run` + :return: + """ + self._serve_dev_bundle = dev_tools_bundles or dev_tools + self.server.run(port=port, debug=dev_tools or debug, + **flask_run_options) From d4763678e5a5037df89d8ee68c36ad5588b32e06 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Fri, 7 Sep 2018 14:22:14 -0400 Subject: [PATCH 03/13] Disable dev_tools for tests. --- tests/IntegrationTests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/IntegrationTests.py b/tests/IntegrationTests.py index 73f211624c..ee249d8cb5 100644 --- a/tests/IntegrationTests.py +++ b/tests/IntegrationTests.py @@ -48,7 +48,8 @@ def run(): port=8050, debug=False, processes=4, - threaded=False + threaded=False, + dev_tools=False ) # Run on a separate process so that it doesn't block From 330f217ebc8db9cc31234426da44f1344d6e484f Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Mon, 10 Sep 2018 18:50:49 -0400 Subject: [PATCH 04/13] Move dev_tools activation to method. --- dash/dash.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index dc659c46a0..3c14aefe35 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -447,6 +447,7 @@ def serve_component_suites(self, package_name, path_in_package_dist): self.config.components_cache_max_age) } + return Response( pkgutil.get_data(package_name, path_in_package_dist), mimetype=mimetype, @@ -983,11 +984,29 @@ def get_asset_url(self, path): return asset + def activate_dev_tools(self, + dev_tools=True, + dev_tools_bundles=True): + """ + Activate the dev tools, called by `run_server`. If your application is + served by wsgi and you want to activate the dev tools, you can call + this method out of `__main__`. + + :param dev_tools: If false no tools will be activated. + :type dev_tools: bool + :param dev_tools_bundles: Serve the dev bundles of component libs. + :type dev_tools_bundles: bool + :return: + """ + if not dev_tools: + return + self._serve_dev_bundle = dev_tools_bundles + def run_server(self, port=8050, debug=False, dev_tools=True, - dev_tools_bundles=False, + dev_tools_bundles=True, **flask_run_options): """ Start the flask server in local mode, you should not run this on a @@ -1005,6 +1024,6 @@ def run_server(self, :param flask_run_options: Given to `Flask.run` :return: """ - self._serve_dev_bundle = dev_tools_bundles or dev_tools + self.activate_dev_tools(dev_tools, dev_tools_bundles) self.server.run(port=port, debug=dev_tools or debug, **flask_run_options) From b0f46cb1ab9e0e44bfc9d309a89deb1d92ebc21c Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Mon, 17 Sep 2018 11:06:02 -0400 Subject: [PATCH 05/13] Refactor enable_dev_tools variables names. --- dash/dash.py | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index 3c14aefe35..f1c0dd5185 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -221,7 +221,9 @@ def add_url(name, view_func, methods=('GET',)): self._layout = None self._cached_layout = None self.routes = [] - self._serve_dev_bundle = False + self._dev_tools = _AttributeDict({ + 'serve_dev_bundles': False + }) # add a handler for components suites errors to return 404 self.server.errorhandler(exceptions.InvalidResourceError)( @@ -375,13 +377,13 @@ def _generate_scripts_html(self): srcs = self._collect_and_register_resources( self.scripts._resources._filter_resources( dash_renderer._js_dist_dependencies, - dev_bundles=self._serve_dev_bundle + dev_bundles=self._dev_tools.serve_dev_bundles )) + self._external_scripts + self._collect_and_register_resources( self.scripts.get_all_scripts( - dev_bundles=self._serve_dev_bundle) + + dev_bundles=self._dev_tools.serve_dev_bundles) + self.scripts._resources._filter_resources( dash_renderer._js_dist, - dev_bundles=self._serve_dev_bundle + dev_bundles=self._dev_tools.serve_dev_bundles )) return '\n'.join([ @@ -984,46 +986,46 @@ def get_asset_url(self, path): return asset - def activate_dev_tools(self, - dev_tools=True, - dev_tools_bundles=True): + def enable_dev_tools(self, + debug=False, + dev_tools_serve_bundles=None): """ Activate the dev tools, called by `run_server`. If your application is served by wsgi and you want to activate the dev tools, you can call this method out of `__main__`. - :param dev_tools: If false no tools will be activated. - :type dev_tools: bool - :param dev_tools_bundles: Serve the dev bundles of component libs. - :type dev_tools_bundles: bool + :param debug: If false no tools will be activated. + :type debug: bool + :param dev_tools_serve_bundles: Serve the dev bundles of component libs. + :type dev_tools_serve_bundles: bool :return: """ - if not dev_tools: + if not debug: return - self._serve_dev_bundle = dev_tools_bundles + + env = _configs.env_configs() + + self._dev_tools['serve_dev_bundles'] = _configs.get_config( + 'serve_dev_bundles', dev_tools_serve_bundles, env, True) def run_server(self, port=8050, debug=False, - dev_tools=True, - dev_tools_bundles=True, + dev_tools_serve_dev_bundles=None, **flask_run_options): """ Start the flask server in local mode, you should not run this on a - production server and use gunicorn/waitress instead. By default will - activate the dev tools (dev bundles). + production server and use gunicorn/waitress instead. :param port: Port the application :type port: int - :param debug: Set the debug mode of flask. + :param debug: Set the debug mode of flask and enable the dev tools. :type debug: bool - :param dev_tools: Activate all the dev tools. - :type dev_tools: bool - :param dev_tools_bundles: Serve the dev bundles of component libs. - :type dev_tools_bundles: bool + :param dev_tools_serve_dev_bundles: Serve the dev bundles of component libs. + :type dev_tools_serve_dev_bundles: bool :param flask_run_options: Given to `Flask.run` :return: """ - self.activate_dev_tools(dev_tools, dev_tools_bundles) - self.server.run(port=port, debug=dev_tools or debug, + self.enable_dev_tools(debug, dev_tools_serve_dev_bundles) + self.server.run(port=port, debug=debug, **flask_run_options) From 0dcb93da902a23cf7429d67edb62057f43ba4caa Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Mon, 17 Sep 2018 11:16:08 -0400 Subject: [PATCH 06/13] Pylint fix. --- .pylintrc | 3 ++- .pylintrc37 | 3 ++- dash/dash.py | 4 ++-- tests/IntegrationTests.py | 3 +-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.pylintrc b/.pylintrc index f85cbf3259..fba35186cc 100644 --- a/.pylintrc +++ b/.pylintrc @@ -56,7 +56,8 @@ confidence= # --disable=W" disable=fixme, missing-docstring, - invalid-name + invalid-name, + too-many-lines # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where diff --git a/.pylintrc37 b/.pylintrc37 index ef6ce31186..8ff5bee0db 100644 --- a/.pylintrc37 +++ b/.pylintrc37 @@ -145,7 +145,8 @@ disable=invalid-name, comprehension-escape, no-else-return, useless-object-inheritance, - possibly-unused-variable + possibly-unused-variable, + too-many-lines # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/dash/dash.py b/dash/dash.py index f1c0dd5185..7936690201 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -996,7 +996,7 @@ def enable_dev_tools(self, :param debug: If false no tools will be activated. :type debug: bool - :param dev_tools_serve_bundles: Serve the dev bundles of component libs. + :param dev_tools_serve_bundles: Serve the dev bundles of component libs :type dev_tools_serve_bundles: bool :return: """ @@ -1021,7 +1021,7 @@ def run_server(self, :type port: int :param debug: Set the debug mode of flask and enable the dev tools. :type debug: bool - :param dev_tools_serve_dev_bundles: Serve the dev bundles of component libs. + :param dev_tools_serve_dev_bundles: Serve the dev bundles of components :type dev_tools_serve_dev_bundles: bool :param flask_run_options: Given to `Flask.run` :return: diff --git a/tests/IntegrationTests.py b/tests/IntegrationTests.py index ee249d8cb5..73f211624c 100644 --- a/tests/IntegrationTests.py +++ b/tests/IntegrationTests.py @@ -48,8 +48,7 @@ def run(): port=8050, debug=False, processes=4, - threaded=False, - dev_tools=False + threaded=False ) # Run on a separate process so that it doesn't block From 774661220bdcc5e46ff54cba7cdfd638084112dc Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Mon, 17 Sep 2018 16:12:54 -0400 Subject: [PATCH 07/13] Add DASH_DEBUG, DASH_SERVE_DEV_BUNDLES env configs. --- dash/_configs.py | 9 ++++++--- dash/dash.py | 11 ++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dash/_configs.py b/dash/_configs.py index 6b46b5cdd4..e5087bd534 100644 --- a/dash/_configs.py +++ b/dash/_configs.py @@ -19,18 +19,21 @@ def env_configs(): 'DASH_SUPPRESS_CALLBACK_EXCEPTIONS', 'DASH_ASSETS_EXTERNAL_PATH', 'DASH_INCLUDE_ASSETS_FILES', - 'DASH_COMPONENTS_CACHE_MAX_AGE' + 'DASH_COMPONENTS_CACHE_MAX_AGE', + 'DASH_INCLUDE_ASSETS_FILES', + 'DASH_SERVE_DEV_BUNDLES', + 'DASH_DEBUG' )}) -def get_config(config_name, init, env, default=None): +def get_config(config_name, init, env, default=None, is_bool=False): if init is not None: return init env_value = env.get('DASH_{}'.format(config_name.upper())) if env_value is None: return default - return env_value + return env_value if not is_bool else env_value.lower() == 'true' def pathname_configs(url_base_pathname=None, diff --git a/dash/dash.py b/dash/dash.py index 7936690201..a53eb0e926 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -1000,13 +1000,18 @@ def enable_dev_tools(self, :type dev_tools_serve_bundles: bool :return: """ + env = _configs.env_configs() + debug = debug or _configs.get_config('debug', None, env, debug, + is_bool=True) + if not debug: return - env = _configs.env_configs() - self._dev_tools['serve_dev_bundles'] = _configs.get_config( - 'serve_dev_bundles', dev_tools_serve_bundles, env, True) + 'serve_dev_bundles', dev_tools_serve_bundles, env, + default=True, + is_bool=True + ) def run_server(self, port=8050, From 44b86a1cca7da270b93caaeed01a5e8e23b18b50 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Wed, 19 Sep 2018 14:28:51 -0400 Subject: [PATCH 08/13] Return debug from enable_dev_tools. --- dash/dash.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dash/dash.py b/dash/dash.py index a53eb0e926..c740587352 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -1012,6 +1012,7 @@ def enable_dev_tools(self, default=True, is_bool=True ) + return debug def run_server(self, port=8050, @@ -1031,6 +1032,6 @@ def run_server(self, :param flask_run_options: Given to `Flask.run` :return: """ - self.enable_dev_tools(debug, dev_tools_serve_dev_bundles) + debug = self.enable_dev_tools(debug, dev_tools_serve_dev_bundles) self.server.run(port=port, debug=debug, **flask_run_options) From 4b4bbc35dfd691b8ba1549dae0a179a8011c0aa3 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 20 Sep 2018 11:07:59 -0400 Subject: [PATCH 09/13] Debug as default for get_config in enable_dev_tools. --- dash/dash.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index c740587352..3901b07a9e 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -548,7 +548,7 @@ def dependencies(self): 'inputs': v['inputs'], 'state': v['state'], 'events': v['events'] - } for k, v in list(self.callback_map.items()) + } for k, v in self.callback_map.items() ]) # pylint: disable=unused-argument, no-self-use @@ -1004,12 +1004,9 @@ def enable_dev_tools(self, debug = debug or _configs.get_config('debug', None, env, debug, is_bool=True) - if not debug: - return - self._dev_tools['serve_dev_bundles'] = _configs.get_config( 'serve_dev_bundles', dev_tools_serve_bundles, env, - default=True, + default=debug, is_bool=True ) return debug From 7952d28fc5295fd90ab623cee7f457609a8b9cad Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 20 Sep 2018 12:06:49 -0400 Subject: [PATCH 10/13] Remove blank line from merge. --- dash/dash.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dash/dash.py b/dash/dash.py index 3901b07a9e..662d47fa37 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -449,7 +449,6 @@ def serve_component_suites(self, package_name, path_in_package_dist): self.config.components_cache_max_age) } - return Response( pkgutil.get_data(package_name, path_in_package_dist), mimetype=mimetype, From 501946847c7c21badb31b76393a88eefc7d49d10 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 20 Sep 2018 12:23:09 -0400 Subject: [PATCH 11/13] Update version and changelogs. --- CHANGELOG.md | 4 ++++ dash/dash.py | 8 ++++---- dash/version.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e6c0c493..055ff56a68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.27.0 - 2018-09-20 +## Added +- Added support for serving dev bundles from the components suite, enable with `app.run_server(dev_tools_serve_dev_bundles=True)` [#369](https://github.com/plotly/dash/pull/369) + ## 0.26.6 - 2018-09-19 ## Fixed - Added `Cache-Control` headers to files served by `Dash.serve_component_suites`. [#387](https://github.com/plotly/dash/pull/387) diff --git a/dash/dash.py b/dash/dash.py index 662d47fa37..e308bad594 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -987,7 +987,7 @@ def get_asset_url(self, path): def enable_dev_tools(self, debug=False, - dev_tools_serve_bundles=None): + dev_tools_serve_dev_bundles=None): """ Activate the dev tools, called by `run_server`. If your application is served by wsgi and you want to activate the dev tools, you can call @@ -995,8 +995,8 @@ def enable_dev_tools(self, :param debug: If false no tools will be activated. :type debug: bool - :param dev_tools_serve_bundles: Serve the dev bundles of component libs - :type dev_tools_serve_bundles: bool + :param dev_tools_serve_dev_bundles: Serve the dev bundles. + :type dev_tools_serve_dev_bundles: bool :return: """ env = _configs.env_configs() @@ -1004,7 +1004,7 @@ def enable_dev_tools(self, is_bool=True) self._dev_tools['serve_dev_bundles'] = _configs.get_config( - 'serve_dev_bundles', dev_tools_serve_bundles, env, + 'serve_dev_bundles', dev_tools_serve_dev_bundles, env, default=debug, is_bool=True ) diff --git a/dash/version.py b/dash/version.py index 0cfff7a2c6..cf7b6d6589 100644 --- a/dash/version.py +++ b/dash/version.py @@ -1 +1 @@ -__version__ = '0.26.6' +__version__ = '0.27.0' From f02e0d9c36fe31e2f27910781126b53ac64b2f1b Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 20 Sep 2018 21:04:59 -0400 Subject: [PATCH 12/13] Update enable_dev_tools docstring. --- dash/dash.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/dash.py b/dash/dash.py index e308bad594..1fb94d83ce 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -993,7 +993,7 @@ def enable_dev_tools(self, served by wsgi and you want to activate the dev tools, you can call this method out of `__main__`. - :param debug: If false no tools will be activated. + :param debug: If True, then activate all the tools unless specified. :type debug: bool :param dev_tools_serve_dev_bundles: Serve the dev bundles. :type dev_tools_serve_dev_bundles: bool From 81d22207e441f18d30e97baccda501cd2ed3cf25 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 20 Sep 2018 21:05:35 -0400 Subject: [PATCH 13/13] Add merged community PR to changelog. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 055ff56a68..cdaebbeac2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Added - Added support for serving dev bundles from the components suite, enable with `app.run_server(dev_tools_serve_dev_bundles=True)` [#369](https://github.com/plotly/dash/pull/369) +## Fixed +- Use HTML5 syntax for the meta tag [#350](https://github.com/plotly/dash/pull/350) + ## 0.26.6 - 2018-09-19 ## Fixed - Added `Cache-Control` headers to files served by `Dash.serve_component_suites`. [#387](https://github.com/plotly/dash/pull/387)