Source code for py_wlc.data.webtag_data

"""Exposes the parsed WebTAG data as :py:mod:`py_wlc` objects."""
import datetime
import json
import logging
from os import path, walk

from ..economics import Discount, GdpDeflator


logger = logging.getLogger(__name__)


[docs]class WebTagData: """Holds the data extracted from WebTAG.""" def __init__(self, base_year, released, version, source, **data): self.base_year = base_year released = datetime.datetime.strptime(released, "%Y-%m-%d") self.released = released.date() if (datetime.datetime.now() - released).days > 365: logger.warning("WebTAG data is more than one year old") self.version = version self.source = source self.discount = self._parse_discount(data.get("discount_rate"), self.base_year) self.deflator = self._parse_deflator(data.get("gdp_growth"), self.base_year) @staticmethod def _parse_deflator(data, base_year): """Parse GDP data from WebTAG into :py:class:`~.GdpDeflator`. Arguments: data (``dict`` or ``None``): The dictionary of GDP data (or ``None`` - this will produce a :py:class:`~.GdpDeflator` with zero rates). base_year (``int``): The base year for the new :py:class:`~.GdpDeflator` object. Returns: :py:class:`~.GdpDeflator`: The new GdpDeflator object. """ if data is not None: rates = {} for key, val in data.items(): if key.isdigit(): rates[int(key)] = float(val) return GdpDeflator(base_year, rates, True) return GdpDeflator(base_year, {base_year: 0.0}, True) @staticmethod def _parse_discount(data, base_year): """Parse discount data from WebTAG into :py:class:`~.Discount`. Assumes that all years will be in dash-separated or space- separated format, with the first part being the start year. Arguments: data (``dict`` or ``None``): The dictionary of discount rate data (or ``None`` - this will produce a :py:class:`~.Discount` with the default rates). base_year (``int``): The base year for the new :py:class:`~.Discount` object. Returns: :py:class:`~.Discount`: The new Discount object. """ if data is not None: rates = {} for key, val in data.items(): if "-" in key: key = int(key.split("-")[0]) else: key = key.split(" ")[0] if key.isdigit(): key = int(key) else: continue # pragma: no cover rates[key] = val return Discount(base_year, rates) return Discount(base_year) @classmethod
[docs] def from_latest_json(cls, dir_): """Extract data from the most recent JSON in the directory. Arguments: dir_ (``str``): The directory to start searching from. Returns: :py:class:`~.WebTagData`: A new class instance. """ latest_data = latest_date = None for curr_dir, _, files in walk(dir_): for file in files: with open(path.join(curr_dir, file)) as file_: try: data = json.load(file_) except ValueError: continue date = data.get("released", "") if latest_date is None or date > latest_date: latest_data = data latest_date = date if latest_data is not None: return cls(**latest_data)
@classmethod
[docs] def from_json(cls, file): """Extract data from the specified JSON. Arguments: file (``str``): The file to import from. Returns: :py:class:`~.WebTagData`: A new class instance. """ with open(file) as file_: data = json.load(file_) return cls(**data)