0
# Serialization
1
2
JSON and YAML loading, dumping, and unified serialization interface supporting both string and file operations. The serialization system provides flexible data format handling with consistent APIs across different formats.
3
4
## Capabilities
5
6
### JSON Serialization
7
8
Core JSON loading and dumping functionality with configurable options for parsing and formatting.
9
10
```python { .api }
11
class JsonLoader:
12
"""Load JSON data from file-like objects or strings."""
13
def __init__(self, **kwargs):
14
"""
15
Initialize JSON loader with options.
16
17
Parameters:
18
- **kwargs: Arguments passed to json.loads() and json.load()
19
- parse_float: callable to parse float values
20
- parse_int: callable to parse integer values
21
- parse_constant: callable to parse constants (null, true, false)
22
- object_hook: callable to transform decoded objects
23
- object_pairs_hook: callable to transform decoded object pairs
24
"""
25
26
def __call__(self, src):
27
"""
28
Parse and return JSON data.
29
30
Parameters:
31
- src: str or file-like object containing JSON data
32
33
Returns:
34
dict: Parsed JSON data
35
36
Raises:
37
- JSONDecodeError: If JSON is malformed
38
"""
39
40
class JsonDumper:
41
"""Write JSON data to strings or file-like objects."""
42
def __init__(self, **kwargs):
43
"""
44
Initialize JSON dumper with formatting options.
45
46
Parameters:
47
- **kwargs: Arguments passed to json.dumps() and json.dump()
48
- indent: int or str for pretty-printing indentation
49
- separators: tuple of (item_separator, key_separator)
50
- sort_keys: bool to sort dictionary keys
51
- ensure_ascii: bool to escape non-ASCII characters
52
- skipkeys: bool to skip non-serializable keys
53
"""
54
55
def __call__(self, obj, dest=None):
56
"""
57
Serialize object to JSON.
58
59
Parameters:
60
- obj: Object to serialize
61
- dest: Optional file-like object to write to
62
63
Returns:
64
str: JSON string if dest is None, otherwise None
65
"""
66
```
67
68
**Usage Examples:**
69
70
```python
71
from jsondiff import JsonLoader, JsonDumper
72
import io
73
74
# Basic JSON loading
75
loader = JsonLoader()
76
data = loader('{"name": "Alice", "age": 30}')
77
print(data) # {'name': 'Alice', 'age': 30}
78
79
# Custom parsing options
80
custom_loader = JsonLoader(
81
parse_float=lambda x: round(float(x), 2), # Round floats
82
parse_int=lambda x: int(x) if int(x) < 1000 else str(x) # Large ints as strings
83
)
84
85
data = custom_loader('{"price": 123.456789, "count": 50000}')
86
print(data) # {'price': 123.46, 'count': '50000'}
87
88
# File loading
89
with open('data.json', 'r') as f:
90
data = loader(f)
91
92
# JSON dumping with formatting
93
dumper = JsonDumper(indent=2, sort_keys=True)
94
json_str = dumper({'name': 'Bob', 'age': 25})
95
print(json_str)
96
# {
97
# "age": 25,
98
# "name": "Bob"
99
# }
100
101
# Compact dumping
102
compact_dumper = JsonDumper(separators=(',', ':'))
103
compact_str = compact_dumper({'a': 1, 'b': 2})
104
print(compact_str) # {"a":1,"b":2}
105
106
# File dumping
107
with open('output.json', 'w') as f:
108
dumper({'result': 'success'}, f)
109
```
110
111
### YAML Serialization
112
113
YAML loading and dumping functionality for human-readable configuration files and data interchange.
114
115
```python { .api }
116
class YamlLoader:
117
"""Load YAML data from file-like objects or strings."""
118
def __call__(self, src):
119
"""
120
Parse and return YAML data using safe loading.
121
122
Parameters:
123
- src: str or file-like object containing YAML data
124
125
Returns:
126
dict: Parsed YAML data
127
128
Raises:
129
- YAMLError: If YAML is malformed
130
"""
131
132
class YamlDumper:
133
"""Write YAML data to strings or file-like objects."""
134
def __init__(self, **kwargs):
135
"""
136
Initialize YAML dumper with formatting options.
137
138
Parameters:
139
- **kwargs: Arguments passed to yaml.dump()
140
- indent: int for indentation level
141
- default_flow_style: bool for flow vs block style
142
- width: int for line width
143
- allow_unicode: bool to allow unicode characters
144
- sort_keys: bool to sort dictionary keys
145
"""
146
147
def __call__(self, obj, dest=None):
148
"""
149
Serialize object to YAML.
150
151
Parameters:
152
- obj: Object to serialize
153
- dest: Optional file-like object to write to
154
155
Returns:
156
str: YAML string if dest is None, otherwise None
157
"""
158
```
159
160
**Usage Examples:**
161
162
```python
163
from jsondiff import YamlLoader, YamlDumper
164
165
# Basic YAML loading
166
loader = YamlLoader()
167
yaml_data = """
168
name: Alice
169
age: 30
170
skills:
171
- Python
172
- Django
173
"""
174
175
data = loader(yaml_data)
176
print(data) # {'name': 'Alice', 'age': 30, 'skills': ['Python', 'Django']}
177
178
# File loading
179
with open('config.yaml', 'r') as f:
180
config = loader(f)
181
182
# YAML dumping with formatting
183
dumper = YamlDumper(indent=2, default_flow_style=False)
184
data = {'database': {'host': 'localhost', 'port': 5432}, 'debug': True}
185
186
yaml_str = dumper(data)
187
print(yaml_str)
188
# database:
189
# host: localhost
190
# port: 5432
191
# debug: true
192
193
# Compact flow style
194
flow_dumper = YamlDumper(default_flow_style=True)
195
compact_yaml = flow_dumper({'a': 1, 'b': [2, 3]})
196
print(compact_yaml) # {a: 1, b: [2, 3]}
197
198
# File dumping
199
with open('output.yaml', 'w') as f:
200
dumper(data, f)
201
```
202
203
### Unified Serializer
204
205
Unified interface for both JSON and YAML serialization with consistent error handling and format detection.
206
207
```python { .api }
208
class Serializer:
209
"""
210
Unified serialization helper for JSON and YAML formats.
211
"""
212
def __init__(self, file_format, indent):
213
"""
214
Initialize serializer for specific format.
215
216
Parameters:
217
- file_format: str, 'json' or 'yaml'
218
- indent: int, indentation level for output formatting
219
220
Raises:
221
- ValueError: If file_format is not supported
222
"""
223
224
def deserialize_file(self, src):
225
"""
226
Deserialize file or string in the configured format.
227
228
Parameters:
229
- src: str or file-like object containing serialized data
230
231
Returns:
232
dict: Parsed data
233
234
Raises:
235
- ValueError: If file contains invalid format data
236
"""
237
238
def serialize_data(self, obj, stream):
239
"""
240
Serialize object and write to stream.
241
242
Parameters:
243
- obj: Object to serialize
244
- stream: Writable stream to output to
245
"""
246
```
247
248
**Usage Examples:**
249
250
```python
251
from jsondiff import Serializer
252
import sys
253
254
# JSON serializer
255
json_serializer = Serializer('json', indent=2)
256
257
# Load JSON data
258
json_data = '{"users": [{"name": "Alice"}, {"name": "Bob"}]}'
259
parsed = json_serializer.deserialize_file(json_data)
260
print(parsed) # {'users': [{'name': 'Alice'}, {'name': 'Bob'}]}
261
262
# Write to stdout
263
json_serializer.serialize_data(parsed, sys.stdout)
264
265
# YAML serializer
266
yaml_serializer = Serializer('yaml', indent=2)
267
268
# Load YAML data
269
yaml_data = """
270
users:
271
- name: Alice
272
- name: Bob
273
"""
274
parsed = yaml_serializer.deserialize_file(yaml_data)
275
276
# Write to file
277
with open('output.yaml', 'w') as f:
278
yaml_serializer.serialize_data(parsed, f)
279
280
# File operations
281
with open('input.json', 'r') as input_file:
282
data = json_serializer.deserialize_file(input_file)
283
284
with open('output.json', 'w') as output_file:
285
json_serializer.serialize_data(data, output_file)
286
287
# Error handling
288
try:
289
invalid_serializer = Serializer('xml', 2)
290
except ValueError as e:
291
print(f"Unsupported format: {e}")
292
293
try:
294
bad_data = json_serializer.deserialize_file('{"invalid": json}')
295
except ValueError as e:
296
print(f"Parse error: {e}")
297
```
298
299
### Default Instances
300
301
Pre-configured loader and dumper instances for common use cases.
302
303
```python { .api }
304
# Default instances available for import
305
default_loader: JsonLoader # Default JSON loader with no special options
306
default_dumper: JsonDumper # Default JSON dumper with no special formatting
307
```
308
309
**Usage Examples:**
310
311
```python
312
from jsondiff import default_loader, default_dumper
313
314
# Use default instances directly
315
data = default_loader('{"key": "value"}')
316
json_string = default_dumper(data)
317
318
# Equivalent to
319
from jsondiff import JsonLoader, JsonDumper
320
loader = JsonLoader()
321
dumper = JsonDumper()
322
```
323
324
## Integration with JsonDiffer
325
326
The serialization classes integrate seamlessly with JsonDiffer for automatic loading and dumping.
327
328
**Usage Examples:**
329
330
```python
331
from jsondiff import JsonDiffer, JsonLoader, JsonDumper, YamlLoader, YamlDumper
332
333
# Auto-loading JSON strings
334
json_differ = JsonDiffer(load=True, loader=JsonLoader())
335
result = json_differ.diff('{"a": 1}', '{"a": 2}')
336
337
# Auto-dumping with custom formatting
338
pretty_dumper = JsonDumper(indent=4, sort_keys=True)
339
pretty_differ = JsonDiffer(dump=True, dumper=pretty_dumper)
340
json_result = pretty_differ.diff({'b': 1}, {'b': 2}) # Returns formatted JSON
341
342
# YAML workflow
343
yaml_differ = JsonDiffer(
344
load=True,
345
dump=True,
346
loader=YamlLoader(),
347
dumper=YamlDumper(default_flow_style=False)
348
)
349
350
yaml1 = "name: Alice\nage: 30"
351
yaml2 = "name: Alice\nage: 31\ncity: NYC"
352
yaml_diff = yaml_differ.diff(yaml1, yaml2) # Returns YAML string
353
354
# Mixed format processing
355
json_loader = JsonLoader()
356
yaml_dumper = YamlDumper(indent=2)
357
mixed_differ = JsonDiffer(load=True, dump=True, loader=json_loader, dumper=yaml_dumper)
358
359
# Load JSON, output YAML
360
result = mixed_differ.diff('{"a": 1}', '{"a": 2}') # JSON in, YAML out
361
```
362
363
## Error Handling and Validation
364
365
Robust error handling for malformed data and unsupported formats.
366
367
```python
368
from jsondiff import Serializer, JsonLoader, YamlLoader
369
from json import JSONDecodeError
370
from yaml import YaMLError
371
372
# Format validation
373
try:
374
bad_serializer = Serializer('unsupported_format', 2)
375
except ValueError as e:
376
print(f"Format error: {e}")
377
378
# JSON parsing errors
379
json_loader = JsonLoader()
380
try:
381
data = json_loader('{"malformed": json}')
382
except JSONDecodeError as e:
383
print(f"JSON error: {e}")
384
385
# YAML parsing errors
386
yaml_loader = YamlLoader()
387
try:
388
data = yaml_loader('malformed: yaml: content:')
389
except YAMLError as e:
390
print(f"YAML error: {e}")
391
392
# File handling errors
393
serializer = Serializer('json', 2)
394
try:
395
with open('nonexistent.json', 'r') as f:
396
data = serializer.deserialize_file(f)
397
except FileNotFoundError as e:
398
print(f"File error: {e}")
399
```