or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-models.mddataclasses-adapters.mderror-handling.mdindex.mdjson-schema.mdplugins.mdserialization-config.mdtype-system.mdvalidation-system.md

serialization-config.mddocs/

0

# Serialization and Configuration

1

2

Computed fields, serialization customization, and model configuration options for controlling validation and serialization behavior.

3

4

## Capabilities

5

6

### Computed Fields

7

8

Create fields that are computed from other fields or model state, useful for derived values and dynamic properties.

9

10

```python { .api }

11

def computed_field(*, alias=None, alias_priority=None, title=None, description=None,

12

examples=None, exclude=None, discriminator=None, json_schema_extra=None,

13

frozen=None, validate_default=None, repr=True, return_type=PydanticUndefined):

14

"""

15

Decorator for computed field properties.

16

17

Args:

18

alias: Alias for the field name

19

alias_priority (int): Priority for alias resolution

20

title (str): Human-readable title

21

description (str): Field description

22

examples: Example values

23

exclude: Whether to exclude from serialization

24

discriminator: Discriminator for union types

25

json_schema_extra: Extra JSON schema properties

26

frozen (bool): Whether field is frozen after initialization

27

validate_default (bool): Validate default values

28

repr (bool): Include in repr output

29

return_type: Return type annotation

30

31

Returns:

32

Decorator function

33

"""

34

35

@computed_field

36

@property

37

def computed_property(self) -> ReturnType:

38

"""

39

Template for computed field property.

40

41

Returns:

42

Computed value

43

"""

44

```

45

46

### Model Configuration

47

48

Configuration options that control model behavior, validation, and serialization.

49

50

```python { .api }

51

class ConfigDict(TypedDict, total=False):

52

"""

53

Configuration dictionary for pydantic models.

54

55

Can be used as model_config class attribute.

56

"""

57

58

# Validation configuration

59

strict: bool # Enable strict validation mode

60

extra: str # Handle extra fields ('ignore', 'allow', 'forbid')

61

frozen: bool # Make model immutable after creation

62

populate_by_name: bool # Allow field population by field name and alias

63

use_enum_values: bool # Use enum values instead of enum instances

64

validate_assignment: bool # Validate field assignments after creation

65

arbitrary_types_allowed: bool # Allow arbitrary types in fields

66

from_attributes: bool # Allow model creation from object attributes

67

68

# Serialization configuration

69

ser_json_timedelta: str # How to serialize timedelta ('iso8601', 'float')

70

ser_json_bytes: str # How to serialize bytes ('utf8', 'base64')

71

ser_json_inf_nan: str # How to serialize inf/nan ('null', 'constants')

72

hide_input_in_errors: bool # Hide input data in validation errors

73

74

# String handling

75

str_to_lower: bool # Convert strings to lowercase

76

str_to_upper: bool # Convert strings to uppercase

77

str_strip_whitespace: bool # Strip whitespace from strings

78

79

# JSON schema configuration

80

title: str # Schema title

81

json_schema_extra: dict # Extra JSON schema properties

82

json_encoders: dict # Custom JSON encoders (deprecated)

83

84

# Deprecated/legacy options

85

validate_default: bool # Validate default values

86

defer_build: bool # Defer model building

87

```

88

89

### Serialization Decorators

90

91

Decorators for customizing field and model serialization behavior.

92

93

```python { .api }

94

def field_serializer(*fields, mode='wrap', when_used='json-unless-none', check_fields=None):

95

"""

96

Decorator for custom field serialization.

97

98

Args:

99

*fields (str): Field names to apply serializer to

100

mode (str): Serialization mode ('wrap', 'plain', 'before', 'after')

101

when_used (str): When to use serializer ('json', 'json-unless-none', 'always')

102

check_fields (bool): Whether to check if fields exist

103

104

Returns:

105

Decorator function

106

"""

107

108

def model_serializer(mode='wrap', when_used='json-unless-none'):

109

"""

110

Decorator for custom model serialization.

111

112

Args:

113

mode (str): Serialization mode ('wrap', 'plain')

114

when_used (str): When to use serializer ('json', 'json-unless-none', 'always')

115

116

Returns:

117

Decorator function

118

"""

119

120

class PlainSerializer:

121

"""

122

Serializer that completely replaces default serialization.

123

"""

124

125

def __init__(self, func, *, return_type=PydanticUndefined, when_used='json-unless-none'):

126

"""

127

Initialize serializer.

128

129

Args:

130

func: Serialization function

131

return_type: Return type annotation

132

when_used (str): When to use serializer

133

"""

134

135

class WrapSerializer:

136

"""

137

Serializer that wraps default serialization.

138

"""

139

140

def __init__(self, func, *, return_type=PydanticUndefined, when_used='json-unless-none'):

141

"""

142

Initialize serializer.

143

144

Args:

145

func: Serialization function

146

return_type: Return type annotation

147

when_used (str): When to use serializer

148

"""

149

150

class BeforeSerializer:

151

"""

152

Serializer that runs before default serialization.

153

"""

154

155

def __init__(self, func, *, when_used='json-unless-none'):

156

"""

157

Initialize serializer.

158

159

Args:

160

func: Serialization function

161

when_used (str): When to use serializer

162

"""

163

164

class AfterSerializer:

165

"""

166

Serializer that runs after default serialization.

167

"""

168

169

def __init__(self, func, *, return_type=PydanticUndefined, when_used='json-unless-none'):

170

"""

171

Initialize serializer.

172

173

Args:

174

func: Serialization function

175

return_type: Return type annotation

176

when_used (str): When to use serializer

177

"""

178

```

179

180

### Field and Alias Configuration

181

182

Advanced field configuration including aliases and serialization control.

183

184

```python { .api }

185

class AliasGenerator:

186

"""Base class for alias generators."""

187

188

def generate_alias(self, field_name: str) -> str:

189

"""

190

Generate alias for field name.

191

192

Args:

193

field_name (str): Original field name

194

195

Returns:

196

str: Generated alias

197

"""

198

199

def alias_generator(func):

200

"""

201

Create alias generator from function.

202

203

Args:

204

func: Function that takes field name and returns alias

205

206

Returns:

207

AliasGenerator instance

208

"""

209

210

class AliasChoices:

211

"""

212

Multiple alias choices for a field.

213

"""

214

215

def __init__(self, *choices):

216

"""

217

Initialize with alias choices.

218

219

Args:

220

*choices: Alias options

221

"""

222

223

class AliasPath:

224

"""

225

Path-based alias for nested data extraction.

226

"""

227

228

def __init__(self, *path):

229

"""

230

Initialize with path components.

231

232

Args:

233

*path: Path components for nested access

234

"""

235

236

### Alias Generator Functions

237

238

Built-in functions for common alias generation patterns.

239

240

```python { .api }

241

def to_pascal(snake_str):

242

"""

243

Convert snake_case string to PascalCase.

244

245

Args:

246

snake_str (str): String in snake_case format

247

248

Returns:

249

str: String in PascalCase format

250

251

Example:

252

to_pascal('user_name') -> 'UserName'

253

"""

254

255

def to_camel(snake_str):

256

"""

257

Convert snake_case string to camelCase.

258

259

Args:

260

snake_str (str): String in snake_case format

261

262

Returns:

263

str: String in camelCase format

264

265

Example:

266

to_camel('user_name') -> 'userName'

267

"""

268

269

def to_snake(camel_str):

270

"""

271

Convert PascalCase or camelCase string to snake_case.

272

273

Args:

274

camel_str (str): String in PascalCase or camelCase format

275

276

Returns:

277

str: String in snake_case format

278

279

Example:

280

to_snake('UserName') -> 'user_name'

281

to_snake('userName') -> 'user_name'

282

"""

283

```

284

285

### Core Schema Classes

286

287

Core classes from pydantic-core that are part of the serialization API.

288

289

```python { .api }

290

class SerializationInfo:

291

"""

292

Information available during serialization.

293

"""

294

295

@property

296

def include(self):

297

"""set | dict | None: Fields to include"""

298

299

@property

300

def exclude(self):

301

"""set | dict | None: Fields to exclude"""

302

303

@property

304

def context(self):

305

"""dict | None: Serialization context"""

306

307

@property

308

def mode(self):

309

"""str: Serialization mode"""

310

311

@property

312

def by_alias(self):

313

"""bool: Whether to use aliases"""

314

315

class FieldSerializationInfo:

316

"""

317

Information available during field serialization.

318

"""

319

320

@property

321

def field_name(self):

322

"""str: Field name"""

323

324

@property

325

def by_alias(self):

326

"""bool: Whether to use aliases"""

327

328

class SerializerFunctionWrapHandler:

329

"""

330

Handler for wrap serializers.

331

"""

332

333

def __call__(self, value):

334

"""

335

Call the wrapped serializer.

336

337

Args:

338

value: Value to serialize

339

340

Returns:

341

Serialized value

342

"""

343

```

344

345

## Usage Examples

346

347

### Computed Fields

348

349

```python

350

from pydantic import BaseModel, computed_field

351

from typing import Optional

352

353

class Person(BaseModel):

354

first_name: str

355

last_name: str

356

birth_year: int

357

358

@computed_field

359

@property

360

def full_name(self) -> str:

361

return f"{self.first_name} {self.last_name}"

362

363

@computed_field

364

@property

365

def age(self) -> int:

366

from datetime import date

367

return date.today().year - self.birth_year

368

369

# Usage

370

person = Person(

371

first_name="John",

372

last_name="Doe",

373

birth_year=1990

374

)

375

376

print(person.full_name) # "John Doe"

377

print(person.age) # Current age

378

print(person.model_dump()) # Includes computed fields

379

```

380

381

### Model Configuration

382

383

```python

384

from pydantic import BaseModel, ConfigDict

385

386

class StrictModel(BaseModel):

387

model_config = ConfigDict(

388

strict=True, # Strict validation

389

extra='forbid', # Forbid extra fields

390

frozen=True, # Immutable after creation

391

validate_assignment=True, # Validate assignments

392

str_strip_whitespace=True # Strip string whitespace

393

)

394

395

name: str

396

value: int

397

398

# Usage

399

model = StrictModel(name=" test ", value=42)

400

print(model.name) # "test" (whitespace stripped)

401

402

# This would raise ValidationError due to strict mode

403

# model = StrictModel(name="test", value="42") # string instead of int

404

405

# This would raise ValidationError due to extra='forbid'

406

# model = StrictModel(name="test", value=42, extra_field="not allowed")

407

```

408

409

### Field Serializers

410

411

```python

412

from pydantic import BaseModel, field_serializer

413

from datetime import datetime

414

from typing import Optional

415

416

class Event(BaseModel):

417

name: str

418

timestamp: datetime

419

metadata: Optional[dict] = None

420

421

@field_serializer('timestamp')

422

def serialize_timestamp(self, value: datetime) -> str:

423

return value.strftime('%Y-%m-%d %H:%M:%S UTC')

424

425

@field_serializer('metadata', when_used='json')

426

def serialize_metadata(self, value: Optional[dict]) -> Optional[str]:

427

if value is None:

428

return None

429

import json

430

return json.dumps(value, sort_keys=True)

431

432

# Usage

433

event = Event(

434

name="Conference",

435

timestamp=datetime(2023, 12, 25, 10, 30),

436

metadata={"location": "New York", "capacity": 100}

437

)

438

439

print(event.model_dump_json())

440

# Custom serialization applied to timestamp and metadata

441

```

442

443

### Model Serializers

444

445

```python

446

from pydantic import BaseModel, model_serializer

447

448

class APIResponse(BaseModel):

449

success: bool

450

data: dict

451

message: str

452

453

@model_serializer

454

def serialize_model(self):

455

# Custom serialization logic

456

result = {

457

'status': 'ok' if self.success else 'error',

458

'payload': self.data,

459

'info': self.message

460

}

461

462

# Add timestamp

463

from datetime import datetime

464

result['timestamp'] = datetime.utcnow().isoformat()

465

466

return result

467

468

# Usage

469

response = APIResponse(

470

success=True,

471

data={'user_id': 123, 'name': 'John'},

472

message='User retrieved successfully'

473

)

474

475

print(response.model_dump())

476

# Uses custom serialization format

477

```

478

479

### Alias Configuration

480

481

```python

482

from pydantic import BaseModel, Field, AliasPath, AliasChoices

483

484

class UserData(BaseModel):

485

user_id: int = Field(alias='id')

486

full_name: str = Field(alias=AliasChoices('fullName', 'full_name', 'name'))

487

address: str = Field(alias=AliasPath('location', 'address'))

488

489

class Config:

490

populate_by_name = True # Allow both field name and alias

491

492

# Usage with different alias formats

493

data1 = {'id': 123, 'fullName': 'John Doe', 'location': {'address': '123 Main St'}}

494

data2 = {'user_id': 456, 'full_name': 'Jane Smith', 'location': {'address': '456 Oak Ave'}}

495

496

user1 = UserData(**data1)

497

user2 = UserData(**data2)

498

499

print(user1.model_dump(by_alias=True)) # Uses aliases in output

500

```

501

502

### Functional Serializers with Annotated

503

504

```python

505

from pydantic import BaseModel, PlainSerializer, field_serializer

506

from typing import Annotated

507

from decimal import Decimal

508

509

def money_serializer(value: Decimal) -> str:

510

"""Serialize decimal as currency string."""

511

return f"${value:.2f}"

512

513

class Invoice(BaseModel):

514

amount: Annotated[Decimal, PlainSerializer(money_serializer, when_used='json')]

515

tax: Decimal

516

517

@field_serializer('tax', when_used='json')

518

def serialize_tax(self, value: Decimal) -> str:

519

return f"${value:.2f}"

520

521

# Usage

522

invoice = Invoice(amount=Decimal('100.50'), tax=Decimal('8.25'))

523

print(invoice.model_dump_json())

524

# {"amount": "$100.50", "tax": "$8.25"}

525

```

526

527

### Configuration Inheritance

528

529

```python

530

from pydantic import BaseModel, ConfigDict

531

532

class BaseConfig(BaseModel):

533

model_config = ConfigDict(

534

str_strip_whitespace=True,

535

validate_assignment=True,

536

frozen=True

537

)

538

539

class APIModel(BaseConfig):

540

model_config = ConfigDict(

541

# Inherits from BaseConfig and adds:

542

extra='forbid',

543

alias_generator=lambda field_name: field_name.replace('_', '-')

544

)

545

546

user_id: int

547

user_name: str

548

549

# Usage

550

model = APIModel(user_id=123, **{'user-name': ' John '})

551

print(model.user_name) # "John" (whitespace stripped)

552

print(model.model_dump(by_alias=True)) # {'user-id': 123, 'user-name': 'John'}

553

```

554

555

### Alias Generator Functions Usage

556

557

```python

558

from pydantic import BaseModel, ConfigDict, Field

559

from pydantic.alias_generators import to_camel, to_pascal, to_snake

560

561

class APIModel(BaseModel):

562

model_config = ConfigDict(alias_generator=to_camel)

563

564

user_id: int

565

user_name: str

566

created_at: str

567

568

# Field names are automatically converted to camelCase

569

data = {'userId': 123, 'userName': 'John', 'createdAt': '2023-12-25T10:30:00Z'}

570

model = APIModel(**data)

571

572

print(model.model_dump(by_alias=True))

573

# {'userId': 123, 'userName': 'John', 'createdAt': '2023-12-25T10:30:00Z'}

574

575

# Manual alias generation

576

class CustomModel(BaseModel):

577

snake_case_field: str = Field(alias=to_pascal('snake_case_field')) # 'SnakeCaseField'

578

another_field: int = Field(alias=to_camel('another_field')) # 'anotherField'

579

580

# Convert between naming conventions

581

original_name = 'user_profile_data'

582

camel_name = to_camel(original_name) # 'userProfileData'

583

pascal_name = to_pascal(original_name) # 'UserProfileData'

584

back_to_snake = to_snake(pascal_name) # 'user_profile_data'

585

586

print(f"Original: {original_name}")

587

print(f"Camel: {camel_name}")

588

print(f"Pascal: {pascal_name}")

589

print(f"Back to snake: {back_to_snake}")

590

```