{"id":1786,"library":"whitenoise","title":"WhiteNoise","description":"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.","status":"active","version":"6.12.0","language":"en","source_language":"en","source_url":"https://github.com/evansd/whitenoise","tags":["web","static files","wsgi","django","performance","cdn"],"install":[{"cmd":"pip install whitenoise","lang":"bash","label":"Install core library"},{"cmd":"pip install whitenoise[brotli,zopfli]","lang":"bash","label":"Install with compression dependencies"}],"dependencies":[{"reason":"Optional: For Brotli compression of static files.","package":"brotli","optional":true},{"reason":"Optional: For Zopfli/Gzip compression of static files.","package":"zopfli","optional":true}],"imports":[{"symbol":"WhiteNoise","correct":"from whitenoise import WhiteNoise"},{"note":"Used specifically for Django applications.","symbol":"WhiteNoiseMiddleware","correct":"from whitenoise.middleware import WhiteNoiseMiddleware"}],"quickstart":{"code":"import os\nfrom whitenoise import WhiteNoise\n\n# Your existing WSGI application (e.g., from Django, Flask, or a simple function)\n# For this example, we use a minimal dummy app:\ndef my_wsgi_app(environ, start_response):\n    status = '200 OK'\n    headers = [('Content-type', 'text/plain')]\n    start_response(status, headers)\n    return [b\"Hello from the main WSGI app!\"]\n\n# Path to your static files (e.g., collected via Django's collectstatic)\n# Ensure this directory exists and contains your static assets (e.g., 'staticfiles/hello.txt')\nSTATIC_ROOT = os.path.join(os.path.dirname(__file__), 'staticfiles')\n\n# Wrap your WSGI application with WhiteNoise\n# Basic setup: serves files from STATIC_ROOT at the root URL path ('/')\napplication = WhiteNoise(my_wsgi_app, root=STATIC_ROOT,\n                         # For production, consider enabling compression and setting a max_age:\n                         # gzip=True, brotli=True, # Requires 'zopfli' and 'brotli' packages\n                         # max_age=31536000 # Cache static files for 1 year in browsers\n                        )\n\n# If you need to serve additional static directories or with specific URL prefixes:\n# application.add_files('/path/to/another/static/dir', prefix='another-prefix/')\n\n# The 'application' object is now ready to be served by any WSGI server\n# e.g., gunicorn -w 4 your_project.wsgi:application","lang":"python","description":"This quickstart demonstrates how to wrap a generic WSGI application with WhiteNoise to serve static files from a specified directory (`STATIC_ROOT`). The resulting `application` object can then be served by any WSGI server. Comments highlight optional but recommended production settings like compression and aggressive caching (`max_age`)."},"warnings":[{"fix":"Explicitly set `max_age` for production deployments, e.g., `max_age=31536000` for one year of caching. For Django, this is typically done in `settings.py` via `WHITENOISE_MAX_AGE`.","message":"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.","severity":"breaking","affected_versions":"6.0.0+"},{"fix":"Explicitly enable compression by passing `gzip=True` and `brotli=True` to the `WhiteNoise` constructor or by setting `WHITENOISE_GZIP=True` and `WHITENOISE_BROTLI=True` in Django `settings.py`. Remember to install `zopfli` and `brotli` packages.","message":"Compression (Gzip/Brotli) is disabled by default in WhiteNoise 5.0+. This can lead to a significant performance regression if not re-enabled.","severity":"breaking","affected_versions":"5.0.0+"},{"fix":"Remove calls to `configure()`. Pass all options as keyword arguments when initializing `WhiteNoise(app, root='/path/to/static', **options)` or use Django settings like `WHITENOISE_ROOT`, `WHITENOISE_MAX_AGE`, etc.","message":"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.","severity":"breaking","affected_versions":"6.0.0+"},{"fix":"Adjust your `MIDDLEWARE` setting in `settings.py` similar to this:\n\n```python\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'whitenoise.middleware.WhiteNoiseMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    # ... other middleware\n]\n```","message":"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.","severity":"gotcha","affected_versions":"All versions with Django"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}