Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(version): use class StudyVersion to handle versions #2156

Merged
merged 32 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
419a48a
almost nothing
MartinBelthle Sep 20, 2024
e1a1ecd
bump version of antares stduy version
MartinBelthle Sep 24, 2024
2ddeebf
fix formatting
MartinBelthle Sep 24, 2024
2179d27
remove useless parsing
MartinBelthle Sep 24, 2024
cd369bb
try to fix mypy issue
MartinBelthle Sep 24, 2024
d7681d4
fix mypy again
MartinBelthle Sep 24, 2024
fd4568a
fix some tests
MartinBelthle Sep 24, 2024
8014591
fix little issues
MartinBelthle Sep 24, 2024
619946a
use next version
MartinBelthle Sep 25, 2024
d6b4c50
serialize version as an int
MartinBelthle Sep 25, 2024
29c58c7
fix tests
MartinBelthle Sep 25, 2024
fe17ecf
fix tests
MartinBelthle Sep 25, 2024
8fcff3b
bump and use v1.0.6
MartinBelthle Sep 25, 2024
8773381
make test work
MartinBelthle Sep 25, 2024
d59f85e
Merge branch 'dev' into feat/use-antares-study-version-widely
MartinBelthle Sep 26, 2024
e8f39a9
handle x.x study versions parsing
MartinBelthle Sep 26, 2024
82e1798
add integration test
MartinBelthle Sep 26, 2024
29c481e
fix typing
MartinBelthle Sep 26, 2024
bfac54b
use StudyVersion more widely
MartinBelthle Sep 26, 2024
bf82160
continue work
MartinBelthle Sep 26, 2024
d0ea8d5
little change
MartinBelthle Sep 26, 2024
318c86e
Merge branch 'dev' into feat/use-antares-study-version-widely
MartinBelthle Sep 26, 2024
53f5be8
fix issue
MartinBelthle Sep 26, 2024
992cb1c
use global variable
MartinBelthle Sep 26, 2024
f1417bc
fix tests
MartinBelthle Sep 26, 2024
a2e3cb5
fix last failing tets
MartinBelthle Sep 26, 2024
563cf31
Merge branch 'dev' into feat/use-antares-study-version-widely
MartinBelthle Sep 27, 2024
775921f
resolve comments
MartinBelthle Sep 27, 2024
167e167
serialize solver version the good way
MartinBelthle Sep 27, 2024
9fb6143
fix test
MartinBelthle Sep 27, 2024
7d4c84b
Merge branch 'dev' into feat/use-antares-study-version-widely
sylvlecl Oct 1, 2024
94f4ea8
merge with dev
MartinBelthle Oct 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions antarest/launcher/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def run_study(
job_uuid = self._generate_new_id()
logger.info(f"New study launch (study={study_uuid}, job_id={job_uuid})")
study_info = self.study_service.get_study_information(uuid=study_uuid, params=params)
solver_version = study_version or study_info.version
solver_version = study_version or study_info.version.__format__(format_spec="ddd")
MartinBelthle marked this conversation as resolved.
Show resolved Hide resolved

self._assert_launcher_is_initialized(launcher)
assert_permission(
Expand All @@ -252,7 +252,7 @@ def run_study(
self.launchers[launcher].run_study(
study_uuid,
job_uuid,
str(solver_version),
solver_version,
sylvlecl marked this conversation as resolved.
Show resolved Hide resolved
launcher_parameters,
params,
)
Expand Down
22 changes: 11 additions & 11 deletions antarest/study/business/adequacy_patch_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from antarest.study.business.all_optional_meta import all_optional_model
from antarest.study.business.enum_ignore_case import EnumIgnoreCase
from antarest.study.business.utils import GENERAL_DATA_PATH, FieldInfo, FormFieldsBaseModel, execute_or_add_commands
from antarest.study.model import Study
from antarest.study.model import STUDY_VERSION_830, STUDY_VERSION_850, Study
from antarest.study.storage.storage_service import StudyStorageService
from antarest.study.storage.variantstudy.model.command.update_config import UpdateConfig

Expand Down Expand Up @@ -52,47 +52,47 @@ class AdequacyPatchFormFields(FormFieldsBaseModel):
"enable_adequacy_patch": {
"path": f"{ADEQUACY_PATCH_PATH}/include-adq-patch",
"default_value": False,
"start_version": 830,
"start_version": STUDY_VERSION_830,
},
"ntc_from_physical_areas_out_to_physical_areas_in_adequacy_patch": {
"path": f"{ADEQUACY_PATCH_PATH}/set-to-null-ntc-from-physical-out-to-physical-in-for-first-step",
"default_value": True,
"start_version": 830,
"start_version": STUDY_VERSION_830,
},
"ntc_between_physical_areas_out_adequacy_patch": {
"path": f"{ADEQUACY_PATCH_PATH}/set-to-null-ntc-between-physical-out-for-first-step",
"default_value": True,
"start_version": 830,
"start_version": STUDY_VERSION_830,
},
"price_taking_order": {
"path": f"{ADEQUACY_PATCH_PATH}/price-taking-order",
"default_value": PriceTakingOrder.DENS.value,
"start_version": 850,
"start_version": STUDY_VERSION_850,
},
"include_hurdle_cost_csr": {
"path": f"{ADEQUACY_PATCH_PATH}/include-hurdle-cost-csr",
"default_value": False,
"start_version": 850,
"start_version": STUDY_VERSION_850,
},
"check_csr_cost_function": {
"path": f"{ADEQUACY_PATCH_PATH}/check-csr-cost-function",
"default_value": False,
"start_version": 850,
"start_version": STUDY_VERSION_850,
},
"threshold_initiate_curtailment_sharing_rule": {
"path": f"{ADEQUACY_PATCH_PATH}/threshold-initiate-curtailment-sharing-rule",
"default_value": 0.0,
"start_version": 850,
"start_version": STUDY_VERSION_850,
},
"threshold_display_local_matching_rule_violations": {
"path": f"{ADEQUACY_PATCH_PATH}/threshold-display-local-matching-rule-violations",
"default_value": 0.0,
"start_version": 850,
"start_version": STUDY_VERSION_850,
},
"threshold_csr_variable_bounds_relaxation": {
"path": f"{ADEQUACY_PATCH_PATH}/threshold-csr-variable-bounds-relaxation",
"default_value": 3,
"start_version": 850,
"start_version": STUDY_VERSION_850,
},
}

Expand All @@ -113,7 +113,7 @@ def get_value(field_info: FieldInfo) -> Any:
path = field_info["path"]
start_version = field_info.get("start_version", -1)
target_name = path.split("/")[-1]
is_in_version = file_study.config.version >= start_version # type: ignore
is_in_version = file_study.config.version >= start_version

return parent.get(target_name, field_info["default_value"]) if is_in_version else None

Expand Down
5 changes: 3 additions & 2 deletions antarest/study/business/advanced_parameters_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@

from typing import Any, Dict, List

from antares.study.version import StudyVersion
from pydantic import field_validator
from pydantic.types import StrictInt, StrictStr

from antarest.core.exceptions import InvalidFieldForVersionError
from antarest.study.business.all_optional_meta import all_optional_model
from antarest.study.business.enum_ignore_case import EnumIgnoreCase
from antarest.study.business.utils import GENERAL_DATA_PATH, FieldInfo, FormFieldsBaseModel, execute_or_add_commands
from antarest.study.model import Study
from antarest.study.model import STUDY_VERSION_880, Study
from antarest.study.storage.storage_service import StudyStorageService
from antarest.study.storage.variantstudy.model.command.update_config import UpdateConfig

Expand Down Expand Up @@ -255,7 +256,7 @@ def set_field_values(self, study: Study, field_values: AdvancedParamsFormFields)
if (
field_name == "unit_commitment_mode"
and value == UnitCommitmentMode.MILP
and int(study.version) < 880
and StudyVersion.parse(study.version) < STUDY_VERSION_880
):
raise InvalidFieldForVersionError("Unit commitment mode `MILP` only exists in v8.8+ studies")

Expand Down
4 changes: 2 additions & 2 deletions antarest/study/business/areas/properties_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from antarest.core.exceptions import ChildNotFoundError
from antarest.study.business.all_optional_meta import all_optional_model
from antarest.study.business.utils import FieldInfo, FormFieldsBaseModel, execute_or_add_commands
from antarest.study.model import Study
from antarest.study.model import STUDY_VERSION_830, Study
from antarest.study.storage.rawstudy.model.filesystem.config.area import AdequacyPatchMode
from antarest.study.storage.storage_service import StudyStorageService
from antarest.study.storage.variantstudy.model.command.update_config import UpdateConfig
Expand Down Expand Up @@ -113,7 +113,7 @@ def validation(cls, values: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
"adequacy_patch_mode": {
"path": f"{AREA_PATH}/adequacy_patch/adequacy-patch/adequacy-patch-mode",
"default_value": AdequacyPatchMode.OUTSIDE.value,
"start_version": 830,
"start_version": STUDY_VERSION_830,
},
}

Expand Down
18 changes: 9 additions & 9 deletions antarest/study/business/areas/renewable_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import collections
import typing as t

from antares.study.version import StudyVersion
from pydantic import field_validator

from antarest.core.exceptions import DuplicateRenewableCluster, RenewableClusterConfigNotFound, RenewableClusterNotFound
Expand Down Expand Up @@ -82,7 +83,7 @@ def validate_name(cls, name: t.Optional[str]) -> str:
raise ValueError("name must not be empty")
return name

def to_config(self, study_version: t.Union[str, int]) -> RenewableConfigType:
def to_config(self, study_version: StudyVersion) -> RenewableConfigType:
values = self.model_dump(by_alias=False, exclude_none=True)
return create_renewable_config(study_version=study_version, **values)

Expand All @@ -109,11 +110,11 @@ def json_schema_extra(schema: t.MutableMapping[str, t.Any]) -> None:


def create_renewable_output(
study_version: t.Union[str, int],
study_version: str,
cluster_id: str,
config: t.Mapping[str, t.Any],
) -> "RenewableClusterOutput":
obj = create_renewable_config(study_version=study_version, **config, id=cluster_id)
obj = create_renewable_config(study_version=StudyVersion.parse(study_version), **config, id=cluster_id)
kwargs = obj.model_dump(by_alias=False)
return RenewableClusterOutput(**kwargs)

Expand Down Expand Up @@ -182,12 +183,11 @@ def get_all_renewables_props(
except KeyError:
raise RenewableClusterConfigNotFound(path)

study_version = study.version
renewables_by_areas: t.MutableMapping[str, t.MutableMapping[str, RenewableClusterOutput]]
renewables_by_areas = collections.defaultdict(dict)
for area_id, cluster_obj in clusters.items():
for cluster_id, cluster in cluster_obj.items():
renewables_by_areas[area_id][cluster_id] = create_renewable_output(study_version, cluster_id, cluster)
renewables_by_areas[area_id][cluster_id] = create_renewable_output(study.version, cluster_id, cluster)

return renewables_by_areas

Expand All @@ -206,7 +206,7 @@ def create_cluster(
The newly created cluster.
"""
file_study = self._get_file_study(study)
cluster = cluster_data.to_config(study.version)
cluster = cluster_data.to_config(StudyVersion.parse(study.version))
command = self._make_create_cluster_cmd(area_id, cluster)
execute_or_add_commands(
study,
Expand Down Expand Up @@ -272,7 +272,7 @@ def update_cluster(
RenewableClusterNotFound: If the cluster to update is not found.
"""

study_version = study.version
study_version = StudyVersion.parse(study.version)
file_study = self._get_file_study(study)
path = _CLUSTER_PATH.format(area_id=area_id, cluster_id=cluster_id)

Expand Down Expand Up @@ -356,7 +356,7 @@ def duplicate_cluster(
current_cluster = self.get_cluster(study, area_id, source_id)
current_cluster.name = new_cluster_name
creation_form = RenewableClusterCreation(**current_cluster.model_dump(by_alias=False, exclude={"id"}))
new_config = creation_form.to_config(study.version)
new_config = creation_form.to_config(StudyVersion.parse(study.version))
create_cluster_cmd = self._make_create_cluster_cmd(area_id, new_config)

# Matrix edition
Expand Down Expand Up @@ -395,7 +395,7 @@ def update_renewables_props(

# Convert the DTO to a configuration object and update the configuration file.
properties = create_renewable_config(
study.version, **new_cluster.model_dump(by_alias=False, exclude_none=True)
StudyVersion.parse(study.version), **new_cluster.model_dump(by_alias=False, exclude_none=True)
)
path = _CLUSTER_PATH.format(area_id=area_id, cluster_id=renewable_id)
cmd = UpdateConfig(
Expand Down
24 changes: 13 additions & 11 deletions antarest/study/business/areas/st_storage_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import typing as t

import numpy as np
from antares.study.version import StudyVersion
from pydantic import BaseModel, field_validator, model_validator
from typing_extensions import Literal

Expand All @@ -30,7 +31,7 @@
from antarest.core.requests import CaseInsensitiveDict
from antarest.study.business.all_optional_meta import all_optional_model, camel_case_model
from antarest.study.business.utils import execute_or_add_commands
from antarest.study.model import Study
from antarest.study.model import STUDY_VERSION_880, Study
from antarest.study.storage.rawstudy.model.filesystem.config.model import transform_name_to_id
from antarest.study.storage.rawstudy.model.filesystem.config.st_storage import (
STStorage880Config,
Expand Down Expand Up @@ -85,7 +86,7 @@ def validate_name(cls, name: t.Optional[str]) -> str:
return name

# noinspection PyUnusedLocal
def to_config(self, study_version: t.Union[str, int]) -> STStorageConfigType:
def to_config(self, study_version: StudyVersion) -> STStorageConfigType:
values = self.model_dump(by_alias=False, exclude_none=True)
return create_st_storage_config(study_version=study_version, **values)

Expand Down Expand Up @@ -239,7 +240,7 @@ def _get_values_by_ids(file_study: FileStudy, area_id: str) -> t.Mapping[str, t.


def create_storage_output(
study_version: t.Union[str, int],
study_version: StudyVersion,
cluster_id: str,
config: t.Mapping[str, t.Any],
) -> "STStorageOutput":
Expand Down Expand Up @@ -283,7 +284,7 @@ def create_storage(
file_study = self._get_file_study(study)
values_by_ids = _get_values_by_ids(file_study, area_id)

storage = form.to_config(study.version)
storage = form.to_config(StudyVersion.parse(study.version))
values = values_by_ids.get(storage.id)
if values is not None:
raise DuplicateSTStorage(area_id, storage.id)
Expand Down Expand Up @@ -333,7 +334,7 @@ def get_storages(

# Sort STStorageConfig by groups and then by name
order_by = operator.attrgetter("group", "name")
study_version = int(study.version)
study_version = StudyVersion.parse(study.version)
storages = [create_storage_output(study_version, storage_id, options) for storage_id, options in config.items()]
return sorted(storages, key=order_by)

Expand Down Expand Up @@ -364,7 +365,7 @@ def get_all_storages_props(
except KeyError:
raise STStorageConfigNotFound(path) from None

study_version = study.version
study_version = StudyVersion.parse(study.version)
storages_by_areas: t.MutableMapping[str, t.MutableMapping[str, STStorageOutput]]
storages_by_areas = collections.defaultdict(dict)
for area_id, cluster_obj in storages.items():
Expand Down Expand Up @@ -393,7 +394,7 @@ def update_storages_props(

# Convert the DTO to a configuration object and update the configuration file.
properties = create_st_storage_config(
study.version, **new_cluster.model_dump(by_alias=False, exclude_none=True)
StudyVersion.parse(study.version), **new_cluster.model_dump(by_alias=False, exclude_none=True)
)
path = _STORAGE_LIST_PATH.format(area_id=area_id, storage_id=storage_id)
cmd = UpdateConfig(
Expand Down Expand Up @@ -432,7 +433,7 @@ def get_storage(
config = file_study.tree.get(path.split("/"), depth=1)
except KeyError:
raise STStorageNotFound(path, storage_id) from None
return create_storage_output(int(study.version), storage_id, config)
return create_storage_output(StudyVersion.parse(study.version), storage_id, config)

def update_storage(
self,
Expand All @@ -452,7 +453,7 @@ def update_storage(
Returns:
Updated form of short-term storage.
"""
study_version = study.version
study_version = StudyVersion.parse(study.version)

# For variants, this method requires generating a snapshot, which takes time.
# But sadly, there's no other way to prevent creating wrong commands.
Expand Down Expand Up @@ -547,11 +548,12 @@ def duplicate_cluster(self, study: Study, area_id: str, source_id: str, new_clus
current_cluster.name = new_cluster_name
fields_to_exclude = {"id"}
# We should remove the field 'enabled' for studies before v8.8 as it didn't exist
if int(study.version) < 880:
study_version = StudyVersion.parse(study.version)
if study_version < STUDY_VERSION_880:
fields_to_exclude.add("enabled")
creation_form = STStorageCreation(**current_cluster.model_dump(by_alias=False, exclude=fields_to_exclude))

new_config = creation_form.to_config(study.version)
new_config = creation_form.to_config(study_version)
create_cluster_cmd = self._make_create_cluster_cmd(area_id, new_config)

# Matrix edition
Expand Down
Loading
Loading