From a1811663115ea778f4e73e203cfdc344456486bc 2017-05-09 13:56:08 From: Brett Smith Date: 2017-05-09 13:56:08 Subject: [PATCH] rate: Initial commit. --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c18dd8d83ceed1806b50b0aaa46beb7e335fff13 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/oxrlib/__init__.py b/oxrlib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/oxrlib/rate.py b/oxrlib/rate.py new file mode 100644 index 0000000000000000000000000000000000000000..fbbc9cbae1615245537b422c93465e88d8cd694f --- /dev/null +++ b/oxrlib/rate.py @@ -0,0 +1,47 @@ +import datetime +import functools +import json + +class Rate: + FIELDS = [ + 'base', + 'disclaimer', + 'license', + 'rates', + 'timestamp', + ] + + @classmethod + def walk_fields(cls, get_field, transform_prefix): + for fieldname in cls.FIELDS: + value = get_field(fieldname) + if value is not None: + try: + transformer = getattr(cls, '{}_{}'.format(transform_prefix, fieldname)) + except AttributeError: + pass + else: + value = transformer(value) + yield (fieldname, value) + + def __init__(self, base, rates, **kwargs): + for key, value in self.walk_fields(kwargs.get, 'deserialize'): + setattr(self, key, value) + self.base = base + self.rates = rates + + @classmethod + def deserialize_timestamp(cls, value): + return datetime.datetime.fromtimestamp(value) + + @classmethod + def serialize_timestamp(cls, value): + return int(value.timestamp()) + + @classmethod + def from_json_file(cls, json_file): + response = json.load(json_file) + return cls(**response) + + def serialize(self): + return dict(self.walk_fields(functools.partial(getattr, self), 'serialize')) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e3fbdfdbd7115d6d1b753e7f340380f48571db9e --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,6 @@ +import pathlib + +TEST_DIR = pathlib.Path(__file__).parent + +def relpath(path): + return TEST_DIR / pathlib.Path(path) diff --git a/tests/historical1.json b/tests/historical1.json new file mode 100644 index 0000000000000000000000000000000000000000..b96812d2d886252dda2a2978a80b607d15682dba --- /dev/null +++ b/tests/historical1.json @@ -0,0 +1,11 @@ +{ + "disclaimer": "https://openexchangerates.org/terms/", + "license": "https://openexchangerates.org/license/", + "timestamp": 982342800, + "base": "USD", + "rates": { + "AED": 3.67246, + "ALL": 144.529793, + "ANG": 1.79 + } +} diff --git a/tests/test_Rate.py b/tests/test_Rate.py new file mode 100644 index 0000000000000000000000000000000000000000..98ebdf9c76dba9eb6eb0eab66994a5cbb0691e4c --- /dev/null +++ b/tests/test_Rate.py @@ -0,0 +1,23 @@ +import datetime +import io +import json + +from . import relpath + +import oxrlib.rate +import pytest + +@pytest.fixture +def historical1_rate(): + with open(relpath('historical1.json').as_posix()) as rate_file: + return oxrlib.rate.Rate.from_json_file(rate_file) + +def test_rate_from_json(historical1_rate): + assert historical1_rate.base == 'USD' + assert historical1_rate.timestamp == datetime.datetime(2001, 2, 16, 12, 0, 0) + +def test_serialize(historical1_rate): + with open(relpath('historical1.json').as_posix()) as rate_file: + expected = json.load(rate_file) + assert expected == historical1_rate.serialize() +