summaryrefslogtreecommitdiff
path: root/requests_cache
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-04-22 17:29:33 -0500
committerJordan Cook <jordan.cook@pioneer.com>2022-04-22 17:57:22 -0500
commit1a4468abb249ec3ea2c1a774bd14fded14e28d69 (patch)
tree8264fe9b6fd727553ec1ff2a4961b0b6564bfa81 /requests_cache
parent0dbd82d4d28875f2c0a592dfc89f50bf1c63cb2b (diff)
downloadrequests-cache-1a4468abb249ec3ea2c1a774bd14fded14e28d69.tar.gz
For SQLite expires column, use time.time() instead of datetime.timestamp()
Diffstat (limited to 'requests_cache')
-rw-r--r--requests_cache/backends/dynamodb.py5
-rw-r--r--requests_cache/backends/redis.py8
-rw-r--r--requests_cache/backends/sqlite.py20
-rwxr-xr-xrequests_cache/models/response.py11
4 files changed, 24 insertions, 20 deletions
diff --git a/requests_cache/backends/dynamodb.py b/requests_cache/backends/dynamodb.py
index f39d267..8411028 100644
--- a/requests_cache/backends/dynamodb.py
+++ b/requests_cache/backends/dynamodb.py
@@ -4,7 +4,6 @@
:classes-only:
:nosignatures:
"""
-from time import time
from typing import Dict, Iterable
import boto3
@@ -151,8 +150,8 @@ class DynamoDbDict(BaseStorage):
item = {**self._composite_key(key), 'value': self.serialize(value)}
# If enabled, set TTL value as a timestamp in unix format
- if self.ttl and getattr(value, 'ttl', None):
- item['ttl'] = round(time() + value.ttl)
+ if self.ttl and getattr(value, 'expires_unix', None):
+ item['ttl'] = value.expires_unix
self._table.put_item(Item=item)
diff --git a/requests_cache/backends/redis.py b/requests_cache/backends/redis.py
index 76c83c1..d61bc95 100644
--- a/requests_cache/backends/redis.py
+++ b/requests_cache/backends/redis.py
@@ -17,7 +17,7 @@ logger = getLogger(__name__)
# TODO: TTL tests
-# TODO: Option to set a different (typically longer) TTL than expire_after, like MongoCache
+# TODO: Option to set a TTL offset, for longer expiration than expire_after
class RedisCache(BaseCache):
"""Redis cache backend.
@@ -79,9 +79,9 @@ class RedisDict(BaseStorage):
def __setitem__(self, key, item):
"""Save an item to the cache, optionally with TTL"""
- ttl_seconds = getattr(item, 'ttl', None)
- if self.ttl and ttl_seconds and ttl_seconds > 0:
- self.connection.setex(self._bkey(key), round(ttl_seconds), self.serialize(item))
+ expires_delta = getattr(item, 'expires_delta', None)
+ if self.ttl and (expires_delta or 0) > 0:
+ self.connection.setex(self._bkey(key), expires_delta, self.serialize(item))
else:
self.connection.set(self._bkey(key), self.serialize(item))
diff --git a/requests_cache/backends/sqlite.py b/requests_cache/backends/sqlite.py
index cb15697..74e0d71 100644
--- a/requests_cache/backends/sqlite.py
+++ b/requests_cache/backends/sqlite.py
@@ -7,18 +7,17 @@
import sqlite3
import threading
from contextlib import contextmanager
-from datetime import datetime
from logging import getLogger
from os import unlink
from os.path import isfile
from pathlib import Path
from tempfile import gettempdir
+from time import time
from typing import Collection, Iterator, List, Tuple, Type, Union
from platformdirs import user_cache_dir
from .._utils import chunkify, get_valid_kwargs
-from ..models import CachedResponse
from ..policy.expiration import ExpirationTime
from . import BaseCache, BaseStorage
@@ -219,14 +218,15 @@ class SQLiteDict(BaseStorage):
return self.deserialize(row[0])
def __setitem__(self, key, value):
- self._insert(key, value)
-
- def _insert(self, key, value, expires: datetime = None):
- posix_expires = round(expires.timestamp()) if expires else None
+ # If available, set expiration as a timestamp in unix format
+ expires = value.expires_unix if getattr(value, 'expires_unix', None) else None
+ value = self.serialize(value)
+ if isinstance(value, bytes):
+ value = sqlite3.Binary(value)
with self.connection(commit=True) as con:
con.execute(
f'INSERT OR REPLACE INTO {self.table_name} (key,value,expires) VALUES (?,?,?)',
- (key, value, posix_expires),
+ (key, value, expires),
)
def __iter__(self):
@@ -262,9 +262,8 @@ class SQLiteDict(BaseStorage):
def clear_expired(self):
"""Remove expired items from the cache"""
- posix_now = round(datetime.utcnow().timestamp())
with self._lock, self.connection(commit=True) as con:
- con.execute(f"DELETE FROM {self.table_name} WHERE expires <= ?", (posix_now,))
+ con.execute(f"DELETE FROM {self.table_name} WHERE expires <= ?", (round(time()),))
self.vacuum()
def sorted(
@@ -283,9 +282,8 @@ class SQLiteDict(BaseStorage):
filter_expr = ''
params: Tuple = ()
if exclude_expired:
- posix_now = round(datetime.utcnow().timestamp())
filter_expr = 'WHERE expires is null or expires > ?'
- params = (posix_now,)
+ params = (time(),)
with self.connection(commit=True) as con:
for row in con.execute(
diff --git a/requests_cache/models/response.py b/requests_cache/models/response.py
index fe6e4da..9ad3a1a 100755
--- a/requests_cache/models/response.py
+++ b/requests_cache/models/response.py
@@ -2,6 +2,7 @@ from __future__ import annotations
from datetime import datetime, timedelta, timezone
from logging import getLogger
+from time import time
from typing import TYPE_CHECKING, List, Optional
import attr
@@ -134,12 +135,18 @@ class CachedResponse(BaseResponse, RichMixin):
return self.expires is not None and datetime.utcnow() >= self.expires
@property
- def ttl(self) -> Optional[float]:
+ def expires_delta(self) -> Optional[int]:
"""Get time to expiration in seconds (rounded to the nearest second)"""
if self.expires is None:
return None
delta = self.expires - datetime.utcnow()
- return delta.total_seconds()
+ return round(delta.total_seconds())
+
+ @property
+ def expires_unix(self) -> Optional[int]:
+ """Get expiration time as a Unix timestamp"""
+ seconds = self.expires_delta
+ return round(time() + seconds) if seconds else None
@property
def next(self) -> Optional[PreparedRequest]: