Files
AutoACCT/scripts/fx_convert.py
Knowit db3d96999e Fix FX endpoint and harden gitignore
- frankfurter.app now redirects to frankfurter.dev/v1/ and blocks the
  default Python urllib UA with 403. Hit the new endpoint directly and
  send a named User-Agent.
- Extend .gitignore to block common service-account and credential file
  patterns (asset/, *-sa.json, *-service-account*.json, *credentials*.json,
  *-key.json) so keys can't be committed by accident.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 15:29:48 +08:00

48 lines
1.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
fx_convert.py <amount> <currency> [--date yyyy-mm-dd]
Convert a given amount in <currency> to HKD.
Prints one tab-separated line: <hkd_amount>\t<fx_rate>\t<fx_date>
Non-zero exit on failure.
Uses frankfurter.app by default: free, no API key, ECB reference rates,
historical dates supported via /{date} path.
"""
from __future__ import annotations
import argparse
import json
import sys
import urllib.request
from datetime import date
def fetch_rate(currency: str, on_date: str) -> tuple[float, str]:
currency = currency.upper()
if currency == "HKD":
return 1.0, on_date
url = f"https://api.frankfurter.dev/v1/{on_date}?from={currency}&to=HKD"
req = urllib.request.Request(url, headers={"User-Agent": "AutoACCT/1.0"})
with urllib.request.urlopen(req, timeout=10) as resp:
data = json.loads(resp.read())
rate = data["rates"]["HKD"]
return float(rate), data["date"]
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("amount", type=float)
ap.add_argument("currency")
ap.add_argument("--date", default=date.today().isoformat())
args = ap.parse_args()
rate, fx_date = fetch_rate(args.currency, args.date)
hkd = round(args.amount * rate, 2)
print(f"{hkd}\t{rate}\t{fx_date}")
return 0
if __name__ == "__main__":
sys.exit(main())