summaryrefslogtreecommitdiff
path: root/requests_cache/serializers
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-04-09 13:33:32 -0500
committerJordan Cook <jordan.cook@pioneer.com>2022-04-09 15:42:39 -0500
commit82e68b9f917ddc78feaa19fb4d63fffe20047089 (patch)
tree8e3b7c0babaa49780639321cdfa01f9d3c4eb473 /requests_cache/serializers
parent9c2defeba951fc166d1d6b5079f0ae7d73dde361 (diff)
downloadrequests-cache-82e68b9f917ddc78feaa19fb4d63fffe20047089.tar.gz
Add compatibility with cattrs 21.1+, and clean up preconf module a bit
Diffstat (limited to 'requests_cache/serializers')
-rw-r--r--requests_cache/serializers/preconf.py89
1 files changed, 48 insertions, 41 deletions
diff --git a/requests_cache/serializers/preconf.py b/requests_cache/serializers/preconf.py
index ed19fb4..cb099b8 100644
--- a/requests_cache/serializers/preconf.py
+++ b/requests_cache/serializers/preconf.py
@@ -1,3 +1,4 @@
+# flake8: noqa: F841
"""The ``cattrs`` library includes a number of `pre-configured converters
<https://cattrs.readthedocs.io/en/latest/preconf.html>`_ that perform some pre-serialization steps
required for specific serialization formats.
@@ -14,69 +15,75 @@ class that raises an ``ImportError`` at initialization time instead of at import
"""
import pickle
from functools import partial
-
-from cattr.preconf import bson as bson_preconf
-from cattr.preconf import json as json_preconf
-from cattr.preconf import msgpack, orjson, pyyaml, tomlkit, ujson
+from importlib import import_module
from .._utils import get_placeholder_class
from .cattrs import CattrStage
from .pipeline import SerializerPipeline, Stage
-base_stage = (
- CattrStage()
-) #: Base stage for all serializer pipelines (or standalone dict serializer)
+
+def make_stage(preconf_module: str):
+ """Create a preconf serializer stage from a module name, if dependencies are installed"""
+ try:
+ return CattrStage(import_module(preconf_module).make_converter)
+ except ImportError as e:
+ return get_placeholder_class(e)
+
+
+base_stage = CattrStage() #: Base stage for all serializer pipelines
dict_serializer = base_stage #: Partial serializer that unstructures responses into dicts
-bson_preconf_stage = CattrStage(bson_preconf.make_converter) #: Pre-serialization steps for BSON
-json_preconf_stage = CattrStage(json_preconf.make_converter) #: Pre-serialization steps for JSON
-msgpack_preconf_stage = CattrStage(msgpack.make_converter) #: Pre-serialization steps for msgpack
-orjson_preconf_stage = CattrStage(orjson.make_converter) #: Pre-serialization steps for orjson
-yaml_preconf_stage = CattrStage(pyyaml.make_converter) #: Pre-serialization steps for YAML
-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], is_binary=True
-) #: Complete pickle serializer
+pickle_serializer = SerializerPipeline([base_stage, pickle], is_binary=True) #: Pickle serializer
utf8_encoder = Stage(dumps=str.encode, loads=lambda x: x.decode()) #: Encode to bytes
+bson_preconf_stage = make_stage('cattr.preconf.bson') #: Pre-serialization steps for BSON
+json_preconf_stage = make_stage('cattr.preconf.json') #: Pre-serialization steps for JSON
+msgpack_preconf_stage = make_stage('cattr.preconf.msgpack') #: Pre-serialization steps for msgpack
+orjson_preconf_stage = make_stage('cattr.preconf.orjson') #: Pre-serialization steps for orjson
+toml_preconf_stage = make_stage('cattr.preconf.tomlkit') #: Pre-serialization steps for TOML
+ujson_preconf_stage = make_stage('cattr.preconf.ujson') #: Pre-serialization steps for ultrajson
+yaml_preconf_stage = make_stage('cattr.preconf.pyyaml') #: Pre-serialization steps for YAML
# Safe pickle serializer
-try:
+def signer_stage(secret_key=None, salt='requests-cache') -> Stage:
+ """Create a stage that uses ``itsdangerous`` to add a signature to responses on write, and
+ validate that signature with a secret key on read. Can be used in a
+ :py:class:`.SerializerPipeline` in combination with any other serialization steps.
+ """
from itsdangerous import Signer
- def signer_stage(secret_key=None, salt='requests-cache') -> Stage:
- """Create a stage that uses ``itsdangerous`` to add a signature to responses on write, and
- validate that signature with a secret key on read. Can be used in a
- :py:class:`.SerializerPipeline` in combination with any other serialization steps.
- """
- return Stage(Signer(secret_key=secret_key, salt=salt), dumps='sign', loads='unsign')
-
- def safe_pickle_serializer(
- secret_key=None, salt='requests-cache', **kwargs
- ) -> SerializerPipeline:
- """Create a serializer that uses ``pickle`` + ``itsdangerous`` to add a signature to
- responses on write, and validate that signature with a secret key on read.
- """
- return SerializerPipeline(
- [base_stage, pickle, signer_stage(secret_key, salt)], is_binary=True
- )
+ return Stage(Signer(secret_key=secret_key, salt=salt), dumps='sign', loads='unsign')
+
+
+def safe_pickle_serializer(secret_key=None, salt='requests-cache', **kwargs) -> SerializerPipeline:
+ """Create a serializer that uses ``pickle`` + ``itsdangerous`` to add a signature to
+ responses on write, and validate that signature with a secret key on read.
+ """
+ return SerializerPipeline([base_stage, pickle, signer_stage(secret_key, salt)], is_binary=True)
+
+try:
+ import itsdangerous # noqa: F401
except ImportError as e:
signer_stage = get_placeholder_class(e)
safe_pickle_serializer = get_placeholder_class(e)
-# BSON serializer
-try:
+def _get_bson_functions():
+ """Handle different function names between pymongo's bson and standalone bson"""
try:
- from bson import decode as _bson_loads
- from bson import encode as _bson_dumps
+ import pymongo # noqa: F401
+
+ return {'dumps': 'encode', 'loads': 'decode'}
except ImportError:
- from bson import dumps as _bson_dumps
- from bson import loads as _bson_loads
+ return {'dumps': 'dumps', 'loads': 'loads'}
+
+
+# BSON serializer
+try:
+ import bson
bson_serializer = SerializerPipeline(
- [bson_preconf_stage, Stage(dumps=_bson_dumps, loads=_bson_loads)], is_binary=True
+ [bson_preconf_stage, Stage(bson, **_get_bson_functions())], is_binary=True
) #: Complete BSON serializer; uses pymongo's ``bson`` if installed, otherwise standalone ``bson`` codec
except ImportError as e:
bson_serializer = get_placeholder_class(e)