From a1811663115ea778f4e73e203cfdc344456486bc Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Tue, 9 May 2017 09:56:08 -0400 Subject: [PATCH] rate: Initial commit. --- .gitignore | 1 + oxrlib/__init__.py | 0 oxrlib/rate.py | 47 ++++++++++++++++++++++++++++++++++++++++++ tests/__init__.py | 6 ++++++ tests/historical1.json | 11 ++++++++++ tests/test_Rate.py | 23 +++++++++++++++++++++ 6 files changed, 88 insertions(+) create mode 100644 .gitignore create mode 100644 oxrlib/__init__.py create mode 100644 oxrlib/rate.py create mode 100644 tests/__init__.py create mode 100644 tests/historical1.json create mode 100644 tests/test_Rate.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/oxrlib/__init__.py b/oxrlib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oxrlib/rate.py b/oxrlib/rate.py new file mode 100644 index 0000000..fbbc9cb --- /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 0000000..e3fbdfd --- /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 0000000..b96812d --- /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 0000000..98ebdf9 --- /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() +