50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
"""Backend-neutral simulation result and preparation error contracts."""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Literal
|
|
from app.simulation.core.metadata import ResultVariableMetadata
|
|
|
|
SimulationRunStatus = Literal["completed", "cancelled", "failed"]
|
|
|
|
@dataclass(frozen=True)
|
|
class SimulationPreparationIssue:
|
|
code: str
|
|
message: str
|
|
|
|
def as_dict(self) -> dict[str, str]:
|
|
return {"code": self.code, "message": self.message}
|
|
|
|
|
|
class SimulationPreparationError(ValueError):
|
|
def __init__(self, issues: tuple[SimulationPreparationIssue, ...]) -> None:
|
|
super().__init__("The compiled model is not ready for simulation.")
|
|
self.issues = issues
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class GenericSimulationResult:
|
|
success: bool
|
|
status: SimulationRunStatus
|
|
message: str
|
|
simulated_until: float
|
|
requested_stop_time: float
|
|
variables: tuple[ResultVariableMetadata, ...]
|
|
series: dict[str, list[float]]
|
|
final: dict[str, float]
|
|
diagnostics: dict[str, object]
|
|
|
|
def as_dict(self) -> dict[str, object]:
|
|
return {
|
|
"success": self.success,
|
|
"status": self.status,
|
|
"partial": self.status != "completed",
|
|
"message": self.message,
|
|
"simulatedUntil": self.simulated_until,
|
|
"requestedStopTime": self.requested_stop_time,
|
|
"variables": [variable.as_dict() for variable in self.variables],
|
|
"series": self.series,
|
|
"final": self.final,
|
|
"diagnostics": self.diagnostics,
|
|
}
|