summaryrefslogtreecommitdiff
path: root/requests_cache/backends
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-04-19 20:27:26 -0500
committerJordan Cook <jordan.cook@pioneer.com>2022-04-19 22:07:05 -0500
commit3fb12461d847e04884f66dcf64ff5cabc79cce91 (patch)
tree5ff350315febd8c50a3c55e92d137a927111513c /requests_cache/backends
parentbb6446d6a975f1771cdb06a97e8b576330a63b0d (diff)
downloadrequests-cache-3fb12461d847e04884f66dcf64ff5cabc79cce91.tar.gz
Store responses in DynamoDB as JSON documents instead of serialized binaries
Diffstat (limited to 'requests_cache/backends')
-rw-r--r--requests_cache/backends/__init__.py8
-rw-r--r--requests_cache/backends/dynamodb.py35
-rw-r--r--requests_cache/backends/mongodb.py6
3 files changed, 31 insertions, 18 deletions
diff --git a/requests_cache/backends/__init__.py b/requests_cache/backends/__init__.py
index 250be7e..9f87908 100644
--- a/requests_cache/backends/__init__.py
+++ b/requests_cache/backends/__init__.py
@@ -15,17 +15,17 @@ logger = getLogger(__name__)
# Import all backend classes for which dependencies are installed
try:
- from .dynamodb import DynamoDbCache, DynamoDbDict
+ from .dynamodb import DynamoDbCache, DynamoDbDict, DynamoDocumentDict
except ImportError as e:
- DynamoDbCache = DynamoDbDict = get_placeholder_class(e) # type: ignore
+ DynamoDbCache = DynamoDbDict = DynamoDocumentDict = get_placeholder_class(e) # type: ignore
try:
from .gridfs import GridFSCache, GridFSPickleDict
except ImportError as e:
GridFSCache = GridFSPickleDict = get_placeholder_class(e) # type: ignore
try:
- from .mongodb import MongoCache, MongoDict, MongoPickleDict
+ from .mongodb import MongoCache, MongoDict, MongoDocumentDict
except ImportError as e:
- MongoCache = MongoDict = MongoPickleDict = get_placeholder_class(e) # type: ignore
+ MongoCache = MongoDict = MongoDocumentDict = get_placeholder_class(e) # type: ignore
try:
from .redis import RedisCache, RedisDict, RedisHashDict
except ImportError as e:
diff --git a/requests_cache/backends/dynamodb.py b/requests_cache/backends/dynamodb.py
index 17721f6..17f4661 100644
--- a/requests_cache/backends/dynamodb.py
+++ b/requests_cache/backends/dynamodb.py
@@ -12,6 +12,7 @@ from boto3.resources.base import ServiceResource
from botocore.exceptions import ClientError
from .._utils import get_valid_kwargs
+from ..serializers import dynamodb_document_serializer
from . import BaseCache, BaseStorage
@@ -30,18 +31,16 @@ class DynamoDbCache(BaseCache):
self, table_name: str = 'http_cache', connection: ServiceResource = None, **kwargs
):
super().__init__(cache_name=table_name, **kwargs)
- self.responses = DynamoDbDict(table_name, 'responses', connection=connection, **kwargs)
+ self.responses = DynamoDocumentDict(
+ table_name, 'responses', connection=connection, **kwargs
+ )
self.redirects = DynamoDbDict(
table_name, 'redirects', connection=self.responses.connection, **kwargs
)
class DynamoDbDict(BaseStorage):
- """A dictionary-like interface for DynamoDB key-value store
-
- **Notes:**
- * The actual table name on the Dynamodb server will be ``namespace:table_name``
- * In order to deal with how DynamoDB stores data, all values are serialized.
+ """A dictionary-like interface for DynamoDB table
Args:
table_name: DynamoDB table name
@@ -54,7 +53,7 @@ class DynamoDbDict(BaseStorage):
def __init__(
self,
table_name: str,
- namespace: str = 'http_cache',
+ namespace: str,
connection: ServiceResource = None,
**kwargs,
):
@@ -111,12 +110,10 @@ class DynamoDbDict(BaseStorage):
# Depending on the serializer, the value may be either a string or Binary object
raw_value = result['Item']['value']
- return self.serializer.loads(
- raw_value.value if isinstance(raw_value, Binary) else raw_value
- )
+ return raw_value.value if isinstance(raw_value, Binary) else raw_value
def __setitem__(self, key, value):
- item = {**self.composite_key(key), 'value': self.serializer.dumps(value)}
+ item = {**self.composite_key(key), 'value': value}
self._table.put_item(Item=item)
def __delitem__(self, key):
@@ -145,3 +142,19 @@ class DynamoDbDict(BaseStorage):
def clear(self):
self.bulk_delete((k for k in self))
+
+
+class DynamoDocumentDict(DynamoDbDict):
+ """Same as :class:`DynamoDbDict`, but serializes values before saving.
+
+ By default, responses are only partially serialized into a DynamoDB-compatible document format.
+ """
+
+ def __init__(self, *args, serializer=None, **kwargs):
+ super().__init__(*args, serializer=serializer or dynamodb_document_serializer, **kwargs)
+
+ def __getitem__(self, key):
+ return self.serializer.loads(super().__getitem__(key))
+
+ def __setitem__(self, key, item):
+ super().__setitem__(key, self.serializer.dumps(item))
diff --git a/requests_cache/backends/mongodb.py b/requests_cache/backends/mongodb.py
index b48f2da..056d658 100644
--- a/requests_cache/backends/mongodb.py
+++ b/requests_cache/backends/mongodb.py
@@ -30,7 +30,7 @@ class MongoCache(BaseCache):
def __init__(self, db_name: str = 'http_cache', connection: MongoClient = None, **kwargs):
super().__init__(cache_name=db_name, **kwargs)
- self.responses: MongoDict = MongoPickleDict(
+ self.responses: MongoDict = MongoDocumentDict(
db_name,
collection_name='responses',
connection=connection,
@@ -140,10 +140,10 @@ class MongoDict(BaseStorage):
self.connection.close()
-class MongoPickleDict(MongoDict):
+class MongoDocumentDict(MongoDict):
"""Same as :class:`MongoDict`, but serializes values before saving.
- By default, responses are only partially serialized into a MongoDB-compatible document mapping.
+ By default, responses are only partially serialized into a MongoDB-compatible document format.
"""
def __init__(self, *args, serializer=None, **kwargs):