prabalGaur commited on
Commit
72677c6
·
verified ·
1 Parent(s): 4e44f88

Upload community_contributions/chrys/agents/data_fetcher.py with huggingface_hub

Browse files
community_contributions/chrys/agents/data_fetcher.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """DATA_FETCHER agent: retrieves live and historical price data from APIs."""
2
+ import time
3
+ from typing import List
4
+
5
+ from agents.base import AgentBase
6
+ from models import AssetData
7
+
8
+ # Import sources - use late or local refs to avoid circular deps
9
+ def _get_sources():
10
+ from sources.alpha_vantage import fetch_alpha_vantage
11
+ from sources.metals_api import fetch_metals
12
+ from sources.coingecko import fetch_coingecko
13
+ return fetch_alpha_vantage, fetch_metals, fetch_coingecko
14
+
15
+
16
+ class DataFetcherAgent(AgentBase):
17
+ name = "DATA_FETCHER"
18
+ logger_name = "aria.data_fetcher"
19
+
20
+ def __init__(self, alpha_key: str = "", metals_key: str = ""):
21
+ super().__init__()
22
+ self.alpha_key = alpha_key
23
+ # metals_key = CommodityPriceAPI key for gold (XAU) and silver (XAG)
24
+ self.metals_key = metals_key
25
+
26
+ def _route(self, symbol: str) -> str:
27
+ s = symbol.upper().replace("/USD", "").strip()
28
+ if s in ("XAU", "XAG"):
29
+ return "metals"
30
+ if s in ("BTC", "ETH"):
31
+ return "coingecko"
32
+ return "alpha" # stocks, indices, WTI, Copper via Alpha Vantage
33
+
34
+ def fetch_one(self, symbol: str) -> AssetData | None:
35
+ route = self._route(symbol)
36
+ fetch_av, fetch_metals, fetch_cg = _get_sources()
37
+ for attempt in range(2):
38
+ try:
39
+ if route == "metals":
40
+ out = fetch_metals(symbol, self.metals_key)
41
+ elif route == "coingecko":
42
+ out = fetch_cg(symbol, "")
43
+ else:
44
+ out = fetch_av(symbol, self.alpha_key)
45
+ if out:
46
+ return out
47
+ except Exception as e:
48
+ self.log(f"Fetch {symbol} attempt {attempt + 1} failed: {e}")
49
+ if attempt == 0:
50
+ time.sleep(10)
51
+ return None
52
+
53
+ def run(self, watchlist: List[str]) -> List[AssetData]:
54
+ self.log("Starting data fetch for watchlist")
55
+ results: List[AssetData] = []
56
+ for symbol in watchlist:
57
+ data = self.fetch_one(symbol)
58
+ if data:
59
+ results.append(data)
60
+ self.log(f"Fetched {symbol}: {data.price}")
61
+ else:
62
+ self.log(f"Skipped {symbol} (fetch failed)")
63
+ self.log(f"Fetched {len(results)}/{len(watchlist)} assets")
64
+ return results