Skip to content
4 changes: 3 additions & 1 deletion aiohttp_client_cache/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ def __init__(
self.responses: BaseCache = DictCache()

self.include_headers = include_headers

# Converted to `set` for fast `in` checks inside `filter_ignored_params`.
self.ignored_params = set(ignored_params or [])

@property
Expand Down Expand Up @@ -164,7 +166,7 @@ async def get_response(self, key: str) -> CachedResponse | None:
# Attempt to fetch the cached response
logger.debug(f'Attempting to get cached response for key: {key}')
try:
response = await self.responses.read(key) or await self._get_redirect_response(str(key))
response = await self.responses.read(key) or await self._get_redirect_response(key)
# Catch "quiet" deserialization errors due to upgrading attrs
if response is not None:
assert response.method # type: ignore
Expand Down
6 changes: 2 additions & 4 deletions aiohttp_client_cache/backends/mongodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ async def bulk_delete(self, keys: set):
await self.collection.delete_many(spec)

async def delete(self, key: str):
spec = {'_id': key}
await self.collection.delete_one(spec)
await self.collection.delete_one({'_id': key})

async def keys(self) -> AsyncIterable[str]:
async for doc in self.collection.find({}, {'_id': True}):
Expand All @@ -96,8 +95,7 @@ async def values(self) -> AsyncIterable[ResponseOrKey]:
yield doc['data']

async def write(self, key: str, item: ResponseOrKey):
update = {'$set': {'data': item}}
await self.collection.update_one({'_id': key}, update, upsert=True)
await self.collection.update_one({'_id': key}, {'$set': {'data': item}}, upsert=True)


class MongoDBPickleCache(MongoDBCache):
Expand Down
6 changes: 5 additions & 1 deletion aiohttp_client_cache/cache_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def create_key(
return key.hexdigest()


def filter_ignored_params(data, ignored_params: Iterable[str]):
def filter_ignored_params(
data,
# Always a set internally, but keep the public utility parameter as-is to avoid breaking changes.
ignored_params: Iterable[str],
):
"""Remove any ignored params from an object, if it's dict-like"""
if not isinstance(data, Mapping) or not ignored_params:
return data
Expand Down
4 changes: 2 additions & 2 deletions aiohttp_client_cache/signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def extend_signature(super_function: Callable, *extra_functions: Callable) -> Ca
def wrapper(target_function: Callable):
try:
target_function = copy_docstrings(target_function, super_function, *extra_functions)
revision = get_combined_revision(target_function, super_function, *extra_functions)
revision = merge_signatures(target_function, super_function, *extra_functions)
return revision(target_function)
except Exception as e:
logger.debug(e)
Expand All @@ -46,7 +46,7 @@ def wrapper(target_function: Callable):
return wrapper


def get_combined_revision(*functions: Callable):
def merge_signatures(*functions: Callable):
"""Combine the parameters of all revisions into a single revision"""
import forge

Expand Down
23 changes: 1 addition & 22 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import logging
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from datetime import datetime
from os import getenv
from tempfile import NamedTemporaryFile

import pytest

from aiohttp_client_cache import CachedResponse, CachedSession, SQLiteBackend
from aiohttp_client_cache import CachedResponse

ALL_METHODS = ['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
CACHE_NAME = 'pytest_cache'
Expand Down Expand Up @@ -53,22 +48,6 @@ def httpbin_custom(path: str = ''):
return base_url + path


@pytest.fixture(scope='function')
async def tempfile_session():
""":py:func:`.get_tempfile_session` as a pytest fixture"""
async with get_tempfile_session() as session:
yield session


@asynccontextmanager
async def get_tempfile_session(**kwargs) -> AsyncIterator[CachedSession]:
"""Get a CachedSession using a temporary SQLite db"""
with NamedTemporaryFile(suffix='.db') as temp:
cache = SQLiteBackend(cache_name=temp.name, allowed_methods=ALL_METHODS, **kwargs)
async with CachedSession(cache=cache) as session:
yield session


def assert_delta_approx_equal(dt1: datetime, dt2: datetime, target_delta, threshold_seconds=2):
"""Assert that the given datetimes are approximately ``target_delta`` seconds apart"""
diff_in_seconds = (dt2 - dt1).total_seconds()
Expand Down
4 changes: 2 additions & 2 deletions test/integration/test_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
def is_db_running():
"""Test if a Redis server is running locally on the default port"""

async def get_db_info():
async def probe_redis():
client = await from_url(DEFAULT_ADDRESS)
await client.info()
await client.aclose() # type: ignore[attr-defined]

try:
asyncio.run(get_db_info())
asyncio.run(probe_redis())
return True
except OSError as e:
print(e)
Expand Down
37 changes: 19 additions & 18 deletions test/unit/test_base_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
TEST_URL = 'https://test.com'


def get_mock_response(**kwargs):
def make_mock_cached_response(**kwargs):
response_kwargs = {
'url': TEST_URL,
'method': 'GET',
Expand Down Expand Up @@ -40,7 +40,7 @@ def __init__(self):

async def test_get_response__cache_response_hit():
cache = CacheBackend()
mock_response = get_mock_response()
mock_response = make_mock_cached_response()
await cache.responses.write('request-key', mock_response)

response = await cache.get_response('request-key')
Expand All @@ -50,7 +50,7 @@ async def test_get_response__cache_response_hit():
async def test_get_response__cache_redirect_hit():
# Set up a cache with a couple cached items and a redirect
cache = CacheBackend()
mock_response = get_mock_response()
mock_response = make_mock_cached_response()
await cache.responses.write('request-key', mock_response)
await cache.redirects.write('redirect-key', 'request-key')

Expand All @@ -60,9 +60,8 @@ async def test_get_response__cache_redirect_hit():

@patch.object(CacheBackend, 'delete')
async def test_get_response__cache_miss(mock_delete):
cache = CacheBackend()

response_1 = await cache.get_response('nonexistent-key')
response_1 = await CacheBackend().get_response('nonexistent-key')
assert response_1 is None
mock_delete.assert_not_called()

Expand All @@ -71,7 +70,7 @@ async def test_get_response__cache_miss(mock_delete):
@patch.object(CacheBackend, 'is_cacheable', return_value=False)
async def test_get_response__cache_expired(mock_is_cacheable, mock_delete):
cache = CacheBackend()
mock_response = get_mock_response(is_expired=True)
mock_response = make_mock_cached_response(is_expired=True)
await cache.responses.write('request-key', mock_response)

response = await cache.get_response('request-key')
Expand All @@ -85,7 +84,7 @@ async def test_get_response__cache_expired(mock_is_cacheable, mock_delete):
async def test_get_response__cache_invalid(mock_read, mock_delete, error_type):
cache = CacheBackend()
mock_read.side_effect = error_type
mock_response = get_mock_response()
mock_response = make_mock_cached_response()
await cache.responses.write('request-key', mock_response)

response = await cache.get_response('request-key')
Expand All @@ -99,7 +98,7 @@ async def test_get_response__quiet_serde_error(mock_read):
missing
"""
cache = CacheBackend()
mock_response = get_mock_response()
mock_response = make_mock_cached_response()
await cache.responses.write('request-key', mock_response)

response = await cache.get_response('request-key')
Expand All @@ -108,7 +107,7 @@ async def test_get_response__quiet_serde_error(mock_read):

async def test_save_response():
cache = CacheBackend()
mock_response = get_mock_response()
mock_response = make_mock_cached_response()
mock_response.history = [MagicMock(method='GET', url='test')]
redirect_key = cache.create_key('GET', 'test')

Expand All @@ -121,7 +120,7 @@ async def test_save_response():
async def test_save_response__manual_save():
"""Manually save a response with no cache key provided"""
cache = CacheBackend()
mock_response = get_mock_response()
mock_response = make_mock_cached_response()

await cache.save_response(mock_response)
cached_response = [r async for r in cache.responses.values()][0]
Expand All @@ -140,7 +139,7 @@ async def test_clear():

async def test_delete():
cache = CacheBackend()
mock_response = get_mock_response()
mock_response = make_mock_cached_response()
mock_response.history = [MagicMock(method='GET', url='test')]
redirect_key = cache.create_key('GET', 'test')

Expand All @@ -155,8 +154,8 @@ async def test_delete():

async def test_delete_expired_responses():
cache = CacheBackend()
await cache.responses.write('request-key-1', get_mock_response(is_expired=False))
await cache.responses.write('request-key-2', get_mock_response(is_expired=True))
await cache.responses.write('request-key-1', make_mock_cached_response(is_expired=False))
await cache.responses.write('request-key-2', make_mock_cached_response(is_expired=True))

assert await cache.responses.size() == 2
await cache.delete_expired_responses()
Expand All @@ -165,7 +164,7 @@ async def test_delete_expired_responses():

async def test_delete_url():
cache = CacheBackend()
mock_response = await CachedResponse.from_client_response(get_mock_response())
mock_response = await CachedResponse.from_client_response(make_mock_cached_response())
cache_key = cache.create_key('GET', TEST_URL, params={'param': 'value'})

await cache.responses.write(cache_key, mock_response)
Expand All @@ -176,7 +175,7 @@ async def test_delete_url():

async def test_has_url():
cache = CacheBackend()
mock_response = await CachedResponse.from_client_response(get_mock_response())
mock_response = await CachedResponse.from_client_response(make_mock_cached_response())
cache_key = cache.create_key('GET', TEST_URL, params={'param': 'value'})

await cache.responses.write(cache_key, mock_response)
Expand Down Expand Up @@ -204,7 +203,7 @@ async def test_create_key(mock_create_key):
async def test_get_urls():
cache = CacheBackend()
for i in range(7):
mock_response = get_mock_response(url=f'https://test.com/{i}')
mock_response = make_mock_cached_response(url=f'https://test.com/{i}')
await cache.responses.write(f'request-key-{i}', mock_response)

urls = {url async for url in cache.get_urls()}
Expand All @@ -223,7 +222,7 @@ async def test_get_urls():
],
)
async def test_is_cacheable(method, status, disabled, expired, filter_return, expected_result):
mock_response = get_mock_response(
mock_response = make_mock_cached_response(
method=method,
status=status,
is_expired=expired,
Expand Down Expand Up @@ -251,7 +250,9 @@ async def filter(resp):

return json_resp['success']

mock_response = get_mock_response(method=method, status=status, is_expired=expired, _body=body)
mock_response = make_mock_cached_response(
method=method, status=status, is_expired=expired, _body=body
)

cache = CacheBackend()
cache.filter_fn = filter
Expand Down
Loading
Loading