mr601s commited on
Commit
059eb48
Β·
verified Β·
1 Parent(s): 8e82e74

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -15
app.py CHANGED
@@ -9,9 +9,9 @@ from datetime import datetime, timedelta
9
  import pandas as pd
10
  import os
11
 
12
- # === POLYGON CONFIG ===
13
- # If using Hugging Face "Secrets", leave as os.getenv; otherwise you may hardcode.
14
  POLYGON_API_KEY = os.getenv("POLYGON_API_KEY") or "fAhg47wPlf4FT6U2Hn23kQoQCQIyW0G_"
 
15
 
16
  # === POLYGON QUOTE for Free Tier (uses Previous Close) ===
17
  def fetch_polygon_quote(ticker, polygon_api_key=POLYGON_API_KEY):
@@ -23,7 +23,6 @@ def fetch_polygon_quote(ticker, polygon_api_key=POLYGON_API_KEY):
23
  if data.get("results"):
24
  last = data["results"][0]
25
  price = last["c"] # close price
26
- # Polygon gives epoch ms; convert to readable date
27
  close_dt = datetime.utcfromtimestamp(last["t"] / 1000).strftime('%Y-%m-%d')
28
  return f"πŸ’° **Previous Close for {ticker.upper()} (as of {close_dt})**\n\nβ€’ **Close Price:** ${price:.2f}\n\n_(Free Polygon plan only provides prior close)_"
29
  else:
@@ -31,6 +30,54 @@ def fetch_polygon_quote(ticker, polygon_api_key=POLYGON_API_KEY):
31
  except Exception as e:
32
  return f"❌ Error: {str(e)}"
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  # === SEC Utilities (no change) ===
35
  class SECUtils:
36
  def __init__(self):
@@ -143,10 +190,6 @@ class ChartUtils:
143
  print(f"Chart error for {ticker}: {e}")
144
  return None
145
 
146
- # === Financial Summary Placeholder ===
147
- def get_financial_summary_placeholder(ticker):
148
- return f"πŸ“Š **Financial Summary for {ticker.upper()}**\n\n❌ Detailed financials unavailable in the free Polygon tier.\n\nπŸ’‘ Try [Yahoo Finance Financials](https://finance.yahoo.com/quote/{ticker}/financials) for more."
149
-
150
  # === Instantiate utilities ===
151
  sec_utils = SECUtils()
152
  news_utils = NewsUtils()
@@ -158,19 +201,14 @@ def update_stock_info(ticker):
158
  empty_msg = "Enter a ticker symbol to see data"
159
  return empty_msg, empty_msg, empty_msg, empty_msg, None
160
  ticker = ticker.upper().strip()
161
- # 1. Fetch quote via Polygon (previous close)
162
  quote_data = fetch_polygon_quote(ticker)
163
  time.sleep(0.3)
164
- # 2. News
165
  news_data = news_utils.get_yahoo_news(ticker)
166
  time.sleep(0.3)
167
- # 3. SEC filings
168
  filings_data = sec_utils.get_recent_filings(ticker)
169
  time.sleep(0.3)
170
- # 4. Financial summary (placeholder)
171
- financial_data = get_financial_summary_placeholder(ticker)
172
  time.sleep(0.3)
173
- # 5. Chart (yfinance)
174
  chart = chart_utils.create_price_chart(ticker)
175
  return quote_data, news_data, filings_data, financial_data, chart
176
 
@@ -193,7 +231,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft(), title="Stock Research Platform")
193
 
194
  🎯 Enter a stock ticker symbol (like **AAPL**, **TSLA**, **MSFT**, **GOOGL**) to explore detailed information.
195
 
196
- ⚠️ **Note**: Stock quote data provided by Polygon (Previous Close for free plans). News and SEC filings remain free. Charts may still be subject to Yahoo limits.
197
  """)
198
  with gr.Row():
199
  with gr.Column(scale=3):
@@ -217,7 +255,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft(), title="Stock Research Platform")
217
  chart_output = gr.Plot(value=None)
218
  gr.Markdown("""
219
  ---
220
- **Data Sources:** Polygon.io for quotes, Yahoo RSS for news, SEC EDGAR for filings.
221
 
222
  **Troubleshooting:** If you encounter errors, double-check your ticker or wait and retry.
223
  """)
 
9
  import pandas as pd
10
  import os
11
 
12
+ # === CONFIG: API KEYS ===
 
13
  POLYGON_API_KEY = os.getenv("POLYGON_API_KEY") or "fAhg47wPlf4FT6U2Hn23kQoQCQIyW0G_"
14
+ FINNHUB_API_KEY = "d2urs69r01qq994h1f5gd2urs69r01qq994h1f60" # <-- Your Finnhub Key
15
 
16
  # === POLYGON QUOTE for Free Tier (uses Previous Close) ===
17
  def fetch_polygon_quote(ticker, polygon_api_key=POLYGON_API_KEY):
 
23
  if data.get("results"):
24
  last = data["results"][0]
25
  price = last["c"] # close price
 
26
  close_dt = datetime.utcfromtimestamp(last["t"] / 1000).strftime('%Y-%m-%d')
27
  return f"πŸ’° **Previous Close for {ticker.upper()} (as of {close_dt})**\n\nβ€’ **Close Price:** ${price:.2f}\n\n_(Free Polygon plan only provides prior close)_"
28
  else:
 
30
  except Exception as e:
31
  return f"❌ Error: {str(e)}"
32
 
33
+ # === FINNHUB FINANCIAL SUMMARY ===
34
+ def get_financial_summary_finnhub(ticker, finnhub_api_key=FINNHUB_API_KEY):
35
+ url = f"https://finnhub.io/api/v1/stock/metric?symbol={ticker.upper()}&metric=all&token={finnhub_api_key}"
36
+ try:
37
+ response = requests.get(url, timeout=10)
38
+ response.raise_for_status()
39
+ data = response.json()
40
+ metrics = data.get('metric', {})
41
+ if not metrics:
42
+ return f"πŸ“Š **Financial Summary for {ticker.upper()}**\n\n❌ No financial data found."
43
+ result = f"πŸ“Š **Financial Summary for {ticker.upper()}**\n\n"
44
+ # Revenue (TTM)
45
+ if metrics.get('totalRevenueTTM'):
46
+ result += f"β€’ **Revenue (TTM):** ${int(metrics['totalRevenueTTM']):,}\n"
47
+ # Net Income
48
+ if metrics.get('netIncomeTTM'):
49
+ result += f"β€’ **Net Income (TTM):** ${int(metrics['netIncomeTTM']):,}\n"
50
+ # PE Ratio
51
+ pe = metrics.get('peNormalizedAnnual') or metrics.get('peExclExtraTTM')
52
+ if pe is not None:
53
+ result += f"β€’ **P/E Ratio:** {pe:.2f}\n"
54
+ # PB Ratio
55
+ pb = metrics.get('pbAnnual')
56
+ if pb is not None:
57
+ result += f"β€’ **P/B Ratio:** {pb:.2f}\n"
58
+ # Dividend Yield
59
+ dy = metrics.get('dividendYieldIndicatedAnnual')
60
+ if dy is not None:
61
+ result += f"β€’ **Dividend Yield:** {dy:.2f}%\n"
62
+ # Debt/Equity
63
+ dte = metrics.get('totalDebt/totalEquityAnnual')
64
+ if dte is not None:
65
+ result += f"β€’ **Debt/Equity:** {dte:.2f}\n"
66
+ # Profit Margin
67
+ pm = metrics.get('netProfitMarginTTM')
68
+ if pm is not None:
69
+ result += f"β€’ **Net Profit Margin:** {pm:.2f}%\n"
70
+ # Market Cap
71
+ mc = metrics.get('marketCapitalization')
72
+ if mc is not None:
73
+ result += f"β€’ **Market Cap:** ${int(mc):,}\n"
74
+ # Show message if no useful data printed
75
+ if result.strip() == f"πŸ“Š **Financial Summary for {ticker.upper()}**":
76
+ return f"πŸ“Š **Financial Summary for {ticker.upper()}**\n\n❌ No data available from Finnhub."
77
+ return result
78
+ except Exception as e:
79
+ return f"πŸ“Š **Financial Summary for {ticker.upper()}**\n\n❌ Error fetching financial summary: {e}"
80
+
81
  # === SEC Utilities (no change) ===
82
  class SECUtils:
83
  def __init__(self):
 
190
  print(f"Chart error for {ticker}: {e}")
191
  return None
192
 
 
 
 
 
193
  # === Instantiate utilities ===
194
  sec_utils = SECUtils()
195
  news_utils = NewsUtils()
 
201
  empty_msg = "Enter a ticker symbol to see data"
202
  return empty_msg, empty_msg, empty_msg, empty_msg, None
203
  ticker = ticker.upper().strip()
 
204
  quote_data = fetch_polygon_quote(ticker)
205
  time.sleep(0.3)
 
206
  news_data = news_utils.get_yahoo_news(ticker)
207
  time.sleep(0.3)
 
208
  filings_data = sec_utils.get_recent_filings(ticker)
209
  time.sleep(0.3)
210
+ financial_data = get_financial_summary_finnhub(ticker)
 
211
  time.sleep(0.3)
 
212
  chart = chart_utils.create_price_chart(ticker)
213
  return quote_data, news_data, filings_data, financial_data, chart
214
 
 
231
 
232
  🎯 Enter a stock ticker symbol (like **AAPL**, **TSLA**, **MSFT**, **GOOGL**) to explore detailed information.
233
 
234
+ ⚠️ **Note**: Stock quote data provided by Polygon (Previous Close for free plans). Financial summary data from Finnhub. News and SEC filings remain free. Charts may still be subject to Yahoo limits.
235
  """)
236
  with gr.Row():
237
  with gr.Column(scale=3):
 
255
  chart_output = gr.Plot(value=None)
256
  gr.Markdown("""
257
  ---
258
+ **Data Sources:** Polygon.io for quotes, Finnhub for financials, Yahoo RSS for news, SEC EDGAR for filings.
259
 
260
  **Troubleshooting:** If you encounter errors, double-check your ticker or wait and retry.
261
  """)