feat: Refactor services architecture and update project structure
- Remove Docker-based microservices (docker-compose.yml, Makefile, Dockerfiles) - Update start-dev.sh to use backend.app:app entry point - Add shared schema and client modules for service communication - Add team coordination modules (messenger, registry, task_delegator, coordinator) - Add evaluation hooks and skill adaptation hooks - Add skill template and gateway server - Update frontend WebSocket URL configuration - Add explain components for insider and technical analysis Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
130
shared/client/news_client.py
Normal file
130
shared/client/news_client.py
Normal file
@@ -0,0 +1,130 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""News service client for news enrichment operations."""
|
||||
|
||||
import httpx
|
||||
|
||||
|
||||
class NewsServiceClient:
|
||||
"""Async client for the News Service API."""
|
||||
|
||||
def __init__(self, base_url: str = "http://localhost:8002"):
|
||||
"""Initialize the client with a base URL.
|
||||
|
||||
Args:
|
||||
base_url: Base URL for the news service API.
|
||||
"""
|
||||
self.base_url = base_url.rstrip("/")
|
||||
self._client: httpx.AsyncClient | None = None
|
||||
|
||||
async def __aenter__(self) -> "NewsServiceClient":
|
||||
self._client = httpx.AsyncClient(base_url=self.base_url, timeout=30.0)
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
||||
if self._client:
|
||||
await self._client.aclose()
|
||||
|
||||
async def get_enriched_news(
|
||||
self,
|
||||
ticker: str,
|
||||
start_date: str | None = None,
|
||||
end_date: str | None = None,
|
||||
) -> dict:
|
||||
"""Get enriched news for a ticker.
|
||||
|
||||
Args:
|
||||
ticker: Stock ticker symbol.
|
||||
start_date: Start date (YYYY-MM-DD).
|
||||
end_date: End date (YYYY-MM-DD).
|
||||
|
||||
Returns:
|
||||
Dictionary with enriched news data.
|
||||
"""
|
||||
params = {"ticker": ticker}
|
||||
if start_date:
|
||||
params["start_date"] = start_date
|
||||
if end_date:
|
||||
params["end_date"] = end_date
|
||||
response = await self._client.get("/api/enriched-news", params=params)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def get_similar_days(
|
||||
self,
|
||||
ticker: str,
|
||||
date: str,
|
||||
n_similar: int = 5,
|
||||
) -> dict:
|
||||
"""Get similar trading days based on price patterns.
|
||||
|
||||
Args:
|
||||
ticker: Stock ticker symbol.
|
||||
date: Reference date (YYYY-MM-DD).
|
||||
n_similar: Number of similar days to return.
|
||||
|
||||
Returns:
|
||||
Dictionary with similar day data.
|
||||
"""
|
||||
params = {"ticker": ticker, "date": date, "n_similar": n_similar}
|
||||
response = await self._client.get("/api/similar-days", params=params)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def get_story(self, story_id: str) -> dict:
|
||||
"""Get a specific news story by ID.
|
||||
|
||||
Args:
|
||||
story_id: The story identifier.
|
||||
|
||||
Returns:
|
||||
Dictionary with story data.
|
||||
"""
|
||||
response = await self._client.get(f"/api/stories/{story_id}")
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def post_enrich(self, news_items: list[dict]) -> dict:
|
||||
"""Enrich news items with additional analysis.
|
||||
|
||||
Args:
|
||||
news_items: List of news items to enrich.
|
||||
|
||||
Returns:
|
||||
Dictionary with enriched news data.
|
||||
"""
|
||||
response = await self._client.post("/api/enrich", json=news_items)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def get_categories(self) -> dict:
|
||||
"""Get available news categories.
|
||||
|
||||
Returns:
|
||||
Dictionary with available categories.
|
||||
"""
|
||||
response = await self._client.get("/api/categories")
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
async def search_news(
|
||||
self,
|
||||
query: str,
|
||||
ticker: str | None = None,
|
||||
limit: int = 10,
|
||||
) -> dict:
|
||||
"""Search news articles.
|
||||
|
||||
Args:
|
||||
query: Search query string.
|
||||
ticker: Optional ticker to filter by.
|
||||
limit: Maximum number of results.
|
||||
|
||||
Returns:
|
||||
Dictionary with search results.
|
||||
"""
|
||||
params = {"query": query, "limit": limit}
|
||||
if ticker:
|
||||
params["ticker"] = ticker
|
||||
response = await self._client.get("/api/search", params=params)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
Reference in New Issue
Block a user