132 lines
4.2 KiB
Python
132 lines
4.2 KiB
Python
# services/training/app/services/data_client.py
|
|
"""
|
|
Training Service Data Client
|
|
Migrated to use shared service clients - much simpler now!
|
|
"""
|
|
|
|
import structlog
|
|
from typing import Dict, Any, List, Optional
|
|
from datetime import datetime
|
|
|
|
# Import the shared clients
|
|
from shared.clients import get_sales_client, get_external_client, get_service_clients
|
|
from app.core.config import settings
|
|
|
|
logger = structlog.get_logger()
|
|
|
|
class DataClient:
|
|
"""
|
|
Data client for training service
|
|
Now uses the shared data service client under the hood
|
|
"""
|
|
|
|
def __init__(self):
|
|
# Get the new specialized clients
|
|
self.sales_client = get_sales_client(settings, "forecasting")
|
|
self.external_client = get_external_client(settings, "forecasting")
|
|
|
|
# Or alternatively, get all clients at once:
|
|
# self.clients = get_service_clients(settings, "forecasting")
|
|
# Then use: self.clients.sales.get_sales_data(...) and self.clients.external.get_weather_forecast(...)
|
|
|
|
|
|
async def fetch_weather_forecast(
|
|
self,
|
|
tenant_id: str,
|
|
days: int = 7,
|
|
latitude: Optional[float] = None,
|
|
longitude: Optional[float] = None
|
|
) -> List[Dict[str, Any]]:
|
|
"""
|
|
Fetch weather forecast data
|
|
Uses new v2.0 optimized endpoint via shared external client
|
|
"""
|
|
try:
|
|
weather_data = await self.external_client.get_weather_forecast(
|
|
tenant_id=tenant_id,
|
|
days=days,
|
|
latitude=latitude,
|
|
longitude=longitude
|
|
)
|
|
|
|
if weather_data:
|
|
logger.info(f"Fetched {len(weather_data)} weather records",
|
|
tenant_id=tenant_id)
|
|
return weather_data
|
|
else:
|
|
logger.warning("No weather data returned", tenant_id=tenant_id)
|
|
return []
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error fetching weather data: {e}", tenant_id=tenant_id)
|
|
return []
|
|
|
|
async def fetch_tenant_calendar(
|
|
self,
|
|
tenant_id: str
|
|
) -> Optional[Dict[str, Any]]:
|
|
"""
|
|
Fetch tenant's assigned school calendar
|
|
Returns None if no calendar assigned
|
|
"""
|
|
try:
|
|
location_context = await self.external_client.get_tenant_location_context(
|
|
tenant_id=tenant_id
|
|
)
|
|
|
|
if location_context and location_context.get("calendar"):
|
|
logger.info(
|
|
"Fetched calendar for tenant",
|
|
tenant_id=tenant_id,
|
|
calendar_name=location_context["calendar"].get("calendar_name")
|
|
)
|
|
return location_context["calendar"]
|
|
else:
|
|
logger.info("No calendar assigned to tenant", tenant_id=tenant_id)
|
|
return None
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error fetching calendar: {e}", tenant_id=tenant_id)
|
|
return None
|
|
|
|
async def check_school_holiday(
|
|
self,
|
|
calendar_id: str,
|
|
check_date: str,
|
|
tenant_id: str
|
|
) -> bool:
|
|
"""
|
|
Check if a date is a school holiday
|
|
|
|
Args:
|
|
calendar_id: School calendar UUID
|
|
check_date: Date in ISO format (YYYY-MM-DD)
|
|
tenant_id: Tenant ID for auth
|
|
|
|
Returns:
|
|
True if school holiday, False otherwise
|
|
"""
|
|
try:
|
|
result = await self.external_client.check_is_school_holiday(
|
|
calendar_id=calendar_id,
|
|
check_date=check_date,
|
|
tenant_id=tenant_id
|
|
)
|
|
|
|
if result:
|
|
is_holiday = result.get("is_holiday", False)
|
|
if is_holiday:
|
|
logger.debug(
|
|
"School holiday detected",
|
|
date=check_date,
|
|
holiday_name=result.get("holiday_name")
|
|
)
|
|
return is_holiday
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error checking school holiday: {e}", date=check_date)
|
|
return False
|
|
|
|
# Global instance - same as before, but much simpler implementation
|
|
data_client = DataClient() |