CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-whitenoise

Radically simplified static file serving for WSGI applications

Overview
Eval results
Files

core-middleware.mddocs/

Core WSGI Middleware

The WhiteNoise class provides the core static file serving functionality as WSGI middleware. It intercepts requests for static files and serves them directly, allowing your application to handle dynamic content while WhiteNoise efficiently serves static assets.

Capabilities

WhiteNoise Class

The main WSGI middleware class that serves static files with comprehensive HTTP feature support including compression, caching, range requests, and proper header handling.

class WhiteNoise:
    """
    WSGI middleware for serving static files.
    
    Wraps a WSGI application to serve static files before passing requests
    to the wrapped application. Supports compression, caching, and HTTP
    best practices.
    """
    
    def __init__(
        self,
        application,
        root=None,
        prefix=None,
        *,
        autorefresh: bool = False,
        max_age: int | None = 60,
        allow_all_origins: bool = True,
        charset: str = "utf-8",
        mimetypes: dict[str, str] | None = None,
        add_headers_function: Callable[[Headers, str, str], None] | None = None,
        index_file: str | bool | None = None,
        immutable_file_test: Callable | str | None = None,
    ):
        """
        Initialize WhiteNoise middleware.
        
        Parameters:
        - application: WSGI application to wrap
        - root: Path to static files directory
        - prefix: URL prefix for static files (e.g., '/static/')
        - autorefresh: Re-scan filesystem on each request (development only)
        - max_age: Cache-Control max-age in seconds (None disables caching)
        - allow_all_origins: Add Access-Control-Allow-Origin: * header
        - charset: Default charset for text files
        - mimetypes: Additional MIME type mappings
        - add_headers_function: Custom function to add headers
        - index_file: Index file name (True for 'index.html')
        - immutable_file_test: Function or regex to identify immutable files
        """
    
    def __call__(self, environ, start_response):
        """
        WSGI application interface.
        
        Parameters:
        - environ: WSGI environment dictionary
        - start_response: WSGI start_response callable
        
        Returns:
        - WSGI response iterator
        """
    
    def add_files(self, root, prefix=None):
        """
        Add a directory of static files to serve.
        
        Parameters:
        - root: Absolute path to static files directory
        - prefix: URL prefix for files (e.g., '/static/')
        """
    
    @staticmethod
    def serve(static_file, environ, start_response):
        """
        Serve a static file (static method).
        
        Parameters:
        - static_file: StaticFile instance to serve
        - environ: WSGI environment dictionary  
        - start_response: WSGI start_response callable
        
        Returns:
        - WSGI response iterator
        """
    
    FOREVER: int  # Cache duration constant (10 years in seconds)

Usage Examples

Basic WSGI Integration

from whitenoise import WhiteNoise
from my_app import application

# Wrap your WSGI application
application = WhiteNoise(application)

# Add static files with URL prefix
application.add_files('/var/www/static', prefix='/static/')
application.add_files('/var/www/media', prefix='/media/')

Development Configuration

# Enable autorefresh for development (performance impact)
application = WhiteNoise(
    application,
    autorefresh=True,
    max_age=0  # Disable caching for development
)

Production Configuration with Custom Headers

def add_security_headers(headers, path, url):
    """Add security headers to static files."""
    if url.endswith('.js'):
        headers['X-Content-Type-Options'] = 'nosniff'
    if url.endswith('.css'):
        headers['X-Content-Type-Options'] = 'nosniff'

application = WhiteNoise(
    application,
    max_age=31536000,  # 1 year cache for production
    allow_all_origins=True,
    add_headers_function=add_security_headers
)

Immutable File Detection

import re

# Using regex pattern for versioned files
versioned_file_re = r'\.[0-9a-f]{8,32}\.'

application = WhiteNoise(
    application,
    immutable_file_test=versioned_file_re
)

# Using custom function
def is_immutable(path, url):
    """Check if file is immutable based on naming convention."""
    return '.min.' in url or '.hash.' in url

application = WhiteNoise(
    application,
    immutable_file_test=is_immutable
)

File Discovery and Caching

WhiteNoise operates in two modes for file discovery:

Static Mode (Default): Files are scanned once at startup and stored in memory for fast lookup. Suitable for production environments.

Autorefresh Mode: Files are discovered on each request by scanning the filesystem. Only use for development as it has significant performance impact.

HTTP Features

WhiteNoise implements comprehensive HTTP best practices:

  • Content Negotiation: Automatically serves compressed variants (gzip, brotli) based on Accept-Encoding header
  • Conditional Requests: Supports If-Modified-Since and If-None-Match headers for 304 responses
  • Range Requests: Handles partial content requests for large files
  • CORS Support: Configurable Cross-Origin Resource Sharing headers
  • Cache Headers: Intelligent cache control with support for immutable files

Static File Response System

Internal classes that handle HTTP responses and file serving, used by WhiteNoise for comprehensive static file delivery.

class Response:
    """
    HTTP response container for static file serving.
    
    Represents the complete HTTP response including status, headers, and file content.
    """
    
    def __init__(self, status, headers, file):
        """
        Initialize HTTP response.
        
        Parameters:
        - status: HTTPStatus enum value
        - headers: List of (name, value) header tuples
        - file: File object or None for responses without body
        """

class StaticFile:
    """
    Represents a static file with all its variants and metadata.
    
    Handles compressed alternatives, conditional requests, range requests,
    and proper HTTP header generation for efficient static file serving.
    """
    
    def __init__(self, path, headers, encodings=None, stat_cache=None):
        """
        Initialize static file representation.
        
        Parameters:
        - path: Absolute path to the file
        - headers: List of (name, value) header tuples
        - encodings: Dict mapping encodings to compressed file paths
        - stat_cache: Optional stat cache for performance
        """
    
    def get_response(self, method, request_headers):
        """
        Generate HTTP response for the file.
        
        Parameters:
        - method: HTTP method (GET, HEAD, etc.)
        - request_headers: Dict of request headers
        
        Returns:
        - Response: Complete HTTP response object
        
        Handles conditional requests, range requests, content negotiation,
        and proper HTTP status codes.
        """

class SlicedFile:
    """
    File-like object for HTTP range requests.
    
    Wraps a file to serve only a specific byte range, enabling
    efficient partial content delivery for large files.
    """
    
    def __init__(self, fileobj, start, end):
        """
        Create sliced file for range request.
        
        Parameters:
        - fileobj: Source file object
        - start: Starting byte position (inclusive)
        - end: Ending byte position (inclusive)
        """
    
    def read(self, size=-1):
        """
        Read bytes respecting range limits.
        
        Parameters:
        - size: Maximum bytes to read (-1 for remaining)
        
        Returns:
        - bytes: File content within range limits
        """

class Redirect:
    """
    HTTP redirect response for URL rewriting.
    
    Used for index file handling and URL canonicalization.
    """
    
    def __init__(self, location, headers=None):
        """
        Create redirect response.
        
        Parameters:
        - location: Target URL for redirect
        - headers: Optional additional headers
        """
    
    def get_response(self, method, request_headers):
        """
        Generate redirect response.
        
        Parameters:
        - method: HTTP method
        - request_headers: Request headers dict
        
        Returns:
        - Response: 302 redirect response
        """

class FileEntry:
    """
    File metadata container for stat caching.
    
    Stores file path, size, and modification time for efficient
    file system operations and HTTP header generation.
    """
    
    def __init__(self, path, stat_cache=None):
        """
        Create file entry with metadata.
        
        Parameters:
        - path: Absolute file path
        - stat_cache: Optional stat cache for performance
        """

Media Type Resolution

MIME type detection system for proper Content-Type header generation.

class MediaTypes:
    """
    MIME type resolver for static files.
    
    Provides consistent media type detection across environments
    using WhiteNoise's built-in type mappings with optional extensions.
    """
    
    def __init__(self, *, extra_types: dict[str, str] | None = None):
        """
        Initialize media type resolver.
        
        Parameters:
        - extra_types: Additional MIME type mappings to include
        """
    
    def get_type(self, path: str) -> str:
        """
        Determine MIME type for file path.
        
        Parameters:
        - path: File path to analyze
        
        Returns:
        - str: MIME type string (defaults to 'application/octet-stream')
        
        Checks both filename and extension, with filename taking precedence
        for special cases like 'apple-app-site-association'.
        """

String Utilities

URL and path processing utilities for consistent handling across WhiteNoise.

def decode_path_info(path_info):
    """
    Decode URL path from WSGI PATH_INFO.
    
    Parameters:
    - path_info: Raw PATH_INFO string from WSGI environ
    
    Returns:
    - str: UTF-8 decoded path string
    
    Handles UTF-8 URLs by undoing Python's implicit ISO-8859-1 decoding.
    """

def ensure_leading_trailing_slash(path):
    """
    Normalize path to have leading and trailing slashes.
    
    Parameters:
    - path: Path string to normalize
    
    Returns:
    - str: Normalized path with leading/trailing slashes
    
    Returns '/' for empty/None input, '/{path}/' for non-empty input.
    """

Exception Classes

Specialized exceptions for static file handling and error reporting.

class NotARegularFileError(Exception):
    """
    Base exception for non-regular file encounters.
    
    Raised when attempting to serve directories, devices, or other
    non-regular file system objects.
    """

class MissingFileError(NotARegularFileError):
    """
    Exception for missing or inaccessible files.
    
    Raised when a requested file cannot be found or accessed.
    """

class IsDirectoryError(MissingFileError):
    """
    Exception for directory access attempts.
    
    Raised when attempting to serve a directory as a file.
    """

Types

from typing import Callable, Any
from wsgiref.headers import Headers
from http import HTTPStatus

# WSGI application type
WSGIApplication = Callable[[dict, Callable], Any]

# Custom header function type  
AddHeadersFunction = Callable[[Headers, str, str], None]

# Immutable file test types
ImmutableFileTest = Callable[[str, str], bool]
ImmutableFilePattern = str

# HTTP response components
HTTPHeaders = list[tuple[str, str]]
RequestHeaders = dict[str, str]

Install with Tessl CLI

npx tessl i tessl/pypi-whitenoise

docs

compression.md

core-middleware.md

django-integration.md

index.md

tile.json