Simple creation of data classes from dictionaries with advanced type support and validation
npx @tessl/cli install tessl/pypi-dacite@1.9.00
# Dacite
1
2
Dacite simplifies the creation of Python data classes from dictionaries. It bridges the gap between raw dictionary data (from HTTP requests, databases, etc.) and strongly-typed data structures, enabling developers to create robust data transfer objects (DTOs) with minimal boilerplate code while maintaining type safety.
3
4
## Package Information
5
6
- **Package Name**: dacite
7
- **Package Type**: pypi
8
- **Language**: Python
9
- **Installation**: `pip install dacite`
10
- **Minimum Python Version**: 3.7
11
12
## Core Imports
13
14
```python
15
from dacite import from_dict, Config
16
```
17
18
For exceptions:
19
20
```python
21
from dacite import (
22
DaciteError,
23
DaciteFieldError,
24
WrongTypeError,
25
MissingValueError,
26
UnionMatchError,
27
StrictUnionMatchError,
28
ForwardReferenceError,
29
UnexpectedDataError,
30
)
31
```
32
33
For cache management:
34
35
```python
36
from dacite import set_cache_size, get_cache_size, clear_cache
37
```
38
39
## Basic Usage
40
41
```python
42
from dataclasses import dataclass
43
from dacite import from_dict
44
45
@dataclass
46
class User:
47
name: str
48
age: int
49
is_active: bool
50
51
data = {
52
'name': 'John',
53
'age': 30,
54
'is_active': True,
55
}
56
57
user = from_dict(data_class=User, data=data)
58
assert user == User(name='John', age=30, is_active=True)
59
```
60
61
## Capabilities
62
63
### Dictionary to Dataclass Conversion
64
65
The core functionality that converts dictionaries to dataclass instances with full type support and validation.
66
67
```python { .api }
68
def from_dict(data_class: Type[T], data: Data, config: Optional[Config] = None) -> T:
69
"""
70
Create a data class instance from a dictionary.
71
72
Args:
73
data_class: A data class type to create an instance of
74
data: Dictionary-like data to convert (must support keys(), __getitem__, __contains__)
75
config: Optional configuration for controlling the conversion process
76
77
Returns:
78
An instance of the specified data class
79
80
Raises:
81
DaciteError: Base exception for all dacite-related errors
82
WrongTypeError: When a value has the wrong type for a field
83
MissingValueError: When a required field is missing from the data
84
UnionMatchError: When a value cannot match any union type
85
StrictUnionMatchError: When multiple union types match in strict mode
86
ForwardReferenceError: When forward references cannot be resolved
87
UnexpectedDataError: When strict mode encounters unexpected fields
88
"""
89
```
90
91
### Configuration
92
93
Control the conversion process with various options for type handling, validation, and data transformation.
94
95
```python { .api }
96
@dataclass
97
class Config:
98
"""
99
Configuration object for controlling from_dict behavior.
100
101
Attributes:
102
type_hooks: Dictionary mapping types to transformation functions
103
cast: List of types to attempt casting values to
104
forward_references: Dictionary for resolving forward references
105
check_types: Enable/disable runtime type checking (default: True)
106
strict: Enable strict mode to reject unexpected fields (default: False)
107
strict_unions_match: Enable strict matching for union types (default: False)
108
convert_key: Function to transform dictionary keys (default: identity function)
109
"""
110
type_hooks: Dict[Type, Callable[[Any], Any]]
111
cast: List[Type]
112
forward_references: Optional[Dict[str, Any]]
113
check_types: bool
114
strict: bool
115
strict_unions_match: bool
116
convert_key: Callable[[str], str]
117
```
118
119
Usage example with configuration:
120
121
```python
122
from dacite import from_dict, Config
123
from dataclasses import dataclass
124
from typing import Optional
125
126
@dataclass
127
class Person:
128
name: str
129
age: Optional[int]
130
email: str
131
132
config = Config(
133
type_hooks={str: str.strip}, # Strip whitespace from strings
134
check_types=True, # Enable type checking
135
strict=True, # Reject unexpected fields
136
convert_key=lambda key: key.lower() # Convert keys to lowercase
137
)
138
139
data = {"NAME": " John Doe ", "AGE": None, "EMAIL": "john@example.com"}
140
person = from_dict(Person, data, config)
141
```
142
143
### Cache Management
144
145
Control internal caching for performance optimization, particularly useful for applications with many dataclass conversions.
146
147
```python { .api }
148
def set_cache_size(size: Optional[int]) -> None:
149
"""
150
Set the maximum cache size for internal caching.
151
152
Args:
153
size: Maximum cache size (None for unlimited, 0 to disable caching)
154
"""
155
156
def get_cache_size() -> Optional[int]:
157
"""
158
Get the current cache size setting.
159
160
Returns:
161
Current cache size (None if unlimited)
162
"""
163
164
def clear_cache() -> None:
165
"""
166
Clear all internal caches.
167
168
This can be useful for memory management or when type definitions change.
169
"""
170
```
171
172
### Exception Handling
173
174
Comprehensive exception hierarchy for different error conditions during conversion.
175
176
```python { .api }
177
class DaciteError(Exception):
178
"""Base exception class for all dacite-related errors."""
179
180
class DaciteFieldError(DaciteError):
181
"""
182
Base class for field-specific errors.
183
184
Attributes:
185
field_path: Path to the problematic field (e.g., 'user.address.street')
186
"""
187
field_path: Optional[str]
188
189
def update_path(self, parent_field_path: str) -> None:
190
"""Update the field path with parent context."""
191
192
class WrongTypeError(DaciteFieldError):
193
"""
194
Raised when a value has the wrong type for a field.
195
196
Attributes:
197
field_type: Expected field type
198
value: Actual value that caused the error
199
"""
200
field_type: Type
201
value: Any
202
203
class MissingValueError(DaciteFieldError):
204
"""Raised when a required field is missing from the input data."""
205
206
class UnionMatchError(WrongTypeError):
207
"""Raised when a value cannot match any type in a union."""
208
209
class StrictUnionMatchError(DaciteFieldError):
210
"""
211
Raised when multiple union types match in strict mode.
212
213
Attributes:
214
union_matches: Dictionary of matching types and their converted values
215
"""
216
union_matches: Dict[Type, Any]
217
218
class ForwardReferenceError(DaciteError):
219
"""
220
Raised when forward references cannot be resolved.
221
222
Attributes:
223
message: Error message describing the resolution failure
224
"""
225
message: str
226
227
class UnexpectedDataError(DaciteError):
228
"""
229
Raised when strict mode encounters unexpected fields in the input data.
230
231
Attributes:
232
keys: Set of unexpected field names
233
"""
234
keys: Set[str]
235
```
236
237
## Advanced Features
238
239
### Nested Structures
240
241
Automatically converts nested dictionaries to nested dataclasses:
242
243
```python
244
@dataclass
245
class Address:
246
street: str
247
city: str
248
249
@dataclass
250
class Person:
251
name: str
252
address: Address
253
254
data = {
255
"name": "John",
256
"address": {
257
"street": "123 Main St",
258
"city": "Anytown"
259
}
260
}
261
262
person = from_dict(Person, data)
263
```
264
265
### Union Types and Optional Fields
266
267
Supports complex type annotations including unions and optional fields:
268
269
```python
270
from typing import Union, Optional
271
272
@dataclass
273
class FlexibleData:
274
value: Union[str, int, float]
275
optional_field: Optional[str] = None
276
277
data = {"value": 42} # optional_field will be None
278
result = from_dict(FlexibleData, data)
279
```
280
281
### Collections and Generics
282
283
Handles lists, tuples, sets, dictionaries, and generic types:
284
285
```python
286
from typing import List, Dict
287
288
@dataclass
289
class Container:
290
items: List[str]
291
mapping: Dict[str, int]
292
293
data = {
294
"items": ["a", "b", "c"],
295
"mapping": {"x": 1, "y": 2}
296
}
297
298
container = from_dict(Container, data)
299
```
300
301
### Custom Type Hooks
302
303
Transform values during conversion using type hooks:
304
305
```python
306
from datetime import datetime
307
308
def parse_datetime(value):
309
return datetime.fromisoformat(value)
310
311
@dataclass
312
class Event:
313
name: str
314
timestamp: datetime
315
316
config = Config(type_hooks={datetime: parse_datetime})
317
data = {"name": "Meeting", "timestamp": "2023-01-01T10:00:00"}
318
event = from_dict(Event, data, config)
319
```
320
321
## Types
322
323
```python { .api }
324
from typing import Protocol, Any, TypeVar, Type, Optional, Dict, Callable, List, Set
325
326
T = TypeVar("T")
327
328
class Data(Protocol):
329
"""
330
Protocol defining the interface for input data objects.
331
Any dictionary-like object that supports these methods can be used.
332
"""
333
def keys(self) -> Any: ...
334
def __getitem__(self, *args, **kwargs) -> Any: ...
335
def __contains__(self, *args, **kwargs) -> bool: ...
336
```