0
# Request Parsing and Validation
1
2
Flask-RESTX provides a comprehensive request parsing system that declaratively extracts and validates data from various request sources including query parameters, form data, JSON body, headers, and uploaded files. The system automatically generates documentation and provides detailed error messages for validation failures.
3
4
## Capabilities
5
6
### RequestParser Class
7
8
Main class for defining and parsing request arguments with automatic validation and documentation generation.
9
10
```python { .api }
11
class RequestParser:
12
def __init__(
13
self,
14
argument_class=None,
15
result_class=None,
16
trim=False,
17
bundle_errors=False
18
):
19
"""
20
Initialize a new request parser.
21
22
Parameters:
23
- argument_class: Custom Argument class to use
24
- result_class: Custom result class for parsed arguments
25
- trim: Whether to trim whitespace from string arguments
26
- bundle_errors: Whether to bundle validation errors
27
"""
28
29
def add_argument(
30
self,
31
name,
32
default=None,
33
dest=None,
34
required=False,
35
ignore=False,
36
type=str,
37
location=("json", "values"),
38
choices=(),
39
action='store',
40
help=None,
41
operators=('=',),
42
case_sensitive=True,
43
store_missing=True,
44
trim=False,
45
nullable=True
46
):
47
"""
48
Add an argument to be parsed from the request.
49
50
Parameters:
51
- name: Argument name or list of option strings
52
- default: Default value if argument is absent
53
- dest: Destination attribute name in parsed result
54
- required: Whether argument is required (raises error if missing)
55
- ignore: Whether to ignore type conversion failures
56
- type: Type conversion function (str, int, float, etc.)
57
- location: Request locations to search ('args', 'form', 'headers', 'json', 'files', 'cookies', 'values')
58
- choices: List of allowed values
59
- action: Action type ('store' or 'append')
60
- help: Help message for validation errors
61
- operators: List of operators for query parsing
62
- case_sensitive: Whether values are case sensitive
63
- store_missing: Whether to store default if missing
64
- trim: Whether to trim whitespace
65
- nullable: Whether null values are allowed
66
"""
67
68
def parse_args(self, req=None, strict=False):
69
"""
70
Parse arguments from request.
71
72
Parameters:
73
- req: Flask request object (uses current request if None)
74
- strict: Whether to raise error for unknown arguments
75
76
Returns:
77
ParseResult: Dictionary-like object with parsed arguments
78
"""
79
80
def copy(self):
81
"""Create a copy of this parser."""
82
83
def replace_argument(self, name, **kwargs):
84
"""Replace an existing argument definition."""
85
86
def remove_argument(self, name):
87
"""Remove an argument from the parser."""
88
```
89
90
### Argument Class
91
92
Individual argument definition with validation rules and documentation.
93
94
```python { .api }
95
class Argument:
96
def __init__(
97
self,
98
name,
99
default=None,
100
dest=None,
101
required=False,
102
ignore=False,
103
type=str,
104
location=("json", "values"),
105
choices=(),
106
action='store',
107
help=None,
108
operators=('=',),
109
case_sensitive=True,
110
store_missing=True,
111
trim=False,
112
nullable=True
113
):
114
"""
115
Define a request argument with validation rules.
116
117
Parameters: Same as RequestParser.add_argument()
118
"""
119
120
def convert(self, value, op):
121
"""Convert and validate argument value."""
122
123
def source(self, request):
124
"""Extract argument values from request."""
125
```
126
127
### ParseResult Class
128
129
Result container for parsed arguments with dictionary-like access and attribute access.
130
131
```python { .api }
132
class ParseResult(dict):
133
"""Dictionary-like container for parsed arguments."""
134
135
def __getattr__(self, name):
136
"""Access parsed arguments as attributes."""
137
138
def __setattr__(self, name, value):
139
"""Set parsed arguments as attributes."""
140
```
141
142
### Input Validation Functions
143
144
Pre-built validation functions for common data types and formats.
145
146
```python { .api }
147
def boolean(value):
148
"""
149
Convert string to boolean.
150
151
Accepts: 'true', 'false', '1', '0', 'yes', 'no', 'on', 'off' (case insensitive)
152
Returns: bool
153
Raises: ValueError for invalid values
154
"""
155
156
def date_from_iso8601(value):
157
"""
158
Parse ISO8601 date string.
159
160
Parameters:
161
- value: ISO8601 date string (YYYY-MM-DD)
162
163
Returns: datetime.date object
164
Raises: ValueError for invalid format
165
"""
166
167
def datetime_from_iso8601(value):
168
"""
169
Parse ISO8601 datetime string.
170
171
Parameters:
172
- value: ISO8601 datetime string
173
174
Returns: datetime.datetime object
175
Raises: ValueError for invalid format
176
"""
177
178
def datetime_from_rfc822(value):
179
"""
180
Parse RFC822 datetime string.
181
182
Parameters:
183
- value: RFC822 datetime string
184
185
Returns: datetime.datetime object
186
Raises: ValueError for invalid format
187
"""
188
189
def ipv4(value):
190
"""
191
Validate IPv4 address.
192
193
Parameters:
194
- value: IP address string
195
196
Returns: str (validated IP address)
197
Raises: ValueError for invalid IP
198
"""
199
200
def ipv6(value):
201
"""
202
Validate IPv6 address.
203
204
Parameters:
205
- value: IP address string
206
207
Returns: str (validated IP address)
208
Raises: ValueError for invalid IP
209
"""
210
211
def ip(value):
212
"""
213
Validate IP address (IPv4 or IPv6).
214
215
Parameters:
216
- value: IP address string
217
218
Returns: str (validated IP address)
219
Raises: ValueError for invalid IP
220
"""
221
222
def natural(value):
223
"""
224
Validate natural number (positive integer).
225
226
Parameters:
227
- value: Value to validate
228
229
Returns: int (validated natural number)
230
Raises: ValueError for non-natural numbers
231
"""
232
233
def positive(value):
234
"""
235
Validate positive number (> 0).
236
237
Parameters:
238
- value: Value to validate
239
240
Returns: int or float (validated positive number)
241
Raises: ValueError for non-positive numbers
242
"""
243
244
def date(value):
245
"""
246
Parse date from various formats.
247
248
Parameters:
249
- value: Date string in various formats
250
251
Returns: datetime.date object
252
Raises: ValueError for unparseable dates
253
"""
254
255
def iso8601interval(value):
256
"""
257
Parse ISO8601 time interval.
258
259
Parameters:
260
- value: ISO8601 interval string
261
262
Returns: tuple of datetime objects (start, end)
263
Raises: ValueError for invalid intervals
264
"""
265
```
266
267
### Input Validation Classes
268
269
Advanced validation classes for complex validation rules.
270
271
```python { .api }
272
class regex:
273
def __init__(self, pattern):
274
"""
275
Regular expression validator.
276
277
Parameters:
278
- pattern: Regular expression pattern string
279
"""
280
281
def __call__(self, value):
282
"""Validate value against pattern."""
283
284
class int_range:
285
def __init__(self, low, high, argument="argument"):
286
"""
287
Integer range validator.
288
289
Parameters:
290
- low: Minimum allowed value
291
- high: Maximum allowed value
292
- argument: Argument name for error messages
293
"""
294
295
def __call__(self, value):
296
"""Validate value is within range."""
297
298
class URL:
299
def __init__(
300
self,
301
check=False,
302
ip=False,
303
local=False,
304
port=False,
305
auth=False,
306
schemes=None,
307
domains=None,
308
exclude=None
309
):
310
"""
311
URL validator.
312
313
Parameters:
314
- check: Whether to check URL accessibility
315
- ip: Whether to allow IP addresses
316
- local: Whether to allow local URLs
317
- port: Whether to require port in URL
318
- auth: Whether to allow authentication in URL
319
- schemes: List of allowed schemes (http, https, etc.)
320
- domains: List of allowed domains
321
- exclude: List of excluded domains
322
"""
323
324
def __call__(self, value):
325
"""Validate URL format and rules."""
326
327
class email:
328
def __init__(
329
self,
330
check=False,
331
ip=False,
332
local=False,
333
domains=None,
334
exclude=None
335
):
336
"""
337
Email address validator.
338
339
Parameters:
340
- check: Whether to check domain accessibility
341
- ip: Whether to allow IP addresses in domain
342
- local: Whether to allow local addresses
343
- domains: List of allowed domains
344
- exclude: List of excluded domains
345
"""
346
347
def __call__(self, value):
348
"""Validate email address format and rules."""
349
```
350
351
## Usage Examples
352
353
### Basic Request Parsing
354
355
```python
356
from flask_restx import Resource, reqparse
357
358
parser = reqparse.RequestParser()
359
parser.add_argument('name', type=str, required=True, help='Name is required')
360
parser.add_argument('age', type=int, default=0, help='Age as integer')
361
parser.add_argument('active', type=bool, default=True)
362
363
class UserCreate(Resource):
364
def post(self):
365
args = parser.parse_args()
366
return {
367
'name': args.name,
368
'age': args.age,
369
'active': args.active
370
}
371
```
372
373
### Multiple Locations
374
375
```python
376
# Parse from different request locations
377
parser = reqparse.RequestParser()
378
parser.add_argument('token', location=['headers'], required=True)
379
parser.add_argument('user_id', location=['json', 'form'], type=int)
380
parser.add_argument('filter', location=['args'], action='append')
381
382
class SecureResource(Resource):
383
def post(self):
384
args = parser.parse_args()
385
# args.token from headers
386
# args.user_id from JSON body or form data
387
# args.filter as list from query parameters
388
return {'received': args}
389
```
390
391
### Advanced Validation
392
393
```python
394
from flask_restx import inputs
395
396
parser = reqparse.RequestParser()
397
parser.add_argument('email', type=inputs.email(), required=True)
398
parser.add_argument('url', type=inputs.url())
399
parser.add_argument('ip_address', type=inputs.ip)
400
parser.add_argument('date', type=inputs.date_from_iso8601)
401
parser.add_argument('priority', type=int, choices=[1, 2, 3, 4, 5])
402
parser.add_argument('pattern', type=inputs.regex(r'^[A-Z]{2,4}$'))
403
404
class ValidatedResource(Resource):
405
def post(self):
406
args = parser.parse_args() # Automatic validation
407
return {'validated_data': args}
408
```
409
410
### File Upload Parsing
411
412
```python
413
from werkzeug.datastructures import FileStorage
414
415
upload_parser = reqparse.RequestParser()
416
upload_parser.add_argument('file',
417
location='files',
418
type=FileStorage,
419
required=True,
420
help='File upload is required')
421
upload_parser.add_argument('description',
422
location='form',
423
type=str)
424
425
class FileUpload(Resource):
426
def post(self):
427
args = upload_parser.parse_args()
428
file = args['file']
429
if file.filename == '':
430
return {'error': 'No file selected'}, 400
431
432
# Process file upload
433
return {
434
'filename': file.filename,
435
'description': args.get('description', '')
436
}
437
```
438
439
### Namespace Integration
440
441
```python
442
from flask_restx import Namespace
443
444
api = Namespace('users', description='User operations')
445
446
# Reusable parser
447
user_parser = api.parser()
448
user_parser.add_argument('name', required=True, help='User name')
449
user_parser.add_argument('email', type=inputs.email(), required=True)
450
451
@api.route('/')
452
class UserList(Resource):
453
@api.expect(user_parser)
454
def post(self):
455
args = user_parser.parse_args()
456
return {'created_user': args}, 201
457
```