from pydantic import BaseModel, conlist, validator from typing import Optional class PlanTriggerRequest(BaseModel): budget: Optional[float] = None goal: str housing_type: str goal_value: str portfolio_id: int trigger_file_path: str already_installed_file_path: Optional[str] = None patches_file_path: Optional[str] = None non_invasive_recommendations_file_path: Optional[str] = None exclusions: Optional[conlist(str, min_items=1)] = None scenario_name: Optional[str] = "" # If true, will allow us to create multiple plans for the same portfolio, whereas if this is false, if this property # exists in the portfolio, it will be ignored multi_plan: Optional[bool] = False # Pre-defined list of possibilities for exclusions _allowed_exclusions = { # Measure classes "wall_insulation", "ventilation", "roof_insulation", "floor_insulation", "windows", "fireplace", "heating", "hot_water", "lighting", "solar_pv", # Specific measures "air_source_heat_pump", } _allowed_goals = {"Increasing EPC"} _allowed_housing_types = {"Social", "Private"} # Validator to ensure exclusions are within the pre-defined possibilities @validator('exclusions', each_item=True) def check_exclusions(cls, v): if v not in cls._allowed_exclusions: raise ValueError(f"{v} is not an allowed exclusion") return v # Validator to ensure that the goal is within the pre-defined possibilities @validator('goal') def check_goal(cls, v): if v not in cls._allowed_goals: raise ValueError(f"{v} is not a valid goal") return v # Validator to ensure that the housing type is within the pre-defined possibilities @validator('housing_type') def check_housing_type(cls, v): if v not in cls._allowed_housing_types: raise ValueError(f"{v} is not a valid housing type") return v class MdsRequest(PlanTriggerRequest): # When creating the mds report, we allow an optional list of measures to select from. If this is passed, it will # cause the service to select the optimal package from the list of measures measures: Optional[conlist(str, min_items=1)] = None