or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdexceptions.mdindex.mdpaging.mdpipeline.mdpolling.mdserialization.mdservice-client.md

serialization.mddocs/

0

# Serialization

1

2

Robust serialization and deserialization system supporting complex data types, XML/JSON formats, date/time handling, custom model classes, and comprehensive validation. The serialization system converts between Python objects and REST API wire formats while maintaining type safety and validation.

3

4

## Capabilities

5

6

### Serialization

7

8

Convert Python objects to REST API formats (JSON/XML) with comprehensive type support.

9

10

```python { .api }

11

class Serializer:

12

def __init__(self, classes=None):

13

"""

14

Initialize serializer with optional model classes.

15

16

Parameters:

17

- classes: Dict of model classes for complex type serialization

18

"""

19

20

basic_types: dict = {str: 'str', int: 'int', bool: 'bool', float: 'float'}

21

client_side_validation: bool = True

22

23

def body(self, data, data_type: str, **kwargs):

24

"""

25

Serialize data for request body.

26

27

Parameters:

28

- data: Python object to serialize

29

- data_type: Target data type string

30

- kwargs: Serialization options (is_xml, etc.)

31

32

Returns:

33

Serialized data (dict for JSON, ET.Element for XML)

34

35

Raises:

36

SerializationError if serialization fails

37

ValidationError if data is None for required field

38

"""

39

40

def url(self, name: str, data, data_type: str, **kwargs) -> str:

41

"""

42

Serialize data for URL path parameters.

43

44

Parameters:

45

- name: Parameter name for error reporting

46

- data: Data to serialize

47

- data_type: Target type ('str', 'int', 'bool', etc.)

48

- kwargs: Options (skip_quote for no URL encoding)

49

50

Returns:

51

URL-encoded string

52

"""

53

54

def query(self, name: str, data, data_type: str, **kwargs) -> str:

55

"""

56

Serialize data for URL query parameters.

57

58

Parameters:

59

- name: Parameter name

60

- data: Data to serialize

61

- data_type: Target type or array type like '[str]'

62

- kwargs: Options (skip_quote for no URL encoding)

63

64

Returns:

65

Query parameter string

66

"""

67

68

def header(self, name: str, data, data_type: str, **kwargs) -> str:

69

"""

70

Serialize data for HTTP headers.

71

72

Parameters:

73

- name: Header name

74

- data: Data to serialize

75

- data_type: Target type

76

- kwargs: Serialization options

77

78

Returns:

79

Header value string

80

"""

81

82

def serialize_data(self, data, data_type: str, **kwargs):

83

"""

84

Core serialization method handling all data types.

85

86

Parameters:

87

- data: Data to serialize

88

- data_type: Target type string

89

- kwargs: Serialization options

90

91

Returns:

92

Serialized data

93

"""

94

95

def serialize_iter(self, data, iter_type: str, **kwargs):

96

"""

97

Serialize iterables (lists, sets, etc.) with XML support.

98

99

Parameters:

100

- data: Iterable to serialize

101

- iter_type: Item type string

102

- kwargs: Options including XML configuration

103

104

Returns:

105

Serialized iterable

106

"""

107

108

def serialize_dict(self, data, dict_type: str, **kwargs):

109

"""

110

Serialize dictionaries with XML support.

111

112

Parameters:

113

- data: Dictionary to serialize

114

- dict_type: Value type string

115

- kwargs: Options including XML configuration

116

117

Returns:

118

Serialized dictionary

119

"""

120

121

def serialize_object(self, data, object_type: str, **kwargs):

122

"""

123

Serialize complex objects/models.

124

125

Parameters:

126

- data: Object to serialize

127

- object_type: Object type string

128

- kwargs: Serialization options

129

130

Returns:

131

Serialized object

132

"""

133

134

def serialize_enum(self, data, enum_obj=None):

135

"""

136

Serialize enum values.

137

138

Parameters:

139

- data: Enum value to serialize

140

- enum_obj: Optional enum class for validation

141

142

Returns:

143

Serialized enum value

144

"""

145

```

146

147

### Deserialization

148

149

Convert REST API responses back to Python objects with type inference and validation.

150

151

```python { .api }

152

class Deserializer:

153

def __init__(self, classes=None):

154

"""

155

Initialize deserializer with model classes.

156

157

Parameters:

158

- classes: Dict of model classes for complex type deserialization

159

"""

160

161

basic_types: dict = {str: 'str', int: 'int', bool: 'bool', float: 'float'}

162

additional_properties_detection: bool = True

163

key_extractors: list

164

165

def __call__(self, target_obj: str, response_data, content_type=None):

166

"""

167

Deserialize response data to target object type.

168

169

Parameters:

170

- target_obj: Target class name or type

171

- response_data: Raw response data

172

- content_type: Response content type

173

174

Returns:

175

Deserialized Python object

176

177

Raises:

178

DeserializationError if deserialization fails

179

"""

180

181

def failsafe_deserialize(self, target_obj: str, data, content_type=None):

182

"""

183

Deserialize with error tolerance for error handling scenarios.

184

185

Parameters:

186

- target_obj: Target object type

187

- data: Response data

188

- content_type: Content type hint

189

190

Returns:

191

Deserialized object or None if deserialization fails

192

"""

193

194

def deserialize_data(self, data, data_type: str):

195

"""

196

Core deserialization method handling all data types.

197

198

Parameters:

199

- data: Data to deserialize

200

- data_type: Target type string

201

202

Returns:

203

Deserialized Python object

204

"""

205

206

def deserialize_iter(self, data, iter_type: str):

207

"""

208

Deserialize iterables from JSON arrays or XML.

209

210

Parameters:

211

- data: Iterable data to deserialize

212

- iter_type: Item type string

213

214

Returns:

215

List of deserialized items

216

"""

217

218

def deserialize_dict(self, data, dict_type: str):

219

"""

220

Deserialize dictionaries from JSON objects or XML.

221

222

Parameters:

223

- data: Dict data to deserialize

224

- dict_type: Value type string

225

226

Returns:

227

Dictionary with deserialized values

228

"""

229

230

def deserialize_object(self, data, object_type: str):

231

"""

232

Deserialize complex objects/models.

233

234

Parameters:

235

- data: Object data to deserialize

236

- object_type: Target object type

237

238

Returns:

239

Deserialized model instance

240

"""

241

242

def deserialize_enum(self, data, enum_obj):

243

"""

244

Deserialize enum values with comprehensive handling.

245

246

Parameters:

247

- data: Enum data to deserialize

248

- enum_obj: Enum class for validation

249

250

Returns:

251

Enum value or string if enum doesn't match

252

"""

253

```

254

255

### Model Base Class

256

257

Base class for request/response model objects with serialization and validation support.

258

259

```python { .api }

260

class Model:

261

_attribute_map: dict = {}

262

_validation: dict = {}

263

_subtype_map: dict = {}

264

265

def __init__(self, **kwargs):

266

"""

267

Initialize model with keyword arguments.

268

269

Parameters:

270

- kwargs: Model field values

271

"""

272

273

def validate(self) -> list:

274

"""

275

Validate model recursively.

276

277

Returns:

278

List of ValidationError objects (empty if valid)

279

"""

280

281

def serialize(self, keep_readonly=False, **kwargs) -> dict:

282

"""

283

Serialize model to JSON-compatible dict.

284

285

Parameters:

286

- keep_readonly: Include readonly fields

287

- kwargs: Serialization options (is_xml, etc.)

288

289

Returns:

290

JSON-compatible dictionary

291

"""

292

293

def as_dict(self, keep_readonly=True, key_transformer=None, **kwargs) -> dict:

294

"""

295

Convert model to dictionary with custom key transformation.

296

297

Parameters:

298

- keep_readonly: Include readonly fields

299

- key_transformer: Function to transform keys

300

- kwargs: Serialization options

301

302

Returns:

303

Dictionary representation

304

"""

305

306

def __eq__(self, other) -> bool:

307

"""Compare models for equality."""

308

309

def __ne__(self, other) -> bool:

310

"""Compare models for inequality."""

311

312

def __str__(self) -> str:

313

"""String representation of model."""

314

315

def is_xml_model(self) -> bool:

316

"""Check if model supports XML serialization."""

317

318

@classmethod

319

def deserialize(cls, data: str, content_type=None):

320

"""

321

Parse string data to create model instance.

322

323

Parameters:

324

- data: JSON/XML string data

325

- content_type: Data format ('application/json' or 'application/xml')

326

327

Returns:

328

Model instance

329

330

Raises:

331

DeserializationError if parsing fails

332

"""

333

334

@classmethod

335

def from_dict(cls, data: dict, key_extractors=None, content_type=None):

336

"""

337

Create model instance from dictionary.

338

339

Parameters:

340

- data: Dictionary data

341

- key_extractors: List of key extraction functions

342

- content_type: Content type hint

343

344

Returns:

345

Model instance

346

"""

347

348

@classmethod

349

def enable_additional_properties_sending(cls):

350

"""Enable serialization of additional properties."""

351

```

352

353

### Utility Classes

354

355

Timezone and datetime utility classes for proper date/time handling.

356

357

```python { .api }

358

class UTC:

359

"""UTC timezone implementation."""

360

361

def utcoffset(self, dt):

362

"""Return UTC offset (always zero)."""

363

364

def tzname(self, dt):

365

"""Return timezone name."""

366

367

def dst(self, dt):

368

"""Return daylight saving time offset."""

369

370

class _FixedOffset:

371

"""Fixed UTC offset timezone."""

372

373

def __init__(self, offset_hours: int, name: str):

374

"""Initialize with hour offset and name."""

375

376

def utcoffset(self, dt):

377

"""Return the fixed UTC offset."""

378

379

def tzname(self, dt):

380

"""Return timezone name."""

381

382

def dst(self, dt):

383

"""Return DST offset (always zero for fixed offset)."""

384

```

385

386

### Key Extractors

387

388

Functions for extracting and transforming dictionary keys during deserialization.

389

390

```python { .api }

391

def rest_key_extractor(attr: str, attr_desc: dict, data: dict):

392

"""

393

Extract REST API key from response data.

394

395

Parameters:

396

- attr: Attribute name

397

- attr_desc: Attribute description from _attribute_map

398

- data: Response data dictionary

399

400

Returns:

401

Extracted key or KeyError

402

"""

403

404

def rest_key_case_insensitive_extractor(attr: str, attr_desc: dict, data: dict):

405

"""Case-insensitive REST key extraction."""

406

407

def last_rest_key_extractor(attr: str, attr_desc: dict, data: dict):

408

"""Extract last matching REST key."""

409

410

def xml_key_extractor(attr: str, attr_desc: dict, data):

411

"""

412

Extract keys from XML data with namespace support.

413

414

Supports XML attributes, elements, text content, and namespaces.

415

"""

416

417

def attribute_key_extractor(attr: str, attr_desc: dict, data: dict):

418

"""Extract using Python attribute names."""

419

420

def attribute_key_case_insensitive_extractor(attr: str, attr_desc: dict, data: dict):

421

"""Case-insensitive attribute key extraction."""

422

```

423

424

### Data Type Support

425

426

Comprehensive support for various data types including dates, times, binary data, and collections.

427

428

```python { .api }

429

# Static serialization methods

430

@staticmethod

431

def serialize_iso(attr, **kwargs) -> str:

432

"""Serialize datetime to ISO-8601 string."""

433

434

@staticmethod

435

def serialize_rfc(attr, **kwargs) -> str:

436

"""Serialize datetime to RFC-1123 string."""

437

438

@staticmethod

439

def serialize_unix(attr, **kwargs) -> int:

440

"""Serialize datetime to Unix timestamp."""

441

442

@staticmethod

443

def serialize_date(attr, **kwargs) -> str:

444

"""Serialize date to ISO format string."""

445

446

@staticmethod

447

def serialize_time(attr, **kwargs) -> str:

448

"""Serialize time to ISO format string."""

449

450

@staticmethod

451

def serialize_duration(attr, **kwargs) -> str:

452

"""Serialize timedelta to ISO-8601 duration."""

453

454

@staticmethod

455

def serialize_decimal(attr, **kwargs) -> float:

456

"""Serialize Decimal to float."""

457

458

@staticmethod

459

def serialize_base64(attr, **kwargs) -> str:

460

"""Serialize bytes to base64 string."""

461

462

@staticmethod

463

def serialize_bytearray(attr, **kwargs) -> str:

464

"""Serialize bytearray to base64 string."""

465

466

# Static deserialization methods

467

@staticmethod

468

def deserialize_iso(attr) -> datetime:

469

"""Deserialize ISO-8601 string to datetime."""

470

471

@staticmethod

472

def deserialize_rfc(attr) -> datetime:

473

"""Deserialize RFC-1123 string to datetime."""

474

475

@staticmethod

476

def deserialize_unix(attr) -> datetime:

477

"""Deserialize Unix timestamp to datetime."""

478

479

@staticmethod

480

def deserialize_date(attr) -> date:

481

"""Deserialize ISO date string to date object."""

482

483

@staticmethod

484

def deserialize_time(attr) -> time:

485

"""Deserialize ISO time string to time object."""

486

487

@staticmethod

488

def deserialize_duration(attr) -> timedelta:

489

"""Deserialize ISO duration to timedelta."""

490

491

@staticmethod

492

def deserialize_decimal(attr) -> Decimal:

493

"""Deserialize string to Decimal object."""

494

495

@staticmethod

496

def deserialize_base64(attr) -> bytes:

497

"""Deserialize base64 string to bytes."""

498

499

@staticmethod

500

def deserialize_bytearray(attr) -> bytearray:

501

"""Deserialize base64 string to bytearray."""

502

```

503

504

### Key Transformers

505

506

Functions for transforming object keys during serialization/deserialization.

507

508

```python { .api }

509

def attribute_transformer(key: str, attr_desc: dict, value) -> tuple:

510

"""

511

Transform using Python attribute names.

512

513

Parameters:

514

- key: Attribute name

515

- attr_desc: Attribute metadata

516

- value: Attribute value

517

518

Returns:

519

Tuple of (key, value)

520

"""

521

522

def full_restapi_key_transformer(key: str, attr_desc: dict, value) -> tuple:

523

"""

524

Transform using full REST API key path.

525

526

Parameters:

527

- key: Attribute name

528

- attr_desc: Attribute metadata

529

- value: Attribute value

530

531

Returns:

532

Tuple of (key_list, value) for nested structures

533

"""

534

535

def last_restapi_key_transformer(key: str, attr_desc: dict, value) -> tuple:

536

"""

537

Transform using last component of REST API key.

538

539

Parameters:

540

- key: Attribute name

541

- attr_desc: Attribute metadata

542

- value: Attribute value

543

544

Returns:

545

Tuple of (last_key, value)

546

"""

547

```

548

549

### Validation

550

551

Comprehensive validation system with multiple validation rules.

552

553

```python { .api }

554

@classmethod

555

def validate(cls, data, name: str, **kwargs):

556

"""

557

Validate data against specified rules.

558

559

Parameters:

560

- data: Data to validate

561

- name: Field name for error reporting

562

- kwargs: Validation rules (required, min_length, max_length, etc.)

563

564

Returns:

565

Validated data

566

567

Raises:

568

ValidationError if validation fails

569

"""

570

571

# Validation rules supported in kwargs:

572

# - required: bool - Field cannot be None

573

# - min_length: int - Minimum string/array length

574

# - max_length: int - Maximum string/array length

575

# - minimum: int/float - Minimum numeric value

576

# - maximum: int/float - Maximum numeric value

577

# - min_items: int - Minimum array items

578

# - max_items: int - Maximum array items

579

# - pattern: str - Regex pattern to match

580

# - unique: bool - Array items must be unique

581

# - multiple: int/float - Value must be multiple of this

582

```

583

584

## Usage Examples

585

586

### Basic Serialization

587

588

```python

589

from msrest.serialization import Serializer

590

591

# Create serializer

592

serializer = Serializer()

593

594

# Serialize for URL parameter

595

user_id = 123

596

url_param = serializer.url('user_id', user_id, 'int') # "123"

597

598

# Serialize for query parameter

599

tags = ['python', 'rest', 'api']

600

query_param = serializer.query('tags', tags, '[str]') # "python,rest,api"

601

602

# Serialize for request body

603

data = {'name': 'John', 'age': 30}

604

body = serializer.body(data, 'UserModel')

605

```

606

607

### Model Class Usage

608

609

```python

610

from msrest.serialization import Model

611

612

class User(Model):

613

_attribute_map = {

614

'name': {'key': 'name', 'type': 'str'},

615

'email': {'key': 'email', 'type': 'str'},

616

'age': {'key': 'age', 'type': 'int'}

617

}

618

_validation = {

619

'name': {'required': True, 'min_length': 1},

620

'email': {'required': True, 'pattern': r'^[^@]+@[^@]+\.[^@]+$'},

621

'age': {'minimum': 0, 'maximum': 150}

622

}

623

624

# Create and validate model

625

user = User(name='John Doe', email='john@example.com', age=30)

626

validation_errors = user.validate()

627

628

if not validation_errors:

629

# Serialize to JSON

630

json_data = user.serialize()

631

632

# Convert to dictionary

633

user_dict = user.as_dict()

634

```

635

636

### Deserialization

637

638

```python

639

from msrest.serialization import Deserializer

640

641

# Create deserializer with model classes

642

classes = {'User': User, 'Address': Address}

643

deserializer = Deserializer(classes)

644

645

# Deserialize JSON response

646

json_response = '{"name": "John", "email": "john@example.com", "age": 30}'

647

user = deserializer('User', json_response)

648

649

# Deserialize from dictionary

650

response_dict = {'name': 'Jane', 'email': 'jane@example.com', 'age': 25}

651

user = User.from_dict(response_dict)

652

```

653

654

### Date/Time Handling

655

656

```python

657

from datetime import datetime, date, timedelta

658

from msrest.serialization import Serializer

659

660

serializer = Serializer()

661

662

# Serialize datetime to ISO-8601

663

dt = datetime(2023, 12, 25, 15, 30, 0)

664

iso_string = serializer.serialize_iso(dt) # "2023-12-25T15:30:00Z"

665

666

# Serialize date

667

d = date(2023, 12, 25)

668

date_string = serializer.serialize_date(d) # "2023-12-25"

669

670

# Serialize duration

671

delta = timedelta(hours=2, minutes=30)

672

duration_string = serializer.serialize_duration(delta) # "PT2H30M"

673

```

674

675

### XML Serialization

676

677

```python

678

from msrest.serialization import Model

679

680

class Product(Model):

681

_attribute_map = {

682

'name': {'key': 'name', 'type': 'str'},

683

'price': {'key': 'price', 'type': 'float'}

684

}

685

_xml_map = {

686

'name': 'Product',

687

'ns': 'http://example.com/products'

688

}

689

690

product = Product(name='Widget', price=19.99)

691

692

# Serialize to XML

693

xml_data = product.serialize(is_xml=True)

694

```

695

696

### Custom Validation

697

698

```python

699

from msrest.serialization import Model

700

from msrest.exceptions import ValidationError

701

702

class OrderItem(Model):

703

_attribute_map = {

704

'quantity': {'key': 'quantity', 'type': 'int'},

705

'price': {'key': 'price', 'type': 'float'}

706

}

707

_validation = {

708

'quantity': {'required': True, 'minimum': 1, 'maximum': 1000},

709

'price': {'required': True, 'minimum': 0.01}

710

}

711

712

# This will raise ValidationError

713

try:

714

item = OrderItem(quantity=0, price=-5.00)

715

item.validate()

716

except ValidationError as e:

717

print(f"Validation failed: {e}")

718

```

719

720

## Exception Handling

721

722

```python

723

from msrest.exceptions import SerializationError, DeserializationError, ValidationError

724

725

try:

726

# Serialization

727

serialized = serializer.body(data, 'ComplexType')

728

729

# Deserialization

730

deserialized = deserializer('ComplexType', response_data)

731

732

except SerializationError as e:

733

print(f"Serialization failed: {e}")

734

except DeserializationError as e:

735

print(f"Deserialization failed: {e}")

736

except ValidationError as e:

737

print(f"Validation failed: {e}")

738

```