A production-quality pure-Python WSGI server with robust HTTP protocol support and comprehensive configuration options
—
Comprehensive configuration system for tuning server performance, security, and behavior through the Adjustments class and utility functions.
Central configuration container for all server parameters, with validation and type conversion.
class Adjustments:
"""Configuration container for all tunable server parameters."""
def __init__(self, **kw):
"""
Initialize server configuration.
Parameters accept both command-line style (with dashes) and
Python style (with underscores) parameter names.
"""
@classmethod
def parse_args(cls, argv):
"""
Parse command-line arguments into configuration dictionary.
Parameters:
- argv (list): Command-line argument list
Returns:
tuple: (kw, args) where kw is configuration dict and args is remaining arguments
Note:
This method creates a dictionary suitable for passing to __init__,
where __init__ performs the type casting and validation.
"""Parameters controlling network binding and socket behavior.
# Network binding attributes
host: str = "0.0.0.0" # Hostname/IP to bind to
port: int = 8080 # TCP port to bind to
listen: list # List of (host, port) tuples for multiple bindings
ipv4: bool = True # Enable IPv4 socket support
ipv6: bool = True # Enable IPv6 socket support
unix_socket: str = None # Unix domain socket path
unix_socket_perms: int = 0o600 # Unix socket file permissions
sockets: list = [] # Pre-existing socket objects to useUsage example:
from waitress import serve
from waitress.adjustments import Adjustments
# Direct parameter passing
serve(app, host='127.0.0.1', port=5000, ipv6=True)
# Using Adjustments class
adj = Adjustments(
host='0.0.0.0',
port=8080,
unix_socket='/tmp/app.sock',
unix_socket_perms=0o666
)
serve(app, **adj.__dict__)
# Multiple listening addresses
serve(app, listen=[('127.0.0.1', 8080), ('127.0.0.1', 8081)])Parameters for tuning server performance and resource usage.
# Threading and concurrency
threads: int = 4 # Number of worker threads
backlog: int = 1024 # Socket listen backlog
connection_limit: int = 100 # Maximum concurrent connections
# Buffer sizes
recv_bytes: int = 8192 # Socket receive buffer size
send_bytes: int = 18000 # Socket send buffer size
inbuf_overflow: int = 512000 # Input buffer overflow threshold
outbuf_overflow: int = 1048576 # Output buffer overflow threshold
# Timeouts
channel_timeout: int = 120 # Idle connection timeout (seconds)
cleanup_interval: int = 30 # Connection cleanup interval (seconds)
asyncore_loop_timeout: float = 1.0 # asyncore loop timeout (seconds)Usage example:
# High-performance configuration
serve(app,
threads=8, # More worker threads
connection_limit=1000, # Higher connection limit
recv_bytes=16384, # Larger receive buffer
channel_timeout=300, # Longer timeout
backlog=2048 # Larger listen backlog
)Parameters controlling request size and processing limits.
# Request size limits
max_request_header_size: int = 262144 # Maximum header size (256KB)
max_request_body_size: int = 1073741824 # Maximum body size (1GB)
# Content handling
expose_tracebacks: bool = False # Show Python tracebacks to clientsUsage example:
# Restrict request sizes for security
serve(app,
max_request_header_size=65536, # 64KB headers max
max_request_body_size=10485760, # 10MB body max
expose_tracebacks=False # Never expose tracebacks
)Parameters for handling requests from reverse proxies and load balancers.
# Proxy trust settings
trusted_proxy: str = None # Trusted proxy IP address
trusted_proxy_count: int = None # Number of trusted proxies
trusted_proxy_headers: set = None # Which proxy headers to trust
# URL scheme handling
url_scheme: str = "http" # Default URL scheme for WSGI environ
url_prefix: str = "" # SCRIPT_NAME prefix for applicationsUsage example:
# Behind nginx reverse proxy
serve(app,
trusted_proxy='127.0.0.1',
trusted_proxy_headers={'x-forwarded-for', 'x-forwarded-proto'},
url_scheme='https' # App sees HTTPS even if proxy uses HTTP
)
# Multiple proxy layers
serve(app,
trusted_proxy_count=2, # Trust 2 proxy hops
trusted_proxy_headers={'x-forwarded-for', 'x-forwarded-proto', 'x-forwarded-host'}
)Parameters controlling server logging and error reporting.
# Logging configuration
log_socket_errors: bool = True # Log socket-level errors
ident: str = "waitress" # Server identification string for logs
expose_tracebacks: bool = False # Show tracebacks in error responsesHelper functions for parsing and converting configuration values.
def asbool(s):
"""
Convert string to boolean value.
Parameters:
- s: String value ('t', 'true', 'y', 'yes', 'on', '1' are truthy)
Returns:
bool: Converted boolean value
"""
def asoctal(s):
"""
Convert octal string to integer.
Parameters:
- s (str): Octal string (e.g., '644', '0o755')
Returns:
int: Integer value
"""
def aslist(value):
"""
Convert value to list, splitting on whitespace and newlines.
Parameters:
- value: String or iterable to convert
Returns:
list: List of string values
"""
def aslist_cronly(value):
"""
Convert value to list, splitting only on newlines.
Parameters:
- value: String or iterable to convert
Returns:
list: List of string values
"""
def asset(value):
"""
Convert value to set using aslist().
Parameters:
- value: Value to convert to set
Returns:
set: Set of string values
"""
def slash_fixed_str(s):
"""
Normalize URL path with leading slash.
Parameters:
- s (str): URL path to normalize
Returns:
str: Path with single leading slash and no trailing slash
Example:
>>> slash_fixed_str('path/to/resource/')
'/path/to/resource'
"""
def str_iftruthy(s):
"""
Convert to string if truthy, else return None.
Parameters:
- s: Value to convert
Returns:
str or None: String representation if truthy, None otherwise
"""
def as_socket_list(sockets):
"""
Filter list to socket objects only.
Parameters:
- sockets (list): List that may contain socket objects
Returns:
list: List containing only actual socket.socket instances
Notes:
- Removes non-socket objects from the list
- Used for validating socket configuration
"""Usage example:
from waitress.adjustments import asbool, asoctal, aslist
# Configuration parsing
expose_tracebacks = asbool('true') # True
socket_perms = asoctal('644') # 420
trusted_headers = asset('x-forwarded-for x-forwarded-proto') # {'x-forwarded-for', 'x-forwarded-proto'}The Adjustments class automatically handles command-line argument parsing.
# Command-line parameter formats accepted:
# --host=127.0.0.1
# --port=8080
# --threads=6
# --unix-socket=/tmp/app.sock
# --trusted-proxy=127.0.0.1
# --max-request-body-size=1048576Usage example:
import sys
from waitress.adjustments import Adjustments
# Parse command-line arguments
adj = Adjustments.parse_args(sys.argv[1:])
serve(app, **adj.__dict__)Install with Tessl CLI
npx tessl i tessl/pypi-waitress