0
# Handler Management System
1
2
Extensible system for registering custom serialization handlers for specific types, allowing you to control how particular objects are encoded and decoded.
3
4
## Capabilities
5
6
### Handler Registration
7
8
Register custom handlers for specific types to control their serialization behavior.
9
10
```python { .api }
11
def register(cls, handler=None, base=False):
12
"""
13
Register a handler for objects of type cls.
14
15
Parameters:
16
- cls: The class/type to register a handler for
17
- handler: Handler instance or class (if None, cls must be a handler)
18
- base: If True, also handle subclasses of cls
19
"""
20
21
def unregister(cls):
22
"""
23
Remove the handler registered for objects of type cls.
24
25
Parameters:
26
- cls: The class/type to unregister
27
"""
28
```
29
30
**Usage Example:**
31
32
```python
33
import jsonpickle
34
from jsonpickle.handlers import BaseHandler
35
36
# Custom handler for a specific type
37
class CustomObjectHandler(BaseHandler):
38
def flatten(self, obj, data):
39
data['custom_field'] = obj.special_attribute
40
return data
41
42
def restore(self, data):
43
obj = self.context.restore(data, reset=False)
44
return obj
45
46
# Register the handler
47
jsonpickle.register(CustomObject, CustomObjectHandler)
48
49
# Use with base=True to handle subclasses too
50
jsonpickle.register(BaseCustomObject, CustomObjectHandler, base=True)
51
52
# Unregister when no longer needed
53
jsonpickle.unregister(CustomObject)
54
```
55
56
### Base Handler Class
57
58
Base class for implementing custom serialization handlers.
59
60
```python { .api }
61
class BaseHandler:
62
def __init__(self, context):
63
"""
64
Initialize handler with pickler/unpickler context.
65
66
Parameters:
67
- context: Active Pickler or Unpickler instance
68
"""
69
70
def flatten(self, obj, data):
71
"""
72
Convert object to JSON-serializable form during encoding.
73
74
Parameters:
75
- obj: Object being serialized
76
- data: Dictionary to populate with serializable data
77
78
Returns:
79
Updated data dictionary
80
"""
81
82
def restore(self, data):
83
"""
84
Restore object from JSON data during decoding.
85
86
Parameters:
87
- data: Dictionary containing object data
88
89
Returns:
90
Restored Python object
91
"""
92
```
93
94
**Implementation Example:**
95
96
```python
97
import jsonpickle
98
from jsonpickle.handlers import BaseHandler
99
import datetime
100
101
class DateTimeHandler(BaseHandler):
102
def flatten(self, obj, data):
103
# Convert datetime to ISO format string
104
data['iso_format'] = obj.isoformat()
105
return data
106
107
def restore(self, data):
108
# Restore datetime from ISO format
109
return datetime.datetime.fromisoformat(data['iso_format'])
110
111
# Register the custom datetime handler
112
jsonpickle.register(datetime.datetime, DateTimeHandler)
113
114
# Test the handler
115
dt = datetime.datetime.now()
116
json_str = jsonpickle.encode(dt)
117
restored_dt = jsonpickle.decode(json_str)
118
```
119
120
### Built-in Handlers
121
122
jsonpickle includes built-in handlers for common Python types.
123
124
```python { .api }
125
# Built-in handler classes (examples)
126
class ArrayHandler(BaseHandler):
127
"""Handler for array.array objects"""
128
129
class DatetimeHandler(BaseHandler):
130
"""Handler for datetime objects"""
131
132
class RegexHandler(BaseHandler):
133
"""Handler for compiled regex patterns"""
134
135
class QueueHandler(BaseHandler):
136
"""Handler for queue objects"""
137
138
class UUIDHandler(BaseHandler):
139
"""Handler for UUID objects"""
140
141
class LockHandler(BaseHandler):
142
"""Handler for threading lock objects"""
143
144
class TextIOHandler(BaseHandler):
145
"""Handler for text I/O objects"""
146
```
147
148
These are automatically registered when jsonpickle is imported.
149
150
### Registry Access
151
152
Access the global handler registry for inspection and management.
153
154
```python { .api }
155
# Registry management functions
156
def get(cls):
157
"""Get the handler registered for a specific class"""
158
159
# Registry class
160
class Registry:
161
def get(self, cls):
162
"""Get handler for type"""
163
164
def register(self, cls, handler, base=False):
165
"""Register handler for type"""
166
167
def unregister(self, cls):
168
"""Remove handler for type"""
169
```
170
171
**Registry Usage Example:**
172
173
```python
174
from jsonpickle.handlers import registry, get
175
176
# Check if a handler is registered
177
handler = get(datetime.datetime)
178
if handler:
179
print(f"Handler registered: {handler}")
180
181
# Access registry directly
182
all_handlers = registry._handlers # Internal access
183
```
184
185
### Custom Handler Patterns
186
187
#### Simple Value Transformation
188
189
```python
190
class SimpleHandler(BaseHandler):
191
def flatten(self, obj, data):
192
data['value'] = str(obj) # Convert to string
193
return data
194
195
def restore(self, data):
196
return MyClass(data['value']) # Reconstruct from string
197
```
198
199
#### Complex Object Handling
200
201
```python
202
class ComplexHandler(BaseHandler):
203
def flatten(self, obj, data):
204
# Handle complex nested objects
205
data['config'] = self.context.flatten(obj.config, reset=False)
206
data['items'] = [self.context.flatten(item, reset=False) for item in obj.items]
207
return data
208
209
def restore(self, data):
210
# Restore complex nested structure
211
config = self.context.restore(data['config'], reset=False)
212
items = [self.context.restore(item, reset=False) for item in data['items']]
213
return ComplexObject(config, items)
214
```
215
216
#### Conditional Handling
217
218
```python
219
class ConditionalHandler(BaseHandler):
220
def flatten(self, obj, data):
221
if hasattr(obj, 'special_method'):
222
data['special_data'] = obj.special_method()
223
else:
224
data['regular_data'] = obj.get_data()
225
return data
226
227
def restore(self, data):
228
if 'special_data' in data:
229
return SpecialObject.from_special_data(data['special_data'])
230
else:
231
return RegularObject.from_data(data['regular_data'])
232
```
233
234
## Handler Best Practices
235
236
1. **Error Handling**: Always handle potential errors in flatten/restore methods
237
2. **Context Usage**: Use `self.context` for recursive serialization of nested objects
238
3. **Reset Parameter**: Use `reset=False` when calling context methods from handlers
239
4. **Type Checking**: Validate data types in restore methods
240
5. **Versioning**: Consider version compatibility when designing handlers
241
6. **Performance**: Cache expensive computations where possible