CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-werkzeug

The comprehensive WSGI web application library providing essential utilities and components for building Python web applications.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

request-response.mddocs/

Request and Response Handling

Complete WSGI request and response wrappers providing high-level access to HTTP data including headers, cookies, form data, file uploads, content negotiation, and conditional requests. These classes form the foundation of Werkzeug's web development capabilities.

Capabilities

Request Object

The Request class wraps a WSGI environ dictionary, providing convenient access to all request data with automatic parsing and type conversion.

class Request:
    def __init__(self, environ, populate_request=True, shallow=False):
        """
        Create a new request wrapper.
        
        Parameters:
        - environ: WSGI environment dictionary
        - populate_request: Whether to parse form data immediately
        - shallow: Don't consume input stream for form parsing
        """
    
    # URL and path information
    method: str  # HTTP method (GET, POST, etc.)
    url: str  # Complete URL
    base_url: str  # URL without query string
    url_root: str  # Protocol, host, and script root
    path: str  # Path portion of URL  
    script_root: str  # SCRIPT_NAME from WSGI
    query_string: str  # Raw query string
    
    # Request data access
    args: MultiDict  # Parsed query parameters
    form: MultiDict  # Parsed form data (POST/PUT)
    files: MultiDict  # Uploaded files as FileStorage objects
    values: MultiDict  # Combined args and form data
    data: bytes  # Raw request body
    json: Any  # Parsed JSON data (if Content-Type is JSON)
    
    # Headers and metadata
    headers: Headers  # Request headers
    cookies: dict  # Request cookies
    authorization: Optional[Authorization]  # Authorization header
    # User-Agent header accessible via headers.get('User-Agent')
    
    # Accept headers for content negotiation
    accept_mimetypes: MIMEAccept  # Accept header
    accept_charsets: CharsetAccept  # Accept-Charset header
    accept_encodings: Accept  # Accept-Encoding header  
    accept_languages: LanguageAccept  # Accept-Language header
    
    # Conditional request headers
    cache_control: RequestCacheControl  # Cache-Control header
    if_match: Optional[ETags]  # If-Match header
    if_none_match: Optional[ETags]  # If-None-Match header
    if_modified_since: Optional[datetime]  # If-Modified-Since header
    if_unmodified_since: Optional[datetime]  # If-Unmodified-Since header
    range: Optional[Range]  # Range header
    
    # Content information
    content_type: Optional[str]  # Content-Type header
    content_length: Optional[int]  # Content-Length header
    mimetype: Optional[str]  # MIME type from Content-Type
    mimetype_params: dict  # Parameters from Content-Type
    
    # Request type checks
    is_json: bool  # True if Content-Type is JSON
    is_secure: bool  # True if request is over HTTPS
    is_xhr: bool  # True if X-Requested-With is XMLHttpRequest
    
    # Client and server information
    remote_addr: Optional[str]  # Client IP address
    remote_user: Optional[str]  # Authenticated username
    scheme: str  # URL scheme (http/https)
    host: str  # Host header value
    port: Optional[int]  # Port number
    
    def get_json(self, force=False, silent=False, cache=True):
        """
        Parse request body as JSON.
        
        Parameters:
        - force: Parse even if Content-Type is not JSON
        - silent: Return None instead of raising on parse errors
        - cache: Cache parsed result
        
        Returns:
        Parsed JSON data or None
        """

Response Object

The Response class provides a high-level interface for creating HTTP responses with proper header management, cookie handling, and caching support.

class Response:
    def __init__(self, response=None, status=None, headers=None, mimetype=None, content_type=None, direct_passthrough=False):
        """
        Create a new response object.
        
        Parameters:
        - response: Response body (string, bytes, or iterable)
        - status: HTTP status code or status line
        - headers: Response headers (dict, list, or Headers object)
        - mimetype: MIME type for Content-Type header
        - content_type: Complete Content-Type header value
        - direct_passthrough: Don't modify response body
        """
    
    # Response data and status
    data: bytes  # Response body as bytes
    status: str  # Complete status line (e.g., "200 OK")
    status_code: int  # Status code number
    headers: Headers  # Response headers
    
    # Content type information
    mimetype: Optional[str]  # MIME type portion
    content_type: Optional[str]  # Complete Content-Type header
    content_length: Optional[int]  # Content-Length header
    
    # Caching headers
    cache_control: ResponseCacheControl  # Cache-Control header
    expires: Optional[datetime]  # Expires header
    last_modified: Optional[datetime]  # Last-Modified header
    etag: Optional[str]  # ETag header
    
    # Other headers
    www_authenticate: Optional[WWWAuthenticate]  # WWW-Authenticate header
    location: Optional[str]  # Location header for redirects
    
    def set_cookie(self, key, value="", max_age=None, expires=None, path="/", domain=None, secure=False, httponly=False, samesite=None):
        """
        Set a cookie.
        
        Parameters:
        - key: Cookie name
        - value: Cookie value
        - max_age: Maximum age in seconds
        - expires: Expiration datetime or timestamp
        - path: Cookie path
        - domain: Cookie domain
        - secure: Only send over HTTPS
        - httponly: Don't allow JavaScript access
        - samesite: SameSite attribute ('Strict', 'Lax', or 'None')
        """
    
    def delete_cookie(self, key, path="/", domain=None, secure=False, httponly=False, samesite=None):
        """
        Delete a cookie by setting it to expire immediately.
        
        Parameters:
        - key: Cookie name to delete
        - path: Cookie path (must match original)
        - domain: Cookie domain (must match original)
        - secure: Secure flag (must match original)
        - httponly: HttpOnly flag (must match original)
        - samesite: SameSite attribute (must match original)
        """
    
    def set_etag(self, etag, weak=False):
        """
        Set the ETag header.
        
        Parameters:
        - etag: ETag value
        - weak: Whether this is a weak ETag
        """
    
    def make_conditional(self, request_or_environ, accept_ranges=False, complete_length=None):
        """
        Make response conditional based on request headers.
        
        Handles If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since
        and Range headers automatically.
        
        Parameters:
        - request_or_environ: Request object or WSGI environ
        - accept_ranges: Whether to accept Range requests
        - complete_length: Total content length for partial content
        
        Returns:
        Response object (may be modified for 304/416 responses)
        """
    
    def add_etag(self, overwrite=False, weak=False):
        """
        Add an ETag header based on response content.
        
        Parameters:
        - overwrite: Replace existing ETag
        - weak: Generate weak ETag
        """
    
    def freeze(self, no_etag=False):
        """
        Make response immutable and add ETag if missing.
        
        Parameters:
        - no_etag: Don't add ETag header
        """

Response Stream

Helper for streaming responses with proper chunked encoding support.

class ResponseStream:
    def __init__(self, response):
        """
        Create a response stream wrapper.
        
        Parameters:
        - response: Response object to wrap
        """
    
    def write(self, data):
        """
        Write data to response stream.
        
        Parameters:
        - data: Data to write (string or bytes)
        """
    
    def writelines(self, lines):
        """
        Write multiple lines to response stream.
        
        Parameters:
        - lines: Iterable of lines to write
        """
    
    def close(self):
        """Close the response stream."""

Usage Examples

Basic Request Handling

from werkzeug.wrappers import Request, Response

def application(environ, start_response):
    request = Request(environ)
    
    # Access request data
    method = request.method
    path = request.path
    user_agent = request.headers.get('User-Agent')
    
    # Handle different content types
    if request.is_json:
        data = request.get_json()
        response = Response(f"Received JSON: {data}")
    elif request.method == 'POST':
        form_data = request.form
        response = Response(f"Form data: {dict(form_data)}")
    else:
        response = Response("Hello World!")
    
    return response(environ, start_response)

File Upload Handling

from werkzeug.wrappers import Request, Response
from werkzeug.utils import secure_filename
import os

def handle_upload(environ, start_response):
    request = Request(environ)
    
    if request.method == 'POST':
        uploaded_file = request.files.get('file')
        if uploaded_file and uploaded_file.filename:
            filename = secure_filename(uploaded_file.filename)
            upload_path = os.path.join('/uploads', filename)
            uploaded_file.save(upload_path)
            response = Response(f"File {filename} uploaded successfully")
        else:
            response = Response("No file uploaded", status=400)
    else:
        response = Response('''
        <form method="POST" enctype="multipart/form-data">
            <input type="file" name="file">
            <input type="submit" value="Upload">
        </form>
        ''', mimetype='text/html')
    
    return response(environ, start_response)

Content Negotiation

from werkzeug.wrappers import Request, Response
import json

def api_endpoint(environ, start_response):
    request = Request(environ)
    
    data = {"message": "Hello", "status": "success"}
    
    # Check what the client accepts
    if request.accept_mimetypes.accept_json:
        response = Response(
            json.dumps(data),
            mimetype='application/json'
        )
    elif request.accept_mimetypes.accept_html:
        html = f"<h1>{data['message']}</h1><p>Status: {data['status']}</p>"
        response = Response(html, mimetype='text/html')
    else:
        # Default to plain text
        response = Response(f"{data['message']} - {data['status']}")
    
    return response(environ, start_response)

Conditional Responses and Caching

from werkzeug.wrappers import Request, Response
from werkzeug.http import http_date
from datetime import datetime

def cached_content(environ, start_response):
    request = Request(environ)
    
    # Create response with content
    content = "This is cached content that changes infrequently"
    response = Response(content)
    
    # Set caching headers
    response.last_modified = datetime(2023, 1, 1)
    response.cache_control.max_age = 3600  # Cache for 1 hour
    response.add_etag()  # Generate ETag from content
    
    # Make response conditional (handles 304 Not Modified)
    response.make_conditional(request)
    
    return response(environ, start_response)

Cookie Handling

from werkzeug.wrappers import Request, Response

def session_example(environ, start_response):
    request = Request(environ)
    
    # Read existing session
    session_id = request.cookies.get('session_id')
    
    if session_id:
        response = Response(f"Welcome back! Session: {session_id}")
    else:
        # Create new session
        import uuid
        new_session_id = str(uuid.uuid4())
        response = Response(f"New session created: {new_session_id}")
        
        # Set secure session cookie
        response.set_cookie(
            'session_id', 
            new_session_id,
            max_age=3600,  # 1 hour
            secure=True,   # HTTPS only
            httponly=True, # No JavaScript access
            samesite='Lax' # CSRF protection
        )
    
    return response(environ, start_response)

Install with Tessl CLI

npx tessl i tessl/pypi-werkzeug

docs

data-structures.md

dev-server.md

exceptions.md

http-utilities.md

index.md

middleware.md

request-response.md

routing.md

security.md

testing.md

url-wsgi-utils.md

tile.json