0
# Serializers
1
2
Serialization formats for persisting HTTP request/response pairs with metadata. Hishel provides multiple serializers for different use cases, from binary Pickle format to human-readable JSON and YAML formats.
3
4
## Capabilities
5
6
### Base Serializer
7
8
Abstract base class defining the serializer interface for converting HTTP requests/responses to/from storage formats.
9
10
```python { .api }
11
class BaseSerializer:
12
def dumps(self, response: Response, request: Request, metadata: Metadata) -> str | bytes:
13
"""
14
Serialize HTTP response, request, and metadata.
15
16
Parameters:
17
- response: HTTP response object
18
- request: HTTP request object
19
- metadata: Cache metadata dictionary
20
21
Returns:
22
- Serialized data as string or bytes
23
"""
24
25
def loads(self, data: str | bytes) -> tuple[Response, Request, Metadata]:
26
"""
27
Deserialize data back to HTTP response, request, and metadata.
28
29
Parameters:
30
- data: Serialized data as string or bytes
31
32
Returns:
33
- Tuple of (Response, Request, Metadata)
34
"""
35
36
@property
37
def is_binary(self) -> bool:
38
"""Whether this serializer produces binary data"""
39
```
40
41
### Pickle Serializer
42
43
Binary serializer using Python's pickle format for compact and fast serialization.
44
45
```python { .api }
46
class PickleSerializer(BaseSerializer):
47
def dumps(self, response: Response, request: Request, metadata: Metadata) -> bytes:
48
"""
49
Serialize using pickle format.
50
51
Parameters:
52
- response: HTTP response object
53
- request: HTTP request object
54
- metadata: Cache metadata dictionary
55
56
Returns:
57
- Pickled data as bytes
58
"""
59
60
def loads(self, data: bytes) -> tuple[Response, Request, Metadata]:
61
"""
62
Deserialize pickle data.
63
64
Parameters:
65
- data: Pickled data as bytes
66
67
Returns:
68
- Tuple of (Response, Request, Metadata)
69
"""
70
71
@property
72
def is_binary(self) -> bool:
73
"""Returns True (pickle produces binary data)"""
74
```
75
76
**Usage Examples:**
77
78
```python
79
import hishel
80
81
# Use pickle serializer for compact storage
82
serializer = hishel.PickleSerializer()
83
84
# Use with file storage
85
storage = hishel.FileStorage(serializer=serializer)
86
with hishel.CacheClient(storage=storage) as client:
87
response = client.get("https://api.example.com/data")
88
89
# Pickle is fastest and most compact but not human-readable
90
```
91
92
### JSON Serializer
93
94
Text-based serializer using JSON format for human-readable and cross-language compatible storage.
95
96
```python { .api }
97
class JSONSerializer(BaseSerializer):
98
def dumps(self, response: Response, request: Request, metadata: Metadata) -> str:
99
"""
100
Serialize using JSON format.
101
102
Parameters:
103
- response: HTTP response object
104
- request: HTTP request object
105
- metadata: Cache metadata dictionary
106
107
Returns:
108
- JSON string with formatted data
109
"""
110
111
def loads(self, data: str) -> tuple[Response, Request, Metadata]:
112
"""
113
Deserialize JSON data.
114
115
Parameters:
116
- data: JSON string
117
118
Returns:
119
- Tuple of (Response, Request, Metadata)
120
"""
121
122
@property
123
def is_binary(self) -> bool:
124
"""Returns False (JSON produces text data)"""
125
```
126
127
**Usage Examples:**
128
129
```python
130
import hishel
131
132
# Use JSON serializer (default for most storage backends)
133
serializer = hishel.JSONSerializer()
134
135
# JSON format is human-readable and debuggable
136
storage = hishel.FileStorage(serializer=serializer)
137
with hishel.CacheClient(storage=storage) as client:
138
response = client.get("https://api.example.com/data")
139
140
# Cached files can be inspected and edited manually
141
```
142
143
### YAML Serializer
144
145
Text-based serializer using YAML format for the most human-readable storage format.
146
147
```python { .api }
148
class YAMLSerializer(BaseSerializer):
149
def dumps(self, response: Response, request: Request, metadata: Metadata) -> str:
150
"""
151
Serialize using YAML format.
152
153
Parameters:
154
- response: HTTP response object
155
- request: HTTP request object
156
- metadata: Cache metadata dictionary
157
158
Returns:
159
- YAML string with formatted data
160
161
Raises:
162
- RuntimeError: If PyYAML is not installed
163
"""
164
165
def loads(self, data: str) -> tuple[Response, Request, Metadata]:
166
"""
167
Deserialize YAML data.
168
169
Parameters:
170
- data: YAML string
171
172
Returns:
173
- Tuple of (Response, Request, Metadata)
174
175
Raises:
176
- RuntimeError: If PyYAML is not installed
177
"""
178
179
@property
180
def is_binary(self) -> bool:
181
"""Returns False (YAML produces text data)"""
182
```
183
184
**Usage Examples:**
185
186
```python
187
import hishel
188
189
# YAML serializer requires pyyaml: pip install hishel[yaml]
190
serializer = hishel.YAMLSerializer()
191
192
# YAML is the most readable format for debugging
193
storage = hishel.FileStorage(serializer=serializer)
194
with hishel.CacheClient(storage=storage) as client:
195
response = client.get("https://api.example.com/data")
196
```
197
198
## Metadata Structure
199
200
Cache metadata contains information about cached responses:
201
202
```python { .api }
203
class Metadata(TypedDict):
204
number_of_uses: int # How many times response was served from cache
205
created_at: datetime # When response was first cached
206
cache_key: str # Cache key for the cached response
207
```
208
209
## Model Cloning
210
211
Utility function for cloning HTTP request/response objects for serialization:
212
213
```python { .api }
214
def clone_model(model: Request | Response) -> Request | Response:
215
"""
216
Clone HTTP request or response object for safe serialization.
217
218
Parameters:
219
- model: Request or Response object to clone
220
221
Returns:
222
- Cloned object with only serializable extensions
223
224
Note: Only includes known safe extensions for serialization.
225
"""
226
```
227
228
**Usage Examples:**
229
230
```python
231
from httpcore import Request, Response
232
import hishel
233
234
# Clone for safe serialization
235
request = Request(b"GET", b"https://api.example.com/data")
236
safe_request = hishel.clone_model(request)
237
238
response = Response(200, [(b"content-type", b"application/json")])
239
safe_response = hishel.clone_model(response)
240
```
241
242
## Serializer Comparison
243
244
| Serializer | Format | Size | Speed | Human Readable | Cross-Language |
245
|------------|--------|------|-------|----------------|----------------|
246
| Pickle | Binary | Small| Fast | No | No (Python only) |
247
| JSON | Text | Medium| Medium| Yes | Yes |
248
| YAML | Text | Large| Slow | Very Good | Yes |
249
250
## Custom Serializers
251
252
You can create custom serializers by inheriting from BaseSerializer:
253
254
```python
255
import json
256
from typing import Union
257
from httpcore import Request, Response
258
import hishel
259
260
class CustomJSONSerializer(hishel.BaseSerializer):
261
def dumps(self, response: Response, request: Request, metadata: hishel.Metadata) -> str:
262
# Custom serialization logic
263
data = {
264
"response": {
265
"status": response.status,
266
"headers": dict(response.headers),
267
"content": response.content.decode('utf-8', errors='ignore')
268
},
269
"request": {
270
"method": request.method.decode(),
271
"url": str(request.url)
272
},
273
"metadata": metadata
274
}
275
return json.dumps(data, indent=2)
276
277
def loads(self, data: str) -> tuple[Response, Request, hishel.Metadata]:
278
# Custom deserialization logic
279
parsed = json.loads(data)
280
# Reconstruct objects...
281
return response, request, metadata
282
283
@property
284
def is_binary(self) -> bool:
285
return False
286
287
# Use custom serializer
288
storage = hishel.FileStorage(serializer=CustomJSONSerializer())
289
```
290
291
## Installation Requirements
292
293
YAML serializer requires additional dependency:
294
295
```bash
296
# Install with YAML support
297
pip install hishel[yaml]
298
299
# Or install PyYAML separately
300
pip install pyyaml
301
```