0
# Field Types
1
2
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.
3
4
## Capabilities
5
6
### Marshmallow Field Integration
7
8
WebArgs re-exports all marshmallow fields for convenient access, enabling the full range of marshmallow's field validation and type conversion capabilities.
9
10
```python { .api }
11
# All marshmallow.fields are available from webargs.fields
12
from webargs.fields import Str, Int, Float, Bool, DateTime, List, Dict, Nested, Email, URL, UUID
13
# ... and all other marshmallow fields
14
```
15
16
### Delimited List Field
17
18
Field that parses delimited strings into lists, useful for parsing comma-separated values from query parameters or form data.
19
20
```python { .api }
21
class DelimitedList(Field):
22
"""
23
A field which parses delimited strings into lists.
24
25
Args:
26
cls_or_instance: A marshmallow field class or instance for list elements
27
delimiter (str): Delimiter between values (default: ",")
28
**kwargs: Additional field arguments
29
30
Attributes:
31
delimiter (str): String used to split input values
32
is_multiple (bool): Always False for webargs parsing logic
33
empty_value: Value used for empty strings in delimited list
34
35
Example:
36
# Parse "1,2,3" into [1, 2, 3]
37
numbers = DelimitedList(Int())
38
39
# Parse "tag1,tag2,tag3" into ["tag1", "tag2", "tag3"]
40
tags = DelimitedList(Str(), delimiter=",")
41
42
# Custom delimiter
43
items = DelimitedList(Str(), delimiter="|")
44
"""
45
46
default_error_messages = {"invalid": "Not a valid delimited list."}
47
48
def __init__(self, cls_or_instance, *, delimiter=None, **kwargs): ...
49
```
50
51
### Delimited Tuple Field
52
53
Field that parses delimited strings into tuples with typed elements, useful for parsing structured data with known element types.
54
55
```python { .api }
56
class DelimitedTuple(Field):
57
"""
58
A field which parses delimited strings into tuples.
59
60
Args:
61
tuple_fields: Iterable of field classes or instances for tuple elements
62
delimiter (str): Delimiter between values (default: ",")
63
**kwargs: Additional field arguments
64
65
Example:
66
# Parse "John,25,true" into ("John", 25, True)
67
user_data = DelimitedTuple((Str(), Int(), Bool()))
68
69
# Parse coordinates "10.5,20.3" into (10.5, 20.3)
70
coordinates = DelimitedTuple((Float(), Float()))
71
"""
72
73
default_error_messages = {"invalid": "Not a valid delimited tuple."}
74
75
def __init__(self, tuple_fields, *, delimiter=None, **kwargs): ...
76
```
77
78
### Delimited Field Mixin
79
80
Base mixin class for creating custom delimited field types that split input on a delimiter.
81
82
```python { .api }
83
class DelimitedFieldMixin:
84
"""
85
Mixin class for creating delimited field types.
86
87
Attributes:
88
delimiter (str): String used to split input values (default: ",")
89
is_multiple (bool): Always False for webargs parsing
90
empty_value: Value to use for empty strings after splitting
91
92
Methods:
93
_serialize(value, attr, obj, **kwargs): Join values with delimiter
94
_deserialize(value, attr, data, **kwargs): Split string and deserialize elements
95
96
Example:
97
class CustomDelimitedList(DelimitedFieldMixin, marshmallow.fields.List):
98
delimiter = ";"
99
"""
100
delimiter = ","
101
is_multiple = False
102
empty_value = ""
103
104
def _serialize(self, value, attr, obj, **kwargs): ...
105
def _deserialize(self, value, attr, data, **kwargs): ...
106
```
107
108
### Enhanced Nested Field
109
110
Enhanced version of marshmallow's Nested field that can accept dictionary schemas for inline schema creation.
111
112
```python { .api }
113
class Nested(marshmallow.fields.Nested):
114
"""
115
Enhanced Nested field that accepts dict input for schema creation.
116
117
Args:
118
nested: Schema class, schema instance, or dict of field definitions
119
**kwargs: Additional nested field arguments
120
121
Note:
122
This is only needed for marshmallow versions prior to 3.15.0.
123
Modern marshmallow versions include this functionality natively.
124
125
Example:
126
# Using dict for inline schema
127
user_field = Nested({
128
"name": Str(required=True),
129
"email": Email()
130
})
131
132
# Using schema class
133
user_field = Nested(UserSchema)
134
"""
135
def __init__(self, nested, *args, **kwargs): ...
136
```
137
138
### Location-Aware Fields
139
140
All webargs fields support a special `location` parameter that specifies where to parse the field from in the HTTP request.
141
142
```python { .api }
143
# Field location examples
144
{
145
"name": fields.Str(location="json"), # From JSON body
146
"page": fields.Int(location="query"), # From query parameters
147
"csrf_token": fields.Str(location="form"), # From form data
148
"auth_token": fields.Str(location="headers", data_key="Authorization"), # From headers
149
"session_id": fields.Str(location="cookies"), # From cookies
150
"upload": fields.Raw(location="files") # From uploaded files
151
}
152
```
153
154
## Field Validation
155
156
Integration with marshmallow's validation system for robust field validation.
157
158
```python { .api }
159
# Import validation functions
160
from webargs import validate
161
162
# Common validation patterns
163
{
164
"age": fields.Int(validate=validate.Range(min=0, max=120)),
165
"email": fields.Email(validate=validate.Length(max=255)),
166
"status": fields.Str(validate=validate.OneOf(["active", "inactive"])),
167
"tags": DelimitedList(fields.Str(validate=validate.Length(min=1))),
168
"priority": fields.Int(validate=[
169
validate.Range(min=1, max=10),
170
validate.OneOf([1, 2, 3, 4, 5])
171
])
172
}
173
```
174
175
## Multi-Value Field Handling
176
177
System for handling multi-value fields from HTML forms and query parameters.
178
179
```python { .api }
180
class MultiDictProxy(collections.abc.MutableMapping):
181
"""
182
Proxy for multidict objects that handles multi-value fields based on schema.
183
184
A proxy object which wraps multidict types along with a matching schema.
185
Whenever a value is looked up, it is checked against the schema to see if
186
there is a matching field where `is_multiple` is True. If there is, then
187
the data should be loaded as a list or tuple.
188
189
Args:
190
multidict (MutableMapping): The source multidict object
191
schema (marshmallow.Schema): Marshmallow schema for field type information
192
known_multi_fields (tuple): Tuple of field types to treat as multi-value
193
(default: (marshmallow.fields.List, marshmallow.fields.Tuple))
194
195
Attributes:
196
data: The wrapped multidict object
197
known_multi_fields: Tuple of field types that handle multiple values
198
multiple_keys: Set of keys that should return multiple values
199
200
Automatically detects which fields should return multiple values based on:
201
- Field type (List, Tuple, DelimitedList, etc.)
202
- Field is_multiple attribute
203
- Known multi-value field types
204
"""
205
def __init__(self, multidict, schema, known_multi_fields=(marshmallow.fields.List, marshmallow.fields.Tuple)): ...
206
207
def _is_multiple(self, field):
208
"""
209
Return whether field handles repeated/multi-value arguments.
210
211
Args:
212
field (marshmallow.fields.Field): Field to check
213
214
Returns:
215
bool: True if field should handle multiple values
216
"""
217
218
def _collect_multiple_keys(self, schema):
219
"""
220
Collect keys that should return multiple values based on schema.
221
222
Args:
223
schema (marshmallow.Schema): Schema to analyze
224
225
Returns:
226
set: Set of field names that should return multiple values
227
"""
228
229
def __getitem__(self, key):
230
"""
231
Get value for key, returning list for multi-value fields.
232
233
For multi-value fields, attempts to use getlist() or getall() methods
234
from the underlying multidict, or converts single values to lists.
235
236
Args:
237
key (str): Key to retrieve
238
239
Returns:
240
Any: Single value or list depending on field type
241
"""
242
243
def __setitem__(self, key, value):
244
"""Set value for key in underlying multidict."""
245
246
def __delitem__(self, key):
247
"""Delete key from underlying multidict."""
248
249
def __iter__(self):
250
"""
251
Iterate over keys in multidict.
252
253
Special handling for header dicts which produce tuples instead of strings.
254
"""
255
256
def __len__(self):
257
"""Return number of keys in underlying multidict."""
258
259
def __str__(self):
260
"""Return string representation of underlying multidict."""
261
262
def __repr__(self):
263
"""Return detailed representation showing data and multiple keys."""
264
265
def __eq__(self, other):
266
"""Compare proxy to other object by comparing underlying data."""
267
268
def __ne__(self, other):
269
"""Return True if proxy data != other."""
270
271
def __contains__(self, key):
272
"""Return True if key exists in underlying multidict."""
273
274
def __getattr__(self, name):
275
"""Proxy attribute access to underlying multidict."""
276
```
277
278
## Type Definitions
279
280
```python { .api }
281
DelimitedFieldMixin = Type[DelimitedFieldMixin]
282
```
283
284
## Usage Examples
285
286
### Basic Field Usage
287
288
```python
289
from webargs import fields
290
291
# Simple field definitions
292
user_args = {
293
"name": fields.Str(required=True, validate=validate.Length(min=1)),
294
"age": fields.Int(missing=18, validate=validate.Range(min=0)),
295
"email": fields.Email(),
296
"is_admin": fields.Bool(location="query", missing=False)
297
}
298
```
299
300
### Delimited Field Examples
301
302
```python
303
# Parse comma-separated tags: "python,web,api" -> ["python", "web", "api"]
304
search_args = {
305
"tags": fields.DelimitedList(fields.Str()),
306
"categories": fields.DelimitedList(fields.Int(), delimiter="|"),
307
"coordinates": fields.DelimitedTuple((fields.Float(), fields.Float()))
308
}
309
```
310
311
### Complex Nested Structures
312
313
```python
314
# Nested object parsing
315
user_schema = {
316
"profile": fields.Nested({
317
"first_name": fields.Str(required=True),
318
"last_name": fields.Str(required=True),
319
"preferences": fields.Nested({
320
"theme": fields.Str(validate=validate.OneOf(["light", "dark"])),
321
"notifications": fields.Bool(missing=True)
322
})
323
})
324
}
325
```
326
327
### Location-Specific Fields
328
329
```python
330
# Parse from different request locations
331
mixed_args = {
332
"user_id": fields.Int(location="json"),
333
"page": fields.Int(location="query", missing=1),
334
"per_page": fields.Int(location="query", missing=20),
335
"auth_token": fields.Str(location="headers", data_key="Authorization"),
336
"csrf_token": fields.Str(location="form"),
337
"uploaded_file": fields.Raw(location="files")
338
}
339
```