mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-08 09:38:12 +08:00
add cache control headers (#1333)
* add cache control headers * add config param check
This commit is contained in:
@@ -20,7 +20,39 @@ from functools import wraps
|
|||||||
webbp = Blueprint("webapp", "server.common.web", template_folder="templates")
|
webbp = Blueprint("webapp", "server.common.web", template_folder="templates")
|
||||||
|
|
||||||
|
|
||||||
|
def _cache_control(always, **cache_kwargs):
|
||||||
|
"""
|
||||||
|
Used to easily manage cache control headers on responses.
|
||||||
|
See Werkzeug for attributes that can be set, eg, no_cache, private, max_age, etc.
|
||||||
|
https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.ResponseCacheControl
|
||||||
|
"""
|
||||||
|
def inner_cache_control(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
response = make_response(f(*args, **kwargs))
|
||||||
|
if not always and not current_app.app_config.server__generate_cache_control_headers:
|
||||||
|
return response
|
||||||
|
if response.status_code >= 400:
|
||||||
|
return response
|
||||||
|
for k, v in cache_kwargs.items():
|
||||||
|
setattr(response.cache_control, k, v)
|
||||||
|
return response
|
||||||
|
return wrapper
|
||||||
|
return inner_cache_control
|
||||||
|
|
||||||
|
|
||||||
|
def cache_control(**cache_kwargs):
|
||||||
|
""" configu driven """
|
||||||
|
return _cache_control(False, **cache_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def cache_control_always(**cache_kwargs):
|
||||||
|
""" always generate headers, regardless of the config """
|
||||||
|
return _cache_control(True, **cache_kwargs)
|
||||||
|
|
||||||
|
|
||||||
@webbp.route("/", methods=["GET"])
|
@webbp.route("/", methods=["GET"])
|
||||||
|
@cache_control(public=True, max_age=3600)
|
||||||
def dataset_index(dataset=None):
|
def dataset_index(dataset=None):
|
||||||
config = current_app.app_config
|
config = current_app.app_config
|
||||||
if dataset is None:
|
if dataset is None:
|
||||||
@@ -52,6 +84,7 @@ def favicon():
|
|||||||
|
|
||||||
|
|
||||||
@webbp.route("/health", methods=["GET"])
|
@webbp.route("/health", methods=["GET"])
|
||||||
|
@cache_control_always(no_cache=True)
|
||||||
def health():
|
def health():
|
||||||
config = current_app.app_config
|
config = current_app.app_config
|
||||||
return health_check(config)
|
return health_check(config)
|
||||||
@@ -132,50 +165,59 @@ def dataroot_index():
|
|||||||
|
|
||||||
|
|
||||||
class SchemaAPI(Resource):
|
class SchemaAPI(Resource):
|
||||||
|
@cache_control(public=True, max_age=3600)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def get(self, data_adaptor):
|
def get(self, data_adaptor):
|
||||||
return common_rest.schema_get(data_adaptor, current_app.annotations)
|
return common_rest.schema_get(data_adaptor, current_app.annotations)
|
||||||
|
|
||||||
|
|
||||||
class ConfigAPI(Resource):
|
class ConfigAPI(Resource):
|
||||||
|
@cache_control(public=True, max_age=3600)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def get(self, data_adaptor):
|
def get(self, data_adaptor):
|
||||||
return common_rest.config_get(current_app.app_config, data_adaptor, current_app.annotations)
|
return common_rest.config_get(current_app.app_config, data_adaptor, current_app.annotations)
|
||||||
|
|
||||||
|
|
||||||
class AnnotationsObsAPI(Resource):
|
class AnnotationsObsAPI(Resource):
|
||||||
|
@cache_control(public=True, max_age=3600)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def get(self, data_adaptor):
|
def get(self, data_adaptor):
|
||||||
return common_rest.annotations_obs_get(request, data_adaptor, current_app.annotations)
|
return common_rest.annotations_obs_get(request, data_adaptor, current_app.annotations)
|
||||||
|
|
||||||
|
@cache_control(no_cache=True)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def put(self, data_adaptor):
|
def put(self, data_adaptor):
|
||||||
return common_rest.annotations_obs_put(request, data_adaptor, current_app.annotations)
|
return common_rest.annotations_obs_put(request, data_adaptor, current_app.annotations)
|
||||||
|
|
||||||
|
|
||||||
class AnnotationsVarAPI(Resource):
|
class AnnotationsVarAPI(Resource):
|
||||||
|
@cache_control(public=True, max_age=3600)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def get(self, data_adaptor):
|
def get(self, data_adaptor):
|
||||||
return common_rest.annotations_var_get(request, data_adaptor, current_app.annotations)
|
return common_rest.annotations_var_get(request, data_adaptor, current_app.annotations)
|
||||||
|
|
||||||
|
|
||||||
class DataVarAPI(Resource):
|
class DataVarAPI(Resource):
|
||||||
|
@cache_control(no_cache=True)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def put(self, data_adaptor):
|
def put(self, data_adaptor):
|
||||||
return common_rest.data_var_put(request, data_adaptor)
|
return common_rest.data_var_put(request, data_adaptor)
|
||||||
|
|
||||||
|
|
||||||
class DiffExpObsAPI(Resource):
|
class DiffExpObsAPI(Resource):
|
||||||
|
@cache_control(no_cache=True)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def post(self, data_adaptor):
|
def post(self, data_adaptor):
|
||||||
return common_rest.diffexp_obs_post(request, data_adaptor)
|
return common_rest.diffexp_obs_post(request, data_adaptor)
|
||||||
|
|
||||||
|
|
||||||
class LayoutObsAPI(Resource):
|
class LayoutObsAPI(Resource):
|
||||||
|
@cache_control(public=True, max_age=3600)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def get(self, data_adaptor):
|
def get(self, data_adaptor):
|
||||||
return common_rest.layout_obs_get(request, data_adaptor)
|
return common_rest.layout_obs_get(request, data_adaptor)
|
||||||
|
|
||||||
|
@cache_control(no_cache=True)
|
||||||
@rest_get_data_adaptor
|
@rest_get_data_adaptor
|
||||||
def put(self, data_adaptor):
|
def put(self, data_adaptor):
|
||||||
return common_rest.layout_obs_put(request, data_adaptor)
|
return common_rest.layout_obs_put(request, data_adaptor)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ class AppConfig(object):
|
|||||||
self.server__about_legal_privacy = dc["server"]["about_legal_privacy"]
|
self.server__about_legal_privacy = dc["server"]["about_legal_privacy"]
|
||||||
self.server__force_https = dc["server"]["force_https"]
|
self.server__force_https = dc["server"]["force_https"]
|
||||||
self.server__flask_secret_key = dc["server"]["flask_secret_key"]
|
self.server__flask_secret_key = dc["server"]["flask_secret_key"]
|
||||||
|
self.server__generate_cache_control_headers = dc["server"]["generate_cache_control_headers"]
|
||||||
|
|
||||||
self.multi_dataset__dataroot = dc["multi_dataset"]["dataroot"]
|
self.multi_dataset__dataroot = dc["multi_dataset"]["dataroot"]
|
||||||
self.multi_dataset__index = dc["multi_dataset"]["index"]
|
self.multi_dataset__index = dc["multi_dataset"]["index"]
|
||||||
@@ -197,6 +198,7 @@ class AppConfig(object):
|
|||||||
self.__check_attr("server__open_browser", bool)
|
self.__check_attr("server__open_browser", bool)
|
||||||
self.__check_attr("server__force_https", bool)
|
self.__check_attr("server__force_https", bool)
|
||||||
self.__check_attr("server__flask_secret_key", (type(None), str))
|
self.__check_attr("server__flask_secret_key", (type(None), str))
|
||||||
|
self.__check_attr("server__generate_cache_control_headers", bool)
|
||||||
|
|
||||||
if self.server__port:
|
if self.server__port:
|
||||||
if not is_port_available(self.server__host, self.server__port):
|
if not is_port_available(self.server__host, self.server__port):
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ server:
|
|||||||
about_legal_privacy: null
|
about_legal_privacy: null
|
||||||
force_https: false
|
force_https: false
|
||||||
flask_secret_key: null
|
flask_secret_key: null
|
||||||
|
generate_cache_control_headers: false
|
||||||
|
|
||||||
presentation:
|
presentation:
|
||||||
max_categories: 1000
|
max_categories: 1000
|
||||||
|
|||||||
Reference in New Issue
Block a user