or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

applications.mdcli.mdexceptions.mdindex.mdoperation-resolution.mdrequest-response.mdsecurity.mdvalidation.md

validation.mddocs/

0

# Validation System

1

2

Automatic request and response validation based on OpenAPI schema definitions. Connexion provides comprehensive validation for various content types with customizable validation strategies.

3

4

## Capabilities

5

6

### Validator Mapping

7

8

Central registry of validators for different content types and validation scenarios.

9

10

```python { .api }

11

VALIDATOR_MAP: dict

12

"""

13

Global mapping of validation types to validator classes.

14

Keys include:

15

- 'body': Request body validators by content type

16

- 'parameter': Parameter validators

17

- 'response': Response validators by content type

18

"""

19

```

20

21

### Abstract Base Validators

22

23

Base classes for implementing custom validators.

24

25

```python { .api }

26

class AbstractRequestBodyValidator:

27

"""Base class for request body validators"""

28

29

def __init__(self, schema: dict, validator=None, **kwargs):

30

"""

31

Initialize request body validator.

32

33

Parameters:

34

- schema: JSON schema for validation

35

- validator: Custom validator instance

36

- **kwargs: Additional validator options

37

"""

38

39

def validate_schema(self, body, url: str) -> dict:

40

"""

41

Validate request body against schema.

42

43

Parameters:

44

- body: Request body to validate

45

- url: Request URL for error context

46

47

Returns:

48

dict: Validated and possibly transformed body

49

50

Raises:

51

BadRequestProblem: If validation fails

52

"""

53

54

@classmethod

55

def validate_formdata_parameter_list(cls, request_body: dict) -> dict:

56

"""

57

Validate form data parameters.

58

59

Parameters:

60

- request_body: Form data dictionary

61

62

Returns:

63

dict: Validated form data

64

"""

65

66

class AbstractParameterValidator:

67

"""Base class for parameter validators"""

68

69

def __init__(self, parameters: list, uri_parser=None, **kwargs):

70

"""

71

Initialize parameter validator.

72

73

Parameters:

74

- parameters: List of parameter definitions

75

- uri_parser: URI parsing utility

76

- **kwargs: Additional options

77

"""

78

79

def validate_query_parameter_list(self, request) -> dict:

80

"""

81

Validate query parameters.

82

83

Parameters:

84

- request: Request object

85

86

Returns:

87

dict: Validated query parameters

88

"""

89

90

def validate_path_parameter_list(self, request) -> dict:

91

"""

92

Validate path parameters.

93

94

Parameters:

95

- request: Request object

96

97

Returns:

98

dict: Validated path parameters

99

"""

100

101

def validate_header_parameter_list(self, request) -> dict:

102

"""

103

Validate header parameters.

104

105

Parameters:

106

- request: Request object

107

108

Returns:

109

dict: Validated header parameters

110

"""

111

112

class AbstractResponseBodyValidator:

113

"""Base class for response body validators"""

114

115

def __init__(self, schema: dict, validator=None, **kwargs):

116

"""

117

Initialize response body validator.

118

119

Parameters:

120

- schema: JSON schema for validation

121

- validator: Custom validator instance

122

- **kwargs: Additional options

123

"""

124

125

def validate_schema(self, data, url: str) -> dict:

126

"""

127

Validate response body against schema.

128

129

Parameters:

130

- data: Response data to validate

131

- url: Request URL for error context

132

133

Returns:

134

dict: Validated response data

135

136

Raises:

137

InternalServerError: If validation fails

138

"""

139

```

140

141

### Request Body Validators

142

143

Concrete validators for different request content types.

144

145

```python { .api }

146

class JSONRequestBodyValidator(AbstractRequestBodyValidator):

147

"""Validator for application/json request bodies"""

148

149

def validate_schema(self, body, url: str) -> dict:

150

"""Validate JSON request body against OpenAPI schema"""

151

152

class FormDataValidator(AbstractRequestBodyValidator):

153

"""Validator for application/x-www-form-urlencoded request bodies"""

154

155

def validate_schema(self, body, url: str) -> dict:

156

"""Validate form data against OpenAPI schema"""

157

158

class MultiPartFormDataValidator(AbstractRequestBodyValidator):

159

"""Validator for multipart/form-data request bodies"""

160

161

def validate_schema(self, body, url: str) -> dict:

162

"""Validate multipart form data including file uploads"""

163

```

164

165

### Parameter Validators

166

167

Validators for URL parameters, query strings, and headers.

168

169

```python { .api }

170

class ParameterValidator(AbstractParameterValidator):

171

"""Validator for URL path, query, and header parameters"""

172

173

def validate_query_parameter_list(self, request) -> dict:

174

"""

175

Validate query parameters against OpenAPI parameter definitions.

176

Handles type coercion, required parameter checking, and format validation.

177

"""

178

179

def validate_path_parameter_list(self, request) -> dict:

180

"""

181

Validate path parameters against OpenAPI parameter definitions.

182

Performs type conversion and validation.

183

"""

184

185

def validate_header_parameter_list(self, request) -> dict:

186

"""

187

Validate header parameters against OpenAPI parameter definitions.

188

Handles case-insensitive header names and type validation.

189

"""

190

```

191

192

### Response Validators

193

194

Validators for response data validation.

195

196

```python { .api }

197

class JSONResponseBodyValidator(AbstractResponseBodyValidator):

198

"""Validator for JSON response bodies"""

199

200

def validate_schema(self, data, url: str) -> dict:

201

"""

202

Validate JSON response data against OpenAPI response schema.

203

Ensures API responses match the specification.

204

"""

205

```

206

207

### Validation Configuration

208

209

Configuration options for validation behavior.

210

211

```python { .api }

212

class ValidationOptions:

213

"""Configuration for validation behavior"""

214

215

def __init__(

216

self,

217

strict_validation: bool = False,

218

validate_responses: bool = False,

219

pythonic_params: bool = False

220

):

221

"""

222

Initialize validation options.

223

224

Parameters:

225

- strict_validation: Enable strict validation mode

226

- validate_responses: Enable response validation

227

- pythonic_params: Convert parameter names to pythonic style

228

"""

229

```

230

231

## Usage Examples

232

233

### Custom Request Body Validator

234

235

```python

236

from connexion.validators import AbstractRequestBodyValidator

237

from connexion.exceptions import BadRequestProblem

238

239

class CustomJSONValidator(AbstractRequestBodyValidator):

240

"""Custom JSON validator with additional business rules"""

241

242

def validate_schema(self, body, url):

243

# First run standard JSON schema validation

244

validated_body = super().validate_schema(body, url)

245

246

# Add custom validation rules

247

if 'email' in validated_body:

248

email = validated_body['email']

249

if not self.is_valid_email(email):

250

raise BadRequestProblem(

251

detail=f"Invalid email format: {email}"

252

)

253

254

# Check for business rule violations

255

if validated_body.get('age', 0) < 0:

256

raise BadRequestProblem(

257

detail="Age cannot be negative"

258

)

259

260

return validated_body

261

262

def is_valid_email(self, email):

263

# Custom email validation logic

264

return '@' in email and '.' in email

265

266

# Register custom validator

267

from connexion.validators import VALIDATOR_MAP

268

VALIDATOR_MAP['body']['application/json'] = CustomJSONValidator

269

```

270

271

### Custom Parameter Validator

272

273

```python

274

from connexion.validators import AbstractParameterValidator

275

from connexion.exceptions import BadRequestProblem

276

277

class EnhancedParameterValidator(AbstractParameterValidator):

278

"""Parameter validator with enhanced type coercion"""

279

280

def validate_query_parameter_list(self, request):

281

validated_params = super().validate_query_parameter_list(request)

282

283

# Custom parameter processing

284

if 'date_range' in validated_params:

285

date_range = validated_params['date_range']

286

try:

287

start, end = date_range.split(',')

288

validated_params['start_date'] = datetime.fromisoformat(start)

289

validated_params['end_date'] = datetime.fromisoformat(end)

290

del validated_params['date_range']

291

except ValueError:

292

raise BadRequestProblem(

293

detail="Invalid date range format. Use: YYYY-MM-DD,YYYY-MM-DD"

294

)

295

296

return validated_params

297

298

# Use custom validator

299

app.add_api(

300

'api.yaml',

301

validator_map={

302

'parameter': EnhancedParameterValidator

303

}

304

)

305

```

306

307

### Response Validation

308

309

```python

310

from connexion import AsyncApp

311

312

# Enable response validation

313

app = AsyncApp(__name__, validate_responses=True)

314

app.add_api('api.yaml')

315

316

# Responses that don't match the OpenAPI schema will raise errors

317

def get_user(user_id):

318

# This response must match the OpenAPI response schema

319

return {

320

"id": user_id,

321

"name": "John Doe",

322

"email": "john@example.com"

323

}

324

```

325

326

### Validation Error Handling

327

328

```python

329

from connexion.exceptions import BadRequestProblem, ValidationError

330

331

def custom_validation_error_handler(exception):

332

"""Handle validation errors with custom responses"""

333

334

if isinstance(exception, ValidationError):

335

return {

336

"error": "Validation failed",

337

"details": str(exception),

338

"field": getattr(exception, 'field', None)

339

}, 400

340

341

return {"error": "Bad request"}, 400

342

343

app.add_error_handler(ValidationError, custom_validation_error_handler)

344

```

345

346

### Strict Validation Mode

347

348

```python

349

# Enable strict validation for all APIs

350

app = AsyncApp(__name__, strict_validation=True)

351

352

# Or per API

353

app.add_api('api.yaml', strict_validation=True)

354

355

# Strict mode enforces:

356

# - All required parameters must be present

357

# - No additional properties in request bodies (if additionalProperties: false)

358

# - Exact type matching

359

# - Format validation (email, date, etc.)

360

```

361

362

### Pythonic Parameter Names

363

364

```python

365

# Enable pythonic parameter conversion

366

app = AsyncApp(__name__, pythonic_params=True)

367

368

# OpenAPI parameter: user-id becomes user_id in Python function

369

def get_user(user_id: int): # Maps from user-id parameter

370

return {"user_id": user_id}

371

372

# Query parameter: max-results becomes max_results

373

def search_users(max_results: int = 10):

374

return {"results": [], "limit": max_results}

375

```

376

377

### File Upload Validation

378

379

```python

380

from connexion.validators import MultiPartFormDataValidator

381

382

def upload_avatar():

383

# Validation automatically handles:

384

# - File size limits (if specified in OpenAPI)

385

# - Content type validation

386

# - Required file fields

387

388

file = request.files['avatar']

389

390

# Additional custom validation

391

if file.content_type not in ['image/jpeg', 'image/png']:

392

raise BadRequestProblem(

393

detail="Only JPEG and PNG images allowed"

394

)

395

396

if len(file.read()) > 5 * 1024 * 1024: # 5MB limit

397

raise BadRequestProblem(

398

detail="File size must be less than 5MB"

399

)

400

401

# Process file...

402

return {"status": "uploaded"}, 201

403

```

404

405

### Custom Validator Integration

406

407

```python

408

from connexion.validators import VALIDATOR_MAP

409

410

# Register custom validators globally

411

VALIDATOR_MAP['body']['application/xml'] = XMLValidator

412

VALIDATOR_MAP['body']['text/csv'] = CSVValidator

413

VALIDATOR_MAP['parameter'] = CustomParameterValidator

414

415

# Or use per-API validator mapping

416

custom_validators = {

417

'body': {

418

'application/json': CustomJSONValidator,

419

'multipart/form-data': CustomMultipartValidator

420

},

421

'parameter': EnhancedParameterValidator,

422

'response': {

423

'application/json': StrictJSONResponseValidator

424

}

425

}

426

427

app.add_api('api.yaml', validator_map=custom_validators)

428

```