Checking onboardin flow - fix 4
This commit is contained in:
140
services/training/app/services/data_client.py
Normal file
140
services/training/app/services/data_client.py
Normal file
@@ -0,0 +1,140 @@
|
||||
import httpx
|
||||
import structlog
|
||||
from typing import List, Dict, Any, Optional
|
||||
from app.core.config import settings
|
||||
from app.core.service_auth import service_auth
|
||||
|
||||
logger = structlog.get_logger()
|
||||
|
||||
class DataServiceClient:
|
||||
"""Client for fetching data through the API Gateway"""
|
||||
|
||||
def __init__(self):
|
||||
self.base_url = settings.API_GATEWAY_URL
|
||||
self.timeout = 30.0
|
||||
|
||||
async def fetch_sales_data(
|
||||
self,
|
||||
tenant_id: str,
|
||||
start_date: Optional[str] = None,
|
||||
end_date: Optional[str] = None,
|
||||
product_name: Optional[str] = None
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Fetch sales data for training via API Gateway
|
||||
✅ Uses proper service authentication
|
||||
"""
|
||||
try:
|
||||
# Get service token
|
||||
token = await service_auth.get_service_token()
|
||||
|
||||
# Prepare headers
|
||||
headers = service_auth.get_request_headers(tenant_id)
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
# Prepare query parameters
|
||||
params = {}
|
||||
if start_date:
|
||||
params["start_date"] = start_date
|
||||
if end_date:
|
||||
params["end_date"] = end_date
|
||||
if product_name:
|
||||
params["product_name"] = product_name
|
||||
|
||||
# Make request via gateway
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/api/v1/tenants/{tenant_id}/sales",
|
||||
headers=headers,
|
||||
params=params
|
||||
)
|
||||
|
||||
logger.info(f"Sales data request: {response.status_code}",
|
||||
tenant_id=tenant_id,
|
||||
url=response.url)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
logger.info(f"Successfully fetched {len(data)} sales records via gateway",
|
||||
tenant_id=tenant_id)
|
||||
return data
|
||||
|
||||
elif response.status_code == 401:
|
||||
logger.error("Authentication failed with gateway",
|
||||
tenant_id=tenant_id,
|
||||
response_text=response.text)
|
||||
return []
|
||||
|
||||
elif response.status_code == 404:
|
||||
logger.warning("Sales data endpoint not found",
|
||||
tenant_id=tenant_id,
|
||||
url=response.url)
|
||||
return []
|
||||
|
||||
else:
|
||||
logger.error(f"Gateway request failed: HTTP {response.status_code}",
|
||||
tenant_id=tenant_id,
|
||||
response_text=response.text)
|
||||
return []
|
||||
|
||||
except httpx.TimeoutException:
|
||||
logger.error("Timeout when fetching sales data via gateway",
|
||||
tenant_id=tenant_id)
|
||||
return []
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching sales data via gateway: {e}",
|
||||
tenant_id=tenant_id)
|
||||
return []
|
||||
|
||||
async def fetch_weather_data(self, tenant_id: str) -> List[Dict[str, Any]]:
|
||||
"""Fetch weather data via API Gateway"""
|
||||
try:
|
||||
token = await service_auth.get_service_token()
|
||||
headers = service_auth.get_request_headers(tenant_id)
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/api/v1/tenants/{tenant_id}/weather/history",
|
||||
headers=headers
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
logger.info(f"Fetched {len(data)} weather records", tenant_id=tenant_id)
|
||||
return data
|
||||
else:
|
||||
logger.warning(f"Weather data fetch failed: {response.status_code}",
|
||||
tenant_id=tenant_id)
|
||||
return []
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching weather data: {e}", tenant_id=tenant_id)
|
||||
return []
|
||||
|
||||
async def fetch_traffic_data(self, tenant_id: str) -> List[Dict[str, Any]]:
|
||||
"""Fetch traffic data via API Gateway"""
|
||||
try:
|
||||
token = await service_auth.get_service_token()
|
||||
headers = service_auth.get_request_headers(tenant_id)
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/api/v1/tenants/{tenant_id}/traffic/historical",
|
||||
headers=headers
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
logger.info(f"Fetched {len(data)} traffic records", tenant_id=tenant_id)
|
||||
return data
|
||||
else:
|
||||
logger.warning(f"Traffic data fetch failed: {response.status_code}",
|
||||
tenant_id=tenant_id)
|
||||
return []
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Error fetching traffic data: {e}", tenant_id=tenant_id)
|
||||
return []
|
||||
@@ -19,6 +19,7 @@ from app.schemas.training import TrainingJobRequest, SingleProductTrainingReques
|
||||
from app.services.messaging import publish_job_completed, publish_job_failed
|
||||
from app.core.config import settings
|
||||
from shared.monitoring.metrics import MetricsCollector
|
||||
from app.services.data_client import DataServiceClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
metrics = MetricsCollector("training-service")
|
||||
@@ -31,6 +32,7 @@ class TrainingService:
|
||||
|
||||
def __init__(self):
|
||||
self.ml_trainer = BakeryMLTrainer()
|
||||
self.data_client = DataServiceClient()
|
||||
|
||||
async def execute_training_job_simple(self, job_id: str, tenant_id_str: str, request: TrainingJobRequest):
|
||||
"""Simple wrapper that creates its own database session"""
|
||||
@@ -136,7 +138,7 @@ class TrainingService:
|
||||
await self._update_job_status(db, job_id, "running", 5, "Fetching training data")
|
||||
|
||||
# Fetch sales data from data service
|
||||
sales_data = await self._fetch_sales_data(tenant_id, request)
|
||||
sales_data = await self.data_client.fetch_sales_data(tenant_id)
|
||||
|
||||
# Fetch external data if requested
|
||||
weather_data = []
|
||||
@@ -144,11 +146,11 @@ class TrainingService:
|
||||
|
||||
if request.include_weather:
|
||||
await self._update_job_status(db, job_id, "running", 15, "Fetching weather data")
|
||||
weather_data = await self._fetch_weather_data(tenant_id, request)
|
||||
weather_data = await self.data_client.fetch_weather_data(tenant_id)
|
||||
|
||||
if request.include_traffic:
|
||||
await self._update_job_status(db, job_id, "running", 25, "Fetching traffic data")
|
||||
traffic_data = await self._fetch_traffic_data(tenant_id, request)
|
||||
traffic_data = await self.data_client.fetch_traffic_data(tenant_id)
|
||||
|
||||
# Execute ML training
|
||||
await self._update_job_status(db, job_id, "running", 35, "Processing training data")
|
||||
|
||||
Reference in New Issue
Block a user