Data provider: key from config.json/env, provider registry, drop hardcoded key
Resolves the Twelve Data API key through app_config.provider_api_key() (env → config.json → no default) instead of a hardcoded field on PlatformConfig. Adds data_provider.PROVIDER_REGISTRY + make_data_provider() so signal_aggregator and the backtester build the active provider through one seam; telegram_bot.py gets the same one-line WS-key fix now (per Task 4's already-planned edit for that line) so the suite doesn't crash on import between this commit and Task 4's full wiring pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VPNF37MP9Kuv62B1VBrZ1b
This commit is contained in:
+21
-7
@@ -5,7 +5,6 @@ Fetches and validates OHLCV via the official `twelvedata` Python SDK.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
from collections import deque
|
||||
@@ -14,6 +13,7 @@ from typing import Dict, Optional
|
||||
import pandas as pd
|
||||
from twelvedata import TDClient
|
||||
|
||||
from app_config import AppConfigError, get_app_config, provider_api_key
|
||||
from config import PlatformConfig, Timeframe, XAUUSD, PAIR_INFO
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -70,10 +70,7 @@ class ForexDataProvider:
|
||||
|
||||
def __init__(self, config: PlatformConfig):
|
||||
self.config = config
|
||||
self._api_key = (
|
||||
os.environ.get("TWELVE_DATA_API_KEY")
|
||||
or config.twelve_data_api_key
|
||||
)
|
||||
self._api_key = provider_api_key() or None
|
||||
self._cache: Dict[str, pd.DataFrame] = {}
|
||||
self._cache_timestamps: Dict[str, float] = {}
|
||||
# The bot shares one provider across a thread pool; cache eviction
|
||||
@@ -264,8 +261,8 @@ class ForexDataProvider:
|
||||
) -> pd.DataFrame:
|
||||
if self._td is None:
|
||||
raise DataIntegrityError(
|
||||
"No Twelve Data API key. Set TWELVE_DATA_API_KEY env var "
|
||||
"or config.twelve_data_api_key."
|
||||
"No data-provider API key. Set the TWELVE_DATA_API_KEY env "
|
||||
"var or data_providers.twelve_data.api_key in config.json."
|
||||
)
|
||||
|
||||
td_symbol = self._to_td_symbol(symbol)
|
||||
@@ -384,3 +381,20 @@ class ForexDataProvider:
|
||||
logger.info(f"{symbol}: Cleaned {cleaned}/{original_len} bars")
|
||||
|
||||
return df
|
||||
|
||||
|
||||
# ── Provider registry ─────────────────────────────────────────────────
|
||||
# config.json data_providers.active selects from here. Adding a provider
|
||||
# later = one adapter class + one entry + one config block.
|
||||
PROVIDER_REGISTRY: Dict[str, type] = {"twelve_data": ForexDataProvider}
|
||||
|
||||
|
||||
def make_data_provider(config: PlatformConfig) -> ForexDataProvider:
|
||||
"""Build the ACTIVE data provider (config.json: data_providers.active)."""
|
||||
name = get_app_config().active_provider
|
||||
cls = PROVIDER_REGISTRY.get(name)
|
||||
if cls is None:
|
||||
raise AppConfigError(
|
||||
f'Unknown data provider "{name}"; '
|
||||
f"registered: {sorted(PROVIDER_REGISTRY)}")
|
||||
return cls(config)
|
||||
|
||||
Reference in New Issue
Block a user