Skip to content

Commit

Permalink
v1.3.1
Browse files Browse the repository at this point in the history
Release v1.3.1 on main
  • Loading branch information
laurent-laporte-pro authored Sep 26, 2023
2 parents 2f6392d + 26082e2 commit 516f94d
Show file tree
Hide file tree
Showing 94 changed files with 20,581 additions and 3,473 deletions.
51 changes: 51 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
# Changelog

<!--
This change log can be generated with [`auto-changelog`](https://github.com/CookPete/auto-changelog), for instance :
```shell
npx auto-changelog -l false --hide-empty-releases -v v1.3.1 -o CHANGES.out.md
```
-->

## [1.3.1] - 2023-09-26

### Changed

- feat(database): simplify launcher database implementation [`#66`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/66)
- feat(cli): add the `--solver-version` option to the command line [`#63`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/63)
- feat(parameters): handle the `--partition` and `--qos` parameters for the `sbatch` command [`#58`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/58)
- feat(retrival): correct the retrival of remote files and improve exception handling to avoid infinite loops [`88efc98`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/88efc98af6a8fd494f07cc9a366a52109eb3ac2d)
- feat(zip-extractor): the uncompress directory is calculated according to the content: study directory or simulation output [`1ffc86e`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/1ffc86e0439814e4549f59c193731c71080c0d59)

### Fixes

- fix(cli): preserve backward compatibility in CLI options [`#65`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/65)
- fix(job-state): consider the `COMPLETING` value as a possible job state [`#61`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/61)
- fix(results-retrieval): handle exceptions in log and ZIP result retrival [`#60`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/60)
- fix(console): use the ISO8601 date format to display messages on the console [`0dbf971`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/0dbf971b1ccc924f4b11cf44b0e0cf16562622c9)

### Refactorings

- refactor: remove `IDisplay` abstract class [`#64`](https://github.com/AntaresSimulatorTeam/antares-launcher/pull/64)
- refactor(launch-controller): simplification of the `LaunchController` class [`4c07551`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/4c07551ae8acf15d784553e7877b9017626b306b)
- refactor(file-manager): remove unused or trivial methods from `FileManager` [`fbb60e0`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/fbb60e0efca6989e7ea79324ed746b55da3cfb3d)
- refactoring(file-manager): drop the `FileManager` class [`9797799`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/9797799df6bf4fd626ea1bc997d11503989d5b94)
- refactoring(tree-structure): drop the `TreeStructureInitializer` class [`8a119af`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/8a119afb06d64f0ccd1e112ef82367f8fdee7ce0)
- refactoring(data-provider): drop the `DataProvider` class [`272965e`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/272965ed618f94ecf0de718bf7e8e0788c4bbb3a)

### Code Style

- style: reformat source code using iSort and Black [`e243fba`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/e243fbab177c46ffc867440b3701d7672566066c)

### Chore

- chore(typing): improve the typing of study parameters [`f11641d`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/f11641d4d233d61f91b9cbebf6263780ff14eb88)
- chore(typing): improve typing in source code [`4ff6abf`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/4ff6abf512b03944d0132d868484ef2d677c8b77)
- chore: replace `COMPETING` with `COMPLETING` (typo) [`e98b7a8`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/e98b7a8627b09a883e48a9b4b883f6b1560da0e9)

### Tests

- test: correct the test fixtures for study retrival [`6f78bd6`](https://github.com/AntaresSimulatorTeam/antares-launcher/commit/6f78bd62a5f7c6b61a6fcb4a9a42c7710e986301)


## [1.3.0] - 2023-06-16

### Changed
Expand Down Expand Up @@ -95,6 +144,8 @@
- Remove unnecessary Optional
- Enable ssh_config_file to be `None`

[1.3.1]: https://github.com/AntaresSimulatorTeam/antares-launcher/releases/tag/v1.3.1

[1.3.0]: https://github.com/AntaresSimulatorTeam/antares-launcher/releases/tag/v1.3.0

[1.2.4]: https://github.com/AntaresSimulatorTeam/antares-launcher/releases/tag/v1.2.4
Expand Down
6 changes: 3 additions & 3 deletions antareslauncher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@

# Standard project metadata

__version__ = "1.3.0"
__version__ = "1.3.1"
__author__ = "RTE, Antares Web Team"
__date__ = "2023-06-16"
__date__ = "2023-09-26"
# noinspection SpellCheckingInspection
__credits__ = "(c) Réseau de Transport de l’Électricité (RTE)"

# Extra project metadata
__project_name__ = "Antares_Launcher"


def _check_metadata():
def _check_metadata() -> None:
# noinspection SpellCheckingInspection
"""
Check the project metadata.
Expand Down
16 changes: 13 additions & 3 deletions antareslauncher/advanced_launch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from pathlib import Path

from antareslauncher.config import Config, get_config_path
Expand All @@ -6,7 +7,7 @@
from antareslauncher.parameters_reader import ParametersReader


def main():
def main() -> None:
config_path: Path = get_config_path()
config = Config.load_config(config_path)
param_reader = ParametersReader(
Expand All @@ -15,8 +16,17 @@ def main():
)
parser_parameters: ParserParameters = param_reader.get_parser_parameters()
parser: MainOptionParser = MainOptionParser(parser_parameters)
parser.add_basic_arguments().add_advanced_arguments()
arguments = parser.parse_args()
parser.add_basic_arguments(antares_versions=param_reader.antares_versions)
ssh_config_required = parser_parameters.ssh_config_file_is_required
alt_ssh_paths = [
parser_parameters.ssh_configfile_path_alternate1,
parser_parameters.ssh_configfile_path_alternate1,
]
parser.add_advanced_arguments(
ssh_config_required=ssh_config_required,
alt_ssh_paths=alt_ssh_paths,
)
arguments = parser.parser.parse_args(sys.argv[1:])
main_parameters: MainParameters = param_reader.get_main_parameters()
run_with(arguments=arguments, parameters=main_parameters, show_banner=True)

Expand Down
24 changes: 7 additions & 17 deletions antareslauncher/antares_launcher.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
from dataclasses import dataclass
from typing import Optional

from antareslauncher.use_cases.check_remote_queue.check_queue_controller import (
CheckQueueController,
)
from antareslauncher.use_cases.create_list.study_list_composer import (
StudyListComposer,
)
from antareslauncher.use_cases.kill_job.job_kill_controller import (
JobKillController,
)
from antareslauncher.use_cases.check_remote_queue.check_queue_controller import CheckQueueController
from antareslauncher.use_cases.create_list.study_list_composer import StudyListComposer
from antareslauncher.use_cases.kill_job.job_kill_controller import JobKillController
from antareslauncher.use_cases.launch.launch_controller import LaunchController
from antareslauncher.use_cases.retrieve.retrieve_controller import (
RetrieveController,
)
from antareslauncher.use_cases.wait_loop_controller.wait_controller import (
WaitController,
)
from antareslauncher.use_cases.retrieve.retrieve_controller import RetrieveController
from antareslauncher.use_cases.wait_loop_controller.wait_controller import WaitController


@dataclass
Expand All @@ -29,7 +19,7 @@ class AntaresLauncher:
wait_controller: WaitController
wait_mode: bool
wait_time: int
xpansion_mode: Optional[str]
xpansion_mode: str
check_queue_bool: bool
job_id_to_kill: Optional[int] = None

Expand All @@ -47,7 +37,7 @@ def run_once_mode(self):
def run_wait_mode(self):
"""Run antares_launcher once then it keeps
checking the status of the unfinished jobs until all jobs are finished,
The code exit when all job are finished the the results are retrieved and extracted
The code exits when all jobs are finished, the results are retrieved and extracted
"""
self.run_once_mode()
while not self.retrieve_controller.all_studies_done:
Expand Down
7 changes: 4 additions & 3 deletions antareslauncher/basic_launch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
from pathlib import Path

from antareslauncher.config import Config, get_config_path
Expand All @@ -6,7 +7,7 @@
from antareslauncher.parameters_reader import ParametersReader


def main():
def main() -> None:
config_path: Path = get_config_path()
config = Config.load_config(config_path)
param_reader = ParametersReader(
Expand All @@ -15,8 +16,8 @@ def main():
)
parser_parameters: ParserParameters = param_reader.get_parser_parameters()
parser: MainOptionParser = MainOptionParser(parser_parameters)
parser.add_basic_arguments()
arguments = parser.parse_args()
parser.add_basic_arguments(antares_versions=param_reader.antares_versions)
arguments = parser.parser.parse_args(sys.argv[1:])
main_parameters: MainParameters = param_reader.get_main_parameters()
run_with(arguments=arguments, parameters=main_parameters, show_banner=True)

Expand Down
29 changes: 7 additions & 22 deletions antareslauncher/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@
import yaml

from antareslauncher import __author__, __project_name__, __version__
from antareslauncher.exceptions import (
InvalidConfigValueError,
UnknownFileSuffixError,
ConfigFileNotFoundError,
)
from antareslauncher.exceptions import ConfigFileNotFoundError, InvalidConfigValueError, UnknownFileSuffixError

APP_NAME = __project_name__
APP_AUTHOR = __author__.split(",")[0]
Expand Down Expand Up @@ -119,9 +115,7 @@ def load_config(cls, ssh_config_path: pathlib.Path) -> "SSHConfig":
obj = parse_config(ssh_config_path)
kwargs = {k.lower(): v for k, v in obj.items()}
private_key_file = kwargs.pop("private_key_file", None)
kwargs["private_key_file"] = (
None if private_key_file is None else pathlib.Path(private_key_file)
)
kwargs["private_key_file"] = None if private_key_file is None else pathlib.Path(private_key_file)
try:
return cls(config_path=ssh_config_path, **kwargs)
except TypeError as exc:
Expand All @@ -139,11 +133,7 @@ def save_config(self, ssh_config_path: pathlib.Path) -> None:
"""
obj = dataclasses.asdict(self)
del obj["config_path"]
obj = {
k: v
for k, v in obj.items()
if v or k not in {"private_key_file", "key_password", "password"}
}
obj = {k: v for k, v in obj.items() if v or k not in {"private_key_file", "key_password", "password"}}
if "private_key_file" in obj:
obj["private_key_file"] = obj["private_key_file"].as_posix()
dump_config(ssh_config_path, obj)
Expand Down Expand Up @@ -212,9 +202,7 @@ def load_config(cls, config_path: pathlib.Path) -> "Config":
obj = parse_config(config_path)
kwargs = {k.lower(): v for k, v in obj.items()}
try:
kwargs["remote_solver_versions"] = kwargs.pop(
"antares_versions_on_remote_server"
)
kwargs["remote_solver_versions"] = kwargs.pop("antares_versions_on_remote_server")
# handle paths
for key in [
"log_dir",
Expand All @@ -226,9 +214,7 @@ def load_config(cls, config_path: pathlib.Path) -> "Config":
kwargs[key] = pathlib.Path(kwargs[key])
ssh_configfile_name = kwargs.pop("default_ssh_configfile_name")
except KeyError as exc:
raise InvalidConfigValueError(
config_path, f"missing parameter '{exc}'"
) from None
raise InvalidConfigValueError(config_path, f"missing parameter '{exc}'") from None
# handle SSH configuration
config_dir = config_path.parent
ssh_config_path = config_dir.joinpath(ssh_configfile_name)
Expand Down Expand Up @@ -286,10 +272,9 @@ def get_user_config_dir(system: str = ""):
"""
username = getpass.getuser()
system = system or sys.platform
config_dir: pathlib.Path
if system == "win32":
config_dir = pathlib.WindowsPath(
rf"C:\Users\{username}\AppData\Local\{APP_AUTHOR}"
)
config_dir = pathlib.WindowsPath(rf"C:\Users\{username}\AppData\Local\{APP_AUTHOR}")
elif system == "darwin":
config_dir = pathlib.PosixPath("~/Library/Preferences").expanduser()
else:
Expand Down
11 changes: 0 additions & 11 deletions antareslauncher/data_repo/data_provider.py

This file was deleted.

73 changes: 42 additions & 31 deletions antareslauncher/data_repo/data_repo_tinydb.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
import logging
from typing import List
import typing as t

import tinydb
from antareslauncher.data_repo.idata_repo import IDataRepo
from antareslauncher.study_dto import StudyDTO
from tinydb import TinyDB, where

from antareslauncher.study_dto import StudyDTO

class DataRepoTinydb(IDataRepo):
logger = logging.getLogger(__name__)


def _calc_diff(
old: t.Mapping[str, t.Any],
new: t.Mapping[str, t.Any],
) -> t.Mapping[str, t.Any]:
old_keys = frozenset(old)
new_keys = frozenset(new)
diff_map = {
"DEL": {k: old[k] for k in old_keys - new_keys},
"ADD": {k: new[k] for k in new_keys - old_keys},
"UPD": {
k: f"{old[k]!r} => {new[k]!r}"
for k in old_keys & new_keys
if old[k] != new[k]
},
}
diff_map = {k: v for k, v in diff_map.items() if v}
return diff_map


class DataRepoTinydb:
def __init__(self, database_file_path, db_primary_key: str):
super(DataRepoTinydb, self).__init__()
self.database_file_path = database_file_path
self.logger = logging.getLogger(f"{__name__}.{__class__.__name__}")
self.db_primary_key = db_primary_key

@property
def db(self) -> tinydb.database.TinyDB:
return TinyDB(self.database_file_path, sort_keys=True, indent=4)

@staticmethod
def doc_to_study(doc: tinydb.database.Document):
"""Create a studyDTO from a tinydb.database.Document
Args:
doc: Document representing a study
Returns:
studyDTO object
"""
study = StudyDTO(path="empty/path")
study.__dict__ = doc
return study
if not hasattr(self, "_tiny_db"):
db = tinydb.TinyDB(self.database_file_path, sort_keys=True, indent=4)
setattr(self, "_tiny_db", db)
return getattr(self, "_tiny_db")

def is_study_inside_database(self, study: StudyDTO) -> bool:
"""Get the study with selected primary key from the database
Expand All @@ -43,7 +51,7 @@ def is_study_inside_database(self, study: StudyDTO) -> bool:
"""
pk_name = self.db_primary_key
pk_value = getattr(study, pk_name)
found_studies = self.db.search(where(key=pk_name) == pk_value)
found_studies = self.db.search(tinydb.where(key=pk_name) == pk_value)
return len(found_studies) == 1

def is_job_id_inside_database(self, job_id: int):
Expand All @@ -58,12 +66,12 @@ def is_job_id_inside_database(self, job_id: int):
studies_list = self.get_list_of_studies()
return any(study.job_id == job_id for study in studies_list)

def get_list_of_studies(self) -> List[StudyDTO]:
def get_list_of_studies(self) -> t.Sequence[StudyDTO]:
"""
Returns:
List of all studies inside the database
"""
return [self.doc_to_study(doc) for doc in self.db.all()]
return [StudyDTO.from_dict(doc) for doc in self.db.all()]

def save_study(self, study: StudyDTO):
"""Saves the selected study inside the database. If the study already exists inside the
Expand All @@ -74,14 +82,17 @@ def save_study(self, study: StudyDTO):
"""
pk_name = self.db_primary_key
pk_value = getattr(study, pk_name)
if self.is_study_inside_database(study=study):
self.logger.info(f"Updating study {pk_name}='{pk_value}' in database")
self.db.update(study.__dict__, where(pk_name) == pk_value)
old = self.db.get(tinydb.where(pk_name) == pk_value)
new = vars(study)
if old:
diff = _calc_diff(old, new)
logger.info(f"Updating study '{pk_value}' in database: {diff!r}")
self.db.update(new, tinydb.where(pk_name) == pk_value)
else:
self.logger.info(f"Inserting new study {pk_name}='{pk_value}' in database")
self.db.insert(study.__dict__)
logger.info(f"Inserting study '{pk_value}' in database: {new!r}")
self.db.insert(new)

def remove_study(self, study_name: str) -> None:
pk_name = self.db_primary_key
self.logger.info(f"Removing study {pk_name}='{study_name}' from database")
self.db.remove(where(pk_name) == study_name)
logger.info(f"Removing study '{study_name}' from database")
self.db.remove(tinydb.where(pk_name) == study_name)
Loading

0 comments on commit 516f94d

Please sign in to comment.