Skip to content

Commit

Permalink
start work
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinBelthle committed Feb 12, 2025
1 parent a5d6a44 commit 45d00e9
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 72 deletions.
34 changes: 13 additions & 21 deletions src/antares/craft/model/binding_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from dataclasses import dataclass
from enum import Enum
from typing import Any, Optional, Union

import pandas as pd

from antares.craft.service.base_services import BaseBindingConstraintService
from antares.craft.tools.all_optional_meta import all_optional_model
from antares.craft.tools.contents_tool import EnumIgnoreCase, transform_name_to_id
from pydantic import BaseModel, Field, model_validator
from pydantic.alias_generators import to_camel


class BindingConstraintFrequency(EnumIgnoreCase):
Expand Down Expand Up @@ -92,20 +90,19 @@ def generate_id(cls, data: Union[dict[str, str], LinkData, ClusterData]) -> str:
return ".".join((data.area.lower(), data.cluster.lower()))


class DefaultBindingConstraintProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel):
"""Default properties for binding constraints
Attributes:
enabled (bool): True
time_step (BindingConstraintFrequency): BindingConstraintFrequency.HOURLY
operator (BindingConstraintOperator): BindingConstraintOperator.LESS
comments (str): None
filter_year_by_year (str): "hourly"
filter_synthesis (str): "hourly"
group (str): "default"
@dataclass
class BindingConstraintPropertiesUpdate:
enabled: Optional[bool] = None
time_step: Optional[BindingConstraintFrequency] = None
operator: Optional[BindingConstraintOperator] = None
comments: Optional[str] = None
filter_year_by_year: Optional[str] = None
filter_synthesis: Optional[str] = None
group: Optional[str] = None

"""

@dataclass
class BindingConstraintProperties:
enabled: bool = True
time_step: BindingConstraintFrequency = BindingConstraintFrequency.HOURLY
operator: BindingConstraintOperator = BindingConstraintOperator.LESS
Expand All @@ -115,11 +112,6 @@ class DefaultBindingConstraintProperties(BaseModel, extra="forbid", populate_by_
group: str = "default"


@all_optional_model
class BindingConstraintProperties(DefaultBindingConstraintProperties):
pass


class BindingConstraint:
def __init__(
self,
Expand Down Expand Up @@ -162,7 +154,7 @@ def delete_term(self, term: ConstraintTerm) -> None:
self._binding_constraint_service.delete_binding_constraint_term(self.id, term.id)
self._terms.pop(term.id)

def update_properties(self, properties: BindingConstraintProperties) -> None:
def update_properties(self, properties: BindingConstraintPropertiesUpdate) -> None:
new_properties = self._binding_constraint_service.update_binding_constraint_properties(self, properties)
self._properties = new_properties

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
#
# See AUTHORS.txt
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from dataclasses import asdict
from typing import Union

from antares.craft.model.binding_constraint import (
BindingConstraintFrequency,
BindingConstraintOperator,
BindingConstraintProperties,
BindingConstraintPropertiesUpdate,
)
from antares.craft.service.api_services.models import APIBaseModel
from antares.craft.tools.all_optional_meta import all_optional_model

BindingConstraintPropertiesType = Union[BindingConstraintProperties, BindingConstraintPropertiesUpdate]


@all_optional_model
class BindingConstraintPropertiesAPI(APIBaseModel):
enabled: bool
time_step: BindingConstraintFrequency
operator: BindingConstraintOperator
comments: str
filter_year_by_year: str
filter_synthesis: str
group: str

@staticmethod
def from_user_model(user_class: BindingConstraintPropertiesType) -> "BindingConstraintPropertiesAPI":
user_dict = asdict(user_class)
return BindingConstraintPropertiesAPI.model_validate(user_dict)

def to_user_model(self) -> BindingConstraintProperties:
return BindingConstraintProperties(
enabled=self.enabled,
time_step=self.time_step,
operator=self.operator,
comments=self.comments,
filter_year_by_year=self.filter_year_by_year,
filter_synthesis=self.filter_synthesis,
group=self.group,
)
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
from antares.craft.model.binding_constraint import (
BindingConstraint,
BindingConstraintProperties,
BindingConstraintPropertiesUpdate,
ConstraintMatrixName,
ConstraintTerm,
)
from antares.craft.service.api_services.models.binding_constraint import BindingConstraintPropertiesAPI
from antares.craft.service.api_services.utils import get_matrix
from antares.craft.service.base_services import BaseBindingConstraintService
from typing_extensions import override
Expand Down Expand Up @@ -77,7 +79,8 @@ def create_binding_constraint(
try:
body = {"name": name}
if properties:
camel_properties = properties.model_dump(mode="json", by_alias=True, exclude_none=True)
api_model = BindingConstraintPropertiesAPI.from_user_model(properties)
camel_properties = api_model.model_dump(mode="json", by_alias=True, exclude_none=True)
body = {**body, **camel_properties}
for matrix, matrix_name in zip(
[less_term_matrix, equal_term_matrix, greater_term_matrix],
Expand All @@ -90,7 +93,8 @@ def create_binding_constraint(
bc_id = created_properties["id"]
for key in ["terms", "id", "name"]:
del created_properties[key]
bc_properties = BindingConstraintProperties.model_validate(created_properties)
api_properties = BindingConstraintPropertiesAPI.model_validate(created_properties)
bc_properties = api_properties.to_user_model()
bc_terms: list[ConstraintTerm] = []

if terms:
Expand Down Expand Up @@ -120,19 +124,21 @@ def delete_binding_constraint_term(self, constraint_id: str, term_id: str) -> No

@override
def update_binding_constraint_properties(
self, binding_constraint: BindingConstraint, properties: BindingConstraintProperties
self, binding_constraint: BindingConstraint, properties: BindingConstraintPropertiesUpdate
) -> BindingConstraintProperties:
url = f"{self._base_url}/studies/{self.study_id}/bindingconstraints/{binding_constraint.id}"
try:
body = properties.model_dump(mode="json", by_alias=True, exclude_none=True)
api_model = BindingConstraintPropertiesAPI.from_user_model(properties)
body = api_model.model_dump(mode="json", by_alias=True, exclude_none=True)
if not body:
return binding_constraint.properties

response = self._wrapper.put(url, json=body)
json_response = response.json()
for key in ["terms", "id", "name"]:
del json_response[key]
new_properties = BindingConstraintProperties.model_validate(json_response)
new_api_properties = BindingConstraintPropertiesAPI.model_validate(json_response)
new_properties = new_api_properties.to_user_model()

except APIError as e:
raise ConstraintPropertiesUpdateError(binding_constraint.id, e.message) from e
Expand Down
3 changes: 2 additions & 1 deletion src/antares/craft/service/base_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from antares.craft.model.binding_constraint import (
BindingConstraint,
BindingConstraintProperties,
BindingConstraintPropertiesUpdate,
ConstraintMatrixName,
ConstraintTerm,
)
Expand Down Expand Up @@ -491,7 +492,7 @@ def delete_binding_constraint_term(self, constraint_id: str, term_id: str) -> No

@abstractmethod
def update_binding_constraint_properties(
self, binding_constraint: "BindingConstraint", properties: "BindingConstraintProperties"
self, binding_constraint: "BindingConstraint", properties: "BindingConstraintPropertiesUpdate"
) -> "BindingConstraintProperties":
"""
Args:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
#
# See AUTHORS.txt
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# SPDX-License-Identifier: MPL-2.0
#
# This file is part of the Antares project.

from dataclasses import asdict
from typing import Union

from antares.craft.model.binding_constraint import (
BindingConstraintFrequency,
BindingConstraintOperator,
BindingConstraintProperties,
BindingConstraintPropertiesUpdate,
)
from antares.craft.service.local_services.models import LocalBaseModel
from antares.craft.tools.all_optional_meta import all_optional_model

BindingConstraintPropertiesType = Union[BindingConstraintProperties, BindingConstraintPropertiesUpdate]


@all_optional_model
class BindingConstraintPropertiesLocal(LocalBaseModel):
enabled: bool
time_step: BindingConstraintFrequency
operator: BindingConstraintOperator
comments: str
filter_year_by_year: str
filter_synthesis: str
group: str

@staticmethod
def from_user_model(user_class: BindingConstraintPropertiesType) -> "BindingConstraintPropertiesLocal":
user_dict = asdict(user_class)
return BindingConstraintPropertiesLocal.model_validate(user_dict)

def to_user_model(self) -> BindingConstraintProperties:
return BindingConstraintProperties(
enabled=self.enabled,
time_step=self.time_step,
operator=self.operator,
comments=self.comments,
filter_year_by_year=self.filter_year_by_year,
filter_synthesis=self.filter_synthesis,
group=self.group,
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,58 +21,18 @@
BindingConstraintFrequency,
BindingConstraintOperator,
BindingConstraintProperties,
BindingConstraintPropertiesUpdate,
ConstraintMatrixName,
ConstraintTerm,
DefaultBindingConstraintProperties,
)
from antares.craft.service.base_services import BaseBindingConstraintService
from antares.craft.service.local_services.models.binding_constraint import BindingConstraintPropertiesLocal
from antares.craft.tools.ini_tool import IniFile, InitializationFilesTypes
from antares.craft.tools.matrix_tool import df_read, df_save
from antares.craft.tools.time_series_tool import TimeSeriesFileType
from pydantic import Field
from typing_extensions import override


class BindingConstraintPropertiesLocal(DefaultBindingConstraintProperties):
"""
Used to create the entries for the bindingconstraints.ini file
Attributes:
constraint_name: The constraint name
constraint_id: The constraint id
properties (BindingConstraintProperties): The BindingConstraintProperties to set
terms (dict[str, ConstraintTerm]]): The terms applying to the binding constraint
"""

constraint_name: str
constraint_id: str
terms: dict[str, ConstraintTerm] = Field(default_factory=dict[str, ConstraintTerm])

@property
def list_ini_fields(self) -> dict[str, str]:
ini_dict = {
"name": self.constraint_name,
"id": self.constraint_id,
"enabled": f"{self.enabled}".lower(),
"type": self.time_step.value,
"operator": self.operator.value,
"comments": self.comments,
"filter-year-by-year": self.filter_year_by_year,
"filter-synthesis": self.filter_synthesis,
"group": self.group,
} | {term_id: term.weight_offset() for term_id, term in self.terms.items()}
return {key: value for key, value in ini_dict.items() if value not in [None, ""]}

def yield_binding_constraint_properties(self) -> BindingConstraintProperties:
excludes = {
"constraint_name",
"constraint_id",
"terms",
"list_ini_fields",
}
return BindingConstraintProperties(**self.model_dump(mode="json", exclude=excludes))


class BindingConstraintLocalService(BaseBindingConstraintService):
def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None:
super().__init__(**kwargs)
Expand Down Expand Up @@ -232,7 +192,7 @@ def delete_binding_constraint_term(self, constraint_id: str, term_id: str) -> No

@override
def update_binding_constraint_properties(
self, binding_constraint: BindingConstraint, properties: BindingConstraintProperties
self, binding_constraint: BindingConstraint, properties: BindingConstraintPropertiesUpdate
) -> BindingConstraintProperties:
raise NotImplementedError

Expand Down
4 changes: 2 additions & 2 deletions src/antares/craft/service/service_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
from antares.craft.config.base_configuration import BaseConfiguration
from antares.craft.config.local_configuration import LocalConfiguration
from antares.craft.service.api_services.area_api import AreaApiService
from antares.craft.service.api_services.binding_constraint_api import BindingConstraintApiService
from antares.craft.service.api_services.hydro_api import HydroApiService
from antares.craft.service.api_services.link_api import LinkApiService
from antares.craft.service.api_services.services.binding_constraint import BindingConstraintApiService
from antares.craft.service.api_services.services.output import OutputApiService
from antares.craft.service.api_services.services.renewable import RenewableApiService
from antares.craft.service.api_services.services.run import RunApiService
Expand All @@ -38,9 +38,9 @@
BaseThermalService,
)
from antares.craft.service.local_services.area_local import AreaLocalService
from antares.craft.service.local_services.binding_constraint_local import BindingConstraintLocalService
from antares.craft.service.local_services.hydro_local import HydroLocalService
from antares.craft.service.local_services.link_local import LinkLocalService
from antares.craft.service.local_services.services.binding_constraint import BindingConstraintLocalService
from antares.craft.service.local_services.services.output import OutputLocalService
from antares.craft.service.local_services.services.renewable import RenewableLocalService
from antares.craft.service.local_services.services.run import RunLocalService
Expand Down

0 comments on commit 45d00e9

Please sign in to comment.