From a5d1290491f2aecc6402fb8beae4ad8c9296d352 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Wed, 1 May 2024 08:31:14 +0200 Subject: [PATCH] Use cached FX rate if fresh rate not available --- agenda/fx.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/agenda/fx.py b/agenda/fx.py index f0ec161..90cbc5f 100644 --- a/agenda/fx.py +++ b/agenda/fx.py @@ -44,6 +44,17 @@ async def get_gbpusd(config: flask.config.Config) -> Decimal: return typing.cast(Decimal, 1 / data["quotes"]["USDGBP"]) +def read_cached_rates(filename: str, currencies: list[str]) -> dict[str, Decimal]: + """Read FX rates from cache.""" + with open(filename) as file: + data = json.load(file, parse_float=Decimal) + return { + cur: Decimal(data["quotes"][f"GBP{cur}"]) + for cur in currencies + if f"GBP{cur}" in data["quotes"] + } + + def get_rates(config: flask.config.Config) -> dict[str, Decimal]: """Get current values of exchange rates for a list of currencies against GBP.""" currencies = config["CURRENCIES"] @@ -65,22 +76,19 @@ def get_rates(config: flask.config.Config) -> dict[str, Decimal]: recent = datetime.strptime(recent_filename[:16], "%Y-%m-%d_%H:%M") delta = now - recent + full_path = os.path.join(fx_dir, recent_filename) if delta < timedelta(hours=12): - full_path = os.path.join(fx_dir, recent_filename) - with open(full_path) as file: - data = json.load(file, parse_float=Decimal) - return { - cur: Decimal(data["quotes"][f"GBP{cur}"]) - for cur in currencies - if f"GBP{cur}" in data["quotes"] - } + return read_cached_rates(full_path, currencies) url = "http://api.exchangerate.host/live" params = {"currencies": currency_string, "source": "GBP", "access_key": access_key} filename = f"{now_str}_{file_suffix}" - with httpx.Client() as client: - response = client.get(url, params=params) + try: + with httpx.Client() as client: + response = client.get(url, params=params) + except httpx.ConnectError: + return read_cached_rates(full_path, currencies) with open(os.path.join(fx_dir, filename), "w") as file: file.write(response.text)