summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Cook <JWCook@users.noreply.github.com>2021-11-19 15:54:15 -0600
committerGitHub <noreply@github.com>2021-11-19 15:54:15 -0600
commit06108e027cb15c4103339a1cfe99095416caf1d4 (patch)
treefac0ab51246fd6e09b6e2a59af1fc84d61e8d82f
parent40d109aef985366f845414df683c2b54af097251 (diff)
parente2e7911453c590d1f084beb81bd3d72ad0492a3e (diff)
downloadrequests-cache-06108e027cb15c4103339a1cfe99095416caf1d4.tar.gz
Merge pull request #453 from JWCook/custom-serializers
Fix some typos in docs for custom serializers
-rw-r--r--docs/user_guide/serializers.md29
-rw-r--r--requests_cache/serializers/__init__.py2
-rw-r--r--requests_cache/serializers/preconf.py1
-rw-r--r--tests/unit/test_serializers.py25
4 files changed, 39 insertions, 18 deletions
diff --git a/docs/user_guide/serializers.md b/docs/user_guide/serializers.md
index 9101731..2e3621e 100644
--- a/docs/user_guide/serializers.md
+++ b/docs/user_guide/serializers.md
@@ -111,12 +111,12 @@ For example, a compressed pickle serializer can be built as:
:::{admonition} Example code
:class: toggle
```python
->>> import pickle, gzip
->>> from requests_cache.serialzers import SerializerPipeline, Stage
+>>> import gzip
+>>> from requests_cache import CachedSession, SerializerPipeline, Stage, pickle_serializer
>>> compressed_serializer = SerializerPipeline([
-... pickle,
-... Stage(gzip, dumps='compress', loads='decompress'),
-...])
+... pickle_serializer,
+... Stage(dumps=gzip.compress, loads=gzip.decompress),
+... ])
>>> session = CachedSession(serializer=compressed_serializer)
```
:::
@@ -124,20 +124,20 @@ For example, a compressed pickle serializer can be built as:
### Text-based Serializers
If you're using a text-based serialization format like JSON or YAML, some extra steps are needed to
encode binary data and non-builtin types. The [cattrs](https://cattrs.readthedocs.io) library can do
-the majority of the work here, and some pre-configured converters are included for serveral common
+the majority of the work here, and some pre-configured converters are included for several common
formats in the {py:mod}`.preconf` module.
For example, a compressed JSON pipeline could be built as follows:
:::{admonition} Example code
:class: toggle
```python
->>> import json, gzip, codecs
->>> from requests_cache.serializers import SerializerPipeline, Stage, json_converter
+>>> import json, gzip
+>>> from requests_cache import CachedSession, SerializerPipeline, Stage, json_serializer, utf8_encoder
>>> comp_json_serializer = SerializerPipeline([
-... json_converter, # Serialize to a JSON string
-... Stage(codecs.utf_8, dumps='encode', loads='decode'), # Encode to bytes
-... Stage(gzip, dumps='compress', loads='decompress'), # Compress
-...])
+... json_serializer, # Serialize to a JSON string
+... utf8_encoder, # Encode to bytes
+... Stage(dumps=gzip.compress, loads=gzip.decompress), # Compress
+... ])
```
:::
@@ -146,11 +146,6 @@ If you want to use a different format that isn't included in {py:mod}`.preconf`,
{py:class}`.CattrStage` as a starting point.
```
-```{note}
-If you want to convert a string representation to bytes (e.g. for compression), you must use a codec
-from {py:mod}`.codecs` (typically `codecs.utf_8`)
-```
-
### Additional Serialization Steps
Some other tools that could be used as a stage in a {py:class}`.SerializerPipeline` include:
diff --git a/requests_cache/serializers/__init__.py b/requests_cache/serializers/__init__.py
index 68ead1b..085f5cb 100644
--- a/requests_cache/serializers/__init__.py
+++ b/requests_cache/serializers/__init__.py
@@ -8,6 +8,7 @@ from .preconf import (
json_serializer,
pickle_serializer,
safe_pickle_serializer,
+ utf8_encoder,
yaml_serializer,
)
@@ -22,6 +23,7 @@ __all__ = [
'safe_pickle_serializer',
'yaml_serializer',
'init_serializer',
+ 'utf8_encoder',
]
SERIALIZERS = {
diff --git a/requests_cache/serializers/preconf.py b/requests_cache/serializers/preconf.py
index 24b0546..cf9aeee 100644
--- a/requests_cache/serializers/preconf.py
+++ b/requests_cache/serializers/preconf.py
@@ -32,6 +32,7 @@ yaml_preconf_stage = CattrStage(pyyaml.make_converter) #: Pre-serialization ste
toml_preconf_stage = CattrStage(tomlkit.make_converter) #: Pre-serialization steps for TOML
ujson_preconf_stage = CattrStage(ujson.make_converter) #: Pre-serialization steps for ultrajson
pickle_serializer = SerializerPipeline([base_stage, pickle]) #: Complete pickle serializer
+utf8_encoder = Stage(dumps=str.encode, loads=lambda x: x.decode()) #: Encode to bytes
# Safe pickle serializer
diff --git a/tests/unit/test_serializers.py b/tests/unit/test_serializers.py
index a1f5e37..a9b71be 100644
--- a/tests/unit/test_serializers.py
+++ b/tests/unit/test_serializers.py
@@ -1,5 +1,6 @@
# Note: Almost all serializer logic is covered by parametrized integration tests.
# Any additional serializer-specific tests can go here.
+import gzip
import json
import sys
from importlib import reload
@@ -10,7 +11,15 @@ import pytest
from itsdangerous import Signer
from itsdangerous.exc import BadSignature
-from requests_cache import CachedResponse, CachedSession, safe_pickle_serializer
+from requests_cache import (
+ CachedResponse,
+ CachedSession,
+ SerializerPipeline,
+ Stage,
+ json_serializer,
+ safe_pickle_serializer,
+ utf8_encoder,
+)
def test_stdlib_json():
@@ -70,3 +79,17 @@ def test_cache_signing(tempfile_path):
session = CachedSession(tempfile_path, serializer=serializer)
with pytest.raises(BadSignature):
session.cache.responses['key']
+
+
+def test_custom_serializer(tempfile_path):
+ serializer = SerializerPipeline(
+ [
+ json_serializer, # Serialize to a JSON string
+ utf8_encoder, # Encode to bytes
+ Stage(dumps=gzip.compress, loads=gzip.decompress), # Compress
+ ]
+ )
+ session = CachedSession(tempfile_path, serializer=serializer)
+ response = CachedResponse()
+ session.cache.responses['key'] = response
+ assert session.cache.responses['key'] == response