Skip to content

Instantly share code, notes, and snippets.

@fancyboynet
Forked from mfenniak/gist:2978805
Last active July 26, 2016 06:50
Show Gist options
  • Save fancyboynet/ae5e1543d26361a756820e93c6fe8dc0 to your computer and use it in GitHub Desktop.
Save fancyboynet/ae5e1543d26361a756820e93c6fe8dc0 to your computer and use it in GitHub Desktop.
An extension of Flask that adds file hashes to static file URLs built by url_for("static"...)
import os.path
import contextlib
import hashlib
from flask import Flask
from flask.helpers import safe_join
# Injects an "h" parameter on the URLs of static files that contains a hash of
# the file. This allows the use of aggressive cache settings on static files,
# while ensuring that content changes are reflected immediately due to the
# changed URLs. Hashes are cached in-memory and only checked for updates when
# the file modtime changes.
class AddStaticFileHashFlask(Flask):
def __init__(self, *args, **kwargs):
super(AddStaticFileHashFlask, self).__init__(*args, **kwargs)
self._file_hash_cache = {}
def inject_url_defaults(self, endpoint, values):
super(AddStaticFileHashFlask, self).inject_url_defaults(endpoint, values)
if "filename" not in values:
return
if values["filename"].lower().endswith("ico"):
return
if "static" not in endpoint:
return
static_folder = self.static_folder
if "." in endpoint:
endpoint = endpoint.split(".")
if self.blueprints and self.blueprints.get(endpoint[0]) is not None:
static_folder = self.blueprints.get(endpoint[0]).static_folder
else:
return
filepath = safe_join(static_folder, values["filename"])
if os.path.isfile(filepath):
cache = self._file_hash_cache.get(filepath)
mtime = os.path.getmtime(filepath)
if cache != None:
cached_mtime, cached_hash = cache
if cached_mtime == mtime:
values["h"] = cached_hash
return
h = hashlib.md5()
with contextlib.closing(open(filepath, "rb")) as f:
h.update(f.read())
h = h.hexdigest()
self._file_hash_cache[filepath] = (mtime, h)
values["h"] = h
app = AddStaticFileHashFlask(__name__)
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment