Skip to content

Commit

Permalink
feat: validate model references and types
Browse files Browse the repository at this point in the history
Make sure only valid model references pass validation

Refs: ECALC-1326 ECALC-1321 ECALC-1199 ECALC-890 ECALC-889
  • Loading branch information
jsolaas committed Jun 28, 2024
1 parent 20be473 commit e17259f
Show file tree
Hide file tree
Showing 28 changed files with 465 additions and 57 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ ignore = [


[tool.interrogate] # Monitor doc-string coverage
fail-under = 37 # Fail CI if the doc-string coverage falls below this level TODO: Set to 100%
fail-under = 25 # Fail CI if the doc-string coverage falls below this level TODO: Set to 100%
ignore-init-method = true
ignore-init-module = false
ignore-magic = false
Expand Down
4 changes: 2 additions & 2 deletions src/libecalc/presentation/yaml/mappers/create_references.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ def create_references(configuration: PyYamlYamlModel, resources: Resources) -> R
facility_input_mapper = FacilityInputMapper(resources=resources)
facility_inputs_from_files = {
facility_input.get(EcalcYamlKeywords.name): facility_input_mapper.from_yaml_to_dto(facility_input)
for facility_input in configuration.facility_inputs
for facility_input in configuration.facility_inputs_raise_if_invalid
}
models = create_model_references(
models_yaml_config=configuration.models,
models_yaml_config=configuration.models_raise_if_invalid,
facility_inputs=facility_inputs_from_files,
resources=resources,
)
Expand Down
31 changes: 29 additions & 2 deletions src/libecalc/presentation/yaml/yaml_models/pyyaml_yaml_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
)
from libecalc.presentation.yaml.yaml_models.yaml_model import YamlModel, YamlValidator
from libecalc.presentation.yaml.yaml_types.components.yaml_asset import YamlAsset
from libecalc.presentation.yaml.yaml_types.facility_model.yaml_facility_model import (
YamlFacilityModel,
)
from libecalc.presentation.yaml.yaml_types.models import YamlModel as YamlModelsModel
from libecalc.presentation.yaml.yaml_types.time_series.yaml_time_series import (
YamlTimeSeriesCollection,
)
Expand Down Expand Up @@ -340,9 +344,32 @@ def yaml_variables(self) -> Dict[YamlVariableReferenceId, dict]:
return self._internal_datamodel.get(EcalcYamlKeywords.variables, {})

@property
def facility_inputs(self):
@deprecated("Deprecated, facility_inputs in combination with validate should be used instead")
def facility_inputs_raise_if_invalid(self):
return self._internal_datamodel.get(EcalcYamlKeywords.facility_inputs, [])

@property
def facility_inputs(self) -> List[YamlFacilityModel]:
facility_inputs = []
for facility_input in self._internal_datamodel.get(EcalcYamlKeywords.facility_inputs, []):
try:
facility_inputs.append(TypeAdapter(YamlFacilityModel).validate_python(facility_input))
except PydanticValidationError:
pass

return facility_inputs

@property
def models(self) -> List[YamlModelsModel]:
models = []
for model in self._internal_datamodel.get(EcalcYamlKeywords.models, []):
try:
models.append(TypeAdapter(YamlModelsModel).validate_python(model))
except PydanticValidationError:
pass

return models

@property
@deprecated("Deprecated, time_series in combination with validate should be used instead")
def time_series_raise_if_invalid(self) -> List[YamlTimeSeriesCollection]:
Expand Down Expand Up @@ -373,7 +400,7 @@ def time_series(self) -> List[YamlTimeSeriesCollection]:
return time_series

@property
def models(self):
def models_raise_if_invalid(self):
return self._internal_datamodel.get(EcalcYamlKeywords.models, [])

@property
Expand Down
2 changes: 2 additions & 0 deletions src/libecalc/presentation/yaml/yaml_models/yaml_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def all_resource_names(self) -> List[str]:
def variables(self) -> Dict[str, YamlVariable]:
pass

@property
@abc.abstractmethod
def facility_inputs(self):
pass
Expand All @@ -51,6 +52,7 @@ def facility_inputs(self):
def time_series(self) -> List[YamlTimeSeriesCollection]:
pass

@property
@abc.abstractmethod
def models(self):
pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
from libecalc.presentation.yaml.yaml_types.components.legacy.energy_usage_model.yaml_energy_usage_model_compressor import (
YamlEnergyUsageModelCompressor,
)
from libecalc.presentation.yaml.yaml_types.components.legacy.energy_usage_model.yaml_energy_usage_model_compressor_train_multiple_streams import (
YamlEnergyUsageModelCompressorTrainMultipleStreams,
)
from libecalc.presentation.yaml.yaml_types.components.legacy.energy_usage_model.yaml_energy_usage_model_consumer_system import (
YamlEnergyUsageModelCompressorSystem,
YamlEnergyUsageModelPumpSystem,
)
from libecalc.presentation.yaml.yaml_types.components.legacy.energy_usage_model.yaml_energy_usage_model_consumer_system_multiple_streams import (
YamlEnergyUsageModelCompressorTrainMultipleStreams,
)
from libecalc.presentation.yaml.yaml_types.components.legacy.energy_usage_model.yaml_energy_usage_model_direct import (
YamlEnergyUsageModelDirect,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import (
YamlExpressionType,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
CompressorEnergyUsageModelModelReference,
)


class YamlEnergyUsageModelCompressor(EnergyUsageModelCommon):
Expand All @@ -16,7 +19,7 @@ class YamlEnergyUsageModelCompressor(EnergyUsageModelCommon):
title="TYPE",
description="Defines the energy usage model type.\n\n$ECALC_DOCS_KEYWORDS_URL/TYPE",
)
energy_function: str = Field(
energy_function: CompressorEnergyUsageModelModelReference = Field(
...,
title="ENERGY_FUNCTION",
description="The compressor energy function, reference to a compressor type facility model defined in FACILITY_INPUTS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import (
YamlExpressionType,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
MultipleStreamsEnergyUsageModelModelReference,
)


class YamlEnergyUsageModelCompressorTrainMultipleStreams(EnergyUsageModelCommon):
Expand All @@ -21,7 +24,7 @@ class YamlEnergyUsageModelCompressorTrainMultipleStreams(EnergyUsageModelCommon)
title="RATE_UNIT",
description="Defaults to SM3_PER_DAY, only SM3_PER_DAY implemented for now",
)
compressor_train_model: str = Field(
compressor_train_model: MultipleStreamsEnergyUsageModelModelReference = Field(
...,
title="COMPRESSOR_TRAIN_MODEL",
description="The compressor train model, reference to a compressor type model defined in MODELS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import (
YamlExpressionType,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
CompressorEnergyUsageModelModelReference,
PumpEnergyUsageModelModelReference,
)


class YamlCompressorSystemCompressor(YamlBase):
Expand All @@ -17,7 +21,7 @@ class YamlCompressorSystemCompressor(YamlBase):
title="NAME",
description="Name of the compressor",
)
compressor_model: str = Field(
compressor_model: CompressorEnergyUsageModelModelReference = Field(
...,
title="COMPRESSOR_MODEL",
description="Reference to a compressor type facility model defined in FACILITY_INPUTS",
Expand Down Expand Up @@ -99,7 +103,7 @@ class YamlPumpSystemPump(YamlBase):
title="NAME",
description="Name of the pump",
)
chart: str = Field(
chart: PumpEnergyUsageModelModelReference = Field(
...,
title="COMPRESSOR_MODEL",
description="Reference to a pump type facility model defined in FACILITY_INPUTS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import (
YamlExpressionType,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
PumpEnergyUsageModelModelReference,
)


class YamlEnergyUsageModelPump(EnergyUsageModelCommon):
Expand All @@ -16,7 +19,7 @@ class YamlEnergyUsageModelPump(EnergyUsageModelCommon):
title="TYPE",
description="Defines the energy usage model type.\n\n$ECALC_DOCS_KEYWORDS_URL/TYPE",
)
energy_function: str = Field(
energy_function: PumpEnergyUsageModelModelReference = Field(
...,
title="ENERGY_FUNCTION",
description="The pump energy function, reference to a pump type facility model defined in FACILITY_INPUTS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_expression_type import (
YamlExpressionType,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
TabulatedEnergyUsageModelModelReference,
)


class YamlTabulatedVariable(YamlBase):
Expand All @@ -30,7 +33,7 @@ class YamlEnergyUsageModelTabulated(EnergyUsageModelCommon):
title="TYPE",
description="Defines the energy usage model type.\n\n$ECALC_DOCS_KEYWORDS_URL/TYPE",
)
energy_function: str = Field(
energy_function: TabulatedEnergyUsageModelModelReference = Field(
...,
title="ENERGY_FUNCTION",
description="The tabulated energy function, reference to a tabular type facility model defined in FACILITY_INPUTS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_installation import (
YamlInstallation,
)
from libecalc.presentation.yaml.yaml_types.facility_type.yaml_facility_type import (
YamlFacilityType,
from libecalc.presentation.yaml.yaml_types.facility_model.yaml_facility_model import (
YamlFacilityModel,
)
from libecalc.presentation.yaml.yaml_types.fuel_type.yaml_fuel_type import YamlFuelType
from libecalc.presentation.yaml.yaml_types.models import YamlModel
Expand All @@ -33,7 +33,7 @@ class YamlAsset(YamlBase):
description="Defines the inputs for time dependent variables, or 'reservoir variables'."
"\n\n$ECALC_DOCS_KEYWORDS_URL/TIME_SERIES",
)
facility_inputs: List[YamlFacilityType] = Field(
facility_inputs: List[YamlFacilityModel] = Field(
None,
title="FACILITY_INPUTS",
description="Defines input files which characterize various facility elements."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
YamlConsumerBase,
)
from libecalc.presentation.yaml.yaml_types.models import YamlCompressorWithTurbine
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
CompressorV2ModelReference,
)
from libecalc.presentation.yaml.yaml_types.yaml_temporal_model import YamlTemporalModel

CompressorModel = Union[YamlCompressorWithTurbine]
Expand All @@ -30,7 +33,7 @@ class YamlCompressor(YamlConsumerBase):
alias="TYPE",
)

energy_usage_model: YamlTemporalModel[str]
energy_usage_model: YamlTemporalModel[CompressorV2ModelReference]

def to_dto(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_category_field import (
CategoryField,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
GeneratorSetModelReference,
)
from libecalc.presentation.yaml.yaml_types.yaml_temporal_model import YamlTemporalModel


Expand All @@ -34,7 +37,7 @@ class YamlGeneratorSet(YamlBase):
title="FUEL",
description="The fuel used by the generator set." "\n\n$ECALC_DOCS_KEYWORDS_URL/FUEL",
)
electricity2fuel: YamlTemporalModel[str] = Field(
electricity2fuel: YamlTemporalModel[GeneratorSetModelReference] = Field(
...,
title="ELECTRICITY2FUEL",
description="Specifies the correlation between the electric power delivered and the fuel burned by a "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
from libecalc.presentation.yaml.yaml_types.components.yaml_base import (
YamlConsumerBase,
)
from libecalc.presentation.yaml.yaml_types.models.model_reference_validation import (
PumpV2ModelReference,
)
from libecalc.presentation.yaml.yaml_types.yaml_temporal_model import YamlTemporalModel


Expand All @@ -27,7 +30,7 @@ class YamlPump(YamlConsumerBase):
alias="TYPE",
)

energy_usage_model: YamlTemporalModel[str]
energy_usage_model: YamlTemporalModel[PumpV2ModelReference]

def to_dto(
self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import enum
from typing import Literal, Union

from pydantic import Field, field_validator
Expand All @@ -9,6 +10,14 @@
)


class YamlFacilityModelType(str, enum.Enum):
ELECTRICITY2FUEL = "ELECTRICITY2FUEL"
TABULAR = "TABULAR"
COMPRESSOR_TABULAR = "COMPRESSOR_TABULAR"
PUMP_CHART_SINGLE_SPEED = "PUMP_CHART_SINGLE_SPEED"
PUMP_CHART_VARIABLE_SPEED = "PUMP_CHART_VARIABLE_SPEED"


def FacilityTypeField():
return Field(
...,
Expand All @@ -30,7 +39,7 @@ class YamlFacilityAdjustment(YamlBase):
)


class YamlFacilityTypeBase(YamlBase):
class YamlFacilityModelBase(YamlBase):
name: str = Field(
...,
title="NAME",
Expand All @@ -50,16 +59,16 @@ class YamlFacilityTypeBase(YamlBase):
validate_file_exists = field_validator("file", mode="after")(file_exists_validator)


class YamlGeneratorSetModel(YamlFacilityTypeBase):
type: Literal["ELECTRICITY2FUEL"] = FacilityTypeField()
class YamlGeneratorSetModel(YamlFacilityModelBase):
type: Literal[YamlFacilityModelType.ELECTRICITY2FUEL] = FacilityTypeField()


class YamlTabularModel(YamlFacilityTypeBase):
type: Literal["TABULAR"] = FacilityTypeField()
class YamlTabularModel(YamlFacilityModelBase):
type: Literal[YamlFacilityModelType.TABULAR] = FacilityTypeField()


class YamlCompressorTabularModel(YamlFacilityTypeBase):
type: Literal["COMPRESSOR_TABULAR"] = FacilityTypeField()
class YamlCompressorTabularModel(YamlFacilityModelBase):
type: Literal[YamlFacilityModelType.COMPRESSOR_TABULAR] = FacilityTypeField()


class YamlPumpChartUnits(YamlBase):
Expand All @@ -80,7 +89,7 @@ class YamlPumpChartUnits(YamlBase):
)


class YamlPumpChartBase(YamlFacilityTypeBase):
class YamlPumpChartBase(YamlFacilityModelBase):
head_margin: float = Field(
None,
title="HEAD_MARGIN",
Expand All @@ -92,14 +101,14 @@ class YamlPumpChartBase(YamlFacilityTypeBase):


class YamlPumpChartSingleSpeed(YamlPumpChartBase):
type: Literal["PUMP_CHART_SINGLE_SPEED"] = FacilityTypeField()
type: Literal[YamlFacilityModelType.PUMP_CHART_SINGLE_SPEED] = FacilityTypeField()


class YamlPumpChartVariableSpeed(YamlPumpChartBase):
type: Literal["PUMP_CHART_VARIABLE_SPEED"] = FacilityTypeField()
type: Literal[YamlFacilityModelType.PUMP_CHART_VARIABLE_SPEED] = FacilityTypeField()


YamlFacilityType = Annotated[
YamlFacilityModel = Annotated[
Union[
YamlGeneratorSetModel,
YamlTabularModel,
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ModelReference = str
ModelName = str
Loading

0 comments on commit e17259f

Please sign in to comment.