summaryrefslogtreecommitdiff
path: root/requests_cache/serializers
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-04-15 14:48:24 -0500
committerJordan Cook <jordan.cook@pioneer.com>2022-04-15 14:49:54 -0500
commit3f6d48707e26e103dfb0029ecb33c520ed21bf1b (patch)
tree27fea0a22208097fa4339d8815a27b50e7ab1069 /requests_cache/serializers
parent8641b93fa298d9edf8ef91a03a7a2d0af6d5810e (diff)
downloadrequests-cache-3f6d48707e26e103dfb0029ecb33c520ed21bf1b.tar.gz
Use BSON preconf stage and store response values under top-level keys, so created_at attribute is compatible with TTL index
Diffstat (limited to 'requests_cache/serializers')
-rw-r--r--requests_cache/serializers/__init__.py2
-rw-r--r--requests_cache/serializers/cattrs.py24
-rw-r--r--requests_cache/serializers/preconf.py9
3 files changed, 25 insertions, 10 deletions
diff --git a/requests_cache/serializers/__init__.py b/requests_cache/serializers/__init__.py
index dc78489..91c5e4c 100644
--- a/requests_cache/serializers/__init__.py
+++ b/requests_cache/serializers/__init__.py
@@ -19,6 +19,7 @@ __all__ = [
'SerializerPipeline',
'Stage',
'bson_serializer',
+ 'dict_serializer',
'json_serializer',
'pickle_serializer',
'safe_pickle_serializer',
@@ -29,7 +30,6 @@ __all__ = [
SERIALIZERS = {
'bson': bson_serializer,
- 'dict': dict_serializer,
'json': json_serializer,
'pickle': pickle_serializer,
'yaml': yaml_serializer,
diff --git a/requests_cache/serializers/cattrs.py b/requests_cache/serializers/cattrs.py
index e0bde94..da7fd79 100644
--- a/requests_cache/serializers/cattrs.py
+++ b/requests_cache/serializers/cattrs.py
@@ -28,8 +28,8 @@ class CattrStage(Stage):
on its own, or as a stage within a :py:class:`.SerializerPipeline`.
"""
- def __init__(self, factory: Callable[..., GenConverter] = None):
- self.converter = init_converter(factory)
+ def __init__(self, factory: Callable[..., GenConverter] = None, **kwargs):
+ self.converter = init_converter(factory, **kwargs)
def dumps(self, value: CachedResponse) -> Dict:
if not isinstance(value, CachedResponse):
@@ -42,14 +42,22 @@ class CattrStage(Stage):
return self.converter.structure(value, cl=CachedResponse)
-def init_converter(factory: Callable[..., GenConverter] = None):
- """Make a converter to structure and unstructure nested objects within a :py:class:`.CachedResponse`"""
+def init_converter(factory: Callable[..., GenConverter] = None, convert_datetime: bool = True):
+ """Make a converter to structure and unstructure nested objects within a
+ :py:class:`.CachedResponse`
+
+ Args:
+ factory: An optional factory function that returns a ``cattrs`` converter
+ convert_datetime: May be set to ``False`` for pre-configured converters that already have
+ datetime support
+ """
factory = factory or GenConverter
converter = factory(omit_if_default=True)
# Convert datetimes to and from iso-formatted strings
- converter.register_unstructure_hook(datetime, lambda obj: obj.isoformat() if obj else None) # type: ignore
- converter.register_structure_hook(datetime, _to_datetime)
+ if convert_datetime:
+ converter.register_unstructure_hook(datetime, lambda obj: obj.isoformat() if obj else None) # type: ignore
+ converter.register_structure_hook(datetime, _to_datetime)
# Convert timedeltas to and from float values in seconds
converter.register_unstructure_hook(timedelta, lambda obj: obj.total_seconds() if obj else None) # type: ignore
@@ -66,6 +74,10 @@ def init_converter(factory: Callable[..., GenConverter] = None):
converter.register_structure_hook(HTTPHeaderDict, lambda obj, cls: HTTPHeaderDict(obj))
# Tell cattrs to resolve forward references (required for CachedResponse.history)
+ converter.register_unstructure_hook_func(
+ lambda cls: cls.__class__ is ForwardRef,
+ lambda obj, cls=None: converter.unstructure(obj, cls.__forward_value__ if cls else None),
+ )
converter.register_structure_hook_func(
lambda cls: cls.__class__ is ForwardRef,
lambda obj, cls: converter.structure(obj, cls.__forward_value__),
diff --git a/requests_cache/serializers/preconf.py b/requests_cache/serializers/preconf.py
index 1236c44..b0ad069 100644
--- a/requests_cache/serializers/preconf.py
+++ b/requests_cache/serializers/preconf.py
@@ -22,10 +22,11 @@ from .cattrs import CattrStage
from .pipeline import SerializerPipeline, Stage
-def make_stage(preconf_module: str):
+def make_stage(preconf_module: str, **kwargs):
"""Create a preconf serializer stage from a module name, if dependencies are installed"""
try:
- return CattrStage(import_module(preconf_module).make_converter)
+ factory = import_module(preconf_module).make_converter
+ return CattrStage(factory, **kwargs)
except ImportError as e:
return get_placeholder_class(e)
@@ -33,7 +34,9 @@ def make_stage(preconf_module: str):
# Pre-serialization stages
base_stage = CattrStage() #: Base stage for all serializer pipelines
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
+bson_preconf_stage = make_stage(
+ 'cattr.preconf.bson', convert_datetime=False
+) #: 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