Files
OpenFin/backend/services/calendar_sync.py
2026-06-30 19:08:33 +02:00

73 lines
2.2 KiB
Python

"""
Unified calendar sync — FXStreet (primary) with FF live fallback.
Called by the background loop in main.py and manually via POST /api/eco/calendar-sync.
"""
import logging
from datetime import datetime, timezone
from typing import Any, Dict
logger = logging.getLogger(__name__)
_sync_status: Dict[str, Any] = {
"running": False,
"last_run": None,
"last_result": None,
"source": None,
"next_run": None,
}
def calendar_sync(weeks_ahead: int = 8) -> Dict[str, Any]:
"""
Sync upcoming economic events:
1. Try FXStreet (no API key, ~300-400 events over weeks_ahead weeks)
2. Fall back to FF live JSON if FXStreet returns 403 or fails
"""
global _sync_status
_sync_status["running"] = True
_sync_status["last_run"] = datetime.now(timezone.utc).isoformat()
result: Dict[str, Any] = {}
source = "unknown"
try:
from services.fxstreet_calendar import fetch_upcoming as fxs_fetch
r = fxs_fetch(weeks_ahead=weeks_ahead)
if r.get("error"):
logger.warning(f"[calendar_sync] FXStreet error: {r['error']} — falling back to FF live")
from services.ff_calendar import sync_live
r_ff = sync_live()
result = {**r_ff, "_fallback": True, "_fxs_error": r["error"]}
source = "ff_fallback"
else:
result = r
source = "fxstreet"
except Exception as e:
logger.error(f"[calendar_sync] Exception: {e}")
result = {"error": str(e)}
source = "error"
# After calendar upsert, log any forecast/actual changes to macro_series_log
try:
from services.database import get_conn
from services.macro_series_log import scan_and_log_all
_conn = get_conn()
log_result = scan_and_log_all(_conn, source=source)
_conn.close()
result["_log"] = log_result
except Exception as e:
logger.warning(f"[calendar_sync] macro_series_log scan failed: {e}")
_sync_status["running"] = False
_sync_status["last_result"] = result
_sync_status["source"] = source
return result
def get_sync_status() -> Dict[str, Any]:
return dict(_sync_status)
def set_next_run(ts: str):
_sync_status["next_run"] = ts