Declarative parsing and validation of HTTP request objects, with built-in support for popular web frameworks.
Custom field types and marshmallow field integration for parsing delimited strings, handling nested data structures, and extending field validation capabilities. WebArgs provides enhanced field types that work seamlessly with HTTP request parsing while maintaining full compatibility with marshmallow's field system.
WebArgs re-exports all marshmallow fields for convenient access, enabling the full range of marshmallow's field validation and type conversion capabilities.
# All marshmallow.fields are available from webargs.fields
from webargs.fields import Str, Int, Float, Bool, DateTime, List, Dict, Nested, Email, URL, UUID
# ... and all other marshmallow fieldsField that parses delimited strings into lists, useful for parsing comma-separated values from query parameters or form data.
class DelimitedList(Field):
"""
A field which parses delimited strings into lists.
Args:
cls_or_instance: A marshmallow field class or instance for list elements
delimiter (str): Delimiter between values (default: ",")
**kwargs: Additional field arguments
Attributes:
delimiter (str): String used to split input values
is_multiple (bool): Always False for webargs parsing logic
empty_value: Value used for empty strings in delimited list
Example:
# Parse "1,2,3" into [1, 2, 3]
numbers = DelimitedList(Int())
# Parse "tag1,tag2,tag3" into ["tag1", "tag2", "tag3"]
tags = DelimitedList(Str(), delimiter=",")
# Custom delimiter
items = DelimitedList(Str(), delimiter="|")
"""
default_error_messages = {"invalid": "Not a valid delimited list."}
def __init__(self, cls_or_instance, *, delimiter=None, **kwargs): ...Field that parses delimited strings into tuples with typed elements, useful for parsing structured data with known element types.
class DelimitedTuple(Field):
"""
A field which parses delimited strings into tuples.
Args:
tuple_fields: Iterable of field classes or instances for tuple elements
delimiter (str): Delimiter between values (default: ",")
**kwargs: Additional field arguments
Example:
# Parse "John,25,true" into ("John", 25, True)
user_data = DelimitedTuple((Str(), Int(), Bool()))
# Parse coordinates "10.5,20.3" into (10.5, 20.3)
coordinates = DelimitedTuple((Float(), Float()))
"""
default_error_messages = {"invalid": "Not a valid delimited tuple."}
def __init__(self, tuple_fields, *, delimiter=None, **kwargs): ...Base mixin class for creating custom delimited field types that split input on a delimiter.
class DelimitedFieldMixin:
"""
Mixin class for creating delimited field types.
Attributes:
delimiter (str): String used to split input values (default: ",")
is_multiple (bool): Always False for webargs parsing
empty_value: Value to use for empty strings after splitting
Methods:
_serialize(value, attr, obj, **kwargs): Join values with delimiter
_deserialize(value, attr, data, **kwargs): Split string and deserialize elements
Example:
class CustomDelimitedList(DelimitedFieldMixin, marshmallow.fields.List):
delimiter = ";"
"""
delimiter = ","
is_multiple = False
empty_value = ""
def _serialize(self, value, attr, obj, **kwargs): ...
def _deserialize(self, value, attr, data, **kwargs): ...Enhanced version of marshmallow's Nested field that can accept dictionary schemas for inline schema creation.
class Nested(marshmallow.fields.Nested):
"""
Enhanced Nested field that accepts dict input for schema creation.
Args:
nested: Schema class, schema instance, or dict of field definitions
**kwargs: Additional nested field arguments
Note:
This is only needed for marshmallow versions prior to 3.15.0.
Modern marshmallow versions include this functionality natively.
Example:
# Using dict for inline schema
user_field = Nested({
"name": Str(required=True),
"email": Email()
})
# Using schema class
user_field = Nested(UserSchema)
"""
def __init__(self, nested, *args, **kwargs): ...All webargs fields support a special location parameter that specifies where to parse the field from in the HTTP request.
# Field location examples
{
"name": fields.Str(location="json"), # From JSON body
"page": fields.Int(location="query"), # From query parameters
"csrf_token": fields.Str(location="form"), # From form data
"auth_token": fields.Str(location="headers", data_key="Authorization"), # From headers
"session_id": fields.Str(location="cookies"), # From cookies
"upload": fields.Raw(location="files") # From uploaded files
}Integration with marshmallow's validation system for robust field validation.
# Import validation functions
from webargs import validate
# Common validation patterns
{
"age": fields.Int(validate=validate.Range(min=0, max=120)),
"email": fields.Email(validate=validate.Length(max=255)),
"status": fields.Str(validate=validate.OneOf(["active", "inactive"])),
"tags": DelimitedList(fields.Str(validate=validate.Length(min=1))),
"priority": fields.Int(validate=[
validate.Range(min=1, max=10),
validate.OneOf([1, 2, 3, 4, 5])
])
}System for handling multi-value fields from HTML forms and query parameters.
class MultiDictProxy(collections.abc.MutableMapping):
"""
Proxy for multidict objects that handles multi-value fields based on schema.
A proxy object which wraps multidict types along with a matching schema.
Whenever a value is looked up, it is checked against the schema to see if
there is a matching field where `is_multiple` is True. If there is, then
the data should be loaded as a list or tuple.
Args:
multidict (MutableMapping): The source multidict object
schema (marshmallow.Schema): Marshmallow schema for field type information
known_multi_fields (tuple): Tuple of field types to treat as multi-value
(default: (marshmallow.fields.List, marshmallow.fields.Tuple))
Attributes:
data: The wrapped multidict object
known_multi_fields: Tuple of field types that handle multiple values
multiple_keys: Set of keys that should return multiple values
Automatically detects which fields should return multiple values based on:
- Field type (List, Tuple, DelimitedList, etc.)
- Field is_multiple attribute
- Known multi-value field types
"""
def __init__(self, multidict, schema, known_multi_fields=(marshmallow.fields.List, marshmallow.fields.Tuple)): ...
def _is_multiple(self, field):
"""
Return whether field handles repeated/multi-value arguments.
Args:
field (marshmallow.fields.Field): Field to check
Returns:
bool: True if field should handle multiple values
"""
def _collect_multiple_keys(self, schema):
"""
Collect keys that should return multiple values based on schema.
Args:
schema (marshmallow.Schema): Schema to analyze
Returns:
set: Set of field names that should return multiple values
"""
def __getitem__(self, key):
"""
Get value for key, returning list for multi-value fields.
For multi-value fields, attempts to use getlist() or getall() methods
from the underlying multidict, or converts single values to lists.
Args:
key (str): Key to retrieve
Returns:
Any: Single value or list depending on field type
"""
def __setitem__(self, key, value):
"""Set value for key in underlying multidict."""
def __delitem__(self, key):
"""Delete key from underlying multidict."""
def __iter__(self):
"""
Iterate over keys in multidict.
Special handling for header dicts which produce tuples instead of strings.
"""
def __len__(self):
"""Return number of keys in underlying multidict."""
def __str__(self):
"""Return string representation of underlying multidict."""
def __repr__(self):
"""Return detailed representation showing data and multiple keys."""
def __eq__(self, other):
"""Compare proxy to other object by comparing underlying data."""
def __ne__(self, other):
"""Return True if proxy data != other."""
def __contains__(self, key):
"""Return True if key exists in underlying multidict."""
def __getattr__(self, name):
"""Proxy attribute access to underlying multidict."""DelimitedFieldMixin = Type[DelimitedFieldMixin]from webargs import fields
# Simple field definitions
user_args = {
"name": fields.Str(required=True, validate=validate.Length(min=1)),
"age": fields.Int(missing=18, validate=validate.Range(min=0)),
"email": fields.Email(),
"is_admin": fields.Bool(location="query", missing=False)
}# Parse comma-separated tags: "python,web,api" -> ["python", "web", "api"]
search_args = {
"tags": fields.DelimitedList(fields.Str()),
"categories": fields.DelimitedList(fields.Int(), delimiter="|"),
"coordinates": fields.DelimitedTuple((fields.Float(), fields.Float()))
}# Nested object parsing
user_schema = {
"profile": fields.Nested({
"first_name": fields.Str(required=True),
"last_name": fields.Str(required=True),
"preferences": fields.Nested({
"theme": fields.Str(validate=validate.OneOf(["light", "dark"])),
"notifications": fields.Bool(missing=True)
})
})
}# Parse from different request locations
mixed_args = {
"user_id": fields.Int(location="json"),
"page": fields.Int(location="query", missing=1),
"per_page": fields.Int(location="query", missing=20),
"auth_token": fields.Str(location="headers", data_key="Authorization"),
"csrf_token": fields.Str(location="form"),
"uploaded_file": fields.Raw(location="files")
}Install with Tessl CLI
npx tessl i tessl/pypi-webargs