""" DTOs para casos de uso de Forecasting. """ from dataclasses import dataclass from typing import List, Optional, Dict @dataclass class ForecastInputDTO: """DTO de entrada para pronóstico univariado.""" values: List[float] prediction_length: int quantile_levels: List[float] timestamps: Optional[List[str]] = None series_id: str = "series_0" freq: str = "D" def validate(self) -> None: """Valida los datos de entrada.""" if not self.values: raise ValueError("values no puede estar vacío") if self.prediction_length < 1: raise ValueError("prediction_length debe ser >= 1") if not all(0 <= q <= 1 for q in self.quantile_levels): raise ValueError("quantile_levels debe estar en [0, 1]") if self.timestamps and len(self.timestamps) != len(self.values): raise ValueError("timestamps y values deben tener la misma longitud") @dataclass class ForecastOutputDTO: """DTO de salida para pronóstico univariado.""" timestamps: List[str] median: List[float] quantiles: Dict[str, List[float]] series_id: str = "series_0" metadata: Optional[Dict] = None def to_dict(self) -> Dict: """Convierte a diccionario.""" result = { "timestamps": self.timestamps, "median": self.median, "quantiles": self.quantiles, "series_id": self.series_id } if self.metadata: result["metadata"] = self.metadata return result @dataclass class SeriesInputDTO: """DTO para una serie individual en pronóstico múltiple.""" series_id: str values: List[float] timestamps: Optional[List[str]] = None @dataclass class MultiForecastInputDTO: """DTO de entrada para pronóstico múltiple.""" series_list: List[SeriesInputDTO] prediction_length: int quantile_levels: List[float] freq: str = "D" def validate(self) -> None: """Valida los datos de entrada.""" if not self.series_list: raise ValueError("series_list no puede estar vacío") if self.prediction_length < 1: raise ValueError("prediction_length debe ser >= 1") if not all(0 <= q <= 1 for q in self.quantile_levels): raise ValueError("quantile_levels debe estar en [0, 1]") # Validar cada serie for series in self.series_list: if not series.values: raise ValueError(f"Serie {series.series_id} está vacía") @dataclass class MultiForecastOutputDTO: """DTO de salida para pronóstico múltiple.""" results: List[ForecastOutputDTO] total_series: int successful: int failed: int def to_dict(self) -> Dict: """Convierte a diccionario.""" return { "results": [r.to_dict() for r in self.results], "total_series": self.total_series, "successful": self.successful, "failed": self.failed }