or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-resources.mddocumentation.mderror-handling.mdfields.mdindex.mdinput-validation.mdmodels-marshalling.mdrequest-parsing.md

request-parsing.mddocs/

0

# Request Parsing

1

2

Request parsing system for handling URL parameters, form data, JSON payloads, and file uploads with validation and type conversion. Flask-RESTPlus provides a comprehensive request parser that integrates with automatic documentation generation.

3

4

## Capabilities

5

6

### RequestParser Class

7

8

Main class for parsing and validating request data from various sources.

9

10

```python { .api }

11

class RequestParser:

12

def __init__(self, argument_class=None, result_class=None, trim=False, bundle_errors=False):

13

"""

14

Initialize the request parser.

15

16

Args:

17

argument_class (class, optional): Custom Argument class

18

result_class (class, optional): Custom result class

19

trim (bool): Automatically trim string values

20

bundle_errors (bool): Return all validation errors at once

21

"""

22

23

def add_argument(self, name, dest=None, type=str, location=('json', 'form', 'args'),

24

required=False, default=None, help=None, action='store',

25

choices=None, ignore=False, case_sensitive=True, store_missing=True,

26

nullable=True, **kwargs):

27

"""

28

Add an argument to the parser.

29

30

Args:

31

name (str): Argument name

32

dest (str, optional): Destination attribute name

33

type (callable): Type conversion function

34

location (tuple or str): Where to look for the argument

35

required (bool): Whether argument is required

36

default: Default value if argument is missing

37

help (str, optional): Help text for documentation

38

action (str): How to handle the argument ('store', 'store_const', 'store_true', 'store_false', 'append', 'append_const', 'count')

39

choices (list, optional): List of allowed values

40

ignore (bool): Ignore parsing errors

41

case_sensitive (bool): Case sensitive argument matching

42

store_missing (bool): Store missing arguments with None value

43

nullable (bool): Allow None values

44

**kwargs: Additional argument options

45

46

Returns:

47

Argument: The added argument instance

48

"""

49

50

def parse_args(self, req=None, strict=False):

51

"""

52

Parse arguments from the request.

53

54

Args:

55

req (Request, optional): Flask request object (uses current request if None)

56

strict (bool): Raise exception on unknown arguments

57

58

Returns:

59

ParseResult: Parsed arguments

60

"""

61

62

def copy(self):

63

"""

64

Create a copy of this parser.

65

66

Returns:

67

RequestParser: Copied parser

68

"""

69

70

def replace_argument(self, name, **kwargs):

71

"""

72

Replace an existing argument.

73

74

Args:

75

name (str): Argument name to replace

76

**kwargs: New argument parameters

77

78

Returns:

79

Argument: The replaced argument

80

"""

81

82

def remove_argument(self, name):

83

"""

84

Remove an argument from the parser.

85

86

Args:

87

name (str): Argument name to remove

88

"""

89

```

90

91

### Argument Class

92

93

Individual argument configuration for request parsing.

94

95

```python { .api }

96

class Argument:

97

def __init__(self, name, default=None, dest=None, required=False, ignore=False,

98

type=str, location=('json', 'form', 'args'), choices=None,

99

action='store', help=None, operators=('=',), case_sensitive=True,

100

store_missing=True, trim=False, nullable=True, **kwargs):

101

"""

102

Initialize an argument.

103

104

Args:

105

name (str): Argument name

106

default: Default value

107

dest (str, optional): Destination attribute name

108

required (bool): Whether argument is required

109

ignore (bool): Ignore parsing errors

110

type (callable): Type conversion function

111

location (tuple or str): Request locations to search

112

choices (list, optional): Allowed values

113

action (str): Parsing action

114

help (str, optional): Help text

115

operators (tuple): Allowed operators for filtering

116

case_sensitive (bool): Case sensitive matching

117

store_missing (bool): Store missing arguments

118

trim (bool): Trim string values

119

nullable (bool): Allow None values

120

**kwargs: Additional options

121

"""

122

123

def source(self, request):

124

"""

125

Extract argument values from request.

126

127

Args:

128

request (Request): Flask request object

129

130

Returns:

131

list: Extracted values

132

"""

133

134

def convert(self, value, op):

135

"""

136

Convert argument value to the specified type.

137

138

Args:

139

value: Raw argument value

140

op (str): Operator used

141

142

Returns:

143

Converted value

144

"""

145

146

def handle_validation_error(self, error, bundle_errors):

147

"""

148

Handle validation errors.

149

150

Args:

151

error (Exception): Validation error

152

bundle_errors (bool): Whether to bundle errors

153

"""

154

155

def parse(self, request, bundle_errors=False):

156

"""

157

Parse this argument from the request.

158

159

Args:

160

request (Request): Flask request object

161

bundle_errors (bool): Bundle all errors

162

163

Returns:

164

tuple: (parsed_value, found_in_request)

165

"""

166

```

167

168

### ParseResult Class

169

170

Container for parsed arguments with attribute-style access.

171

172

```python { .api }

173

class ParseResult(dict):

174

def __init__(self, *args, **kwargs):

175

"""

176

Initialize parse result.

177

178

Args:

179

*args: Dictionary arguments

180

**kwargs: Keyword arguments

181

"""

182

183

def __getattr__(self, name):

184

"""

185

Get parsed argument by attribute access.

186

187

Args:

188

name (str): Argument name

189

190

Returns:

191

Parsed argument value

192

"""

193

194

def __setattr__(self, name, value):

195

"""

196

Set parsed argument by attribute access.

197

198

Args:

199

name (str): Argument name

200

value: Argument value

201

"""

202

```

203

204

### Constants and Helpers

205

206

Request parsing constants and utility mappings.

207

208

```python { .api }

209

LOCATIONS: dict # Maps Flask-RESTPlus locations to Swagger parameter types

210

PY_TYPES: dict # Maps Python types to Swagger types

211

SPLIT_CHAR: str = ',' # Default character for splitting array values

212

```

213

214

## Usage Examples

215

216

### Basic Request Parsing

217

218

```python

219

from flask_restplus import Api, Resource, reqparse

220

221

api = Api()

222

223

# Create a request parser

224

parser = reqparse.RequestParser()

225

226

# Add arguments

227

parser.add_argument('name', type=str, required=True, help='Name is required')

228

parser.add_argument('age', type=int, location='args', help='Age parameter')

229

parser.add_argument('active', type=bool, default=True, help='Active status')

230

231

@api.route('/users')

232

class UserList(Resource):

233

@api.expect(parser)

234

def post(self):

235

# Parse arguments from request

236

args = parser.parse_args()

237

238

# Access parsed values

239

name = args['name'] # or args.name

240

age = args['age']

241

active = args['active']

242

243

# Process the data...

244

return {'message': f'Created user {name}, age {age}, active: {active}'}, 201

245

```

246

247

### Argument Locations

248

249

```python

250

from flask_restplus import reqparse

251

252

parser = reqparse.RequestParser()

253

254

# URL query parameters (?param=value)

255

parser.add_argument('page', type=int, location='args', default=1)

256

257

# Form data (POST form submission)

258

parser.add_argument('username', type=str, location='form', required=True)

259

260

# JSON payload data

261

parser.add_argument('data', type=dict, location='json')

262

263

# HTTP headers

264

parser.add_argument('api-key', location='headers', required=True)

265

266

# File uploads

267

parser.add_argument('upload', location='files', type=FileStorage)

268

269

# Cookies

270

parser.add_argument('session_id', location='cookies')

271

272

# Multiple locations (search in order)

273

parser.add_argument('token', location=['headers', 'args'], required=True)

274

275

# All locations (json, form, args)

276

parser.add_argument('flexible_param', location=('json', 'form', 'args'))

277

```

278

279

### Type Conversion and Validation

280

281

```python

282

from flask_restplus import reqparse

283

from datetime import datetime

284

285

parser = reqparse.RequestParser()

286

287

# Built-in type conversions

288

parser.add_argument('count', type=int, help='Must be an integer')

289

parser.add_argument('rate', type=float, help='Must be a float')

290

parser.add_argument('enabled', type=bool, help='Boolean value')

291

292

# Custom type conversion function

293

def date_type(date_str):

294

"""Convert date string to datetime object."""

295

try:

296

return datetime.strptime(date_str, '%Y-%m-%d')

297

except ValueError:

298

raise ValueError(f"Invalid date format: {date_str}. Use YYYY-MM-DD")

299

300

parser.add_argument('start_date', type=date_type, help='Date in YYYY-MM-DD format')

301

302

# Choices validation

303

parser.add_argument('status',

304

choices=['active', 'inactive', 'pending'],

305

help='Status must be one of: active, inactive, pending')

306

307

# List/array arguments

308

parser.add_argument('tags', action='append', help='Can be specified multiple times')

309

310

# Store constants

311

parser.add_argument('verbose', action='store_true', help='Enable verbose mode')

312

parser.add_argument('quiet', action='store_false', help='Disable quiet mode')

313

```

314

315

### Advanced Parsing Features

316

317

```python

318

from flask_restplus import reqparse

319

320

# Bundle all validation errors

321

parser = reqparse.RequestParser(bundle_errors=True)

322

323

parser.add_argument('name', type=str, required=True, trim=True)

324

parser.add_argument('email', type=str, required=True)

325

parser.add_argument('age', type=int, required=True)

326

327

@api.route('/users')

328

class UserCreate(Resource):

329

@api.expect(parser)

330

def post(self):

331

try:

332

args = parser.parse_args()

333

# All arguments validated successfully

334

return {'message': 'User created', 'data': args}, 201

335

except Exception as e:

336

# Returns all validation errors at once:

337

# {

338

# "message": "Input payload validation failed",

339

# "errors": {

340

# "name": "Name is required",

341

# "email": "Email is required",

342

# "age": "Age must be an integer"

343

# }

344

# }

345

return {'error': str(e)}, 400

346

```

347

348

### Parser Inheritance and Modification

349

350

```python

351

from flask_restplus import reqparse

352

353

# Base parser with common arguments

354

base_parser = reqparse.RequestParser()

355

base_parser.add_argument('page', type=int, location='args', default=1)

356

base_parser.add_argument('per_page', type=int, location='args', default=10)

357

358

# Create specialized parsers by copying

359

user_parser = base_parser.copy()

360

user_parser.add_argument('name', type=str, location='args')

361

user_parser.add_argument('active', type=bool, location='args')

362

363

product_parser = base_parser.copy()

364

product_parser.add_argument('category', type=str, location='args')

365

product_parser.add_argument('min_price', type=float, location='args')

366

product_parser.add_argument('max_price', type=float, location='args')

367

368

# Modify existing arguments

369

user_parser.replace_argument('per_page', type=int, default=20, help='Users per page')

370

371

# Remove arguments

372

user_parser.remove_argument('page') # Remove pagination

373

```

374

375

### File Upload Handling

376

377

```python

378

from flask_restplus import reqparse

379

from werkzeug.datastructures import FileStorage

380

381

upload_parser = reqparse.RequestParser()

382

383

# Single file upload

384

upload_parser.add_argument('file',

385

location='files',

386

type=FileStorage,

387

required=True,

388

help='File to upload')

389

390

# Multiple file uploads

391

upload_parser.add_argument('attachments',

392

location='files',

393

type=FileStorage,

394

action='append',

395

help='Multiple files can be uploaded')

396

397

@api.route('/upload')

398

class FileUpload(Resource):

399

@api.expect(upload_parser)

400

def post(self):

401

args = upload_parser.parse_args()

402

uploaded_file = args['file']

403

404

if uploaded_file and uploaded_file.filename:

405

# Save the file

406

filename = secure_filename(uploaded_file.filename)

407

uploaded_file.save(os.path.join('/uploads', filename))

408

return {'message': f'File {filename} uploaded successfully'}, 201

409

410

return {'error': 'No file provided'}, 400

411

```

412

413

### Integration with API Documentation

414

415

```python

416

from flask_restplus import Api, Resource, reqparse, fields

417

418

api = Api()

419

420

# Parser automatically generates Swagger documentation

421

user_parser = reqparse.RequestParser()

422

user_parser.add_argument('name',

423

type=str,

424

required=True,

425

help='User full name (required)')

426

user_parser.add_argument('email',

427

type=str,

428

required=True,

429

help='User email address (required)')

430

user_parser.add_argument('age',

431

type=int,

432

help='User age (optional)')

433

user_parser.add_argument('active',

434

type=bool,

435

default=True,

436

help='Account status (default: true)')

437

438

@api.route('/users')

439

class UserList(Resource):

440

@api.expect(user_parser) # Documents expected parameters

441

def post(self):

442

"""Create a new user"""

443

args = user_parser.parse_args()

444

# Implementation...

445

return {'message': 'User created'}, 201

446

```

447

448

### Error Handling and Validation

449

450

```python

451

from flask_restplus import reqparse, abort

452

453

parser = reqparse.RequestParser()

454

455

def validate_positive_int(value):

456

"""Custom validator for positive integers."""

457

try:

458

int_value = int(value)

459

if int_value <= 0:

460

raise ValueError("Must be a positive integer")

461

return int_value

462

except (ValueError, TypeError):

463

raise ValueError("Must be a valid positive integer")

464

465

parser.add_argument('quantity',

466

type=validate_positive_int,

467

required=True,

468

help='Quantity must be a positive integer')

469

470

@api.route('/orders')

471

class OrderCreate(Resource):

472

@api.expect(parser)

473

def post(self):

474

try:

475

args = parser.parse_args()

476

quantity = args['quantity']

477

# Process order...

478

return {'message': f'Order created for {quantity} items'}, 201

479

except Exception as e:

480

# Validation errors are automatically handled by Flask-RESTPlus

481

# and return appropriate error responses

482

abort(400, message=str(e))

483

```

484

485

### Complex Nested Parsing

486

487

```python

488

from flask_restplus import reqparse

489

import json

490

491

parser = reqparse.RequestParser()

492

493

def json_type(value):

494

"""Parse JSON string into Python object."""

495

try:

496

return json.loads(value)

497

except (json.JSONDecodeError, TypeError):

498

raise ValueError("Must be valid JSON")

499

500

# Accept complex nested data as JSON strings

501

parser.add_argument('metadata',

502

type=json_type,

503

location='json',

504

help='Metadata as JSON object')

505

506

parser.add_argument('settings',

507

type=json_type,

508

location=['json', 'form'],

509

help='Settings configuration as JSON')

510

511

@api.route('/configure')

512

class Configuration(Resource):

513

@api.expect(parser)

514

def post(self):

515

args = parser.parse_args()

516

metadata = args['metadata'] # Already parsed as dict/list

517

settings = args['settings'] # Already parsed as dict/list

518

519

# Use the parsed objects directly

520

return {

521

'message': 'Configuration updated',

522

'metadata_keys': list(metadata.keys()) if isinstance(metadata, dict) else [],

523

'settings_keys': list(settings.keys()) if isinstance(settings, dict) else []

524

}, 200

525

```