First install relevant modules
sudo a2enmod expires sudo a2enmod headers
Then add something like this to your .htaccess
file:
# Expire headers
<ifModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</ifModule>
# Cache-Control Headers
<ifModule mod_headers.c>
<filesMatch "\.(ico|jpe?g|png|gif)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
<filesMatch "\.(css|js)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
</ifModule>
# END Cache-Control Headers
This tutorial details how to manage static files with Flask and WhiteNoise. We'll also configure Amazon CloudFront to get the best possible performance.,The official WhiteNoise documentation -- Using WhiteNoise with Flask -- is, as of writing, outdated and inaccurate.,There are no tutorials on using Flask with WhiteNoise and CloudFront.,You can now use the provided CloudFront domain in the Flask app to handle static file requests:
import os from flask import Flask, jsonify from whitenoise import WhiteNoise def create_app(script_info = None): app = Flask(__name__, static_folder = "staticfiles") WHITENOISE_MAX_AGE = 31536000 if not app.config["DEBUG"] else 0 # configure WhiteNoise app.wsgi_app = WhiteNoise( app.wsgi_app, root = os.path.join(os.path.dirname(__file__), "staticfiles"), prefix = "assets/", max_age = WHITENOISE_MAX_AGE, ) @app.route("/") def hello_world(): return jsonify(hello = "world") return app
├──
app.py├── static│└── bootstrap.css└── staticfiles
import os import gzip INPUT_PATH = os.path.join(os.path.dirname(__file__), "static") OUTPUT_PATH = os.path.join(os.path.dirname(__file__), "staticfiles") SKIP_COMPRESS_EXTENSIONS = [ # Images ".jpg", ".jpeg", ".png", ".gif", ".webp", # Compressed files ".zip", ".gz", ".tgz", ".bz2", ".tbz", ".xz", ".br", # Flash ".swf", ".flv", # Fonts ".woff", ".woff2", ] def remove_files(path): print(f "Removing files from {path}") for filename in os.listdir(path): file_path = os.path.join(path, filename) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: print(e) def main(): # remove all files from "staticfiles" remove_files(OUTPUT_PATH) for dirpath, dirs, files in os.walk(INPUT_PATH): for filename in files: input_file = os.path.join(dirpath, filename) with open(input_file, "rb") as f: data = f.read() # compress if file extension is not part of SKIP_COMPRESS_EXTENSIONS name, ext = os.path.splitext(filename) if ext not in SKIP_COMPRESS_EXTENSIONS: # save compressed file to the "staticfiles" directory compressed_output_file = os.path.join(OUTPUT_PATH, f "{filename}.gz") print(f "\nCompressing {filename}") print(f "Saving {filename}.gz") output = gzip.open(compressed_output_file, "wb") try: output.write(data) finally: output.close() else: print(f "\nSkipping compression of {filename}") # save original file to the "staticfiles" directory output_file = os.path.join(OUTPUT_PATH, filename) print(f "Saving {filename}") with open(output_file, "wb") as f: f.write(data) if __name__ == "__main__": main()
$ pip install whitenoise
$ touch static / test.png
$ python compress.py
Removing files from staticfiles
Compressing bootstrap.css
Saving bootstrap.css.gz
Saving bootstrap.css
Skipping compression of test.png
Saving test.png
But all the static files still have max-age=0. I read about Webassets on Python Flask, but I am not sure how to use it, since I didn't find a tutorial to make all the static files have the same cache-control. How can I continue to make the same as I did for the page?,I had a low score due to Leverage browser caching since I hadn't added any max-age on headers response and it was 0. Now I have this in Python Flask:,I am doing a few tests about my website health in Google Developers site
I had a low score due to Leverage browser caching since I hadn't added any max-age on headers response and it was 0. Now I have this in Python Flask:
@app.after_request
def add_header(response):
response.cache_control.max_age = 86400
return response
The header response for the website:
Cache - Control max - age = 86400