Shivam4096 commited on
Commit
4442699
Β·
verified Β·
1 Parent(s): e8798e7

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. config.py +1 -0
  2. pipeline/peer_selector.py +70 -3
  3. web_app/app.py +19 -0
config.py CHANGED
@@ -16,6 +16,7 @@ CLAUDE_API_KEY: str = os.environ.get("CLAUDE_API_KEY", "")
16
  OPENAI_API_KEY: str = os.environ.get("OPENAI_API_KEY", "")
17
  GROQ_API_KEY: str = os.environ.get("GROQ_API_KEY", "")
18
  NVIDIA_API_KEY: str = os.environ.get("NVIDIA_API_KEY", "")
 
19
 
20
  # ── Data settings ─────────────────────────────────────────────────────────────
21
  DEFAULT_YEARS: int = 5
 
16
  OPENAI_API_KEY: str = os.environ.get("OPENAI_API_KEY", "")
17
  GROQ_API_KEY: str = os.environ.get("GROQ_API_KEY", "")
18
  NVIDIA_API_KEY: str = os.environ.get("NVIDIA_API_KEY", "")
19
+ HF_API_KEY: str = os.environ.get("HF_API_KEY", "")
20
 
21
  # ── Data settings ─────────────────────────────────────────────────────────────
22
  DEFAULT_YEARS: int = 5
pipeline/peer_selector.py CHANGED
@@ -12,6 +12,8 @@ from typing import List, Dict, Optional
12
  import requests
13
 
14
  sys.path.insert(0, str(Path(__file__).parent.parent))
 
 
15
  from config import FMP_API_KEY, FMP_BASE, REQUEST_TIMEOUT
16
  from pipeline.resolver import CompanyMeta
17
  from pipeline.fetcher import fetch_peer_snapshot, _fmp_get
@@ -65,6 +67,69 @@ def _fmp_peers(ticker: str) -> List[str]:
65
  return []
66
 
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  def select_peers(
69
  meta: CompanyMeta,
70
  max_peers: int = 4,
@@ -83,9 +148,11 @@ def select_peers(
83
 
84
  log(f"Selecting peers for {meta.name} ({meta.industry}) …")
85
 
86
- # 1. Try FMP peers endpoint
87
- peer_tickers = []
88
- if FMP_API_KEY and meta.is_listed and ticker != "UNLISTED":
 
 
89
  peer_tickers = _fmp_peers(ticker)
90
  if peer_tickers:
91
  log(f" β†’ FMP suggested {len(peer_tickers)} peers")
 
12
  import requests
13
 
14
  sys.path.insert(0, str(Path(__file__).parent.parent))
15
+ sys.path.insert(0, str(Path(__file__).parent.parent))
16
+ import config
17
  from config import FMP_API_KEY, FMP_BASE, REQUEST_TIMEOUT
18
  from pipeline.resolver import CompanyMeta
19
  from pipeline.fetcher import fetch_peer_snapshot, _fmp_get
 
67
  return []
68
 
69
 
70
+ def _hf_intelligent_peers(meta: CompanyMeta, log_fn=None) -> List[str]:
71
+ """Use Hugging Face Serverless API to intelligently select granular peers."""
72
+ def log(msg):
73
+ if log_fn: log_fn(msg)
74
+
75
+ hf_key = getattr(config, "HF_API_KEY", "")
76
+ if not hf_key:
77
+ return []
78
+
79
+ log(" β†’ Hugging Face API key detected. Using AI for granular sector breakdown and peer selection...")
80
+
81
+ # Try a fast, high-quality instruction model
82
+ url = "https://api-inference.huggingface.co/models/meta-llama/Meta-Llama-3-8B-Instruct"
83
+ headers = {
84
+ "Authorization": f"Bearer {hf_key}",
85
+ "Content-Type": "application/json"
86
+ }
87
+
88
+ desc = meta.description if meta.description else "No description available."
89
+ prompt = (
90
+ f"You are a top-tier financial analyst. Given the following company, break down its exact sub-sector "
91
+ f"and identify its 5 closest publicly traded peers.\n"
92
+ f"Company Name: {meta.name}\n"
93
+ f"Industry: {meta.industry}\n"
94
+ f"Description: {desc}\n\n"
95
+ f"Return ONLY a valid JSON array of their Yahoo Finance ticker symbols (e.g., [\"MSFT\", \"GOOGL\"]). "
96
+ f"Do not include any other text, markdown, or explanation. Only the JSON array."
97
+ )
98
+
99
+ payload = {
100
+ "inputs": prompt,
101
+ "parameters": {
102
+ "max_new_tokens": 100,
103
+ "return_full_text": False,
104
+ "temperature": 0.1
105
+ }
106
+ }
107
+
108
+ try:
109
+ r = requests.post(url, headers=headers, json=payload, timeout=25)
110
+ if r.status_code == 200:
111
+ result = r.json()
112
+ if isinstance(result, list) and len(result) > 0:
113
+ text = result[0].get("generated_text", "")
114
+
115
+ # Extract JSON array using regex
116
+ import re, json
117
+ match = re.search(r'\[(.*?)\]', text, re.DOTALL)
118
+ if match:
119
+ arr_str = match.group(0)
120
+ tickers = json.loads(arr_str)
121
+ if isinstance(tickers, list) and all(isinstance(t, str) for t in tickers):
122
+ log(f" βœ“ HF AI successfully identified highly specific peers: {tickers}")
123
+ return tickers
124
+ log(" ⚠ HF AI returned invalid format, falling back...")
125
+ else:
126
+ log(f" ⚠ HF API Error {r.status_code}: {r.text}. Falling back...")
127
+ except Exception as e:
128
+ log(f" ⚠ HF AI Request Failed: {e}. Falling back...")
129
+
130
+ return []
131
+
132
+
133
  def select_peers(
134
  meta: CompanyMeta,
135
  max_peers: int = 4,
 
148
 
149
  log(f"Selecting peers for {meta.name} ({meta.industry}) …")
150
 
151
+ # 1. Try Hugging Face Intelligent Peers
152
+ peer_tickers = _hf_intelligent_peers(meta, log_fn)
153
+
154
+ # 2. Try FMP peers endpoint if HF fails
155
+ if not peer_tickers and FMP_API_KEY and meta.is_listed and ticker != "UNLISTED":
156
  peer_tickers = _fmp_peers(ticker)
157
  if peer_tickers:
158
  log(f" β†’ FMP suggested {len(peer_tickers)} peers")
web_app/app.py CHANGED
@@ -170,6 +170,18 @@ gemini_key = st.sidebar.text_input(
170
  key="inp_gemini"
171
  )
172
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  # ── PAID OPTIONS ───────────────────────────────────────────────────────
174
  st.sidebar.markdown("""
175
  <div style='background:rgba(99,102,241,0.08);border:1px solid rgba(99,102,241,0.25);
@@ -335,6 +347,13 @@ if start_btn:
335
  config.OPENAI_API_KEY = openai_key
336
  config.GROQ_API_KEY = groq_key
337
  config.NVIDIA_API_KEY = nvidia_key
 
 
 
 
 
 
 
338
 
339
  pipeline.analyst.GEMINI_API_KEY = gemini_key
340
  pipeline.analyst.CLAUDE_API_KEY = claude_key
 
170
  key="inp_gemini"
171
  )
172
 
173
+ st.sidebar.markdown("""
174
+ **Hugging Face** *(Serverless API)*
175
+ <a href='https://huggingface.co/settings/tokens' target='_blank' style='font-size:0.75rem;color:#34D399;'>Get free key β†’ huggingface.co</a>
176
+ """, unsafe_allow_html=True)
177
+ hf_key = st.sidebar.text_input(
178
+ "Hugging Face API Key", type="password",
179
+ placeholder="hf_…",
180
+ value=os.environ.get("HF_API_KEY", ""),
181
+ help="Used for intelligent peer selection via Hugging Face Models.",
182
+ key="inp_hf"
183
+ )
184
+
185
  # ── PAID OPTIONS ───────────────────────────────────────────────────────
186
  st.sidebar.markdown("""
187
  <div style='background:rgba(99,102,241,0.08);border:1px solid rgba(99,102,241,0.25);
 
347
  config.OPENAI_API_KEY = openai_key
348
  config.GROQ_API_KEY = groq_key
349
  config.NVIDIA_API_KEY = nvidia_key
350
+ config.HF_API_KEY = hf_key
351
+
352
+ os.environ["GEMINI_API_KEY"] = gemini_key
353
+ os.environ["CLAUDE_API_KEY"] = claude_key
354
+ os.environ["OPENAI_API_KEY"] = openai_key
355
+ os.environ["NVIDIA_API_KEY"] = nvidia_key
356
+ os.environ["HF_API_KEY"] = hf_key
357
 
358
  pipeline.analyst.GEMINI_API_KEY = gemini_key
359
  pipeline.analyst.CLAUDE_API_KEY = claude_key