From 0b0efd7a07106974bf85ba210ab19cf258111d7b Mon Sep 17 00:00:00 2001 From: Viren070 Date: Wed, 6 Nov 2024 17:41:37 +0000 Subject: [PATCH] ci: experiment with automatic currency rates fetching --- .github/workflows/update_exchange_rates.yml | 40 ++++++++++ scripts/generate_exchange_rates.py | 87 +++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 .github/workflows/update_exchange_rates.yml create mode 100644 scripts/generate_exchange_rates.py diff --git a/.github/workflows/update_exchange_rates.yml b/.github/workflows/update_exchange_rates.yml new file mode 100644 index 0000000..db036da --- /dev/null +++ b/.github/workflows/update_exchange_rates.yml @@ -0,0 +1,40 @@ +name: Generate Currency Rates + +on: + schedule: + - cron: '23 7 * * 4' + workflow_dispatch: + +jobs: + generate-currency-rates: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install requests + + - name: Run generate_currency_rates.py + run: | + python scripts/generate_exchange_rates.py -o static/currency_rates.json + env: + EXCHANGE_RATE_API_KEY: ${{ secrets.EXCHANGE_RATE_API_KEY }} + + - name: Commit and push changes + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + git add static/currency_rates.json + git commit -m 'chore: update currency rates' + git push + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/scripts/generate_exchange_rates.py b/scripts/generate_exchange_rates.py new file mode 100644 index 0000000..1f921d6 --- /dev/null +++ b/scripts/generate_exchange_rates.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +import argparse +import json +import logging +import requests +import os +import sys +import time + +LOG_FORMAT = "[%(asctime)s] [%(levelname)s]: %(message)s" +DATE_FORMAT = "%Y-%m-%d %H:%M:%S" + +API_KEY = os.getenv("EXCHANGE_RATE_API_KEY") +API_URL = 'https://v6.exchangerate-api.com/v6/{API_KEY}/latest/{currency}' + +CURRENCIES_TO_FETCH = ["USD", "EUR"] + +logging.basicConfig(level=logging.INFO, format=LOG_FORMAT, datefmt=DATE_FORMAT) + + +def parse_args() -> argparse.Namespace: + """Parse the arguments passed to the script + + Returns: + argparse.Namespace: Object containing output_file, input_file and fields arguments + """ + parser = argparse.ArgumentParser(description="Reduce the size of the titleDB JSON file by removing entries without a name and only keeping the specified fields.") + parser.add_argument("-o", "--output_file", type=str, required=True, help="Path to the output file") + return parser.parse_args() + + +def write_to_file(output_file: str, new_data: dict) -> None: + """Write a dictionary to a file as JSON + + Args: + output_file (str): path to the file to write to + new_data (dict): data to write to the file + """ + try: + # write the new data to the output_file file + with open(output_file, "w") as f: + json.dump(new_data, f, separators=(",", ":")) # use separators to remove whitespaces + except Exception as e: + # if there is an error writing to the output_file file, log an error and exit + logging.error(f"Error writing to {output_file}. {e}") + sys.exit(1) + + +def fetch_currency_rates(currency): + """Fetch the currency rates from the API + + Args: + currency (str): The currency to fetch the rates for + + Returns: + dict: The currency rates + """ + try: + logging.info(f"Fetching currency rates for {currency}") + response = requests.get(API_URL.format(API_KEY=API_KEY, currency=currency)) + response.raise_for_status() + data = response.json() + if data["result"] != "success": + logging.error(f"Failed to fetch currency rates for {currency}. {data["error-type"]}") + sys.exit(1) + logging.info(f"Fetched currency rates for {currency} last updated at: {data["time_last_update_utc"]}") + return data["conversion_rates"] + except requests.exceptions.RequestException as e: + logging.error(f"Failed to fetch currency rates for {currency}. {e}") + sys.exit(1) + + + +if __name__ == "__main__": + start_time = time.perf_counter() + + # parse the arguments + args = parse_args() + + output_file = args.output_file + + currency_rates = {} + for currency in CURRENCIES_TO_FETCH: + currency_rates[currency] = fetch_currency_rates(currency) + + write_to_file(output_file, currency_rates)