import os import sys import argparse from datetime import date, timedelta from dotenv import load_dotenv from loguru import logger load_dotenv() def setup_logging(log_file: str | None = None) -> None: logger.remove() logger.add( sys.stderr, level="INFO", format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {message}", ) if log_file: log_dir = os.getenv("LOGDIR") if log_dir: logger.add( f"{log_dir}/{log_file}", rotation="7 days", retention="30 days", compression="zip", level="DEBUG", ) def main() -> None: parser = argparse.ArgumentParser( prog="spotrates", description="Daily spot exchange rates ingestion (USD base) to Snowflake and ReportingDB", ) parser.add_argument( "mode", choices=["backfill", "daily", "sync", "all"], help="Execution mode: backfill (historical load), daily (incremental), sync (Snowflake->Redshift), all (daily+sync)", ) parser.add_argument( "--start-date", "-s", type=str, default=None, help="Start date for backfill (YYYY-MM-DD). Defaults to 5 years ago.", ) parser.add_argument( "--log-file", "-l", type=str, default="spotrates-cea.log", help="Log file name (stored in LOGDIR)", ) args = parser.parse_args() setup_logging(args.log_file) try: if args.mode == "backfill": from .services.ingest import run_backfill start = None if args.start_date: start = date.fromisoformat(args.start_date) run_backfill(start) elif args.mode == "daily": from .services.ingest import run_daily run_daily() elif args.mode == "sync": from .services.sync import run_sync run_sync() elif args.mode == "all": from .services.ingest import run_daily from .services.sync import run_sync run_daily() run_sync() except KeyboardInterrupt: logger.info("Interrupted by user") sys.exit(130) except Exception as e: logger.exception(f"Fatal error: {e}") sys.exit(1) if __name__ == "__main__": main()