Skip to content

Commit

Permalink
feat(commands): add the command_id in ICommand
Browse files Browse the repository at this point in the history
  • Loading branch information
laurent-laporte-pro committed Mar 26, 2024
1 parent fb774c4 commit 3ce27f6
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
)
from antarest.study.storage.rawstudy.model.filesystem.config.model import FileStudyTreeConfig
from antarest.study.storage.rawstudy.model.filesystem.factory import FileStudy
from antarest.study.storage.variantstudy.model.command.common import BindingConstraintOperator, CommandOutput
from antarest.study.storage.variantstudy.model.command.common import BindingConstraintOperator


def apply_binding_constraint(
Expand All @@ -29,7 +29,7 @@ def apply_binding_constraint(
filter_year_by_year: t.Optional[str] = None,
filter_synthesis: t.Optional[str] = None,
group: t.Optional[str] = None,
) -> CommandOutput:
) -> str:
version = study_data.config.version
binding_constraints[new_key] = {
"name": name,
Expand All @@ -52,19 +52,13 @@ def apply_binding_constraint(
if "%" in link_or_cluster:
area_1, area_2 = link_or_cluster.split("%")
if area_1 not in study_data.config.areas or area_2 not in study_data.config.areas[area_1].links:
return CommandOutput(
status=False,
message=f"Link '{link_or_cluster}' does not exist in binding constraint '{bd_id}'",
)
return f"Link '{link_or_cluster}' does not exist in binding constraint '{bd_id}'"
elif "." in link_or_cluster:
# Cluster IDs are stored in lower case in the binding constraints file.
area, cluster_id = link_or_cluster.split(".")
thermal_ids = {thermal.id.lower() for thermal in study_data.config.areas[area].thermals}
if area not in study_data.config.areas or cluster_id.lower() not in thermal_ids:
return CommandOutput(
status=False,
message=f"Cluster '{link_or_cluster}' does not exist in binding constraint '{bd_id}'",
)
return f"Cluster '{link_or_cluster}' does not exist in binding constraint '{bd_id}'"
else:
raise NotImplementedError(f"Invalid link or thermal ID: {link_or_cluster}")

Expand Down Expand Up @@ -95,7 +89,7 @@ def apply_binding_constraint(
raise TypeError(repr(matrix_term))
if version >= 870:
study_data.tree.save(matrix_term, ["input", "bindingconstraints", f"{bd_id}_{matrix_alias}"])
return CommandOutput(status=True)
return "" # success


def parse_bindings_coeffs_and_save_into_config(
Expand Down
22 changes: 15 additions & 7 deletions antarest/study/storage/variantstudy/command_factory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
import typing as t

from antarest.core.model import JSON
from antarest.matrixstore.service import ISimpleMatrixService
Expand Down Expand Up @@ -74,14 +74,19 @@ def __init__(
patch_service=patch_service,
)

def _to_single_command(self, action: str, args: JSON, version: int) -> ICommand:
def _to_single_command(self, command_id: t.Optional[str], action: str, args: JSON, version: int) -> ICommand:
"""Convert a single CommandDTO to ICommand."""
if action in COMMAND_MAPPING:
command_class = COMMAND_MAPPING[action]
return command_class(**args, command_context=self.command_context, version=version) # type: ignore
return command_class( # type: ignore
**args,
command_context=self.command_context,
version=version,
command_id=command_id,
)
raise NotImplementedError(action)

def to_command(self, command_dto: CommandDTO) -> List[ICommand]:
def to_command(self, command_dto: CommandDTO) -> t.List[ICommand]:
"""
Convert a CommandDTO to a list of ICommand.
Expand All @@ -96,12 +101,15 @@ def to_command(self, command_dto: CommandDTO) -> List[ICommand]:
"""
args = command_dto.args
if isinstance(args, dict):
return [self._to_single_command(command_dto.action, args, command_dto.version)]
return [self._to_single_command(command_dto.id, command_dto.action, args, command_dto.version)]
elif isinstance(args, list):
return [self._to_single_command(command_dto.action, argument, command_dto.version) for argument in args]
return [
self._to_single_command(command_dto.id, command_dto.action, argument, command_dto.version)
for argument in args
]
raise NotImplementedError()

def to_commands(self, cmd_dto_list: List[CommandDTO]) -> List[ICommand]:
def to_commands(self, cmd_dto_list: t.List[CommandDTO]) -> t.List[ICommand]:
"""
Convert a list of CommandDTO to a list of ICommand.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def _apply(self, study_data: FileStudy) -> CommandOutput:
bd_id = transform_name_to_id(self.name)
self.validates_and_fills_matrices(specific_matrices=None, version=study_data.config.version, create=True)

return apply_binding_constraint(
err_msg = apply_binding_constraint(
study_data,
binding_constraints,
str(new_key),
Expand All @@ -260,6 +260,7 @@ def _apply(self, study_data: FileStudy) -> CommandOutput:
self.filter_synthesis,
self.group,
)
return CommandOutput(status=not err_msg, message=err_msg)

def to_dto(self) -> CommandDTO:
dto = super().to_dto()
Expand Down
24 changes: 18 additions & 6 deletions antarest/study/storage/variantstudy/model/command/icommand.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import typing as t
import uuid
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Dict, List, Tuple

from pydantic import BaseModel, Extra

Expand All @@ -11,20 +12,31 @@
from antarest.study.storage.variantstudy.model.command_context import CommandContext
from antarest.study.storage.variantstudy.model.model import CommandDTO

if TYPE_CHECKING: # False at runtime, for mypy
if t.TYPE_CHECKING: # False at runtime, for mypy
from antarest.study.storage.variantstudy.business.command_extractor import CommandExtractor

MATCH_SIGNATURE_SEPARATOR = "%"
logger = logging.getLogger(__name__)


class ICommand(ABC, BaseModel, extra=Extra.forbid, arbitrary_types_allowed=True):
"""
Interface for all commands that can be applied to a study.
Attributes:
command_id: The ID of the command extracted from the database, if any.
command_name: The name of the command.
version: The version of the command (currently always equal to 1).
command_context: The context of the command.
"""

command_id: t.Optional[uuid.UUID] = None
command_name: CommandName
version: int
command_context: CommandContext

@abstractmethod
def _apply_config(self, study_data: FileStudyTreeConfig) -> Tuple[CommandOutput, Dict[str, Any]]:
def _apply_config(self, study_data: FileStudyTreeConfig) -> t.Tuple[CommandOutput, t.Dict[str, t.Any]]:
"""
Applies configuration changes to the study data.
Expand Down Expand Up @@ -112,7 +124,7 @@ def match(self, other: "ICommand", equal: bool = False) -> bool:
raise NotImplementedError()

@abstractmethod
def _create_diff(self, other: "ICommand") -> List["ICommand"]:
def _create_diff(self, other: "ICommand") -> t.List["ICommand"]:
"""
Creates a list of commands representing the differences between
the current instance and another `ICommand` object.
Expand All @@ -126,7 +138,7 @@ def _create_diff(self, other: "ICommand") -> List["ICommand"]:
"""
raise NotImplementedError()

def create_diff(self, other: "ICommand") -> List["ICommand"]:
def create_diff(self, other: "ICommand") -> t.List["ICommand"]:
"""
Creates a list of commands representing the differences between
the current instance and another `ICommand` object.
Expand All @@ -142,7 +154,7 @@ def create_diff(self, other: "ICommand") -> List["ICommand"]:
return self._create_diff(other)

@abstractmethod
def get_inner_matrices(self) -> List[str]:
def get_inner_matrices(self) -> t.List[str]:
"""
Retrieves the list of matrix IDs.
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def _apply_config(self, study_data: FileStudyTreeConfig) -> Tuple[CommandOutput,
dict(),
)
study_data.bindings.remove(next(iter([bind for bind in study_data.bindings if bind.id == self.id])))
return CommandOutput(status=True), dict()
return CommandOutput(status=True), {}

def _apply(self, study_data: FileStudy) -> CommandOutput:
if self.id not in [bind.id for bind in study_data.config.bindings]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def _apply(self, study_data: FileStudy) -> CommandOutput:
self.validates_and_fills_matrices(specific_matrices=updated_matrices or None, version=study_data.config.version, create=False)
# fmt: on

return apply_binding_constraint(
err_msg = apply_binding_constraint(
study_data,
binding_constraints,
new_key,
Expand All @@ -75,6 +75,7 @@ def _apply(self, study_data: FileStudy) -> CommandOutput:
self.filter_synthesis,
self.group,
)
return CommandOutput(status=not err_msg, message=err_msg)

def to_dto(self) -> CommandDTO:
dto = super().to_dto()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class UpdateConfig(ICommand):
data: Union[str, int, float, bool, JSON, None]

def _apply_config(self, study_data: FileStudyTreeConfig) -> Tuple[CommandOutput, Dict[str, Any]]:
return CommandOutput(status=True, message="ok"), dict()
return CommandOutput(status=True, message="ok"), {}

def _apply(self, study_data: FileStudy) -> CommandOutput:
url = self.target.split("/")
Expand Down

0 comments on commit 3ce27f6

Please sign in to comment.