"""News API adapter - fetches company-linked headlines and article metadata.""" import hashlib import logging from datetime import datetime from typing import Any, Dict import httpx from .base import AdapterResult, BaseAdapter logger = logging.getLogger("news_adapter") class NewsApiAdapter(BaseAdapter): """Concrete adapter for a news API provider.""" def __init__(self, api_key: str = "", base_url: str = ""): self.api_key = api_key self.base_url = base_url def source_type(self) -> str: return "news_api" async def fetch(self, ticker: str, config: Dict[str, Any]) -> AdapterResult: endpoint = config.get("endpoint", "/v2/everything") url = f"{self.base_url}{endpoint}" params = config.get("params", {}) params.setdefault("q", ticker) params.setdefault("sortBy", "publishedAt") params.setdefault("pageSize", 20) if self.api_key: params["apiKey"] = self.api_key async with httpx.AsyncClient(timeout=30) as client: try: resp = await client.get(url, params=params) resp.raise_for_status() raw = resp.content data = resp.json() content_hash = hashlib.sha256(raw).hexdigest() articles = data.get("articles", []) return AdapterResult( source_type="news_api", ticker=ticker, items=articles, raw_payload=raw, content_hash=content_hash, fetched_at=datetime.utcnow(), ) except Exception as e: logger.error(f"News fetch failed for {ticker}: {e}") return AdapterResult( source_type="news_api", ticker=ticker, items=[], raw_payload=b"", content_hash="", fetched_at=datetime.utcnow(), error=str(e), )