Skip to content

Instantly share code, notes, and snippets.

@soxofaan
Last active June 2, 2022 12:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soxofaan/4a646f0ac24208cd097c7ab6ea21cc85 to your computer and use it in GitHub Desktop.
Save soxofaan/4a646f0ac24208cd097c7ab6ea21cc85 to your computer and use it in GitHub Desktop.
Flask view decorator for injecting Cache-Control headers

POC decorator for flask fiew functions to inject Cache-Control headers in a response.

Instructions to run example

Set up env, for example:

python -m venv venv
. venv/bin/activate
pip install flask

Run flask app:

export FLASK_APP=example.py
export FLASK_ENV=development 
flask run

Visit http://127.0.0.1:5000/, e.g.

$ curl -i http://127.0.0.1:5000/

HTTP/1.1 200 OK
...
Cache-Control: max-age=900, public
Expires: Wed, 01 Jun 2022 16:00:36 GMT
...
{
  "hello": "world"
}
import datetime
import functools
import flask
def cache_control(
max_age=None, no_cache=None, no_store=None,
public=None, private=None, must_revalidate=None,
):
"""
Parameterized decorator for Flask view functions to set `Cache-Control` headers on the response.
"""
if isinstance(max_age, datetime.timedelta):
max_age = int(max_age.total_seconds())
settings = dict(
max_age=max_age, no_cache=no_cache, no_store=no_store,
public=public, private=private, must_revalidate=must_revalidate,
)
settings = {key: value for key, value in settings.items() if value is not None}
def add_cache_control_headers(response: flask.Response) -> flask.Response:
# TODO: option to take status code into account
if 200 <= response.status_code < 300:
for key, value in settings.items():
setattr(response.cache_control, key, value)
if max_age is not None:
response.expires = datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age)
return response
def decorator(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
flask.after_this_request(add_cache_control_headers)
return func(*args, **kwargs)
return wrapped
return decorator
from datetime import timedelta
from flask import Flask, jsonify
from cache_control import cache_control
app = Flask(__name__)
@app.route("/")
@cache_control(max_age=timedelta(minutes=15), public=True)
def index():
return jsonify(hello="world")
@soxofaan
Copy link
Author

soxofaan commented Jun 2, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment