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

models-marshalling.mddocs/

0

# Models and Marshalling

1

2

Data model definition and automatic marshalling system for request/response handling. Flask-RESTPlus provides model classes for defining data structures and marshalling functions for automatic serialization and validation.

3

4

## Capabilities

5

6

### Model Classes

7

8

Base classes for defining data models used in request validation and response marshalling.

9

10

```python { .api }

11

class Model(dict):

12

def __init__(self, name, *args, mask=None, **kwargs):

13

"""

14

Initialize a field-based model.

15

16

Args:

17

name (str): Model name for documentation

18

*args: Additional positional arguments

19

mask (str or Mask, optional): Default model mask

20

**kwargs: Field definitions

21

"""

22

23

@classmethod

24

def inherit(cls, name, *parents):

25

"""

26

Create a new model inheriting from parent models using Swagger composition.

27

28

Args:

29

name (str): New model name

30

*parents (Model): Parent models to inherit from

31

32

Returns:

33

Model: New inherited model

34

"""

35

36

def clone(self, name=None, *parents):

37

"""

38

Clone this model by duplicating all fields.

39

40

Args:

41

name (str, optional): New model name

42

*parents (Model): Additional parent models

43

44

Returns:

45

Model: Cloned model

46

"""

47

48

def validate(self, data, resolver=None, format_checker=None):

49

"""

50

Validate data against the model schema.

51

52

Args:

53

data: Data to validate

54

resolver: JSON schema resolver

55

format_checker: JSON schema format checker

56

57

Raises:

58

ValidationError: If validation fails

59

"""

60

61

def get_parent(self, name):

62

"""

63

Get a parent model by name.

64

65

Args:

66

name (str): Parent model name

67

68

Returns:

69

Model: Parent model instance

70

"""

71

72

@property

73

def ancestors(self):

74

"""

75

Return the inheritance tree as a set.

76

77

Returns:

78

set: Set of ancestor model names

79

"""

80

81

@property

82

def __schema__(self):

83

"""

84

Return the JSON Schema representation.

85

86

Returns:

87

dict: JSON Schema with inheritance support

88

"""

89

90

@property

91

def resolved(self):

92

"""

93

Get the resolved model definition.

94

95

Returns:

96

dict: Resolved field definitions

97

"""

98

99

class OrderedModel(Model):

100

def __init__(self, name, *args, mask=None, **kwargs):

101

"""

102

Initialize an ordered model that preserves field insertion order.

103

Inherits all methods from Model but maintains field ordering.

104

105

Args:

106

name (str): Model name for documentation

107

*args: Additional positional arguments

108

mask (str or Mask, optional): Default model mask

109

**kwargs: Field definitions in order

110

"""

111

112

class SchemaModel:

113

def __init__(self, name, schema=None):

114

"""

115

Initialize a model based on a JSON schema definition.

116

Unlike Model/OrderedModel, this doesn't manage fields directly.

117

118

Args:

119

name (str): Model name for documentation

120

schema (dict, optional): JSON schema definition

121

"""

122

123

@classmethod

124

def inherit(cls, name, *parents):

125

"""

126

Create a new schema model inheriting from parent models.

127

128

Args:

129

name (str): New model name

130

*parents (SchemaModel): Parent models to inherit from

131

132

Returns:

133

SchemaModel: New inherited model

134

"""

135

136

def validate(self, data, resolver=None, format_checker=None):

137

"""

138

Validate data against the schema.

139

140

Args:

141

data: Data to validate

142

resolver: JSON schema resolver

143

format_checker: JSON schema format checker

144

145

Raises:

146

ValidationError: If validation fails

147

"""

148

149

@property

150

def __schema__(self):

151

"""

152

Return the stored JSON schema.

153

154

Returns:

155

dict: JSON Schema definition

156

"""

157

158

@property

159

def ancestors(self):

160

"""

161

Return the inheritance tree as a set.

162

163

Returns:

164

set: Set of ancestor model names

165

"""

166

```

167

168

### Marshalling Functions

169

170

Functions for serializing Python objects to JSON responses using field definitions.

171

172

```python { .api }

173

def marshal(data, fields, envelope=None, skip_none=False, mask=None, ordered=False):

174

"""

175

Marshal data using field definitions.

176

177

Args:

178

data: The data to marshal (dict, list, or object)

179

fields (dict): Field definitions for marshalling

180

envelope (str, optional): Envelope key for response wrapping

181

skip_none (bool): Skip None values in output

182

mask (str, optional): Field mask for partial responses

183

ordered (bool): Preserve field ordering

184

185

Returns:

186

dict or list: Marshalled data

187

"""

188

189

def marshal_with(fields, as_list=False, code=200, description=None, **kwargs):

190

"""

191

Decorator for automatic response marshalling.

192

193

Args:

194

fields (dict or Model): Fields for marshalling

195

as_list (bool): Marshal response as a list

196

code (int): HTTP status code for successful response

197

description (str, optional): Response description

198

**kwargs: Additional marshal options (envelope, skip_none, mask, ordered)

199

200

Returns:

201

callable: Decorator function

202

"""

203

204

def marshal_with_field(field, **kwargs):

205

"""

206

Decorator for marshalling with a single field.

207

208

Args:

209

field (Field): Single field for marshalling

210

**kwargs: Additional marshal options

211

212

Returns:

213

callable: Decorator function

214

"""

215

```

216

217

### Response Masking

218

219

Response field masking system for partial responses and field filtering.

220

221

```python { .api }

222

class Mask:

223

def __init__(self, mask=None, skip=False, **kwargs):

224

"""

225

Initialize a field mask.

226

227

Args:

228

mask (str, optional): Mask string (e.g., "field1,field2{subfield}")

229

skip (bool): Skip masked fields instead of including them

230

**kwargs: Additional mask options

231

"""

232

233

def parse(self, mask):

234

"""

235

Parse a mask string.

236

237

Args:

238

mask (str): Mask string to parse

239

240

Returns:

241

dict: Parsed mask structure

242

"""

243

244

def apply(self, data):

245

"""

246

Apply the mask to data.

247

248

Args:

249

data: Data to mask

250

251

Returns:

252

Masked data

253

"""

254

255

def filter_data(self, data):

256

"""

257

Filter data according to the mask.

258

259

Args:

260

data: Data to filter

261

262

Returns:

263

Filtered data

264

"""

265

266

def apply_mask(data, mask, skip=False):

267

"""

268

Apply a field mask to data.

269

270

Args:

271

data: Data to mask

272

mask (str or Mask): Field mask

273

skip (bool): Skip masked fields

274

275

Returns:

276

Masked data

277

"""

278

```

279

280

## Usage Examples

281

282

### Basic Model Definition

283

284

```python

285

from flask_restplus import Api, fields

286

287

api = Api()

288

289

# Define a simple model

290

user_model = api.model('User', {

291

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

292

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

293

'email': fields.String(required=True, description='Email address'),

294

'active': fields.Boolean(description='Account status')

295

})

296

297

# Define a nested model

298

post_model = api.model('Post', {

299

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

300

'title': fields.String(required=True, description='Post title'),

301

'content': fields.String(description='Post content'),

302

'author': fields.Nested(user_model, description='Post author'),

303

'tags': fields.List(fields.String, description='Post tags'),

304

'created_at': fields.DateTime(description='Creation timestamp')

305

})

306

```

307

308

### Model Inheritance

309

310

```python

311

from flask_restplus import Api, fields

312

313

api = Api()

314

315

# Base model

316

base_model = api.model('BaseModel', {

317

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

318

'created_at': fields.DateTime(description='Creation timestamp'),

319

'updated_at': fields.DateTime(description='Last update timestamp')

320

})

321

322

# Inherited model

323

user_model = api.inherit('User', base_model, {

324

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

325

'email': fields.String(required=True, description='Email address'),

326

})

327

328

# Multiple inheritance

329

admin_model = api.inherit('Admin', user_model, {

330

'permissions': fields.List(fields.String, description='Admin permissions'),

331

'is_super_admin': fields.Boolean(description='Super admin status')

332

})

333

```

334

335

### Model Cloning

336

337

```python

338

from flask_restplus import Api, fields

339

340

api = Api()

341

342

user_model = api.model('User', {

343

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

344

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

345

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

346

'password': fields.String(required=True)

347

})

348

349

# Clone model without password field for responses

350

user_public = api.clone('UserPublic', user_model)

351

del user_public['password']

352

353

# Or create a new model with modifications

354

user_update = api.clone('UserUpdate', user_model, {

355

'password': fields.String(description='New password (optional)')

356

})

357

# Make all fields optional for updates

358

for field_name, field in user_update.items():

359

field.required = False

360

```

361

362

### Response Marshalling

363

364

```python

365

from flask_restplus import Api, Resource, fields, marshal_with

366

367

api = Api()

368

369

user_model = api.model('User', {

370

'id': fields.Integer,

371

'name': fields.String,

372

'email': fields.String

373

})

374

375

@api.route('/users/<int:user_id>')

376

class User(Resource):

377

@api.marshal_with(user_model)

378

def get(self, user_id):

379

# Return raw data - will be automatically marshalled

380

user_data = {

381

'id': user_id,

382

'name': 'John Doe',

383

'email': 'john@example.com',

384

'internal_field': 'hidden' # Not in model, will be filtered out

385

}

386

return user_data

387

388

@api.route('/users')

389

class UserList(Resource):

390

@api.marshal_list_with(user_model)

391

def get(self):

392

# Return list of raw data

393

users = [

394

{'id': 1, 'name': 'John', 'email': 'john@example.com'},

395

{'id': 2, 'name': 'Jane', 'email': 'jane@example.com'}

396

]

397

return users

398

```

399

400

### Manual Marshalling

401

402

```python

403

from flask_restplus import Api, fields, marshal

404

405

api = Api()

406

407

user_fields = {

408

'id': fields.Integer,

409

'name': fields.String,

410

'email': fields.String

411

}

412

413

# Manual marshalling

414

user_data = {'id': 1, 'name': 'John', 'email': 'john@example.com', 'secret': 'hidden'}

415

marshalled = marshal(user_data, user_fields)

416

# Result: {'id': 1, 'name': 'John', 'email': 'john@example.com'}

417

418

# Marshal with envelope

419

marshalled_with_envelope = marshal(user_data, user_fields, envelope='user')

420

# Result: {'user': {'id': 1, 'name': 'John', 'email': 'john@example.com'}}

421

422

# Marshal list

423

users_data = [

424

{'id': 1, 'name': 'John', 'email': 'john@example.com'},

425

{'id': 2, 'name': 'Jane', 'email': 'jane@example.com'}

426

]

427

marshalled_list = marshal(users_data, user_fields)

428

429

# Skip None values

430

data_with_none = {'id': 1, 'name': None, 'email': 'john@example.com'}

431

marshalled_skip_none = marshal(data_with_none, user_fields, skip_none=True)

432

# Result: {'id': 1, 'email': 'john@example.com'}

433

```

434

435

### Field Masking

436

437

```python

438

from flask_restplus import Api, Resource, fields, marshal_with

439

440

api = Api()

441

442

user_model = api.model('User', {

443

'id': fields.Integer,

444

'name': fields.String,

445

'email': fields.String,

446

'profile': fields.Nested({

447

'bio': fields.String,

448

'avatar_url': fields.String,

449

'preferences': fields.Nested({

450

'theme': fields.String,

451

'notifications': fields.Boolean

452

})

453

})

454

})

455

456

@api.route('/users/<int:user_id>')

457

class User(Resource):

458

@api.marshal_with(user_model)

459

def get(self, user_id):

460

# Client can request specific fields with ?mask= parameter

461

# Examples:

462

# ?mask=id,name - returns only id and name

463

# ?mask=id,name,profile{bio} - includes id, name, and profile.bio

464

# ?mask=profile{preferences{theme}} - nested field selection

465

466

user_data = {

467

'id': user_id,

468

'name': 'John Doe',

469

'email': 'john@example.com',

470

'profile': {

471

'bio': 'Software developer',

472

'avatar_url': 'http://example.com/avatar.jpg',

473

'preferences': {

474

'theme': 'dark',

475

'notifications': True

476

}

477

}

478

}

479

return user_data

480

```

481

482

### Ordered Models

483

484

```python

485

from flask_restplus import Api, fields, OrderedModel

486

487

api = Api()

488

489

# Regular model - field order not guaranteed

490

regular_model = api.model('Regular', {

491

'name': fields.String,

492

'id': fields.Integer,

493

'email': fields.String

494

})

495

496

# Ordered model - preserves field order

497

ordered_model = api.model('Ordered', OrderedModel('OrderedUser', {

498

'id': fields.Integer, # Will appear first

499

'name': fields.String, # Will appear second

500

'email': fields.String # Will appear third

501

}))

502

```

503

504

### Schema-based Models

505

506

```python

507

from flask_restplus import Api, SchemaModel

508

509

api = Api()

510

511

# JSON schema definition

512

user_schema = {

513

"type": "object",

514

"properties": {

515

"id": {"type": "integer"},

516

"name": {"type": "string"},

517

"email": {"type": "string", "format": "email"}

518

},

519

"required": ["id", "name"]

520

}

521

522

# Create model from JSON schema

523

user_model = api.model('User', SchemaModel('User', schema=user_schema))

524

```