working cache
Some checks failed
Build and deploy the backend to staging / Build and push image (pull_request) Successful in 2m19s
Run linting on the backend code / Build (pull_request) Successful in 25s
Run testing on the backend code / Build (pull_request) Failing after 7m37s
Build and deploy the backend to staging / Deploy to staging (pull_request) Successful in 24s

This commit is contained in:
2025-01-23 08:04:26 +01:00
parent c668158341
commit ca40de82dd
7 changed files with 389 additions and 388 deletions

View File

@@ -0,0 +1,133 @@
import os
import xml.etree.ElementTree as ET
import hashlib
import ujson
from ..constants import OSM_CACHE_DIR
def get_cache_key(query: str) -> str:
"""
Generate a unique cache key for the query using a hash function.
This ensures that queries with different parameters are cached separately.
"""
return hashlib.md5(query.encode('utf-8')).hexdigest()
class CachingStrategyBase:
def get(self, key):
raise NotImplementedError('Subclass should implement get')
def set(self, key, data):
raise NotImplementedError('Subclass should implement set')
def close(self):
pass
# For later use if xml does not suit well
class JSONCache(CachingStrategyBase):
def __init__(self, cache_dir=OSM_CACHE_DIR):
# Add the class name as a suffix to the directory
self._cache_dir = f'{cache_dir}_JSON'
if not os.path.exists(self._cache_dir):
os.makedirs(self._cache_dir)
def _filename(self, key):
return os.path.join(self._cache_dir, f'{key}.json')
def get(self, key):
filename = self._filename(key)
if os.path.exists(filename):
with open(filename, 'r') as file:
return ujson.load(file)
return None
def set(self, key, value):
with open(self._filename(key), 'w') as file:
ujson.dump(value, file)
class XMLCache(CachingStrategyBase):
def __init__(self, cache_dir=OSM_CACHE_DIR):
# Add the class name as a suffix to the directory
self._cache_dir = f'{cache_dir}_XML'
if not os.path.exists(self._cache_dir):
os.makedirs(self._cache_dir)
def _filename(self, key):
return os.path.join(self._cache_dir, f'{key}.xml')
def get(self, key):
"""Retrieve XML data from the cache and parse it as an ElementTree."""
filename = self._filename(key)
if os.path.exists(filename):
try:
# Parse and return the cached XML data
tree = ET.parse(filename)
return tree.getroot() # Return the root element of the parsed XML
except ET.ParseError:
print(f"Error parsing cached XML file: {filename}")
return None
return None
def set(self, key, value):
"""Save the XML data as an ElementTree to the cache."""
filename = self._filename(key)
tree = ET.ElementTree(value) # value is expected to be an ElementTree root element
try:
# Write the XML data to a file
with open(filename, 'wb') as file:
tree.write(file, encoding='utf-8', xml_declaration=True)
except IOError as e:
print(f"Error writing to cache file: {filename} - {e}")
class CachingStrategy:
__strategy = XMLCache() # Default caching strategy
# Dictionary to map string identifiers to caching strategy classes
__strategies = {
'XML': XMLCache,
'JSON': JSONCache,
# Add more strategies here if needed
}
@classmethod
def use(cls, strategy_name='XML', **kwargs):
"""
Set the caching strategy based on the strategy_name provided.
Args:
strategy_name (str): The name of the caching strategy (e.g., 'XML').
**kwargs: Additional keyword arguments to pass when initializing the strategy.
"""
# If a previous strategy exists, close it
if cls.__strategy:
cls.__strategy.close()
# Retrieve the strategy class based on the strategy name
strategy_class = cls.__strategies.get(strategy_name)
if not strategy_class:
raise ValueError(f"Unknown caching strategy: {strategy_name}")
# Instantiate the new strategy with the provided arguments
cls.__strategy = strategy_class(**kwargs)
return cls.__strategy
@classmethod
def get(cls, key):
"""Get data from the current strategy's cache."""
if not cls.__strategy:
raise RuntimeError("Caching strategy has not been set.")
return cls.__strategy.get(key)
@classmethod
def set(cls, key, value):
"""Set data in the current strategy's cache."""
if not cls.__strategy:
raise RuntimeError("Caching strategy has not been set.")
cls.__strategy.set(key, value)