When using the flask-caching===2.0.2 library together with flask-compress==1.14.0 I run into an issue where the caching doesn't work properly.
I tested three scenarios:
1.
using just the @cache.cached(timeout=600, query_string=True) decorator:
as expected the cached response is not compressed but the one served to the webpage is compressed
2.
using the @cache.cached(timeout=600, query_string=True) decorator and
compress.cache = cache
compress.cache_key = get_cache_key
# Define a function to return cache key for incoming requests
def get_cache_key(request):
return request.url
Taking the get_cache_key function from documentation results in caching both the non-compressed response and the compressed response.
3.
def get_cache_key(request):
args_as_sorted_tuple = tuple(
sorted(pair for pair in request.args.items(multi=True))
)
# ... now hash the sorted (key, value) tuple so it can be
# used as a key for cache. Turn them into bytes so that the
# hash function will accept them
args_as_bytes = str(args_as_sorted_tuple).encode()
cache_hash = hashlib.md5(args_as_bytes)
cache_hash = str(cache_hash.hexdigest())
cache_key = request.path + cache_hash
return cache_key
unifying the get_cache_key functions so that they return the same cache key results in an error
eds-eds-1 | Traceback (most recent call last):
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle
eds-eds-1 | keepalive = self.handle_request(req, conn)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request
eds-eds-1 | respiter = self.wsgi(environ, resp.start_response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2213, in call
eds-eds-1 | return self.wsgi_app(environ, start_response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2193, in wsgi_app
eds-eds-1 | response = self.handle_exception(e)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function
eds-eds-1 | return cors_after_request(app.make_response(f(*args, **kwargs)))
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2190, in wsgi_app
eds-eds-1 | response = self.full_dispatch_request()
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1487, in full_dispatch_request
eds-eds-1 | return self.finalize_request(rv)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1508, in finalize_request
eds-eds-1 | response = self.process_response(response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2002, in process_response
eds-eds-1 | response = self.ensure_sync(func)(response)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask_compress/flask_compress.py", line 208, in after_request
eds-eds-1 | response.set_data(compressed_content)
eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/werkzeug/wrappers/response.py", line 302, in set_data
eds-eds-1 | self.headers["Content-Length"] = str(len(value))
eds-eds-1 | TypeError: object of type 'Response' has no len()
I want to cache only the compressed response to save resources, am I doing something wrong, or is that a bug in either of the packages?
When using the flask-caching===2.0.2 library together with flask-compress==1.14.0 I run into an issue where the caching doesn't work properly. I tested three scenarios:
1. using just the @cache.cached(timeout=600, query_string=True) decorator: as expected the cached response is not compressed but the one served to the webpage is compressed
2. using the @cache.cached(timeout=600, query_string=True) decorator and
Taking the get_cache_key function from documentation results in caching both the non-compressed response and the compressed response.
3.
unifying the get_cache_key functions so that they return the same cache key results in an error
eds-eds-1 | Traceback (most recent call last): eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle eds-eds-1 | keepalive = self.handle_request(req, conn) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request eds-eds-1 | respiter = self.wsgi(environ, resp.start_response) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2213, in call eds-eds-1 | return self.wsgi_app(environ, start_response) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2193, in wsgi_app eds-eds-1 | response = self.handle_exception(e) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function eds-eds-1 | return cors_after_request(app.make_response(f(*args, **kwargs))) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2190, in wsgi_app eds-eds-1 | response = self.full_dispatch_request() eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1487, in full_dispatch_request eds-eds-1 | return self.finalize_request(rv) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1508, in finalize_request eds-eds-1 | response = self.process_response(response) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2002, in process_response eds-eds-1 | response = self.ensure_sync(func)(response) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/flask_compress/flask_compress.py", line 208, in after_request eds-eds-1 | response.set_data(compressed_content) eds-eds-1 | File "/usr/local/lib/python3.9/site-packages/werkzeug/wrappers/response.py", line 302, in set_data eds-eds-1 | self.headers["Content-Length"] = str(len(value)) eds-eds-1 | TypeError: object of type 'Response' has no len()
I want to cache only the compressed response to save resources, am I doing something wrong, or is that a bug in either of the packages?