Files
@ 5a73d3d8f8d4
Branch filter:
Location: NPO-Accounting/oxrlib/oxrlib/cache.py - annotation
5a73d3d8f8d4
2.6 KiB
text/x-python
historical: Move normalize_rate and _pretty_rate to base Formatter.
This reduces the number of method overrides to help readability,
and gets rid of the annoying format_rate/pretty_rate distinction.
This reduces the number of method overrides to help readability,
and gets rid of the annoying format_rate/pretty_rate distinction.
eba27c16ae78 6a416b162d8a eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 7ae8c359e0b9 7ae8c359e0b9 7ae8c359e0b9 7ae8c359e0b9 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 7ae8c359e0b9 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 eba27c16ae78 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 2d482bb7b045 6a416b162d8a 6a416b162d8a 6a416b162d8a 6a416b162d8a 6a416b162d8a 6a416b162d8a 6a416b162d8a | import functools
import json
from . import errors
class CacheFileBase:
def __init__(self, path, *args, **kwargs):
self.path = path
try:
self.open_file = path.open(*args, **kwargs)
except OSError as error:
self._translate_error(error, 'init')
def _translate_error(self, error, when):
for orig_type, mapped_type in self.ERRORS_MAP:
if isinstance(error, orig_type):
raise mapped_type(self.path) from error
raise error
def __enter__(self):
return self.open_file
def __exit__(self, exc_type, exc_value, exc_tb):
try:
self.open_file.close()
except OSError as error:
self._translate_error(error, 'exit')
class CacheBase:
ConfigurationError = errors.CacheConfigurationError
def __init__(self, dir_path, **kwargs):
self.dir_path = dir_path
try:
self.CacheFile = kwargs.pop('file_class')
except KeyError:
pass
self.fn_patterns = {}
self.setup(**kwargs)
def setup(self, **kwargs):
for method_name, pattern in kwargs.items():
try:
is_api_method = getattr(self, method_name).is_api_method
except AttributeError:
is_api_method = False
if not is_api_method:
raise errors.CacheConfigurationError(method_name)
self.fn_patterns[method_name] = pattern
def _wrap_api_method(orig_func):
@functools.wraps(orig_func)
def api_method_wrapper(self, *args, **kwargs):
try:
fn_pattern = self.fn_patterns[orig_func.__name__]
except KeyError:
raise self.ConfigurationError(orig_func.__name__) from None
pattern_kwargs = orig_func(self, *args, **kwargs)
path = self.dir_path / fn_pattern.format(**pattern_kwargs)
return self.open(path)
api_method_wrapper.is_api_method = True
return api_method_wrapper
@_wrap_api_method
def historical(self, date, base):
return {'date': date.isoformat(), 'base': base}
class WriteCacheFile(CacheFileBase):
ERRORS_MAP = []
class CacheWriter(CacheBase):
CacheFile = WriteCacheFile
def open(self, path):
return self.CacheFile(path, 'w')
def write_json(self, cache_file, thing):
json.dump(thing, cache_file, indent=2)
def save_rate(self, rate):
with self.historical(rate.timestamp.date(), rate.base) as cache_file:
self.write_json(cache_file, rate.serialize())
|