diff options
| author | Jordan Cook <jordan.cook@pioneer.com> | 2022-04-09 13:33:32 -0500 |
|---|---|---|
| committer | Jordan Cook <jordan.cook@pioneer.com> | 2022-04-09 15:42:39 -0500 |
| commit | 82e68b9f917ddc78feaa19fb4d63fffe20047089 (patch) | |
| tree | 8e3b7c0babaa49780639321cdfa01f9d3c4eb473 /requests_cache/serializers | |
| parent | 9c2defeba951fc166d1d6b5079f0ae7d73dde361 (diff) | |
| download | requests-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.py | 89 |
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) |
