WhiteNoise
Radically simplified static file serving for WSGI applications. WhiteNoise takes a WSGI application and wraps it, serving static files directly from the application itself. It's commonly used with Django to serve `STATIC_ROOT` contents. Current version 6.12.0, with regular updates typically following major Django releases or when significant improvements are made.
Warnings
- breaking The `max_age` default for static file caching was changed. In version 6.0+, it's 0 (no caching) in development and 60 seconds in production. Previously, it was 1 year by default.
- breaking Compression (Gzip/Brotli) is disabled by default in WhiteNoise 5.0+. This can lead to a significant performance regression if not re-enabled.
- breaking The `WhiteNoise.configure()` method was removed in version 6.0.0. All configuration must now be passed directly to the `WhiteNoise` constructor or, for Django, via `settings.py` variables.
- gotcha In Django applications, the order of `WhiteNoiseMiddleware` in `MIDDLEWARE` is critical. It should be placed after `django.middleware.security.SecurityMiddleware` and any other middleware that may redirect or rewrite URLs, but *before* `django.contrib.sessions.middleware.SessionMiddleware` and *especially before* `django.middleware.gzip.GZipMiddleware` if you are using both.
Install
-
pip install whitenoise -
pip install whitenoise[brotli,zopfli]
Imports
- WhiteNoise
from whitenoise import WhiteNoise
- WhiteNoiseMiddleware
from whitenoise.middleware import WhiteNoiseMiddleware
Quickstart
import os
from whitenoise import WhiteNoise
# Your existing WSGI application (e.g., from Django, Flask, or a simple function)
# For this example, we use a minimal dummy app:
def my_wsgi_app(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain')]
start_response(status, headers)
return [b"Hello from the main WSGI app!"]
# Path to your static files (e.g., collected via Django's collectstatic)
# Ensure this directory exists and contains your static assets (e.g., 'staticfiles/hello.txt')
STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'staticfiles')
# Wrap your WSGI application with WhiteNoise
# Basic setup: serves files from STATIC_ROOT at the root URL path ('/')
application = WhiteNoise(my_wsgi_app, root=STATIC_ROOT,
# For production, consider enabling compression and setting a max_age:
# gzip=True, brotli=True, # Requires 'zopfli' and 'brotli' packages
# max_age=31536000 # Cache static files for 1 year in browsers
)
# If you need to serve additional static directories or with specific URL prefixes:
# application.add_files('/path/to/another/static/dir', prefix='another-prefix/')
# The 'application' object is now ready to be served by any WSGI server
# e.g., gunicorn -w 4 your_project.wsgi:application