From eb92a382786c66b1e461f0864efa78d851e57f69 Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Thu, 26 Jul 2018 12:14:59 -0400 Subject: [PATCH] Add `external_js/css_urls` to dash ctor, support for external only urls --- dash/dash.py | 13 ++++++++++++- dash/resources.py | 3 ++- tests/test_integration.py | 24 +++++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/dash/dash.py b/dash/dash.py index 44fad1efee..0780e8bd59 100644 --- a/dash/dash.py +++ b/dash/dash.py @@ -9,6 +9,7 @@ import warnings import re +import itertools from functools import wraps import plotly @@ -61,7 +62,7 @@ # pylint: disable=too-many-instance-attributes -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments, too-many-locals class Dash(object): def __init__( self, @@ -75,6 +76,8 @@ def __init__( compress=True, meta_tags=None, index_string=_default_index, + external_script_urls=None, + external_css_urls=None, **kwargs): # pylint-disable: too-many-instance-attributes @@ -128,6 +131,14 @@ def _handle_error(error): # static files from the packages self.css = Css() self.scripts = Scripts() + + for method, resource in itertools.chain( + ((self.scripts.append_script, x) + for x in (external_script_urls or [])), + ((self.css.append_css, x) + for x in (external_css_urls or []))): + method({'external_url': resource, 'external_only': True}) + self.registered_paths = {} # urls diff --git a/dash/resources.py b/dash/resources.py index 70f37a5389..f17b3e3555 100644 --- a/dash/resources.py +++ b/dash/resources.py @@ -21,7 +21,8 @@ def _filter_resources(self, all_resources): filtered_resource = {} if 'namespace' in s: filtered_resource['namespace'] = s['namespace'] - if 'external_url' in s and not self.config.serve_locally: + if 'external_url' in s and ( + not self.config.serve_locally or s.get('external_only')): filtered_resource['external_url'] = s['external_url'] elif 'relative_package_path' in s: filtered_resource['relative_package_path'] = ( diff --git a/tests/test_integration.py b/tests/test_integration.py index 770b9152cb..aef8f05ffd 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -434,4 +434,26 @@ def will_raise(): self.assertTrue('{%config%}' in exc_msg) self.assertTrue('{%scripts%}' in exc_msg) time.sleep(0.5) - print('invalid index string') + + def test_external_files_init(self): + js_files = [ + 'https://www.google-analytics.com/analytics.js', + 'https://cdn.polyfill.io/v2/polyfill.min.js' + ] + css_files = [ + 'https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css', + 'https://codepen.io/chriddyp/pen/bWLwgP.css' + ] + + app = dash.Dash( + external_script_urls=js_files, external_css_urls=css_files) + + app.layout = html.Div() + + self.startServer(app) + time.sleep(0.5) + + for fmt, url in itertools.chain( + (("//script[@src='{}']", x) for x in js_files), + (("//link[@href='{}']", x) for x in css_files)): + self.driver.find_element_by_xpath(fmt.format(url))