"""Financial Modeling Prep API — ratios, peers, company news.""" import os import requests import streamlit as st from dotenv import load_dotenv load_dotenv() BASE_URL = "https://financialmodelingprep.com/api/v3" def _api_key() -> str: key = os.getenv("FMP_API_KEY", "") return key def _get(endpoint: str, params: dict = None) -> dict | list | None: params = params or {} params["apikey"] = _api_key() try: resp = requests.get(f"{BASE_URL}{endpoint}", params=params, timeout=10) resp.raise_for_status() return resp.json() except Exception: return None @st.cache_data(ttl=3600) def get_key_ratios(ticker: str) -> dict: """Return latest TTM key ratios.""" data = _get(f"/ratios-ttm/{ticker.upper()}") if data and isinstance(data, list) and len(data) > 0: return data[0] return {} @st.cache_data(ttl=21600) def get_peers(ticker: str) -> list[str]: """Return list of comparable ticker symbols.""" data = _get(f"/stock_peers", params={"symbol": ticker.upper()}) if data and isinstance(data, list) and len(data) > 0: return data[0].get("peersList", []) return [] @st.cache_data(ttl=3600) def get_ratios_for_tickers(tickers: list[str]) -> list[dict]: """Return TTM ratios for a list of tickers (for comps table).""" results = [] for t in tickers: data = _get(f"/ratios-ttm/{t}") if data and isinstance(data, list) and len(data) > 0: row = data[0] row["symbol"] = t results.append(row) return results @st.cache_data(ttl=600) def get_company_news(ticker: str, limit: int = 20) -> list[dict]: """Return recent news articles for a ticker.""" data = _get("/stock_news", params={"tickers": ticker.upper(), "limit": limit}) if data and isinstance(data, list): return data return []