From f08aac1a1ab5b6e442e75aa3977ae94526cdb5bf Mon Sep 17 00:00:00 2001 From: PIROT Killian Date: Fri, 13 Sep 2024 12:25:18 +0200 Subject: [PATCH] linter --- src/antares/api_conf/request_wrapper.py | 18 +- src/antares/exceptions/exceptions.py | 92 ++++++-- src/antares/model/area.py | 78 +++++-- src/antares/model/binding_constraint.py | 38 +++- src/antares/model/cluster.py | 4 +- src/antares/model/hydro.py | 44 +++- src/antares/model/link.py | 20 +- src/antares/model/renewable.py | 19 +- src/antares/model/settings/adequacy_patch.py | 4 +- src/antares/model/settings/optimization.py | 4 +- src/antares/model/st_storage.py | 48 +++-- src/antares/model/study.py | 58 +++-- src/antares/model/thermal.py | 70 ++++-- src/antares/service/api_services/area_api.py | 109 +++++++--- .../api_services/binding_constraint_api.py | 70 ++++-- src/antares/service/api_services/link_api.py | 18 +- .../service/api_services/renewable_api.py | 27 ++- .../service/api_services/st_storage_api.py | 28 ++- src/antares/service/api_services/study_api.py | 14 +- .../service/api_services/thermal_api.py | 29 ++- src/antares/service/api_services/utils.py | 4 +- src/antares/service/base_services.py | 104 ++++++--- .../service/local_services/area_local.py | 201 +++++++++++++----- .../binding_constraint_local.py | 27 ++- .../service/local_services/link_local.py | 43 ++-- .../service/local_services/renewable_local.py | 8 +- .../local_services/st_storage_local.py | 4 +- .../service/local_services/study_local.py | 19 +- .../service/local_services/thermal_local.py | 14 +- src/antares/service/service_factory.py | 67 ++++-- src/antares/tools/contents_tool.py | 4 +- src/antares/tools/ini_tool.py | 26 ++- src/antares/tools/time_series_tool.py | 24 ++- 33 files changed, 1003 insertions(+), 334 deletions(-) diff --git a/src/antares/api_conf/request_wrapper.py b/src/antares/api_conf/request_wrapper.py index d0904c5c..a28c6ee2 100644 --- a/src/antares/api_conf/request_wrapper.py +++ b/src/antares/api_conf/request_wrapper.py @@ -17,7 +17,9 @@ from antares.exceptions.exceptions import APIError -DATA_TYPE = Union[str, bytes, Mapping[str, Any], Iterable[Tuple[str, Optional[str]]], IO] +DATA_TYPE = Union[ + str, bytes, Mapping[str, Any], Iterable[Tuple[str, Optional[str]]], IO +] def _handle_exceptions(response: requests.Response) -> requests.Response: @@ -46,16 +48,24 @@ def get(self, url: str, **kwargs: Any) -> requests.Response: return _handle_exceptions(response) def post( - self, url: str, data: Optional[DATA_TYPE] = None, json: Optional[Any] = None, **kwargs: Any + self, + url: str, + data: Optional[DATA_TYPE] = None, + json: Optional[Any] = None, + **kwargs: Any ) -> requests.Response: response = self.session.post(url, data, json, **kwargs) return _handle_exceptions(response) - def put(self, url: str, data: Optional[DATA_TYPE] = None, **kwargs: Any) -> requests.Response: + def put( + self, url: str, data: Optional[DATA_TYPE] = None, **kwargs: Any + ) -> requests.Response: response = self.session.put(url, data, **kwargs) return _handle_exceptions(response) - def patch(self, url: str, data: Optional[DATA_TYPE] = None, **kwargs: Any) -> requests.Response: + def patch( + self, url: str, data: Optional[DATA_TYPE] = None, **kwargs: Any + ) -> requests.Response: response = self.session.patch(url, data, **kwargs) return _handle_exceptions(response) diff --git a/src/antares/exceptions/exceptions.py b/src/antares/exceptions/exceptions.py index 88b97cf0..35074538 100644 --- a/src/antares/exceptions/exceptions.py +++ b/src/antares/exceptions/exceptions.py @@ -80,14 +80,18 @@ def __init__(self, link_name: str, message: str) -> None: class ThermalCreationError(Exception): def __init__(self, thermal_name: str, area_id: str, message: str) -> None: - self.message = f"Could not create the thermal cluster {thermal_name} inside area {area_id}: " + message + self.message = ( + f"Could not create the thermal cluster {thermal_name} inside area {area_id}: " + + message + ) super().__init__(self.message) class ThermalPropertiesUpdateError(Exception): def __init__(self, thermal_name: str, area_id: str, message: str) -> None: self.message = ( - f"Could not update properties for thermal cluster {thermal_name} inside area {area_id}: " + message + f"Could not update properties for thermal cluster {thermal_name} inside area {area_id}: " + + message ) super().__init__(self.message) @@ -109,14 +113,18 @@ def __init__(self, area_id: str, message: str) -> None: class RenewableCreationError(Exception): def __init__(self, renewable_name: str, area_id: str, message: str) -> None: - self.message = f"Could not create the renewable cluster {renewable_name} inside area {area_id}: " + message + self.message = ( + f"Could not create the renewable cluster {renewable_name} inside area {area_id}: " + + message + ) super().__init__(self.message) class RenewablePropertiesUpdateError(Exception): def __init__(self, renewable_name: str, area_id: str, message: str) -> None: self.message = ( - f"Could not update properties for renewable cluster {renewable_name} inside area {area_id}: " + message + f"Could not update properties for renewable cluster {renewable_name} inside area {area_id}: " + + message ) super().__init__(self.message) @@ -132,30 +140,40 @@ def __init__(self, area_id: str, renewable_names: List[str], message: str) -> No class STStorageCreationError(Exception): def __init__(self, st_storage_name: str, area_id: str, message: str) -> None: - self.message = f"Could not create the short term storage {st_storage_name} inside area {area_id}: " + message + self.message = ( + f"Could not create the short term storage {st_storage_name} inside area {area_id}: " + + message + ) super().__init__(self.message) class STStoragePropertiesUpdateError(Exception): def __init__(self, st_storage_name: str, area_id: str, message: str) -> None: self.message = ( - f"Could not update properties for short term storage {st_storage_name} inside area {area_id}: " + message + f"Could not update properties for short term storage {st_storage_name} inside area {area_id}: " + + message ) super().__init__(self.message) class STStorageMatrixDownloadError(Exception): - def __init__(self, area_name: str, storage_name: str, matrix_name: str, message: str) -> None: + def __init__( + self, area_name: str, storage_name: str, matrix_name: str, message: str + ) -> None: self.message = ( - f"Could not download {matrix_name} matrix for storage {storage_name} inside area {area_name}: " + message + f"Could not download {matrix_name} matrix for storage {storage_name} inside area {area_name}: " + + message ) super().__init__(self.message) class STStorageMatrixUploadError(Exception): - def __init__(self, area_name: str, storage_name: str, matrix_name: str, message: str) -> None: + def __init__( + self, area_name: str, storage_name: str, matrix_name: str, message: str + ) -> None: self.message = ( - f"Could not upload {matrix_name} matrix for storage {storage_name} inside area {area_name}: " + message + f"Could not upload {matrix_name} matrix for storage {storage_name} inside area {area_name}: " + + message ) super().__init__(self.message) @@ -171,30 +189,43 @@ def __init__(self, area_id: str, st_storage_names: List[str], message: str) -> N class BindingConstraintCreationError(Exception): def __init__(self, constraint_name: str, message: str) -> None: - self.message = f"Could not create the binding constraint {constraint_name}: " + message + self.message = ( + f"Could not create the binding constraint {constraint_name}: " + message + ) super().__init__(self.message) class ConstraintPropertiesUpdateError(Exception): def __init__(self, constraint_name: str, message: str) -> None: - self.message = f"Could not update properties for binding constraint {constraint_name}: " + message + self.message = ( + f"Could not update properties for binding constraint {constraint_name}: " + + message + ) super().__init__(self.message) class ConstraintMatrixUpdateError(Exception): def __init__(self, constraint_name: str, matrix_name: str, message: str) -> None: - self.message = f"Could not update matrix {matrix_name} for binding constraint {constraint_name}: " + message + self.message = ( + f"Could not update matrix {matrix_name} for binding constraint {constraint_name}: " + + message + ) super().__init__(self.message) class ConstraintMatrixDownloadError(Exception): def __init__(self, constraint_name: str, matrix_name: str, message: str) -> None: - self.message = f"Could not download matrix {matrix_name} for binding constraint {constraint_name}: " + message + self.message = ( + f"Could not download matrix {matrix_name} for binding constraint {constraint_name}: " + + message + ) super().__init__(self.message) class ConstraintTermAdditionError(Exception): - def __init__(self, constraint_name: str, terms_ids: List[str], message: str) -> None: + def __init__( + self, constraint_name: str, terms_ids: List[str], message: str + ) -> None: self.message = ( f"Could not add the following constraint terms: {', '.join(terms_ids)} inside constraint {constraint_name}: " + message @@ -204,13 +235,18 @@ def __init__(self, constraint_name: str, terms_ids: List[str], message: str) -> class BindingConstraintDeletionError(Exception): def __init__(self, constraint_name: str, message: str) -> None: - self.message = f"Could not delete the binding constraint {constraint_name}: " + message + self.message = ( + f"Could not delete the binding constraint {constraint_name}: " + message + ) super().__init__(self.message) class ConstraintTermDeletionError(Exception): def __init__(self, constraint_id: str, term_id: str, message: str) -> None: - self.message = f"Could not delete the term {term_id} of the binding constraint {constraint_id}: " + message + self.message = ( + f"Could not delete the term {term_id} of the binding constraint {constraint_id}: " + + message + ) super().__init__(self.message) @@ -240,21 +276,29 @@ def __init__(self, area_name: str, message: str) -> None: class LoadMatrixDownloadError(Exception): def __init__(self, area_name: str, message: str) -> None: - self.message = f"Could not download load matrix for area {area_name}: " + message + self.message = ( + f"Could not download load matrix for area {area_name}: " + message + ) super().__init__(self.message) class ThermalMatrixDownloadError(Exception): - def __init__(self, area_name: str, cluster_name: str, matrix_name: str, message: str) -> None: + def __init__( + self, area_name: str, cluster_name: str, matrix_name: str, message: str + ) -> None: self.message = ( - f"Could not download {matrix_name} for cluster {cluster_name} inside area {area_name}: " + message + f"Could not download {matrix_name} for cluster {cluster_name} inside area {area_name}: " + + message ) super().__init__(self.message) class RenewableMatrixDownloadError(Exception): def __init__(self, area_name: str, renewable_name: str, message: str) -> None: - self.message = f"Could not download matrix for cluster {renewable_name} inside area {area_name}: " + message + self.message = ( + f"Could not download matrix for cluster {renewable_name} inside area {area_name}: " + + message + ) super().__init__(self.message) @@ -272,5 +316,9 @@ def __init__(self, message: str = "Error") -> None: class ConfigurationError(Exception): def __init__(self, message: str = "Error") -> None: - self.message = "Unsupported configuration type" + f" {message}" if message != "Error" else "" + self.message = ( + "Unsupported configuration type" + f" {message}" + if message != "Error" + else "" + ) super().__init__(self.message) diff --git a/src/antares/model/area.py b/src/antares/model/area.py index f56905d6..cb1ce58e 100644 --- a/src/antares/model/area.py +++ b/src/antares/model/area.py @@ -48,7 +48,9 @@ class AdequacyPatchMode(EnumIgnoreCase): # todo: Warning, with filesystem, we want to avoid camel case and use link_aliasing. -class AreaProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): +class AreaProperties( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel +): """ DTO for updating area properties """ @@ -78,10 +80,14 @@ def __init__( **kwargs: Optional[Any], ): super().__init__(**kwargs) - self._energy_cost_unsupplied = input_area_properties.energy_cost_unsupplied or 0.0 + self._energy_cost_unsupplied = ( + input_area_properties.energy_cost_unsupplied or 0.0 + ) self._energy_cost_spilled = input_area_properties.energy_cost_spilled or 0.0 self._non_dispatch_power = ( - input_area_properties.non_dispatch_power if input_area_properties.non_dispatch_power is not None else True + input_area_properties.non_dispatch_power + if input_area_properties.non_dispatch_power is not None + else True ) self._dispatch_hydro_power = ( input_area_properties.dispatch_hydro_power @@ -112,8 +118,12 @@ def __init__( if input_area_properties.adequacy_patch_mode else AdequacyPatchMode.OUTSIDE ) - self._spread_spilled_energy_cost = input_area_properties.spread_spilled_energy_cost or 0.0 - self._spread_unsupplied_energy_cost = input_area_properties.spread_unsupplied_energy_cost or 0.0 + self._spread_spilled_energy_cost = ( + input_area_properties.spread_spilled_energy_cost or 0.0 + ) + self._spread_unsupplied_energy_cost = ( + input_area_properties.spread_unsupplied_energy_cost or 0.0 + ) @computed_field # type: ignore[misc] @property @@ -132,12 +142,20 @@ def nodal_optimization(self) -> Mapping[str, str]: @property def filtering(self) -> Mapping[str, str]: return { - "filter-synthesis": ", ".join(filter_value for filter_value in sort_filter_values(self._filter_synthesis)), - "filter-year-by-year": ", ".join(filter_value for filter_value in sort_filter_values(self._filter_by_year)), + "filter-synthesis": ", ".join( + filter_value + for filter_value in sort_filter_values(self._filter_synthesis) + ), + "filter-year-by-year": ", ".join( + filter_value + for filter_value in sort_filter_values(self._filter_by_year) + ), } def adequacy_patch_mode(self) -> dict[str, dict[str, str]]: - return {"adequacy-patch": {"adequacy-patch-mode": self._adequacy_patch_mode.value}} + return { + "adequacy-patch": {"adequacy-patch-mode": self._adequacy_patch_mode.value} + } def yield_area_properties(self) -> AreaProperties: return AreaProperties( @@ -154,7 +172,9 @@ def yield_area_properties(self) -> AreaProperties: ) -class AreaUi(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): +class AreaUi( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel +): """ DTO for updating area UI """ @@ -184,7 +204,11 @@ def __init__( super().__init__(**kwargs) self._x = input_area_ui.x or 0 self._y = input_area_ui.y or 0 - self._color_r, self._color_g, self._color_b = input_area_ui.color_rgb or [230, 108, 44] + self._color_r, self._color_g, self._color_b = input_area_ui.color_rgb or [ + 230, + 108, + 44, + ] self._layers = input_area_ui.layer or 0 self._layer_x = input_area_ui.layer_x or {self._layers: self._x} self._layer_y = input_area_ui.layer_y or {self._layers: self._y} @@ -300,7 +324,9 @@ def ui(self) -> AreaUi: def create_thermal_cluster( self, thermal_name: str, properties: Optional[ThermalClusterProperties] = None ) -> ThermalCluster: - thermal = self._area_service.create_thermal_cluster(self.id, thermal_name, properties) + thermal = self._area_service.create_thermal_cluster( + self.id, thermal_name, properties + ) self._thermals[thermal.id] = thermal return thermal @@ -315,20 +341,36 @@ def create_thermal_cluster_with_matrices( fuelCost: Optional[pd.DataFrame], ) -> ThermalCluster: thermal = self._area_service.create_thermal_cluster_with_matrices( - self.id, cluster_name, parameters, prepro, modulation, series, CO2Cost, fuelCost + self.id, + cluster_name, + parameters, + prepro, + modulation, + series, + CO2Cost, + fuelCost, ) self._thermals[thermal.id] = thermal return thermal def create_renewable_cluster( - self, renewable_name: str, properties: Optional[RenewableClusterProperties], series: Optional[pd.DataFrame] + self, + renewable_name: str, + properties: Optional[RenewableClusterProperties], + series: Optional[pd.DataFrame], ) -> RenewableCluster: - renewable = self._area_service.create_renewable_cluster(self.id, renewable_name, properties, series) + renewable = self._area_service.create_renewable_cluster( + self.id, renewable_name, properties, series + ) self._renewables[renewable.id] = renewable return renewable - def create_st_storage(self, st_storage_name: str, properties: Optional[STStorageProperties] = None) -> STStorage: - storage = self._area_service.create_st_storage(self.id, st_storage_name, properties) + def create_st_storage( + self, st_storage_name: str, properties: Optional[STStorageProperties] = None + ) -> STStorage: + storage = self._area_service.create_st_storage( + self.id, st_storage_name, properties + ) self._st_storages[storage.id] = storage return storage @@ -347,7 +389,9 @@ def delete_thermal_clusters(self, thermal_clusters: List[ThermalCluster]) -> Non def delete_thermal_cluster(self, thermal_cluster: ThermalCluster) -> None: self.delete_thermal_clusters([thermal_cluster]) - def delete_renewable_clusters(self, renewable_clusters: List[RenewableCluster]) -> None: + def delete_renewable_clusters( + self, renewable_clusters: List[RenewableCluster] + ) -> None: self._area_service.delete_renewable_clusters(self, renewable_clusters) for cluster in renewable_clusters: self._renewables.pop(cluster.id) diff --git a/src/antares/model/binding_constraint.py b/src/antares/model/binding_constraint.py index ee7f0468..8a35c097 100644 --- a/src/antares/model/binding_constraint.py +++ b/src/antares/model/binding_constraint.py @@ -84,7 +84,9 @@ def generate_id(cls, data: Union[Dict[str, str], LinkData, ClusterData]) -> str: return ".".join((data.area.lower(), data.cluster.lower())) -class BindingConstraintProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): +class BindingConstraintProperties( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel +): enabled: Optional[bool] = None time_step: Optional[BindingConstraintFrequency] = None operator: Optional[BindingConstraintOperator] = None @@ -129,27 +131,45 @@ def add_terms(self, terms: List[ConstraintTerm]) -> None: self._terms[term.id] = term def delete_term(self, term: ConstraintTerm) -> None: - self._binding_constraint_service.delete_binding_constraint_term(self.id, term.id) + self._binding_constraint_service.delete_binding_constraint_term( + self.id, term.id + ) self._terms.pop(term.id) def update_properties(self, properties: BindingConstraintProperties) -> None: - new_properties = self._binding_constraint_service.update_binding_constraint_properties(self, properties) + new_properties = ( + self._binding_constraint_service.update_binding_constraint_properties( + self, properties + ) + ) self._properties = new_properties def get_less_term_matrix(self) -> pd.DataFrame: - return self._binding_constraint_service.get_constraint_matrix(self, ConstraintMatrixName.LESS_TERM) + return self._binding_constraint_service.get_constraint_matrix( + self, ConstraintMatrixName.LESS_TERM + ) def get_equal_term_matrix(self) -> pd.DataFrame: - return self._binding_constraint_service.get_constraint_matrix(self, ConstraintMatrixName.EQUAL_TERM) + return self._binding_constraint_service.get_constraint_matrix( + self, ConstraintMatrixName.EQUAL_TERM + ) def get_greater_term_matrix(self) -> pd.DataFrame: - return self._binding_constraint_service.get_constraint_matrix(self, ConstraintMatrixName.GREATER_TERM) + return self._binding_constraint_service.get_constraint_matrix( + self, ConstraintMatrixName.GREATER_TERM + ) def update_less_term_matrix(self, matrix: pd.DataFrame) -> None: - self._binding_constraint_service.update_constraint_matrix(self, ConstraintMatrixName.LESS_TERM, matrix) + self._binding_constraint_service.update_constraint_matrix( + self, ConstraintMatrixName.LESS_TERM, matrix + ) def update_equal_term_matrix(self, matrix: pd.DataFrame) -> None: - self._binding_constraint_service.update_constraint_matrix(self, ConstraintMatrixName.EQUAL_TERM, matrix) + self._binding_constraint_service.update_constraint_matrix( + self, ConstraintMatrixName.EQUAL_TERM, matrix + ) def update_greater_term_matrix(self, matrix: pd.DataFrame) -> None: - self._binding_constraint_service.update_constraint_matrix(self, ConstraintMatrixName.GREATER_TERM, matrix) + self._binding_constraint_service.update_constraint_matrix( + self, ConstraintMatrixName.GREATER_TERM, matrix + ) diff --git a/src/antares/model/cluster.py b/src/antares/model/cluster.py index 8b54b5ed..8f6e1c6c 100644 --- a/src/antares/model/cluster.py +++ b/src/antares/model/cluster.py @@ -16,7 +16,9 @@ from pydantic.alias_generators import to_camel -class ClusterProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): +class ClusterProperties( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel +): """ Common properties for thermal and renewable clusters """ diff --git a/src/antares/model/hydro.py b/src/antares/model/hydro.py index ac4efed1..eed2e3fe 100644 --- a/src/antares/model/hydro.py +++ b/src/antares/model/hydro.py @@ -32,7 +32,9 @@ class HydroMatrixName(Enum): COMMON_CREDIT_MODULATIONS = "creditmodulations" -class HydroProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): +class HydroProperties( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel +): """ Properties of hydro system read from the configuration files. @@ -66,15 +68,23 @@ def __init__( super().__init__(**kwargs) self._area_id = area_id hydro_properties = hydro_properties or HydroProperties() - self._inter_daily_breakdown = check_if_none(hydro_properties.inter_daily_breakdown, 1) - self._intra_daily_modulation = check_if_none(hydro_properties.intra_daily_modulation, 24) - self._inter_monthly_breakdown = check_if_none(hydro_properties.inter_monthly_breakdown, 1) + self._inter_daily_breakdown = check_if_none( + hydro_properties.inter_daily_breakdown, 1 + ) + self._intra_daily_modulation = check_if_none( + hydro_properties.intra_daily_modulation, 24 + ) + self._inter_monthly_breakdown = check_if_none( + hydro_properties.inter_monthly_breakdown, 1 + ) self._reservoir = check_if_none(hydro_properties.reservoir, False) self._reservoir_capacity = check_if_none(hydro_properties.reservoir_capacity, 0) self._follow_load = check_if_none(hydro_properties.follow_load, True) self._use_water = check_if_none(hydro_properties.use_water, False) self._hard_bounds = check_if_none(hydro_properties.hard_bounds, False) - self._initialize_reservoir_date = check_if_none(hydro_properties.initialize_reservoir_date, 0) + self._initialize_reservoir_date = check_if_none( + hydro_properties.initialize_reservoir_date, 0 + ) self._use_heuristic = check_if_none(hydro_properties.use_heuristic, True) self._power_to_level = check_if_none(hydro_properties.power_to_level, False) self._use_leeway = check_if_none(hydro_properties.use_leeway, False) @@ -86,21 +96,33 @@ def __init__( @property def hydro_ini_fields(self) -> dict[str, dict[str, str]]: return { - "inter-daily-breakdown": {f"{self._area_id}": f"{self._inter_daily_breakdown:.6f}"}, - "intra-daily-modulation": {f"{self._area_id}": f"{self._intra_daily_modulation:.6f}"}, - "inter-monthly-breakdown": {f"{self._area_id}": f"{self._inter_monthly_breakdown:.6f}"}, + "inter-daily-breakdown": { + f"{self._area_id}": f"{self._inter_daily_breakdown:.6f}" + }, + "intra-daily-modulation": { + f"{self._area_id}": f"{self._intra_daily_modulation:.6f}" + }, + "inter-monthly-breakdown": { + f"{self._area_id}": f"{self._inter_monthly_breakdown:.6f}" + }, "reservoir": {f"{self._area_id}": f"{self._reservoir}".lower()}, - "reservoir capacity": {f"{self._area_id}": f"{self._reservoir_capacity:.6f}"}, + "reservoir capacity": { + f"{self._area_id}": f"{self._reservoir_capacity:.6f}" + }, "follow load": {f"{self._area_id}": f"{self._follow_load}".lower()}, "use water": {f"{self._area_id}": f"{self._use_water}".lower()}, "hard bounds": {f"{self._area_id}": f"{self._hard_bounds}".lower()}, - "initialize reservoir date": {f"{self._area_id}": f"{self._initialize_reservoir_date}"}, + "initialize reservoir date": { + f"{self._area_id}": f"{self._initialize_reservoir_date}" + }, "use heuristic": {f"{self._area_id}": f"{self._use_heuristic}".lower()}, "power to level": {f"{self._area_id}": f"{self._power_to_level}".lower()}, "use leeway": {f"{self._area_id}": f"{self._use_leeway}".lower()}, "leeway low": {f"{self._area_id}": f"{self._leeway_low:.6f}"}, "leeway up": {f"{self._area_id}": f"{self._leeway_up:.6f}"}, - "pumping efficiency": {f"{self._area_id}": f"{self._pumping_efficiency:.6f}"}, + "pumping efficiency": { + f"{self._area_id}": f"{self._pumping_efficiency:.6f}" + }, } def yield_hydro_properties(self) -> HydroProperties: diff --git a/src/antares/model/link.py b/src/antares/model/link.py index 1a59d672..c793061e 100644 --- a/src/antares/model/link.py +++ b/src/antares/model/link.py @@ -44,7 +44,9 @@ def link_aliasing(string: str) -> str: return string.replace("_", "-") -class LinkProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=link_aliasing): +class LinkProperties( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=link_aliasing +): """ DTO for updating link properties """ @@ -75,7 +77,9 @@ def __init__( if link_properties.transmission_capacities else TransmissionCapacities.ENABLED ) - self._asset_type = link_properties.asset_type if link_properties.asset_type else AssetType.AC + self._asset_type = ( + link_properties.asset_type if link_properties.asset_type else AssetType.AC + ) self._display_comments = link_properties.display_comments or True self._filter_synthesis = link_properties.filter_synthesis or { FilterOption.HOURLY, @@ -102,9 +106,13 @@ def ini_fields(self) -> Mapping[str, str]: "transmission-capacities": f"{self._transmission_capacities.value}", "asset-type": f"{self._asset_type.value}", "display-comments": f"{self._display_comments}".lower(), - "filter-synthesis": ", ".join(filter_value for filter_value in sort_filter_values(self._filter_synthesis)), + "filter-synthesis": ", ".join( + filter_value + for filter_value in sort_filter_values(self._filter_synthesis) + ), "filter-year-by-year": ", ".join( - filter_value for filter_value in sort_filter_values(self._filter_year_by_year) + filter_value + for filter_value in sort_filter_values(self._filter_year_by_year) ), } @@ -121,7 +129,9 @@ def yield_link_properties(self) -> LinkProperties: ) -class LinkUi(BaseModel, extra="forbid", populate_by_name=True, alias_generator=link_aliasing): +class LinkUi( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=link_aliasing +): """ DTO for updating link UI """ diff --git a/src/antares/model/renewable.py b/src/antares/model/renewable.py index c98ef8b1..2d36eae5 100644 --- a/src/antares/model/renewable.py +++ b/src/antares/model/renewable.py @@ -74,13 +74,19 @@ def __init__( **kwargs: Optional[Any], ): super().__init__(**kwargs) - renewable_cluster_properties = renewable_cluster_properties or RenewableClusterProperties() + renewable_cluster_properties = ( + renewable_cluster_properties or RenewableClusterProperties() + ) self._renewable_name = renewable_name self._enabled = ( - renewable_cluster_properties.enabled if renewable_cluster_properties.enabled is not None else True + renewable_cluster_properties.enabled + if renewable_cluster_properties.enabled is not None + else True ) self._unit_count = ( - renewable_cluster_properties.unit_count if renewable_cluster_properties.unit_count is not None else 1 + renewable_cluster_properties.unit_count + if renewable_cluster_properties.unit_count is not None + else 1 ) self._nominal_capacity = ( renewable_cluster_properties.nominal_capacity @@ -89,7 +95,8 @@ def __init__( ) self._group = renewable_cluster_properties.group or RenewableClusterGroup.OTHER1 self._ts_interpretation = ( - renewable_cluster_properties.ts_interpretation or TimeSeriesInterpretation.POWER_GENERATION + renewable_cluster_properties.ts_interpretation + or TimeSeriesInterpretation.POWER_GENERATION ) @property @@ -153,7 +160,9 @@ def properties(self) -> RenewableClusterProperties: return self._properties def update_properties(self, properties: RenewableClusterProperties) -> None: - new_properties = self._renewable_service.update_renewable_properties(self, properties) + new_properties = self._renewable_service.update_renewable_properties( + self, properties + ) self._properties = new_properties def get_renewable_matrix(self) -> pd.DataFrame: diff --git a/src/antares/model/settings/adequacy_patch.py b/src/antares/model/settings/adequacy_patch.py index b0c843a9..1c6050f2 100644 --- a/src/antares/model/settings/adequacy_patch.py +++ b/src/antares/model/settings/adequacy_patch.py @@ -25,7 +25,9 @@ class PriceTakingOrder(Enum): class AdequacyPatchProperties(BaseModel, alias_generator=to_camel): # version 830 enable_adequacy_patch: Optional[bool] = None - ntc_from_physical_areas_out_to_physical_areas_in_adequacy_patch: Optional[bool] = None + ntc_from_physical_areas_out_to_physical_areas_in_adequacy_patch: Optional[bool] = ( + None + ) ntc_between_physical_areas_out_adequacy_patch: Optional[bool] = None # version 850 price_taking_order: Optional[PriceTakingOrder] = None diff --git a/src/antares/model/settings/optimization.py b/src/antares/model/settings/optimization.py index bc895b05..712a4500 100644 --- a/src/antares/model/settings/optimization.py +++ b/src/antares/model/settings/optimization.py @@ -44,7 +44,9 @@ class SimplexOptimizationRange(Enum): class OptimizationProperties(BaseModel, alias_generator=to_camel): binding_constraints: Optional[bool] = None hurdle_costs: Optional[bool] = None - transmission_capacities: Union[bool, Union[LegacyTransmissionCapacities, TransmissionCapacities], None] = None + transmission_capacities: Union[ + bool, Union[LegacyTransmissionCapacities, TransmissionCapacities], None + ] = None thermal_clusters_min_stable_power: Optional[bool] = None thermal_clusters_min_ud_time: Optional[bool] = None day_ahead_reserve: Optional[bool] = None diff --git a/src/antares/model/st_storage.py b/src/antares/model/st_storage.py index 963e99d8..bbf50557 100644 --- a/src/antares/model/st_storage.py +++ b/src/antares/model/st_storage.py @@ -42,7 +42,9 @@ class STStorageMatrixName(Enum): INFLOWS = "inflows" -class STStorageProperties(BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel): +class STStorageProperties( + BaseModel, extra="forbid", populate_by_name=True, alias_generator=to_camel +): """ Properties of a short-term storage system read from the configuration files. @@ -71,12 +73,20 @@ def __init__( st_storage_properties = st_storage_properties or STStorageProperties() self._st_storage_name = st_storage_name self._group = check_if_none(st_storage_properties.group, STStorageGroup.OTHER1) - self._injection_nominal_capacity = check_if_none(st_storage_properties.injection_nominal_capacity, 0) - self._withdrawal_nominal_capacity = check_if_none(st_storage_properties.withdrawal_nominal_capacity, 0) - self._reservoir_capacity = check_if_none(st_storage_properties.reservoir_capacity, 0) + self._injection_nominal_capacity = check_if_none( + st_storage_properties.injection_nominal_capacity, 0 + ) + self._withdrawal_nominal_capacity = check_if_none( + st_storage_properties.withdrawal_nominal_capacity, 0 + ) + self._reservoir_capacity = check_if_none( + st_storage_properties.reservoir_capacity, 0 + ) self._efficiency = check_if_none(st_storage_properties.efficiency, 1) self._initial_level = check_if_none(st_storage_properties.initial_level, 0.5) - self._initial_level_optim = check_if_none(st_storage_properties.initial_level_optim, False) + self._initial_level_optim = check_if_none( + st_storage_properties.initial_level_optim, False + ) self._enabled = check_if_none(st_storage_properties.enabled, True) @property @@ -140,23 +150,35 @@ def properties(self) -> STStorageProperties: return self._properties def update_properties(self, properties: STStorageProperties) -> None: - new_properties = self._storage_service.update_st_storage_properties(self, properties) + new_properties = self._storage_service.update_st_storage_properties( + self, properties + ) self._properties = new_properties def get_pmax_injection(self) -> pd.DataFrame: - return self._storage_service.get_storage_matrix(self, STStorageMatrixName.PMAX_INJECTION) + return self._storage_service.get_storage_matrix( + self, STStorageMatrixName.PMAX_INJECTION + ) def get_pmax_withdrawal(self) -> pd.DataFrame: - return self._storage_service.get_storage_matrix(self, STStorageMatrixName.PMAX_WITHDRAWAL) + return self._storage_service.get_storage_matrix( + self, STStorageMatrixName.PMAX_WITHDRAWAL + ) def get_lower_rule_curve(self) -> pd.DataFrame: - return self._storage_service.get_storage_matrix(self, STStorageMatrixName.LOWER_CURVE_RULE) + return self._storage_service.get_storage_matrix( + self, STStorageMatrixName.LOWER_CURVE_RULE + ) def get_upper_rule_curve(self) -> pd.DataFrame: - return self._storage_service.get_storage_matrix(self, STStorageMatrixName.UPPER_RULE_CURVE) + return self._storage_service.get_storage_matrix( + self, STStorageMatrixName.UPPER_RULE_CURVE + ) def get_storage_inflows(self) -> pd.DataFrame: - return self._storage_service.get_storage_matrix(self, STStorageMatrixName.INFLOWS) + return self._storage_service.get_storage_matrix( + self, STStorageMatrixName.INFLOWS + ) def upload_pmax_injection(self, p_max_injection_matrix: pd.DataFrame) -> None: return self._storage_service.upload_storage_matrix( @@ -179,4 +201,6 @@ def upload_upper_rule_curve(self, upper_rule_curve_matrix: pd.DataFrame) -> None ) def upload_storage_inflows(self, inflows_matrix: pd.DataFrame) -> None: - return self._storage_service.upload_storage_matrix(self, STStorageMatrixName.INFLOWS, inflows_matrix) + return self._storage_service.upload_storage_matrix( + self, STStorageMatrixName.INFLOWS, inflows_matrix + ) diff --git a/src/antares/model/study.py b/src/antares/model/study.py index edf91d19..a709d494 100644 --- a/src/antares/model/study.py +++ b/src/antares/model/study.py @@ -24,7 +24,11 @@ from antares.config.local_configuration import LocalConfiguration from antares.exceptions.exceptions import APIError, StudyCreationError from antares.model.area import Area, AreaProperties, AreaUi -from antares.model.binding_constraint import BindingConstraint, BindingConstraintProperties, ConstraintTerm +from antares.model.binding_constraint import ( + BindingConstraint, + BindingConstraintProperties, + ConstraintTerm, +) from antares.model.link import Link, LinkUi, LinkProperties from antares.model.settings import StudySettings from antares.service.api_services.study_api import _returns_study_settings @@ -41,7 +45,10 @@ def create_study_api( - study_name: str, version: str, api_config: APIconf, settings: Optional[StudySettings] = None + study_name: str, + version: str, + api_config: APIconf, + settings: Optional[StudySettings] = None, ) -> "Study": """ Args: @@ -65,11 +72,15 @@ def create_study_api( response = wrapper.post(url) study_id = response.json() - study_settings = _returns_study_settings(base_url, study_id, wrapper, False, settings) + study_settings = _returns_study_settings( + base_url, study_id, wrapper, False, settings + ) except APIError as e: raise StudyCreationError(study_name, e.message) from e - return Study(study_name, version, ServiceFactory(api_config, study_id), study_settings) + return Study( + study_name, version, ServiceFactory(api_config, study_id), study_settings + ) def _verify_study_already_exists(study_directory: Path) -> None: @@ -86,8 +97,12 @@ def _directories_can_be_read(local_path: Path) -> None: except PermissionError: raise PermissionError(f"Some content cannot be accessed in {local_path}") + def create_study_local( - study_name: str, version: str, local_config: LocalConfiguration, settings: Optional[StudySettings] = None + study_name: str, + version: str, + local_config: LocalConfiguration, + settings: Optional[StudySettings] = None, ) -> "Study": """ Create a directory structure for the study with empty files. @@ -156,7 +171,8 @@ def _directory_not_exists(local_path: Path) -> None: def read_study_local( - study_name: str, version: str, local_config: LocalConfiguration) -> "Study": + study_name: str, version: str, local_config: LocalConfiguration +) -> "Study": """ Create a directory structure for the study with empty files. Args: @@ -169,6 +185,7 @@ def read_study_local( ValueError if the provided directory does not exist """ + def _directory_not_exists(local_path: Path) -> None: if local_path is None or not os.path.exists(local_path): raise ValueError(f"Provided directory {local_path} does not exist.") @@ -187,7 +204,12 @@ def _directory_not_exists(local_path: Path) -> None: class Study: def __init__( - self, name: str, version: str, service_factory, settings: Optional[StudySettings] = None, mode: str = "create" + self, + name: str, + version: str, + service_factory, + settings: Optional[StudySettings] = None, + mode: str = "create", ): self.name = name self.version = version @@ -195,7 +217,9 @@ def __init__( self._study_service = service_factory.create_study_service() self._area_service = service_factory.create_area_service() self._link_service = service_factory.create_link_service() - self._binding_constraints_service = service_factory.create_binding_constraints_service() + self._binding_constraints_service = ( + service_factory.create_binding_constraints_service() + ) self._settings = settings or StudySettings() self._areas: Dict[str, Area] = dict() self._links: Dict[str, Link] = dict() @@ -207,7 +231,6 @@ def __init__( self._areas: Dict[str, Area] = dict() self._links: Dict[str, Link] = dict() - @property def service(self) -> BaseStudyService: return self._study_service @@ -225,7 +248,11 @@ def get_binding_constraints(self) -> MappingProxyType[str, BindingConstraint]: return MappingProxyType(self._binding_constraints) def create_area( - self, area_name: str, *, properties: Optional[AreaProperties] = None, ui: Optional[AreaUi] = None + self, + area_name: str, + *, + properties: Optional[AreaProperties] = None, + ui: Optional[AreaUi] = None, ) -> Area: area = self._area_service.create_area(area_name, properties, ui) self._areas[area.id] = area @@ -244,7 +271,9 @@ def create_link( ui: Optional[LinkUi] = None, existing_areas: Optional[MappingProxyType[str, Area]] = None, ) -> Link: - link = self._link_service.create_link(area_from, area_to, properties, ui, existing_areas) + link = self._link_service.create_link( + area_from, area_to, properties, ui, existing_areas + ) self._links[link.name] = link return link @@ -263,7 +292,12 @@ def create_binding_constraint( greater_term_matrix: Optional[pd.DataFrame] = None, ) -> BindingConstraint: constraint = self._binding_constraints_service.create_binding_constraint( - name, properties, terms, less_term_matrix, equal_term_matrix, greater_term_matrix + name, + properties, + terms, + less_term_matrix, + equal_term_matrix, + greater_term_matrix, ) self._binding_constraints[constraint.id] = constraint return constraint diff --git a/src/antares/model/thermal.py b/src/antares/model/thermal.py index eab6ea47..6f08c4e0 100644 --- a/src/antares/model/thermal.py +++ b/src/antares/model/thermal.py @@ -115,30 +115,49 @@ def __init__( **kwargs: Optional[Any], ): super().__init__(**kwargs) - thermal_cluster_properties = thermal_cluster_properties or ThermalClusterProperties() + thermal_cluster_properties = ( + thermal_cluster_properties or ThermalClusterProperties() + ) self._thermal_name = thermal_name self._enabled = check_if_none(thermal_cluster_properties.enabled, True) self._unit_count = check_if_none(thermal_cluster_properties.unit_count, 1) - self._nominal_capacity = check_if_none(thermal_cluster_properties.nominal_capacity, 0) + self._nominal_capacity = check_if_none( + thermal_cluster_properties.nominal_capacity, 0 + ) self._group = ( # The value OTHER1 matches AntaresWeb if a cluster is created via API without providing a group - thermal_cluster_properties.group or ThermalClusterGroup.OTHER1 + thermal_cluster_properties.group + or ThermalClusterGroup.OTHER1 + ) + self._gen_ts = check_if_none( + thermal_cluster_properties.gen_ts, LocalTSGenerationBehavior.USE_GLOBAL + ) + self._min_stable_power = check_if_none( + thermal_cluster_properties.min_stable_power, 0 ) - self._gen_ts = check_if_none(thermal_cluster_properties.gen_ts, LocalTSGenerationBehavior.USE_GLOBAL) - self._min_stable_power = check_if_none(thermal_cluster_properties.min_stable_power, 0) self._min_up_time = check_if_none(thermal_cluster_properties.min_up_time, 1) self._min_down_time = check_if_none(thermal_cluster_properties.min_down_time, 1) self._must_run = check_if_none(thermal_cluster_properties.must_run, False) self._spinning = check_if_none(thermal_cluster_properties.spinning, 0) - self._volatility_forced = check_if_none(thermal_cluster_properties.volatility_forced, 0) - self._volatility_planned = check_if_none(thermal_cluster_properties.volatility_planned, 0) - self._law_forced = check_if_none(thermal_cluster_properties.law_forced, LawOption.UNIFORM) - self._law_planned = check_if_none(thermal_cluster_properties.law_planned, LawOption.UNIFORM) + self._volatility_forced = check_if_none( + thermal_cluster_properties.volatility_forced, 0 + ) + self._volatility_planned = check_if_none( + thermal_cluster_properties.volatility_planned, 0 + ) + self._law_forced = check_if_none( + thermal_cluster_properties.law_forced, LawOption.UNIFORM + ) + self._law_planned = check_if_none( + thermal_cluster_properties.law_planned, LawOption.UNIFORM + ) self._marginal_cost = check_if_none(thermal_cluster_properties.marginal_cost, 0) self._spread_cost = check_if_none(thermal_cluster_properties.spread_cost, 0) self._fixed_cost = check_if_none(thermal_cluster_properties.fixed_cost, 0) self._startup_cost = check_if_none(thermal_cluster_properties.startup_cost, 0) - self._market_bid_cost = check_if_none(thermal_cluster_properties.market_bid_cost, 0) + self._market_bid_cost = check_if_none( + thermal_cluster_properties.market_bid_cost, 0 + ) self._co2 = check_if_none(thermal_cluster_properties.co2, 0) self._nh3 = check_if_none(thermal_cluster_properties.nh3, 0) self._so2 = check_if_none(thermal_cluster_properties.so2, 0) @@ -153,10 +172,13 @@ def __init__( self._op4 = check_if_none(thermal_cluster_properties.op4, 0) self._op5 = check_if_none(thermal_cluster_properties.op5, 0) self._cost_generation = check_if_none( - thermal_cluster_properties.cost_generation, ThermalCostGeneration.SET_MANUALLY + thermal_cluster_properties.cost_generation, + ThermalCostGeneration.SET_MANUALLY, ) self._efficiency = check_if_none(thermal_cluster_properties.efficiency, 100) - self._variable_o_m_cost = check_if_none(thermal_cluster_properties.variable_o_m_cost, 0) + self._variable_o_m_cost = check_if_none( + thermal_cluster_properties.variable_o_m_cost, 0 + ) @computed_field # type: ignore[misc] @property @@ -277,20 +299,32 @@ def properties(self) -> ThermalClusterProperties: return self._properties def update_properties(self, properties: ThermalClusterProperties) -> None: - new_properties = self._thermal_service.update_thermal_properties(self, properties) + new_properties = self._thermal_service.update_thermal_properties( + self, properties + ) self._properties = new_properties def get_prepro_data_matrix(self) -> pd.DataFrame: - return self._thermal_service.get_thermal_matrix(self, ThermalClusterMatrixName.PREPRO_DATA) + return self._thermal_service.get_thermal_matrix( + self, ThermalClusterMatrixName.PREPRO_DATA + ) def get_prepro_modulation_matrix(self) -> pd.DataFrame: - return self._thermal_service.get_thermal_matrix(self, ThermalClusterMatrixName.PREPRO_MODULATION) + return self._thermal_service.get_thermal_matrix( + self, ThermalClusterMatrixName.PREPRO_MODULATION + ) def get_series_matrix(self) -> pd.DataFrame: - return self._thermal_service.get_thermal_matrix(self, ThermalClusterMatrixName.SERIES) + return self._thermal_service.get_thermal_matrix( + self, ThermalClusterMatrixName.SERIES + ) def get_co2_cost_matrix(self) -> pd.DataFrame: - return self._thermal_service.get_thermal_matrix(self, ThermalClusterMatrixName.SERIES_CO2_COST) + return self._thermal_service.get_thermal_matrix( + self, ThermalClusterMatrixName.SERIES_CO2_COST + ) def get_fuel_cost_matrix(self) -> pd.DataFrame: - return self._thermal_service.get_thermal_matrix(self, ThermalClusterMatrixName.SERIES_FUEL_COST) + return self._thermal_service.get_thermal_matrix( + self, ThermalClusterMatrixName.SERIES_FUEL_COST + ) diff --git a/src/antares/service/api_services/area_api.py b/src/antares/service/api_services/area_api.py index 5a846ca0..6d75e3ff 100644 --- a/src/antares/service/api_services/area_api.py +++ b/src/antares/service/api_services/area_api.py @@ -75,7 +75,10 @@ def set_renewable_service(self, renewable_service: BaseRenewableService) -> None self.renewable_service = renewable_service def create_area( - self, area_name: str, properties: Optional[AreaProperties] = None, ui: Optional[AreaUi] = None + self, + area_name: str, + properties: Optional[AreaProperties] = None, + ui: Optional[AreaUi] = None, ) -> Area: """ Args: @@ -94,7 +97,9 @@ def create_area( base_area_url = f"{self._base_url}/studies/{self.study_id}/areas" try: - response = self._wrapper.post(base_area_url, json={"name": area_name, "type": "AREA"}) + response = self._wrapper.post( + base_area_url, json={"name": area_name, "type": "AREA"} + ) area_id = response.json()["id"] if properties: @@ -145,7 +150,10 @@ def create_area( ) def create_thermal_cluster( - self, area_id: str, thermal_name: str, properties: Optional[ThermalClusterProperties] = None + self, + area_id: str, + thermal_name: str, + properties: Optional[ThermalClusterProperties] = None, ) -> ThermalCluster: """ Args: @@ -165,7 +173,9 @@ def create_thermal_cluster( url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/clusters/thermal" body = {"name": thermal_name.lower()} if properties: - camel_properties = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + camel_properties = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) body = {**body, **camel_properties} response = self._wrapper.post(url, json=body) json_response = response.json() @@ -214,7 +224,11 @@ def create_thermal_cluster_with_matrices( url = f"{self._base_url}/studies/{self.study_id}/commands" body = { "action": "create_cluster", - "args": {"area_id": area_id, "cluster_name": cluster_name, "parameters": {}}, + "args": { + "area_id": area_id, + "cluster_name": cluster_name, + "parameters": {}, + }, } args = body.get("args") @@ -222,7 +236,9 @@ def create_thermal_cluster_with_matrices( raise TypeError("body['args'] must be a dictionary") if parameters: - camel_properties = json.loads(parameters.model_dump_json(by_alias=True, exclude_none=True)) + camel_properties = json.loads( + parameters.model_dump_json(by_alias=True, exclude_none=True) + ) args["parameters"].update(camel_properties) if prepro is not None: @@ -235,7 +251,9 @@ def create_thermal_cluster_with_matrices( response.raise_for_status() if series is not None or CO2Cost is not None or fuelCost is not None: - self._create_thermal_series(area_id, cluster_name, series, CO2Cost, fuelCost) + self._create_thermal_series( + area_id, cluster_name, series, CO2Cost, fuelCost + ) except APIError as e: raise ThermalCreationError(cluster_name, area_id, e.message) from e @@ -252,15 +270,21 @@ def _create_thermal_series( ) -> None: command_body = [] if series is not None: - series_path = f"input/thermal/series/{area_id}/{cluster_name.lower()}/series" + series_path = ( + f"input/thermal/series/{area_id}/{cluster_name.lower()}/series" + ) command_body.append(prepare_args_replace_matrix(series, series_path)) if CO2Cost is not None: - co2_cost_path = f"input/thermal/series/{area_id}/{cluster_name.lower()}/CO2Cost" + co2_cost_path = ( + f"input/thermal/series/{area_id}/{cluster_name.lower()}/CO2Cost" + ) command_body.append(prepare_args_replace_matrix(CO2Cost, co2_cost_path)) if fuelCost is not None: - fuel_cost_path = f"input/thermal/series/{area_id}/{cluster_name.lower()}/fuelCost" + fuel_cost_path = ( + f"input/thermal/series/{area_id}/{cluster_name.lower()}/fuelCost" + ) command_body.append(prepare_args_replace_matrix(fuelCost, fuel_cost_path)) if command_body: @@ -304,7 +328,9 @@ def create_renewable_cluster( url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/clusters/renewable" body = {"name": renewable_name.lower()} if properties: - camel_properties = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + camel_properties = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) body = {**body, **camel_properties} response = self._wrapper.post(url, json=body) json_response = response.json() @@ -314,7 +340,9 @@ def create_renewable_cluster( properties = RenewableClusterProperties.model_validate(json_response) if series is not None: - series_path = f"input/renewables/series/{area_id}/{renewable_name.lower()}/series" + series_path = ( + f"input/renewables/series/{area_id}/{renewable_name.lower()}/series" + ) command_body = [prepare_args_replace_matrix(series, series_path)] self._replace_matrix_request(command_body) @@ -324,7 +352,10 @@ def create_renewable_cluster( return RenewableCluster(self.renewable_service, area_id, name, properties) def create_st_storage( - self, area_id: str, st_storage_name: str, properties: Optional[STStorageProperties] = None + self, + area_id: str, + st_storage_name: str, + properties: Optional[STStorageProperties] = None, ) -> STStorage: """ Args: @@ -343,7 +374,9 @@ def create_st_storage( url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/storages" body = {"name": st_storage_name} if properties: - camel_properties = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + camel_properties = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) body = {**body, **camel_properties} response = self._wrapper.post(url, json=body) json_response = response.json() @@ -357,7 +390,9 @@ def create_st_storage( return STStorage(self.storage_service, area_id, name, properties) - def _upload_series(self, area: Area, series: Optional[pd.DataFrame], path: str) -> None: + def _upload_series( + self, area: Area, series: Optional[pd.DataFrame], path: str + ) -> None: try: url = f"{self._base_url}/studies/{self.study_id}/raw?path={path}" if series is not None: @@ -403,7 +438,9 @@ def create_hydro( url = f"{self._base_url}/studies/{self.study_id}/areas/{area_id}/hydro/form" body = {} if properties: - camel_properties = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + camel_properties = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) body = {**camel_properties} self._wrapper.put(url, json=body) @@ -415,7 +452,9 @@ def create_hydro( return Hydro(self, area_id, properties) - def _create_hydro_series(self, area_id: str, matrices: Dict[HydroMatrixName, pd.DataFrame]) -> None: + def _create_hydro_series( + self, area_id: str, matrices: Dict[HydroMatrixName, pd.DataFrame] + ) -> None: command_body = [] for matrix_name, series in matrices.items(): if "SERIES" in matrix_name.name: @@ -425,15 +464,21 @@ def _create_hydro_series(self, area_id: str, matrices: Dict[HydroMatrixName, pd. series_path = f"input/hydro/prepro/{area_id}/{matrix_name.value}" command_body.append(prepare_args_replace_matrix(series, series_path)) if "COMMON" in matrix_name.name: - series_path = f"input/hydro/common/capacity/{matrix_name.value}_{area_id}" + series_path = ( + f"input/hydro/common/capacity/{matrix_name.value}_{area_id}" + ) command_body.append(prepare_args_replace_matrix(series, series_path)) if command_body: json_payload = command_body self._replace_matrix_request(json_payload) - def update_area_properties(self, area: Area, properties: AreaProperties) -> AreaProperties: - url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/properties/form" + def update_area_properties( + self, area: Area, properties: AreaProperties + ) -> AreaProperties: + url = ( + f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/properties/form" + ) try: body = json.loads(properties.model_dump_json(exclude_none=True)) if not body: @@ -489,15 +534,21 @@ def delete_area(self, area: Area) -> None: except APIError as e: raise AreaDeletionError(area_id, e.message) from e - def delete_thermal_clusters(self, area: Area, clusters: List[ThermalCluster]) -> None: - url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/clusters/thermal" + def delete_thermal_clusters( + self, area: Area, clusters: List[ThermalCluster] + ) -> None: + url = ( + f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/clusters/thermal" + ) body = [cluster.id for cluster in clusters] try: self._wrapper.delete(url, json=body) except APIError as e: raise ThermalDeletionError(area.id, body, e.message) from e - def delete_renewable_clusters(self, area: Area, clusters: List[RenewableCluster]) -> None: + def delete_renewable_clusters( + self, area: Area, clusters: List[RenewableCluster] + ) -> None: url = f"{self._base_url}/studies/{self.study_id}/areas/{area.id}/clusters/renewable" body = [cluster.id for cluster in clusters] try: @@ -521,7 +572,9 @@ def upload_load_matrix(self, area: Area, load_matrix: pd.DataFrame) -> None: rows_number = load_matrix.shape[0] expected_rows = 8760 if rows_number < expected_rows: - raise APIError(f"Expected {expected_rows} rows and received {rows_number}.") + raise APIError( + f"Expected {expected_rows} rows and received {rows_number}." + ) array_data = load_matrix.to_numpy().tolist() self._wrapper.post(url, json=array_data) except APIError as e: @@ -531,11 +584,15 @@ def get_matrix(self, path: PurePosixPath) -> pd.DataFrame: raw_url = f"{self._base_url}/studies/{self.study_id}/raw?path={path}" response = self._wrapper.get(raw_url) json_df = response.json() - dataframe = pd.DataFrame(data=json_df["data"], index=json_df["index"], columns=json_df["columns"]) + dataframe = pd.DataFrame( + data=json_df["data"], index=json_df["index"], columns=json_df["columns"] + ) return dataframe def get_load_matrix(self, area: Area) -> pd.DataFrame: try: - return self.get_matrix(PurePosixPath("input") / "load" / "series" / f"load_{area.id}") + return self.get_matrix( + PurePosixPath("input") / "load" / "series" / f"load_{area.id}" + ) except APIError as e: raise LoadMatrixDownloadError(area.id, e.message) from e diff --git a/src/antares/service/api_services/binding_constraint_api.py b/src/antares/service/api_services/binding_constraint_api.py index 22d2138a..dd1c5711 100644 --- a/src/antares/service/api_services/binding_constraint_api.py +++ b/src/antares/service/api_services/binding_constraint_api.py @@ -75,7 +75,9 @@ def create_binding_constraint( try: body = {"name": name} if properties: - camel_properties = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + camel_properties = json.loads( + properties.model_dump_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], @@ -88,7 +90,9 @@ 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) + bc_properties = BindingConstraintProperties.model_validate( + created_properties + ) bc_terms: List[ConstraintTerm] = [] if terms: @@ -99,7 +103,9 @@ def create_binding_constraint( url = f"{base_url}/{bc_id}" response = self._wrapper.get(url) created_terms = response.json()["terms"] - bc_terms = [ConstraintTerm.model_validate(term) for term in created_terms] + bc_terms = [ + ConstraintTerm.model_validate(term) for term in created_terms + ] except APIError as e: raise BindingConstraintCreationError(name, e.message) from e @@ -114,11 +120,15 @@ def delete_binding_constraint_term(self, constraint_id: str, term_id: str) -> No raise ConstraintTermDeletionError(constraint_id, term_id, e.message) from e def update_binding_constraint_properties( - self, binding_constraint: BindingConstraint, properties: BindingConstraintProperties + self, + binding_constraint: BindingConstraint, + properties: BindingConstraintProperties, ) -> BindingConstraintProperties: url = f"{self._base_url}/studies/{self.study_id}/bindingconstraints/{binding_constraint.id}" try: - body = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + body = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) if not body: return binding_constraint.properties @@ -129,19 +139,35 @@ def update_binding_constraint_properties( new_properties = BindingConstraintProperties.model_validate(json_response) except APIError as e: - raise ConstraintPropertiesUpdateError(binding_constraint.id, e.message) from e + raise ConstraintPropertiesUpdateError( + binding_constraint.id, e.message + ) from e return new_properties - def get_constraint_matrix(self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName) -> pd.DataFrame: + def get_constraint_matrix( + self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName + ) -> pd.DataFrame: try: - path = PurePosixPath("input") / "bindingconstraints" / f"{constraint.id}_{matrix_name.value}" - return get_matrix(f"{self._base_url}/studies/{self.study_id}/raw?path={path}", self._wrapper) + path = ( + PurePosixPath("input") + / "bindingconstraints" + / f"{constraint.id}_{matrix_name.value}" + ) + return get_matrix( + f"{self._base_url}/studies/{self.study_id}/raw?path={path}", + self._wrapper, + ) except APIError as e: - raise ConstraintMatrixDownloadError(constraint.id, matrix_name.value, e.message) from e + raise ConstraintMatrixDownloadError( + constraint.id, matrix_name.value, e.message + ) from e def update_constraint_matrix( - self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName, matrix: pd.DataFrame + self, + constraint: BindingConstraint, + matrix_name: ConstraintMatrixName, + matrix: pd.DataFrame, ) -> None: mapping = { ConstraintMatrixName.LESS_TERM: "lessTermMatrix", @@ -153,19 +179,31 @@ def update_constraint_matrix( body = {mapping[matrix_name]: matrix.to_numpy().tolist()} self._wrapper.put(url, json=body) except APIError as e: - raise ConstraintMatrixUpdateError(constraint.id, matrix_name.value, e.message) from e + raise ConstraintMatrixUpdateError( + constraint.id, matrix_name.value, e.message + ) from e - def add_constraint_terms(self, constraint: BindingConstraint, terms: List[ConstraintTerm]) -> List[ConstraintTerm]: + def add_constraint_terms( + self, constraint: BindingConstraint, terms: List[ConstraintTerm] + ) -> List[ConstraintTerm]: url = f"{self._base_url}/studies/{self.study_id}/bindingconstraints/{constraint.id}" try: json_terms = [term.model_dump() for term in terms] self._wrapper.post(f"{url}/terms", json=json_terms) response = self._wrapper.get(url) all_terms = response.json()["terms"] - validated_terms = [ConstraintTerm.model_validate(term) for term in all_terms] - new_terms = [term for term in validated_terms if term.id not in constraint.get_terms()] + validated_terms = [ + ConstraintTerm.model_validate(term) for term in all_terms + ] + new_terms = [ + term + for term in validated_terms + if term.id not in constraint.get_terms() + ] except APIError as e: - raise ConstraintTermAdditionError(constraint.id, [term.id for term in terms], e.message) from e + raise ConstraintTermAdditionError( + constraint.id, [term.id for term in terms], e.message + ) from e return new_terms diff --git a/src/antares/service/api_services/link_api.py b/src/antares/service/api_services/link_api.py index 4a56f05c..f35973e4 100644 --- a/src/antares/service/api_services/link_api.py +++ b/src/antares/service/api_services/link_api.py @@ -74,9 +74,15 @@ def create_link( # TODO update to use check_if_none or similar if properties or ui: link_properties = json.loads( - check_if_none(properties, LinkProperties()).model_dump_json(by_alias=True, exclude_none=True) + check_if_none(properties, LinkProperties()).model_dump_json( + by_alias=True, exclude_none=True + ) + ) + link_ui = json.loads( + check_if_none(ui, LinkUi()).model_dump_json( + by_alias=True, exclude_none=True + ) ) - link_ui = json.loads(check_if_none(ui, LinkUi()).model_dump_json(by_alias=True, exclude_none=True)) body = {**link_properties, **link_ui} if body: json_file = _join_filter_values_for_json(json_file, body) @@ -109,12 +115,16 @@ def delete_link(self, link: Link) -> None: except APIError as e: raise LinkDeletionError(link.name, e.message) from e - def update_link_properties(self, link: Link, properties: LinkProperties) -> LinkProperties: + def update_link_properties( + self, link: Link, properties: LinkProperties + ) -> LinkProperties: # todo: change this code when AntaresWeb will have a real endpoint area1_id, area2_id = sorted([link.area_from.id, link.area_to.id]) raw_url = f"{self._base_url}/studies/{self.study_id}/raw?path=input/links/{area1_id}/properties/{area2_id}" try: - new_properties = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + new_properties = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) if not new_properties: return link.properties diff --git a/src/antares/service/api_services/renewable_api.py b/src/antares/service/api_services/renewable_api.py index 9a2be268..266311f9 100644 --- a/src/antares/service/api_services/renewable_api.py +++ b/src/antares/service/api_services/renewable_api.py @@ -17,7 +17,11 @@ from antares.api_conf.api_conf import APIconf from antares.api_conf.request_wrapper import RequestWrapper -from antares.exceptions.exceptions import APIError, RenewablePropertiesUpdateError, RenewableMatrixDownloadError +from antares.exceptions.exceptions import ( + APIError, + RenewablePropertiesUpdateError, + RenewableMatrixDownloadError, +) from antares.model.renewable import RenewableCluster, RenewableClusterProperties from antares.service.api_services.utils import get_matrix from antares.service.base_services import BaseRenewableService @@ -32,11 +36,15 @@ def __init__(self, config: APIconf, study_id: str): self._wrapper = RequestWrapper(self.config.set_up_api_conf()) def update_renewable_properties( - self, renewable_cluster: RenewableCluster, properties: RenewableClusterProperties + self, + renewable_cluster: RenewableCluster, + properties: RenewableClusterProperties, ) -> RenewableClusterProperties: url = f"{self._base_url}/studies/{self.study_id}/areas/{renewable_cluster.area_id}/clusters/renewable/{renewable_cluster.id}" try: - body = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + body = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) if not body: return renewable_cluster.properties @@ -47,7 +55,9 @@ def update_renewable_properties( new_properties = RenewableClusterProperties.model_validate(json_response) except APIError as e: - raise RenewablePropertiesUpdateError(renewable_cluster.id, renewable_cluster.area_id, e.message) from e + raise RenewablePropertiesUpdateError( + renewable_cluster.id, renewable_cluster.area_id, e.message + ) from e return new_properties @@ -61,6 +71,11 @@ def get_renewable_matrix(self, renewable: RenewableCluster) -> pd.DataFrame: / f"{renewable.name}" / "series" ) - return get_matrix(f"{self._base_url}/studies/{self.study_id}/raw?path={path}", self._wrapper) + return get_matrix( + f"{self._base_url}/studies/{self.study_id}/raw?path={path}", + self._wrapper, + ) except APIError as e: - raise RenewableMatrixDownloadError(renewable.area_id, renewable.name, e.message) from e + raise RenewableMatrixDownloadError( + renewable.area_id, renewable.name, e.message + ) from e diff --git a/src/antares/service/api_services/st_storage_api.py b/src/antares/service/api_services/st_storage_api.py index 45f58dc3..f67475b7 100644 --- a/src/antares/service/api_services/st_storage_api.py +++ b/src/antares/service/api_services/st_storage_api.py @@ -39,7 +39,9 @@ def update_st_storage_properties( ) -> STStorageProperties: url = f"{self._base_url}/studies/{self.study_id}/areas/{st_storage.area_id}/storages/{st_storage.id}" try: - body = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + body = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) if not body: return st_storage.properties @@ -50,11 +52,15 @@ def update_st_storage_properties( new_properties = STStorageProperties.model_validate(json_response) except APIError as e: - raise STStoragePropertiesUpdateError(st_storage.id, st_storage.area_id, e.message) from e + raise STStoragePropertiesUpdateError( + st_storage.id, st_storage.area_id, e.message + ) from e return new_properties - def upload_storage_matrix(self, storage: STStorage, ts_name: STStorageMatrixName, matrix: pd.DataFrame) -> None: + def upload_storage_matrix( + self, storage: STStorage, ts_name: STStorageMatrixName, matrix: pd.DataFrame + ) -> None: url = f"{self._base_url}/studies/{self.study_id}/areas/{storage.area_id}/storages/{storage.id}/series/{ts_name.value}" try: body = { @@ -64,14 +70,22 @@ def upload_storage_matrix(self, storage: STStorage, ts_name: STStorageMatrixName } self._wrapper.put(url, json=body) except APIError as e: - raise STStorageMatrixUploadError(storage.area_id, storage.id, ts_name.value, e.message) from e + raise STStorageMatrixUploadError( + storage.area_id, storage.id, ts_name.value, e.message + ) from e - def get_storage_matrix(self, storage: STStorage, ts_name: STStorageMatrixName) -> pd.DataFrame: + def get_storage_matrix( + self, storage: STStorage, ts_name: STStorageMatrixName + ) -> pd.DataFrame: url = f"{self._base_url}/studies/{self.study_id}/areas/{storage.area_id}/storages/{storage.id}/series/{ts_name.value}" try: response = self._wrapper.get(url) json_df = response.json() - dataframe = pd.DataFrame(data=json_df["data"], index=json_df["index"], columns=json_df["columns"]) + dataframe = pd.DataFrame( + data=json_df["data"], index=json_df["index"], columns=json_df["columns"] + ) except APIError as e: - raise STStorageMatrixDownloadError(storage.area_id, storage.id, ts_name.value, e.message) from e + raise STStorageMatrixDownloadError( + storage.area_id, storage.id, ts_name.value, e.message + ) from e return dataframe diff --git a/src/antares/service/api_services/study_api.py b/src/antares/service/api_services/study_api.py index adb5634b..2b24efaa 100644 --- a/src/antares/service/api_services/study_api.py +++ b/src/antares/service/api_services/study_api.py @@ -35,7 +35,11 @@ def _returns_study_settings( - base_url: str, study_id: str, wrapper: RequestWrapper, update: bool, settings: Optional[StudySettings] + base_url: str, + study_id: str, + wrapper: RequestWrapper, + update: bool, + settings: Optional[StudySettings], ) -> Optional[StudySettings]: settings_base_url = f"{base_url}/studies/{study_id}/config" mapping = { @@ -48,7 +52,9 @@ def _returns_study_settings( "playlist": ("playlist", None), } if settings: - json_settings = json.loads(settings.model_dump_json(by_alias=True, exclude_none=True)) + json_settings = json.loads( + settings.model_dump_json(by_alias=True, exclude_none=True) + ) if not json_settings and update: return None @@ -88,7 +94,9 @@ def config(self) -> APIconf: def update_study_settings(self, settings: StudySettings) -> Optional[StudySettings]: try: - new_settings = _returns_study_settings(self._base_url, self.study_id, self._wrapper, True, settings) + new_settings = _returns_study_settings( + self._base_url, self.study_id, self._wrapper, True, settings + ) except APIError as e: raise StudySettingsUpdateError(self.study_id, e.message) from e return new_settings diff --git a/src/antares/service/api_services/thermal_api.py b/src/antares/service/api_services/thermal_api.py index f2fd8987..191a9488 100644 --- a/src/antares/service/api_services/thermal_api.py +++ b/src/antares/service/api_services/thermal_api.py @@ -17,8 +17,16 @@ from antares.api_conf.api_conf import APIconf from antares.api_conf.request_wrapper import RequestWrapper -from antares.exceptions.exceptions import APIError, ThermalPropertiesUpdateError, ThermalMatrixDownloadError -from antares.model.thermal import ThermalCluster, ThermalClusterProperties, ThermalClusterMatrixName +from antares.exceptions.exceptions import ( + APIError, + ThermalPropertiesUpdateError, + ThermalMatrixDownloadError, +) +from antares.model.thermal import ( + ThermalCluster, + ThermalClusterProperties, + ThermalClusterMatrixName, +) from antares.service.api_services.utils import get_matrix from antares.service.base_services import BaseThermalService @@ -36,7 +44,9 @@ def update_thermal_properties( ) -> ThermalClusterProperties: url = f"{self._base_url}/studies/{self.study_id}/areas/{thermal_cluster.area_id}/clusters/thermal/{thermal_cluster.id}" try: - body = json.loads(properties.model_dump_json(by_alias=True, exclude_none=True)) + body = json.loads( + properties.model_dump_json(by_alias=True, exclude_none=True) + ) if not body: return thermal_cluster.properties @@ -47,11 +57,15 @@ def update_thermal_properties( new_properties = ThermalClusterProperties.model_validate(json_response) except APIError as e: - raise ThermalPropertiesUpdateError(thermal_cluster.id, thermal_cluster.area_id, e.message) from e + raise ThermalPropertiesUpdateError( + thermal_cluster.id, thermal_cluster.area_id, e.message + ) from e return new_properties - def get_thermal_matrix(self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName) -> pd.DataFrame: + def get_thermal_matrix( + self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName + ) -> pd.DataFrame: try: keyword = "series" if "SERIES" in ts_name.name else "prepro" path = ( @@ -62,7 +76,10 @@ def get_thermal_matrix(self, thermal_cluster: ThermalCluster, ts_name: ThermalCl / f"{thermal_cluster.name.lower()}" / ts_name.value ) - return get_matrix(f"{self._base_url}/studies/{self.study_id}/raw?path={path}", self._wrapper) + return get_matrix( + f"{self._base_url}/studies/{self.study_id}/raw?path={path}", + self._wrapper, + ) except APIError as e: raise ThermalMatrixDownloadError( thermal_cluster.area_id, thermal_cluster.name, ts_name.value, e.message diff --git a/src/antares/service/api_services/utils.py b/src/antares/service/api_services/utils.py index 29b1a9e7..a1cc26b2 100644 --- a/src/antares/service/api_services/utils.py +++ b/src/antares/service/api_services/utils.py @@ -18,5 +18,7 @@ def get_matrix(url: str, wrapper: RequestWrapper) -> pd.DataFrame: response = wrapper.get(url) json_df = response.json() - dataframe = pd.DataFrame(data=json_df["data"], index=json_df["index"], columns=json_df["columns"]) + dataframe = pd.DataFrame( + data=json_df["data"], index=json_df["index"], columns=json_df["columns"] + ) return dataframe diff --git a/src/antares/service/base_services.py b/src/antares/service/base_services.py index 2c74f0af..a535fdd5 100644 --- a/src/antares/service/base_services.py +++ b/src/antares/service/base_services.py @@ -32,13 +32,19 @@ from antares.model.settings import StudySettings from antares.model.solar import Solar from antares.model.st_storage import STStorageProperties, STStorage -from antares.model.thermal import ThermalClusterProperties, ThermalCluster, ThermalClusterMatrixName +from antares.model.thermal import ( + ThermalClusterProperties, + ThermalCluster, + ThermalClusterMatrixName, +) from antares.model.wind import Wind class BaseAreaService(ABC): @abstractmethod - def set_storage_service(self, storage_service: "BaseShortTermStorageService") -> None: + def set_storage_service( + self, storage_service: "BaseShortTermStorageService" + ) -> None: pass @abstractmethod @@ -51,13 +57,19 @@ def set_renewable_service(self, renewable_service: "BaseRenewableService") -> No @abstractmethod def create_area( - self, area_name: str, properties: Optional[AreaProperties] = None, ui: Optional[AreaUi] = None + self, + area_name: str, + properties: Optional[AreaProperties] = None, + ui: Optional[AreaUi] = None, ) -> Area: pass @abstractmethod def create_thermal_cluster( - self, area_id: str, thermal_name: str, properties: Optional[ThermalClusterProperties] = None + self, + area_id: str, + thermal_name: str, + properties: Optional[ThermalClusterProperties] = None, ) -> ThermalCluster: """ Args: @@ -122,7 +134,10 @@ def create_renewable_cluster( @abstractmethod def create_st_storage( - self, area_id: str, st_storage_name: str, properties: Optional[STStorageProperties] = None + self, + area_id: str, + st_storage_name: str, + properties: Optional[STStorageProperties] = None, ) -> STStorage: """ Args: @@ -195,7 +210,9 @@ def create_hydro( pass @abstractmethod - def update_area_properties(self, area: Area, properties: AreaProperties) -> AreaProperties: + def update_area_properties( + self, area: Area, properties: AreaProperties + ) -> AreaProperties: """ Args: area: concerned area @@ -221,7 +238,9 @@ def delete_area(self, area: Area) -> None: pass @abstractmethod - def delete_thermal_clusters(self, area: Area, thermal_clusters: List[ThermalCluster]) -> None: + def delete_thermal_clusters( + self, area: Area, thermal_clusters: List[ThermalCluster] + ) -> None: """ Args: area: area containing the cluster @@ -230,7 +249,9 @@ def delete_thermal_clusters(self, area: Area, thermal_clusters: List[ThermalClus pass @abstractmethod - def delete_renewable_clusters(self, area: Area, renewable_clusters: List[RenewableCluster]) -> None: + def delete_renewable_clusters( + self, area: Area, renewable_clusters: List[RenewableCluster] + ) -> None: """ Args: area: area containing the cluster @@ -269,27 +290,29 @@ def get_load_matrix(self, area: Area) -> pd.DataFrame: @abstractmethod def read_thermal_cluster( - self, - area_id: str, - thermal_name: str, - properties: Optional[ThermalClusterProperties] = None, + self, + area_id: str, + thermal_name: str, + properties: Optional[ThermalClusterProperties] = None, ) -> ThermalCluster: pass - @abstractmethod def read_renewable_cluster( - self, - area_id: str, - renewable_name: str, - properties: Optional[RenewableClusterProperties] = None, - series: Optional[pd.DataFrame] = None, + self, + area_id: str, + renewable_name: str, + properties: Optional[RenewableClusterProperties] = None, + series: Optional[pd.DataFrame] = None, ) -> RenewableCluster: pass @abstractmethod def read_st_storage( - self, area_id: str, st_storage_name: str, properties: Optional[STStorageProperties] = None + self, + area_id: str, + st_storage_name: str, + properties: Optional[STStorageProperties] = None, ) -> STStorage: pass @@ -311,16 +334,19 @@ def read_misc_gen(self, area: Area, series: Optional[pd.DataFrame]) -> MiscGen: @abstractmethod def read_hydro( - self, - area_id: str, - properties: Optional[HydroProperties] = None, - matrices: Optional[Dict[HydroMatrixName, pd.DataFrame]] = None, + self, + area_id: str, + properties: Optional[HydroProperties] = None, + matrices: Optional[Dict[HydroMatrixName, pd.DataFrame]] = None, ) -> Hydro: pass @abstractmethod def read_area( - self, area_name: str, properties: Optional[AreaProperties] = None, ui: Optional[AreaUi] = None + self, + area_name: str, + properties: Optional[AreaProperties] = None, + ui: Optional[AreaUi] = None, ) -> Area: """ Args: @@ -367,7 +393,9 @@ def delete_link(self, link: Link) -> None: pass @abstractmethod - def update_link_properties(self, link: Link, properties: LinkProperties) -> LinkProperties: + def update_link_properties( + self, link: Link, properties: LinkProperties + ) -> LinkProperties: """ Args: link: concerned link @@ -420,7 +448,9 @@ def update_thermal_properties( pass @abstractmethod - def get_thermal_matrix(self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName) -> pd.DataFrame: + def get_thermal_matrix( + self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName + ) -> pd.DataFrame: """ Args: thermal_cluster: cluster to retrieve matrix @@ -458,7 +488,9 @@ def create_binding_constraint( pass @abstractmethod - def add_constraint_terms(self, constraint: BindingConstraint, terms: List[ConstraintTerm]) -> List[ConstraintTerm]: + def add_constraint_terms( + self, constraint: BindingConstraint, terms: List[ConstraintTerm] + ) -> List[ConstraintTerm]: """ Args: constraint: the concerned binding constraint @@ -480,7 +512,9 @@ 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: BindingConstraintProperties, ) -> BindingConstraintProperties: """ Args: @@ -490,7 +524,9 @@ def update_binding_constraint_properties( pass @abstractmethod - def get_constraint_matrix(self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName) -> pd.DataFrame: + def get_constraint_matrix( + self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName + ) -> pd.DataFrame: """ Args: constraint: the concerned binding constraint @@ -500,7 +536,10 @@ def get_constraint_matrix(self, constraint: BindingConstraint, matrix_name: Cons @abstractmethod def update_constraint_matrix( - self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName, matrix: pd.DataFrame + self, + constraint: BindingConstraint, + matrix_name: ConstraintMatrixName, + matrix: pd.DataFrame, ) -> None: """ Args: @@ -578,10 +617,13 @@ def read_areas(self) -> None: """ pass + class BaseRenewableService(ABC): @abstractmethod def update_renewable_properties( - self, renewable_cluster: RenewableCluster, properties: RenewableClusterProperties + self, + renewable_cluster: RenewableCluster, + properties: RenewableClusterProperties, ) -> RenewableClusterProperties: """ Args: diff --git a/src/antares/service/local_services/area_local.py b/src/antares/service/local_services/area_local.py index 72174020..1fefde37 100644 --- a/src/antares/service/local_services/area_local.py +++ b/src/antares/service/local_services/area_local.py @@ -19,14 +19,37 @@ from antares.config.local_configuration import LocalConfiguration from antares.exceptions.exceptions import CustomError -from antares.model.area import AreaProperties, AreaUi, Area, AreaPropertiesLocal, AreaUiLocal -from antares.model.hydro import HydroProperties, HydroMatrixName, Hydro, HydroPropertiesLocal +from antares.model.area import ( + AreaProperties, + AreaUi, + Area, + AreaPropertiesLocal, + AreaUiLocal, +) +from antares.model.hydro import ( + HydroProperties, + HydroMatrixName, + Hydro, + HydroPropertiesLocal, +) from antares.model.misc_gen import MiscGen -from antares.model.renewable import RenewableClusterProperties, RenewableCluster, RenewableClusterPropertiesLocal +from antares.model.renewable import ( + RenewableClusterProperties, + RenewableCluster, + RenewableClusterPropertiesLocal, +) from antares.model.reserves import Reserves from antares.model.solar import Solar -from antares.model.st_storage import STStorageProperties, STStorage, STStoragePropertiesLocal -from antares.model.thermal import ThermalClusterProperties, ThermalCluster, ThermalClusterPropertiesLocal +from antares.model.st_storage import ( + STStorageProperties, + STStorage, + STStoragePropertiesLocal, +) +from antares.model.thermal import ( + ThermalClusterProperties, + ThermalCluster, + ThermalClusterPropertiesLocal, +) from antares.model.wind import Wind from antares.service.base_services import ( BaseAreaService, @@ -56,7 +79,9 @@ def _sets_ini_content() -> ConfigParser: class AreaLocalService(BaseAreaService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.config = config self.study_name = study_name @@ -76,14 +101,21 @@ def create_thermal_cluster( thermal_name: str, properties: Optional[ThermalClusterProperties] = None, ) -> ThermalCluster: - local_thermal_properties = ThermalClusterPropertiesLocal(thermal_name, properties) + local_thermal_properties = ThermalClusterPropertiesLocal( + thermal_name, properties + ) - list_ini = IniFile(self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id) + list_ini = IniFile( + self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id + ) list_ini.add_section(local_thermal_properties.list_ini_fields) list_ini.write_ini_file(sort_sections=True) return ThermalCluster( - self.thermal_service, area_id, thermal_name, local_thermal_properties.yield_thermal_cluster_properties() + self.thermal_service, + area_id, + thermal_name, + local_thermal_properties.yield_thermal_cluster_properties(), ) def create_thermal_cluster_with_matrices( @@ -108,20 +140,32 @@ def create_renewable_cluster( ) -> RenewableCluster: local_properties = RenewableClusterPropertiesLocal(renewable_name, properties) - list_ini = IniFile(self.config.study_path, IniFileTypes.RENEWABLES_LIST_INI, area_name=area_id) + list_ini = IniFile( + self.config.study_path, IniFileTypes.RENEWABLES_LIST_INI, area_name=area_id + ) list_ini.add_section(local_properties.ini_fields) list_ini.write_ini_file() return RenewableCluster( - self.renewable_service, area_id, renewable_name, local_properties.yield_renewable_cluster_properties() + self.renewable_service, + area_id, + renewable_name, + local_properties.yield_renewable_cluster_properties(), ) def create_st_storage( - self, area_id: str, st_storage_name: str, properties: Optional[STStorageProperties] = None + self, + area_id: str, + st_storage_name: str, + properties: Optional[STStorageProperties] = None, ) -> STStorage: - local_st_storage_properties = STStoragePropertiesLocal(st_storage_name, properties) + local_st_storage_properties = STStoragePropertiesLocal( + st_storage_name, properties + ) - list_ini = IniFile(self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id) + list_ini = IniFile( + self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id + ) list_ini.add_section(local_st_storage_properties.list_ini_fields) list_ini.write_ini_file(sort_sections=True) @@ -134,22 +178,30 @@ def create_st_storage( def create_wind(self, area: Area, series: Optional[pd.DataFrame]) -> Wind: series = series if series is not None else pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.WIND, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.WIND, self.config.study_path, area.id, series + ) return Wind(series, local_file) def create_reserves(self, area: Area, series: Optional[pd.DataFrame]) -> Reserves: series = series if series is not None else pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.RESERVES, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.RESERVES, self.config.study_path, area.id, series + ) return Reserves(series, local_file) def create_solar(self, area: Area, series: Optional[pd.DataFrame]) -> Solar: series = series if series is not None else pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.SOLAR, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.SOLAR, self.config.study_path, area.id, series + ) return Solar(series, local_file) def create_misc_gen(self, area: Area, series: Optional[pd.DataFrame]) -> MiscGen: series = series if series is not None else pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.MISC_GEN, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.MISC_GEN, self.config.study_path, area.id, series + ) return MiscGen(series, local_file) def create_hydro( @@ -167,7 +219,10 @@ def create_hydro( return Hydro(self, area_id, local_hydro_properties.yield_hydro_properties()) def create_area( - self, area_name: str, properties: Optional[AreaProperties] = None, ui: Optional[AreaUi] = None + self, + area_name: str, + properties: Optional[AreaProperties] = None, + ui: Optional[AreaUi] = None, ) -> Area: """ Args: @@ -205,8 +260,12 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool: with open(list_path, "r") as list_file: list_file_content = list_file.read() if _line_exists_in_file(list_file_content, area_to_add): - raise ValueError(f"The Area '{area_name}' already exists in the study {self.study_name}.") - updated_list = sorted(list_file_content.splitlines(keepends=True) + [area_to_add]) + raise ValueError( + f"The Area '{area_name}' already exists in the study {self.study_name}." + ) + updated_list = sorted( + list_file_content.splitlines(keepends=True) + [area_to_add] + ) else: updated_list = [area_to_add] @@ -217,19 +276,29 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool: # TODO: Handle districts in sets.ini later sets_ini_content = _sets_ini_content() - with (self.config.study_path / IniFileTypes.AREAS_SETS_INI.value).open("w") as sets_ini: + with (self.config.study_path / IniFileTypes.AREAS_SETS_INI.value).open( + "w" + ) as sets_ini: sets_ini_content.write(sets_ini) - local_properties = AreaPropertiesLocal(properties) if properties else AreaPropertiesLocal() + local_properties = ( + AreaPropertiesLocal(properties) if properties else AreaPropertiesLocal() + ) - adequacy_patch_ini = IniFile(self.config.study_path, IniFileTypes.AREA_ADEQUACY_PATCH_INI, area_name) + adequacy_patch_ini = IniFile( + self.config.study_path, IniFileTypes.AREA_ADEQUACY_PATCH_INI, area_name + ) adequacy_patch_ini.add_section(local_properties.adequacy_patch_mode()) adequacy_patch_ini.write_ini_file() optimization_ini = ConfigParser() - optimization_ini.read_dict(local_properties.model_dump(by_alias=True, exclude_none=True)) + optimization_ini.read_dict( + local_properties.model_dump(by_alias=True, exclude_none=True) + ) - with open(new_area_directory / "optimization.ini", "w") as optimization_ini_file: + with open( + new_area_directory / "optimization.ini", "w" + ) as optimization_ini_file: optimization_ini.write(optimization_ini_file) areas_ini = IniFile(self.config.study_path, IniFileTypes.THERMAL_AREAS_INI) @@ -237,12 +306,12 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool: areas_ini.add_section({"unserverdenergycost": {}}) areas_ini.add_section({"spilledenergycost": {}}) areas_ini.write_ini_file() - areas_ini.parsed_ini["unserverdenergycost"][area_name] = local_properties.nodal_optimization[ - "average-unsupplied-energy-cost" - ] - areas_ini.parsed_ini["spilledenergycost"][area_name] = local_properties.nodal_optimization[ - "average-spilled-energy-cost" - ] + areas_ini.parsed_ini["unserverdenergycost"][area_name] = ( + local_properties.nodal_optimization["average-unsupplied-energy-cost"] + ) + areas_ini.parsed_ini["spilledenergycost"][area_name] = ( + local_properties.nodal_optimization["average-spilled-energy-cost"] + ) areas_ini.write_ini_file() local_ui = AreaUiLocal(ui) if ui else AreaUiLocal() @@ -270,16 +339,22 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool: def delete_area(self, area: Area) -> None: raise NotImplementedError - def update_area_properties(self, area: Area, properties: AreaProperties) -> AreaProperties: + def update_area_properties( + self, area: Area, properties: AreaProperties + ) -> AreaProperties: raise NotImplementedError def update_area_ui(self, area: Area, ui: AreaUi) -> AreaUi: raise NotImplementedError - def delete_thermal_clusters(self, area: Area, thermal_clusters: List[ThermalCluster]) -> None: + def delete_thermal_clusters( + self, area: Area, thermal_clusters: List[ThermalCluster] + ) -> None: raise NotImplementedError - def delete_renewable_clusters(self, area: Area, renewable_clusters: List[RenewableCluster]) -> None: + def delete_renewable_clusters( + self, area: Area, renewable_clusters: List[RenewableCluster] + ) -> None: raise NotImplementedError def delete_st_storages(self, area: Area, storages: List[STStorage]) -> None: @@ -297,17 +372,23 @@ def read_thermal_cluster( thermal_name: str, properties: Optional[ThermalClusterProperties] = None, ) -> ThermalCluster: - local_thermal_properties = ThermalClusterPropertiesLocal(thermal_name, properties) + local_thermal_properties = ThermalClusterPropertiesLocal( + thermal_name, properties + ) - list_ini = IniFile(self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id) + list_ini = IniFile( + self.config.study_path, IniFileTypes.THERMAL_LIST_INI, area_name=area_id + ) list_ini.add_section(local_thermal_properties.list_ini_fields) list_ini.write_ini_file(sort_sections=True) return ThermalCluster( - self.thermal_service, area_id, thermal_name, local_thermal_properties.yield_thermal_cluster_properties() + self.thermal_service, + area_id, + thermal_name, + local_thermal_properties.yield_thermal_cluster_properties(), ) - def read_renewable_cluster( self, area_id: str, @@ -316,20 +397,32 @@ def read_renewable_cluster( ) -> RenewableCluster: local_properties = RenewableClusterPropertiesLocal(renewable_name, properties) - list_ini = IniFile(self.config.study_path, IniFileTypes.RENEWABLES_LIST_INI, area_name=area_id) + list_ini = IniFile( + self.config.study_path, IniFileTypes.RENEWABLES_LIST_INI, area_name=area_id + ) list_ini.add_section(local_properties.ini_fields) list_ini.write_ini_file() return RenewableCluster( - self.renewable_service, area_id, renewable_name, local_properties.yield_renewable_cluster_properties() + self.renewable_service, + area_id, + renewable_name, + local_properties.yield_renewable_cluster_properties(), ) def read_st_storage( - self, area_id: str, st_storage_name: str, properties: Optional[STStorageProperties] = None + self, + area_id: str, + st_storage_name: str, + properties: Optional[STStorageProperties] = None, ) -> STStorage: - local_st_storage_properties = STStoragePropertiesLocal(st_storage_name, properties) + local_st_storage_properties = STStoragePropertiesLocal( + st_storage_name, properties + ) - list_ini = IniFile(self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id) + list_ini = IniFile( + self.config.study_path, IniFileTypes.ST_STORAGE_LIST_INI, area_name=area_id + ) list_ini.add_section(local_st_storage_properties.list_ini_fields) list_ini.write_ini_file(sort_sections=True) @@ -342,22 +435,30 @@ def read_st_storage( def read_wind(self, area: Area) -> Wind: series = pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.WIND, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.WIND, self.config.study_path, area.id, series + ) return Wind(series, local_file) def read_reserves(self, area: Area) -> Reserves: series = pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.RESERVES, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.RESERVES, self.config.study_path, area.id, series + ) return Reserves(series, local_file) def read_solar(self, area: Area) -> Solar: series = pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.SOLAR, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.SOLAR, self.config.study_path, area.id, series + ) return Solar(series, local_file) def read_misc_gen(self, area: Area, series: Optional[pd.DataFrame]) -> MiscGen: series = series if series is not None else pd.DataFrame([]) - local_file = TimeSeriesFile(TimeSeriesFileType.MISC_GEN, self.config.study_path, area.id, series) + local_file = TimeSeriesFile( + TimeSeriesFileType.MISC_GEN, self.config.study_path, area.id, series + ) return MiscGen(series, local_file) def read_hydro( @@ -373,8 +474,7 @@ def read_hydro( return Hydro(self, area_id, local_hydro_properties.yield_hydro_properties()) - def read_area( - self, area_name: str, area_id: str) -> Area: + def read_area(self, area_name: str, area_id: str) -> Area: """ Args: area_name: area to be added to study @@ -395,7 +495,6 @@ def _line_exists_in_file(file_content: str, line_to_add: str) -> bool: """ return line_to_add.strip() in file_content.split("\n") - existing_path = self._config.local_path study_path = existing_path / self.study_name list_ini = IniFile(self.config.study_path, IniFileTypes.AREAS_SETS_INI) diff --git a/src/antares/service/local_services/binding_constraint_local.py b/src/antares/service/local_services/binding_constraint_local.py index e4980f53..dfa6a7ee 100644 --- a/src/antares/service/local_services/binding_constraint_local.py +++ b/src/antares/service/local_services/binding_constraint_local.py @@ -13,7 +13,9 @@ class BindingConstraintLocalService(BaseBindingConstraintService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.config = config self.study_name = study_name @@ -29,27 +31,38 @@ def create_binding_constraint( ) -> BindingConstraint: raise NotImplementedError - def add_constraint_terms(self, constraint: BindingConstraint, terms: List[ConstraintTerm]) -> List[ConstraintTerm]: + def add_constraint_terms( + self, constraint: BindingConstraint, terms: List[ConstraintTerm] + ) -> List[ConstraintTerm]: raise NotImplementedError def delete_binding_constraint_term(self, constraint_id: str, term_id: str) -> None: raise NotImplementedError def update_binding_constraint_properties( - self, binding_constraint: BindingConstraint, properties: BindingConstraintProperties + self, + binding_constraint: BindingConstraint, + properties: BindingConstraintProperties, ) -> BindingConstraintProperties: raise NotImplementedError - def get_constraint_matrix(self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName) -> pd.DataFrame: + def get_constraint_matrix( + self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName + ) -> pd.DataFrame: raise NotImplementedError def update_constraint_matrix( - self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName, matrix: pd.DataFrame + self, + constraint: BindingConstraint, + matrix_name: ConstraintMatrixName, + matrix: pd.DataFrame, ) -> None: raise NotImplementedError def read_binding_constraint( - self, constraint: BindingConstraint, matrix_name: ConstraintMatrixName, matrix: pd.DataFrame + self, + constraint: BindingConstraint, + matrix_name: ConstraintMatrixName, + matrix: pd.DataFrame, ) -> None: raise NotImplementedError - diff --git a/src/antares/service/local_services/link_local.py b/src/antares/service/local_services/link_local.py index 13ca9ad9..e5136fa8 100644 --- a/src/antares/service/local_services/link_local.py +++ b/src/antares/service/local_services/link_local.py @@ -6,13 +6,21 @@ from antares.config.local_configuration import LocalConfiguration from antares.exceptions.exceptions import LinkCreationError, CustomError from antares.model.area import Area -from antares.model.link import LinkProperties, LinkUi, Link, LinkPropertiesLocal, LinkUiLocal +from antares.model.link import ( + LinkProperties, + LinkUi, + Link, + LinkPropertiesLocal, + LinkUiLocal, +) from antares.service.base_services import BaseLinkService from antares.tools.contents_tool import sort_ini_sections class LinkLocalService(BaseLinkService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.config = config self.study_name = study_name @@ -44,16 +52,22 @@ def create_link( if existing_areas is not None: for area in areas.keys(): if area not in existing_areas: - raise LinkCreationError(area_from.name, area_to.name, f"{area} does not exist.") + raise LinkCreationError( + area_from.name, area_to.name, f"{area} does not exist." + ) else: - raise LinkCreationError(area_from.name, area_to.name, "Cannot verify existing areas.") + raise LinkCreationError( + area_from.name, area_to.name, "Cannot verify existing areas." + ) area_from, area_to = areas.values() link_dir = self.config.study_path / "input/links" / area_from.name os.makedirs(link_dir, exist_ok=True) - local_properties = LinkPropertiesLocal(properties) if properties else LinkPropertiesLocal() + local_properties = ( + LinkPropertiesLocal(properties) if properties else LinkPropertiesLocal() + ) local_ui = LinkUiLocal(ui) if ui else LinkUiLocal() properties_ini_file = link_dir / "properties.ini" @@ -65,7 +79,9 @@ def create_link( try: properties_ini.add_section(area_to.name) except configparser.DuplicateSectionError as e: - raise CustomError(f"Link exists already, section already exists in properties.ini:\n\n{e.message}") + raise CustomError( + f"Link exists already, section already exists in properties.ini:\n\n{e.message}" + ) ini_dict = dict(local_properties.ini_fields) ini_dict.update(local_ui.ini_fields) properties_ini[area_to.name] = self.sort_link_properties_dict(ini_dict) @@ -86,7 +102,9 @@ def create_link( def delete_link(self, link: Link) -> None: raise NotImplementedError - def update_link_properties(self, link: Link, properties: LinkProperties) -> LinkProperties: + def update_link_properties( + self, link: Link, properties: LinkProperties + ) -> LinkProperties: raise NotImplementedError def update_link_ui(self, link: Link, ui: LinkUi) -> LinkUi: @@ -110,13 +128,11 @@ def sort_link_properties_dict(ini_dict: Dict[str, str]) -> Dict[str, str]: "filter-synthesis", "filter-year-by-year", ] - return dict(sorted(ini_dict.items(), key=lambda item: dict_order.index(item[0]))) + return dict( + sorted(ini_dict.items(), key=lambda item: dict_order.index(item[0])) + ) - def read_link( - self, - area_from: Area, - area_to: Area - ) -> Link: + def read_link(self, area_from: Area, area_to: Area) -> Link: """ Args: area_from: area where the link goes from @@ -132,4 +148,3 @@ def read_link( LinkCreationError if an area doesn't exist or existing areas have not been provided """ pass - diff --git a/src/antares/service/local_services/renewable_local.py b/src/antares/service/local_services/renewable_local.py index 34b3c408..c2b43322 100644 --- a/src/antares/service/local_services/renewable_local.py +++ b/src/antares/service/local_services/renewable_local.py @@ -8,13 +8,17 @@ class RenewableLocalService(BaseRenewableService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.config = config self.study_name = study_name def update_renewable_properties( - self, renewable_cluster: RenewableCluster, properties: RenewableClusterProperties + self, + renewable_cluster: RenewableCluster, + properties: RenewableClusterProperties, ) -> RenewableClusterProperties: raise NotImplementedError diff --git a/src/antares/service/local_services/st_storage_local.py b/src/antares/service/local_services/st_storage_local.py index c196815a..3293e870 100644 --- a/src/antares/service/local_services/st_storage_local.py +++ b/src/antares/service/local_services/st_storage_local.py @@ -6,7 +6,9 @@ class ShortTermStorageLocalService(BaseShortTermStorageService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.config = config self.study_name = study_name diff --git a/src/antares/service/local_services/study_local.py b/src/antares/service/local_services/study_local.py index 678026c5..37e19302 100644 --- a/src/antares/service/local_services/study_local.py +++ b/src/antares/service/local_services/study_local.py @@ -9,7 +9,9 @@ class StudyLocalService(BaseStudyService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self._config = config self._study_name = study_name @@ -35,20 +37,25 @@ def read_areas(self) -> json: local_path = self._config.local_path patch_path = local_path / self._study_name / "patch.json" if not os.path.exists(patch_path): - return json.loads(f"Le fichier {patch_path} n'existe pas dans le dossier {local_path / self._study_name}") + return json.loads( + f"Le fichier {patch_path} n'existe pas dans le dossier {local_path / self._study_name}" + ) try: - with open(patch_path, 'r') as file: + with open(patch_path, "r") as file: content = file.read() try: data = json.loads(content) except json.JSONDecodeError: - return json.loads(f"Le fichier {patch_path} ne contient pas du JSON valide") + return json.loads( + f"Le fichier {patch_path} ne contient pas du JSON valide" + ) if "areas" in data: areas = data["areas"] if isinstance(areas, dict): return list(areas.keys()) else: - return json.loads(f"The key 'areas' n'existe pas dans le fichier JSON") + return json.loads( + f"The key 'areas' n'existe pas dans le fichier JSON" + ) except IOError: return f"Impossible de lire le fichier {patch_path}" - diff --git a/src/antares/service/local_services/thermal_local.py b/src/antares/service/local_services/thermal_local.py index b1be88c7..25282354 100644 --- a/src/antares/service/local_services/thermal_local.py +++ b/src/antares/service/local_services/thermal_local.py @@ -3,12 +3,18 @@ import pandas as pd from antares.config.local_configuration import LocalConfiguration -from antares.model.thermal import ThermalCluster, ThermalClusterMatrixName, ThermalClusterProperties +from antares.model.thermal import ( + ThermalCluster, + ThermalClusterMatrixName, + ThermalClusterProperties, +) from antares.service.base_services import BaseThermalService class ThermalLocalService(BaseThermalService): - def __init__(self, config: LocalConfiguration, study_name: str, **kwargs: Any) -> None: + def __init__( + self, config: LocalConfiguration, study_name: str, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.config = config self.study_name = study_name @@ -18,5 +24,7 @@ def update_thermal_properties( ) -> ThermalClusterProperties: raise NotImplementedError - def get_thermal_matrix(self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName) -> pd.DataFrame: + def get_thermal_matrix( + self, thermal_cluster: ThermalCluster, ts_name: ThermalClusterMatrixName + ) -> pd.DataFrame: raise NotImplementedError diff --git a/src/antares/service/service_factory.py b/src/antares/service/service_factory.py index e11791c3..2e50bd1c 100644 --- a/src/antares/service/service_factory.py +++ b/src/antares/service/service_factory.py @@ -14,7 +14,9 @@ from antares.config.base_configuration import BaseConfiguration from antares.config.local_configuration import LocalConfiguration from antares.service.api_services.area_api import AreaApiService -from antares.service.api_services.binding_constraint_api import BindingConstraintApiService +from antares.service.api_services.binding_constraint_api import ( + BindingConstraintApiService, +) from antares.service.api_services.link_api import LinkApiService from antares.service.api_services.renewable_api import RenewableApiService from antares.service.api_services.st_storage_api import ShortTermStorageApiService @@ -30,7 +32,9 @@ BaseShortTermStorageService, ) from antares.service.local_services.area_local import AreaLocalService -from antares.service.local_services.binding_constraint_local import BindingConstraintLocalService +from antares.service.local_services.binding_constraint_local import ( + BindingConstraintLocalService, +) from antares.service.local_services.link_local import LinkLocalService from antares.service.local_services.renewable_local import RenewableLocalService from antares.service.local_services.st_storage_local import ShortTermStorageLocalService @@ -41,7 +45,9 @@ class ServiceFactory: - def __init__(self, config: BaseConfiguration, study_id: str = "", study_name: str = ""): + def __init__( + self, config: BaseConfiguration, study_id: str = "", study_name: str = "" + ): self.config = config self.study_id = study_id self.study_name = study_name @@ -49,9 +55,15 @@ def __init__(self, config: BaseConfiguration, study_id: str = "", study_name: st def create_area_service(self) -> BaseAreaService: if isinstance(self.config, APIconf): area_service: BaseAreaService = AreaApiService(self.config, self.study_id) - storage_service: BaseShortTermStorageService = ShortTermStorageApiService(self.config, self.study_id) - thermal_service: BaseThermalService = ThermalApiService(self.config, self.study_id) - renewable_service: BaseRenewableService = RenewableApiService(self.config, self.study_id) + storage_service: BaseShortTermStorageService = ShortTermStorageApiService( + self.config, self.study_id + ) + thermal_service: BaseThermalService = ThermalApiService( + self.config, self.study_id + ) + renewable_service: BaseRenewableService = RenewableApiService( + self.config, self.study_id + ) area_service.set_storage_service(storage_service) area_service.set_thermal_service(thermal_service) area_service.set_renewable_service(renewable_service) @@ -78,7 +90,9 @@ def create_link_service(self) -> BaseLinkService: def create_thermal_service(self) -> BaseThermalService: if isinstance(self.config, APIconf): - thermal_service: BaseThermalService = ThermalApiService(self.config, self.study_id) + thermal_service: BaseThermalService = ThermalApiService( + self.config, self.study_id + ) elif isinstance(self.config, LocalConfiguration): thermal_service = ThermalLocalService(self.config, self.study_name) else: @@ -87,18 +101,22 @@ def create_thermal_service(self) -> BaseThermalService: def create_binding_constraints_service(self) -> BaseBindingConstraintService: if isinstance(self.config, APIconf): - binding_constraint_service: BaseBindingConstraintService = BindingConstraintApiService( - self.config, self.study_id + binding_constraint_service: BaseBindingConstraintService = ( + BindingConstraintApiService(self.config, self.study_id) ) elif isinstance(self.config, LocalConfiguration): - binding_constraint_service = BindingConstraintLocalService(self.config, self.study_name) + binding_constraint_service = BindingConstraintLocalService( + self.config, self.study_name + ) else: raise TypeError(f"{ERROR_MESSAGE}{repr(self.config)}") return binding_constraint_service def create_study_service(self) -> BaseStudyService: if isinstance(self.config, APIconf): - study_service: BaseStudyService = StudyApiService(self.config, self.study_id) + study_service: BaseStudyService = StudyApiService( + self.config, self.study_id + ) elif isinstance(self.config, LocalConfiguration): study_service = StudyLocalService(self.config, self.study_name) else: @@ -107,7 +125,9 @@ def create_study_service(self) -> BaseStudyService: def create_renewable_service(self) -> BaseRenewableService: if isinstance(self.config, APIconf): - renewable_service: BaseRenewableService = RenewableApiService(self.config, self.study_id) + renewable_service: BaseRenewableService = RenewableApiService( + self.config, self.study_id + ) elif isinstance(self.config, LocalConfiguration): renewable_service = RenewableLocalService(self.config, self.study_name) else: @@ -116,18 +136,22 @@ def create_renewable_service(self) -> BaseRenewableService: def create_st_storage_service(self) -> BaseShortTermStorageService: if isinstance(self.config, APIconf): - short_term_storage_service: BaseShortTermStorageService = ShortTermStorageApiService( - self.config, self.study_id + short_term_storage_service: BaseShortTermStorageService = ( + ShortTermStorageApiService(self.config, self.study_id) ) elif isinstance(self.config, LocalConfiguration): - short_term_storage_service = ShortTermStorageLocalService(self.config, self.study_name) + short_term_storage_service = ShortTermStorageLocalService( + self.config, self.study_name + ) else: raise TypeError(f"{ERROR_MESSAGE}{repr(self.config)}") return short_term_storage_service class ServiceReader: - def __init__(self, config: BaseConfiguration, study_name: str = "", study_id: str = ""): + def __init__( + self, config: BaseConfiguration, study_name: str = "", study_id: str = "" + ): self.config = config self.study_id = study_id self.study_name = study_name @@ -135,13 +159,17 @@ def __init__(self, config: BaseConfiguration, study_name: str = "", study_id: st self._binding_constraints = [] self._links = [] -# we can have read area service here, for just one area + # we can have read area service here, for just one area def read_study_service(self) -> BaseStudyService: if isinstance(self.config, LocalConfiguration): - study_service: BaseStudyService = StudyLocalService(self.config, self.study_name) + study_service: BaseStudyService = StudyLocalService( + self.config, self.study_name + ) areas = study_service.read_areas() for area_name in range(areas): - area_service: BaseStudyService = AreaLocalService(self.config, self.study_name) + area_service: BaseStudyService = AreaLocalService( + self.config, self.study_name + ) area = area_service.read_area(area_name) self._areas[area.id] = area @@ -155,4 +183,3 @@ def read_study_service(self) -> BaseStudyService: raise TypeError(f"{ERROR_MESSAGE}{repr(self.config)}") return areas - diff --git a/src/antares/tools/contents_tool.py b/src/antares/tools/contents_tool.py index c2c3cd91..7be58d0e 100644 --- a/src/antares/tools/contents_tool.py +++ b/src/antares/tools/contents_tool.py @@ -117,7 +117,9 @@ def to_craft(self) -> Dict[str, Any]: # TODO maybe put sorting functions together -def sort_ini_sections(ini_to_sort: configparser.ConfigParser) -> configparser.ConfigParser: +def sort_ini_sections( + ini_to_sort: configparser.ConfigParser, +) -> configparser.ConfigParser: sorted_ini = configparser.ConfigParser() for section in sorted(ini_to_sort.sections()): sorted_ini[section] = ini_to_sort[section] diff --git a/src/antares/tools/ini_tool.py b/src/antares/tools/ini_tool.py index 78991f7d..1e313671 100644 --- a/src/antares/tools/ini_tool.py +++ b/src/antares/tools/ini_tool.py @@ -49,7 +49,9 @@ def __init__( ini_contents: Optional[ConfigParser] = None, ) -> None: if "{area_name}" in ini_file_type.value and not area_name: - raise ValueError(f"Area name not provided, ini type {ini_file_type.name} requires 'area_name'") + raise ValueError( + f"Area name not provided, ini type {ini_file_type.name} requires 'area_name'" + ) self._full_path = study_path / ( ini_file_type.value.format(area_name=area_name) if ("{area_name}" in ini_file_type.value and area_name) @@ -66,7 +68,10 @@ def __init__( @property def ini_dict(self) -> dict: """Ini contents as a python dictionary""" - return {section: dict(self._ini_contents[section]) for section in self._ini_contents.sections()} + return { + section: dict(self._ini_contents[section]) + for section in self._ini_contents.sections() + } @ini_dict.setter def ini_dict(self, new_ini_dict: dict[str, dict[str, str]]) -> None: @@ -119,8 +124,16 @@ def write_ini_file( ) -> None: if not self._file_path.is_dir(): self._file_path.mkdir(parents=True) - ini_to_write = self._ini_contents if not sort_sections else self._sort_ini_sections(self._ini_contents) - ini_to_write = ini_to_write if not sort_section_content else self._sort_ini_section_content(ini_to_write) + ini_to_write = ( + self._ini_contents + if not sort_sections + else self._sort_ini_sections(self._ini_contents) + ) + ini_to_write = ( + ini_to_write + if not sort_section_content + else self._sort_ini_section_content(ini_to_write) + ) with self._full_path.open("w") as file: ini_to_write.write(file) @@ -136,7 +149,10 @@ def _sort_ini_sections(ini_to_sort: ConfigParser) -> ConfigParser: def _sort_ini_section_content(ini_to_sort: ConfigParser) -> ConfigParser: sorted_ini = ConfigParser() for section in ini_to_sort.sections(): - sorted_ini[section] = {key: value for (key, value) in sorted(list(ini_to_sort[section].items()))} + sorted_ini[section] = { + key: value + for (key, value) in sorted(list(ini_to_sort[section].items())) + } return sorted_ini diff --git a/src/antares/tools/time_series_tool.py b/src/antares/tools/time_series_tool.py index ea2ebb9c..605ffa2c 100644 --- a/src/antares/tools/time_series_tool.py +++ b/src/antares/tools/time_series_tool.py @@ -59,15 +59,23 @@ def __init__( raise ValueError("area_id is required for this file type.") self.file_path = study_path / ( - ts_file_type.value if not area_id else ts_file_type.value.format(area_id=area_id) + ts_file_type.value + if not area_id + else ts_file_type.value.format(area_id=area_id) ) if self.file_path.is_file() and time_series is not None: - raise ValueError(f"File {self.file_path} already exists and a time series was provided.") + raise ValueError( + f"File {self.file_path} already exists and a time series was provided." + ) elif self.file_path.is_file() and time_series is None: - self._time_series = pd.read_csv(self.file_path, sep="\t", header=None, index_col=None, encoding="utf-8") + self._time_series = pd.read_csv( + self.file_path, sep="\t", header=None, index_col=None, encoding="utf-8" + ) else: - self._time_series = time_series if time_series is not None else pd.DataFrame([]) + self._time_series = ( + time_series if time_series is not None else pd.DataFrame([]) + ) self._write_file() @property @@ -81,7 +89,9 @@ def time_series(self, time_series: pd.DataFrame) -> None: def _write_file(self) -> None: self.file_path.parent.mkdir(parents=True, exist_ok=True) - self._time_series.to_csv(self.file_path, sep="\t", header=False, index=False, encoding="utf-8") + self._time_series.to_csv( + self.file_path, sep="\t", header=False, index=False, encoding="utf-8" + ) class TimeSeries: @@ -90,7 +100,9 @@ class TimeSeries: """ def __init__( - self, time_series: pd.DataFrame = pd.DataFrame([]), local_file: Optional[TimeSeriesFile] = None + self, + time_series: pd.DataFrame = pd.DataFrame([]), + local_file: Optional[TimeSeriesFile] = None, ) -> None: self._time_series = time_series self._local_file = local_file