mirror of
https://github.com/jdejaegh/python-irceline.git
synced 2025-06-27 03:35:56 +02:00
Implement caching based on ETag
This commit is contained in:
parent
8bbddacfe9
commit
c62b135b52
3 changed files with 31 additions and 8 deletions
|
@ -10,6 +10,7 @@ from aiohttp import ClientResponse
|
||||||
|
|
||||||
from . import project_transform, rio_wfs_base_url, user_agent
|
from . import project_transform, rio_wfs_base_url, user_agent
|
||||||
from .data import RioFeature, FeatureValue
|
from .data import RioFeature, FeatureValue
|
||||||
|
from .utils import SizedDict
|
||||||
|
|
||||||
|
|
||||||
class IrcelineApiError(Exception):
|
class IrcelineApiError(Exception):
|
||||||
|
@ -19,8 +20,9 @@ class IrcelineApiError(Exception):
|
||||||
class IrcelineBaseClient:
|
class IrcelineBaseClient:
|
||||||
def __init__(self, session: aiohttp.ClientSession) -> None:
|
def __init__(self, session: aiohttp.ClientSession) -> None:
|
||||||
self._session = session
|
self._session = session
|
||||||
|
self._cache = SizedDict(20)
|
||||||
|
|
||||||
async def _api_wrapper(self, url: str, querystring: dict, method: str = 'GET'):
|
async def _api_wrapper(self, url: str, querystring: dict = None, headers: dict = None, method: str = 'GET'):
|
||||||
"""
|
"""
|
||||||
Call the URL with the specified query string. Raises exception for >= 400 response code
|
Call the URL with the specified query string. Raises exception for >= 400 response code
|
||||||
:param url: base URL
|
:param url: base URL
|
||||||
|
@ -28,7 +30,10 @@ class IrcelineBaseClient:
|
||||||
:return: response from the client
|
:return: response from the client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
headers = {'User-Agent': user_agent}
|
if headers is None:
|
||||||
|
headers = dict()
|
||||||
|
if 'User-Agent' not in headers:
|
||||||
|
headers |= {'User-Agent': user_agent}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with async_timeout.timeout(60):
|
async with async_timeout.timeout(60):
|
||||||
|
@ -48,6 +53,20 @@ class IrcelineBaseClient:
|
||||||
except Exception as exception: # pylint: disable=broad-except
|
except Exception as exception: # pylint: disable=broad-except
|
||||||
raise IrcelineApiError(f"Something really wrong happened! {exception}") from exception
|
raise IrcelineApiError(f"Something really wrong happened! {exception}") from exception
|
||||||
|
|
||||||
|
async def _api_cached_wrapper(self, url: str, method: str = 'GET'):
|
||||||
|
if url in self._cache:
|
||||||
|
headers = {"If-None-Match": f'{self._cache.get(url, {}).get("etag")}'}
|
||||||
|
else:
|
||||||
|
headers = None
|
||||||
|
|
||||||
|
r: ClientResponse = await self._api_wrapper(url, headers=headers, method=method)
|
||||||
|
if r.status == 304:
|
||||||
|
return self._cache.get(url, {}).get("response")
|
||||||
|
elif 'ETag' in r.headers:
|
||||||
|
self._cache[url] = {'etag': r.headers['ETag'],
|
||||||
|
'response': r}
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
class IrcelineRioClient(IrcelineBaseClient):
|
class IrcelineRioClient(IrcelineBaseClient):
|
||||||
"""API client for RIO interpolated IRCEL - CELINE open data"""
|
"""API client for RIO interpolated IRCEL - CELINE open data"""
|
||||||
|
|
|
@ -12,11 +12,15 @@ class SizedDict(OrderedDict):
|
||||||
super().__setitem__(key, value)
|
super().__setitem__(key, value)
|
||||||
self.move_to_end(key)
|
self.move_to_end(key)
|
||||||
if len(self) > self._size:
|
if len(self) > self._size:
|
||||||
self.popitem(False)
|
print('drop', self.popitem(False)[0])
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
super().__getitem__(key)
|
|
||||||
self.move_to_end(key)
|
self.move_to_end(key)
|
||||||
|
return super().__getitem__(key)
|
||||||
|
|
||||||
|
def get(self, __key, __default=None):
|
||||||
|
self.move_to_end(__key)
|
||||||
|
return super().get(__key, __default)
|
||||||
|
|
||||||
def update(self, __m, **kwargs):
|
def update(self, __m, **kwargs):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
@ -14,14 +14,14 @@ def test_size_dict():
|
||||||
|
|
||||||
s_dict['f'] = 6
|
s_dict['f'] = 6
|
||||||
assert 'a' not in s_dict
|
assert 'a' not in s_dict
|
||||||
assert 'f' in s_dict
|
assert s_dict['f'] == 6
|
||||||
assert len(s_dict) == 5
|
assert len(s_dict) == 5
|
||||||
|
|
||||||
s_dict['b'] = 42
|
s_dict['b'] = 42
|
||||||
s_dict['g'] = 7
|
s_dict['g'] = 7
|
||||||
assert 'f' in s_dict
|
assert s_dict['f'] == 6
|
||||||
assert 'g' in s_dict
|
assert s_dict['g'] == 7
|
||||||
assert 'b' in s_dict
|
assert s_dict['b'] == 42
|
||||||
assert 'c' not in s_dict
|
assert 'c' not in s_dict
|
||||||
assert len(s_dict) == 5
|
assert len(s_dict) == 5
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue