From edc08ab7e4a5c5bfa4c1ec1c1f23e4e18b8ac52c Mon Sep 17 00:00:00 2001 From: Philippe Duval Date: Tue, 11 Sep 2018 10:18:07 -0400 Subject: [PATCH] Add cache control header and cache busting urls to components suites. --- dash/_configs.py | 3 ++- dash/dash.py | 26 ++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/dash/_configs.py b/dash/_configs.py index 6849f5be8d..6b46b5cdd4 100644 --- a/dash/_configs.py +++ b/dash/_configs.py @@ -18,7 +18,8 @@ def env_configs(): 'DASH_REQUESTS_PATHNAME_PREFIX', 'DASH_SUPPRESS_CALLBACK_EXCEPTIONS', 'DASH_ASSETS_EXTERNAL_PATH', - 'DASH_INCLUDE_ASSETS_FILES' + 'DASH_INCLUDE_ASSETS_FILES', + 'DASH_COMPONENTS_CACHE_MAX_AGE' )}) diff --git a/dash/dash.py b/dash/dash.py index 28e2dfb912..ec15aada7b 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, + components_cache_max_age=None, **kwargs): # pylint-disable: too-many-instance-attributes @@ -136,6 +137,9 @@ def __init__( True), 'assets_external_path': _configs.get_config( 'assets_external_path', assets_external_path, env_configs, ''), + 'components_cache_max_age': int(_configs.get_config( + 'components_cache_max_age', components_cache_max_age, + env_configs, 2678400)) }) # list of dependencies @@ -302,11 +306,18 @@ def _relative_url_path(relative_package_path='', namespace=''): else: self.registered_paths[namespace] = [relative_package_path] - return '{}_dash-component-suites/{}/{}?v={}'.format( + module_path = os.path.join( + os.path.dirname(sys.modules[namespace].__file__), + relative_package_path) + + modified = int(os.stat(module_path).st_mtime) + + return '{}_dash-component-suites/{}/{}?v={}&m={}'.format( self.config['requests_pathname_prefix'], namespace, relative_package_path, - importlib.import_module(namespace).__version__ + importlib.import_module(namespace).__version__, + modified ) srcs = [] @@ -422,9 +433,16 @@ def serve_component_suites(self, package_name, path_in_package_dist): 'js': 'application/JavaScript', 'css': 'text/css' })[path_in_package_dist.split('.')[-1]] + + headers = { + 'Cache-Control': 'public, max-age={}'.format( + self.config.components_cache_max_age) + } + return Response( pkgutil.get_data(package_name, path_in_package_dist), - mimetype=mimetype + mimetype=mimetype, + headers=headers ) def index(self, *args, **kwargs): # pylint: disable=unused-argument @@ -435,7 +453,7 @@ def index(self, *args, **kwargs): # pylint: disable=unused-argument title = getattr(self, 'title', 'Dash') if self._favicon: favicon = ''.format( - flask.url_for('assets.static', filename=self._favicon)) + self.get_asset_url(self._favicon)) else: favicon = ''