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

input-validation.mddocs/

0

# Input Validation

1

2

Pre-built validation functions for common input types including emails, URLs, IP addresses, dates, and custom regular expression patterns. Flask-RESTPlus provides a comprehensive set of input validators that can be used with request parsing and field validation.

3

4

## Capabilities

5

6

### Network Address Validation

7

8

Functions for validating IP addresses and network-related inputs.

9

10

```python { .api }

11

def ipv4(value):

12

"""

13

Validate IPv4 addresses.

14

15

Args:

16

value (str): IP address string to validate

17

18

Returns:

19

str: Validated IPv4 address

20

21

Raises:

22

ValueError: If not a valid IPv4 address

23

"""

24

25

def ipv6(value):

26

"""

27

Validate IPv6 addresses.

28

29

Args:

30

value (str): IP address string to validate

31

32

Returns:

33

str: Validated IPv6 address

34

35

Raises:

36

ValueError: If not a valid IPv6 address

37

"""

38

39

def ip(value):

40

"""

41

Validate IP addresses (both IPv4 and IPv6).

42

43

Args:

44

value (str): IP address string to validate

45

46

Returns:

47

str: Validated IP address

48

49

Raises:

50

ValueError: If not a valid IP address

51

"""

52

```

53

54

### Date and Time Validation

55

56

Functions for parsing and validating date and time formats.

57

58

```python { .api }

59

def date(value):

60

"""

61

Parse date strings in YYYY-MM-DD format.

62

63

Args:

64

value (str): Date string to parse

65

66

Returns:

67

datetime.date: Parsed date object

68

69

Raises:

70

ValueError: If not a valid date format

71

"""

72

73

def datetime_from_rfc822(value):

74

"""

75

Parse RFC822 format datetime strings.

76

77

Args:

78

value (str): RFC822 datetime string

79

80

Returns:

81

datetime.datetime: Parsed datetime object

82

83

Raises:

84

ValueError: If not a valid RFC822 datetime

85

"""

86

87

def datetime_from_iso8601(value):

88

"""

89

Parse ISO8601 format datetime strings.

90

91

Args:

92

value (str): ISO8601 datetime string

93

94

Returns:

95

datetime.datetime: Parsed datetime object

96

97

Raises:

98

ValueError: If not a valid ISO8601 datetime

99

"""

100

101

def date_from_iso8601(value):

102

"""

103

Parse ISO8601 format date strings.

104

105

Args:

106

value (str): ISO8601 date string

107

108

Returns:

109

datetime.date: Parsed date object

110

111

Raises:

112

ValueError: If not a valid ISO8601 date

113

"""

114

115

def iso8601interval(value, argument='argument'):

116

"""

117

Parse ISO8601 interval strings.

118

119

Args:

120

value (str): ISO8601 interval string

121

argument (str): Argument name for error messages

122

123

Returns:

124

dict: Parsed interval with 'start' and 'end' datetime objects

125

126

Raises:

127

ValueError: If not a valid ISO8601 interval

128

"""

129

```

130

131

### Numeric Validation

132

133

Functions for validating numeric inputs with constraints.

134

135

```python { .api }

136

def natural(value, argument='argument'):

137

"""

138

Validate natural numbers (non-negative integers >= 0).

139

140

Args:

141

value (str or int): Value to validate

142

argument (str): Argument name for error messages

143

144

Returns:

145

int: Validated natural number

146

147

Raises:

148

ValueError: If not a natural number

149

"""

150

151

def positive(value, argument='argument'):

152

"""

153

Validate positive integers (>= 1).

154

155

Args:

156

value (str or int): Value to validate

157

argument (str): Argument name for error messages

158

159

Returns:

160

int: Validated positive integer

161

162

Raises:

163

ValueError: If not a positive integer

164

"""

165

166

def boolean(value):

167

"""

168

Parse boolean values from various string representations.

169

170

Accepts: 'true', 'false', '1', '0', 'yes', 'no', 'on', 'off' (case insensitive)

171

172

Args:

173

value (str or bool): Value to parse

174

175

Returns:

176

bool: Parsed boolean value

177

178

Raises:

179

ValueError: If not a valid boolean representation

180

"""

181

```

182

183

### Validator Classes

184

185

Configurable validator classes for complex validation scenarios.

186

187

```python { .api }

188

class URL:

189

def __init__(self, check=False, ip=False, local=False, port=False,

190

auth=False, schemes=None, domains=None, exclude=None):

191

"""

192

Configurable URL validator.

193

194

Args:

195

check (bool): Perform additional URL checks

196

ip (bool): Allow IP addresses as hostnames

197

local (bool): Allow local/private URLs

198

port (bool): Require port number

199

auth (bool): Allow authentication in URL

200

schemes (list, optional): Allowed URL schemes

201

domains (list, optional): Allowed domains

202

exclude (list, optional): Excluded domains

203

"""

204

205

def __call__(self, value):

206

"""

207

Validate URL string.

208

209

Args:

210

value (str): URL string to validate

211

212

Returns:

213

str: Validated URL

214

215

Raises:

216

ValueError: If URL doesn't meet validation criteria

217

"""

218

219

class email:

220

def __init__(self, check=False, ip=False, local=False, domains=None, exclude=None):

221

"""

222

Email address validator with domain checking.

223

224

Args:

225

check (bool): Perform additional email checks

226

ip (bool): Allow IP addresses as domains

227

local (bool): Allow local email addresses

228

domains (list, optional): Allowed domains

229

exclude (list, optional): Excluded domains

230

"""

231

232

def __call__(self, value):

233

"""

234

Validate email address.

235

236

Args:

237

value (str): Email address to validate

238

239

Returns:

240

str: Validated email address

241

242

Raises:

243

ValueError: If email doesn't meet validation criteria

244

"""

245

246

class regex:

247

def __init__(self, pattern):

248

"""

249

Regular expression validator.

250

251

Args:

252

pattern (str): Regular expression pattern

253

"""

254

255

def __call__(self, value):

256

"""

257

Validate value against regular expression.

258

259

Args:

260

value (str): Value to validate

261

262

Returns:

263

str: Validated value

264

265

Raises:

266

ValueError: If value doesn't match pattern

267

"""

268

269

class int_range:

270

def __init__(self, low, high, argument='argument'):

271

"""

272

Integer range validator.

273

274

Args:

275

low (int): Minimum value (inclusive)

276

high (int): Maximum value (inclusive)

277

argument (str): Argument name for error messages

278

"""

279

280

def __call__(self, value):

281

"""

282

Validate integer is within range.

283

284

Args:

285

value (str or int): Value to validate

286

287

Returns:

288

int: Validated integer

289

290

Raises:

291

ValueError: If integer is outside range

292

"""

293

```

294

295

### Pre-configured Validators

296

297

Ready-to-use validator instances for common use cases.

298

299

```python { .api }

300

url: URL # Pre-configured URL validator instance

301

```

302

303

### Time Constants

304

305

Constants for time-based validation and processing.

306

307

```python { .api }

308

START_OF_DAY: datetime.time # Time representing start of day (00:00:00)

309

END_OF_DAY: datetime.time # Time representing end of day (23:59:59)

310

```

311

312

## Usage Examples

313

314

### Basic Input Validation

315

316

```python

317

from flask_restplus import Api, Resource, reqparse, inputs

318

319

api = Api()

320

321

parser = reqparse.RequestParser()

322

323

# IP address validation

324

parser.add_argument('server_ip', type=inputs.ipv4, required=True)

325

parser.add_argument('client_ip', type=inputs.ip) # IPv4 or IPv6

326

327

# Date validation

328

parser.add_argument('start_date', type=inputs.date)

329

parser.add_argument('created_at', type=inputs.datetime_from_iso8601)

330

331

# Numeric validation

332

parser.add_argument('page', type=inputs.natural, default=0)

333

parser.add_argument('count', type=inputs.positive, required=True)

334

335

# Boolean validation

336

parser.add_argument('active', type=inputs.boolean, default=True)

337

338

@api.route('/search')

339

class Search(Resource):

340

@api.expect(parser)

341

def get(self):

342

args = parser.parse_args()

343

return {

344

'server_ip': args['server_ip'],

345

'page': args['page'],

346

'count': args['count'],

347

'active': args['active']

348

}

349

```

350

351

### Email and URL Validation

352

353

```python

354

from flask_restplus import reqparse, inputs

355

356

parser = reqparse.RequestParser()

357

358

# Basic email validation

359

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

360

361

# Email with domain restrictions

362

allowed_email = inputs.email(domains=['company.com', 'partner.org'])

363

parser.add_argument('work_email', type=allowed_email)

364

365

# Email excluding certain domains

366

restricted_email = inputs.email(exclude=['spam.com', 'temp-mail.org'])

367

parser.add_argument('user_email', type=restricted_email)

368

369

# Basic URL validation

370

parser.add_argument('website', type=inputs.url)

371

372

# URL with restrictions

373

secure_url = inputs.URL(schemes=['https'], check=True)

374

parser.add_argument('secure_website', type=secure_url)

375

376

# URL allowing local addresses

377

local_url = inputs.URL(local=True, ip=True)

378

parser.add_argument('internal_url', type=local_url)

379

```

380

381

### Regular Expression Validation

382

383

```python

384

from flask_restplus import reqparse, inputs

385

386

parser = reqparse.RequestParser()

387

388

# Phone number validation (US format)

389

phone_validator = inputs.regex(r'^\+?1?[2-9]\d{2}[2-9]\d{2}\d{4}$')

390

parser.add_argument('phone', type=phone_validator)

391

392

# Username validation (alphanumeric + underscore, 3-20 chars)

393

username_validator = inputs.regex(r'^[a-zA-Z0-9_]{3,20}$')

394

parser.add_argument('username', type=username_validator, required=True)

395

396

# Color hex code validation

397

color_validator = inputs.regex(r'^#[0-9A-Fa-f]{6}$')

398

parser.add_argument('color', type=color_validator)

399

400

# UUID validation

401

uuid_validator = inputs.regex(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$')

402

parser.add_argument('uuid', type=uuid_validator)

403

404

@api.route('/profile')

405

class Profile(Resource):

406

@api.expect(parser)

407

def post(self):

408

args = parser.parse_args()

409

return {'message': 'Profile updated', 'data': args}

410

```

411

412

### Range Validation

413

414

```python

415

from flask_restplus import reqparse, inputs

416

417

parser = reqparse.RequestParser()

418

419

# Age validation (0-150)

420

age_validator = inputs.int_range(0, 150, argument='age')

421

parser.add_argument('age', type=age_validator)

422

423

# Percentage validation (0-100)

424

percentage_validator = inputs.int_range(0, 100, argument='percentage')

425

parser.add_argument('completion', type=percentage_validator)

426

427

# Port number validation (1-65535)

428

port_validator = inputs.int_range(1, 65535, argument='port')

429

parser.add_argument('port', type=port_validator)

430

431

# Priority levels (1-10)

432

priority_validator = inputs.int_range(1, 10, argument='priority')

433

parser.add_argument('priority', type=priority_validator, default=5)

434

```

435

436

### Date and Time Parsing

437

438

```python

439

from flask_restplus import reqparse, inputs

440

from datetime import datetime, date

441

442

parser = reqparse.RequestParser()

443

444

# Simple date parsing (YYYY-MM-DD)

445

parser.add_argument('birth_date', type=inputs.date)

446

447

# ISO8601 datetime parsing

448

parser.add_argument('event_time', type=inputs.datetime_from_iso8601)

449

450

# RFC822 datetime parsing

451

parser.add_argument('mail_date', type=inputs.datetime_from_rfc822)

452

453

# ISO8601 interval parsing

454

parser.add_argument('time_range', type=inputs.iso8601interval)

455

456

@api.route('/events')

457

class Events(Resource):

458

@api.expect(parser)

459

def post(self):

460

args = parser.parse_args()

461

462

# dates are automatically parsed to Python objects

463

birth_date = args['birth_date'] # datetime.date object

464

event_time = args['event_time'] # datetime.datetime object

465

466

return {

467

'birth_date': birth_date.isoformat() if birth_date else None,

468

'event_time': event_time.isoformat() if event_time else None,

469

'age_years': (date.today() - birth_date).days // 365 if birth_date else None

470

}

471

```

472

473

### Custom Validation Functions

474

475

```python

476

from flask_restplus import reqparse

477

import re

478

479

def validate_password(value):

480

"""

481

Validate password strength.

482

483

Requirements:

484

- At least 8 characters

485

- Contains uppercase and lowercase letters

486

- Contains at least one digit

487

- Contains at least one special character

488

"""

489

if len(value) < 8:

490

raise ValueError("Password must be at least 8 characters long")

491

492

if not re.search(r'[A-Z]', value):

493

raise ValueError("Password must contain at least one uppercase letter")

494

495

if not re.search(r'[a-z]', value):

496

raise ValueError("Password must contain at least one lowercase letter")

497

498

if not re.search(r'\d', value):

499

raise ValueError("Password must contain at least one digit")

500

501

if not re.search(r'[!@#$%^&*(),.?":{}|<>]', value):

502

raise ValueError("Password must contain at least one special character")

503

504

return value

505

506

def validate_credit_card(value):

507

"""Validate credit card number using Luhn algorithm."""

508

# Remove spaces and dashes

509

card_number = re.sub(r'[^0-9]', '', value)

510

511

if not card_number.isdigit():

512

raise ValueError("Credit card number must contain only digits")

513

514

if len(card_number) < 13 or len(card_number) > 19:

515

raise ValueError("Credit card number must be 13-19 digits long")

516

517

# Luhn algorithm

518

def luhn_check(card_num):

519

digits = [int(d) for d in card_num]

520

for i in range(len(digits) - 2, -1, -2):

521

digits[i] *= 2

522

if digits[i] > 9:

523

digits[i] -= 9

524

return sum(digits) % 10 == 0

525

526

if not luhn_check(card_number):

527

raise ValueError("Invalid credit card number")

528

529

return card_number

530

531

parser = reqparse.RequestParser()

532

parser.add_argument('password', type=validate_password, required=True)

533

parser.add_argument('card_number', type=validate_credit_card)

534

```

535

536

### Boolean Input Handling

537

538

```python

539

from flask_restplus import reqparse, inputs

540

541

parser = reqparse.RequestParser()

542

543

# Boolean inputs accept various formats

544

parser.add_argument('active', type=inputs.boolean)

545

parser.add_argument('verified', type=inputs.boolean, default=False)

546

parser.add_argument('premium', type=inputs.boolean)

547

548

@api.route('/user-settings')

549

class UserSettings(Resource):

550

@api.expect(parser)

551

def put(self):

552

args = parser.parse_args()

553

554

# These all work for boolean inputs:

555

# active=true, active=True, active=1, active=yes, active=on

556

# active=false, active=False, active=0, active=no, active=off

557

558

return {

559

'settings_updated': True,

560

'active': args['active'],

561

'verified': args['verified'],

562

'premium': args['premium']

563

}

564

```

565

566

### Field Integration

567

568

```python

569

from flask_restplus import Api, fields, inputs

570

571

api = Api()

572

573

# Using validators in field definitions

574

user_model = api.model('User', {

575

'id': fields.Integer(required=True),

576

'email': fields.String(required=True, validate=inputs.email()),

577

'website': fields.String(validate=inputs.url),

578

'age': fields.Integer(validate=inputs.int_range(13, 120, 'age')),

579

'active': fields.Boolean(validate=inputs.boolean)

580

})

581

582

# Custom field with validation

583

class EmailField(fields.String):

584

def __init__(self, **kwargs):

585

super().__init__(**kwargs)

586

self.validate = inputs.email()

587

588

class URLField(fields.String):

589

def __init__(self, **kwargs):

590

super().__init__(**kwargs)

591

self.validate = inputs.URL(schemes=['http', 'https'])

592

593

# Using custom fields

594

profile_model = api.model('Profile', {

595

'name': fields.String(required=True),

596

'email': EmailField(required=True),

597

'website': URLField(),

598

'birth_date': fields.Date(validate=inputs.date)

599

})

600

```