fix: resolve curl_cffi TLS errors and fix FRED/upgrades endpoints
All checks were successful
continuous-integration/drone/push Build is passing

- Pin curl_cffi==0.7.4 to avoid BoringSSL bug in 0.12-0.14
- Patch curl_cffi Session to use safari TLS fingerprint instead of
  chrome, which triggers SSL_ERROR_SYSCALL on some networks
- Register FRED API key with OpenBB credentials at startup
- Fix macro overview to return latest data instead of oldest, and
  extract values by FRED series ID key
- Replace Finnhub upgrades endpoint (premium-only) with yfinance
  upgrades_downgrades which includes price target changes
- Remove redundant curl_cffi upgrade from Dockerfile
This commit is contained in:
Yaojia Wang
2026-03-19 15:40:41 +01:00
parent b631c888a5
commit f5b22deec3
6 changed files with 77 additions and 25 deletions

View File

@@ -171,3 +171,30 @@ async def get_growth() -> list[dict]:
obb.equity.discovery.growth_tech, provider=PROVIDER
)
return _to_dicts(result)
async def get_upgrades_downgrades(symbol: str, limit: int = 20) -> list[dict]:
"""Get analyst upgrades/downgrades via yfinance."""
import yfinance as yf
def _fetch() -> list[dict[str, Any]]:
t = yf.Ticker(symbol)
df = t.upgrades_downgrades
if df is None or df.empty:
return []
df = df.head(limit).reset_index()
return [
{
"date": str(row.get("GradeDate", "")),
"company": row.get("Firm"),
"action": row.get("Action"),
"from_grade": row.get("FromGrade"),
"to_grade": row.get("ToGrade"),
"price_target_action": row.get("priceTargetAction"),
"current_price_target": row.get("currentPriceTarget"),
"prior_price_target": row.get("priorPriceTarget"),
}
for _, row in df.iterrows()
]
return await asyncio.to_thread(_fetch)