From 918489427f40334beed5806c275859204d44c397 Mon Sep 17 00:00:00 2001 From: Vasu Jaganath Date: Wed, 31 Jul 2024 22:23:14 -0400 Subject: [PATCH 1/2] remove old config when building pypi package --- .github/workflows/test_and_publish_pypi.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_and_publish_pypi.yml b/.github/workflows/test_and_publish_pypi.yml index 27e5a154..9291d414 100644 --- a/.github/workflows/test_and_publish_pypi.yml +++ b/.github/workflows/test_and_publish_pypi.yml @@ -19,6 +19,10 @@ jobs: with: python-version: 3.9 + - name: Remove old global config + if: always() + run: rm -rf "/home/$(whoami)/wic/" && rm -rf "/home/$(whoami)/.toil/" + - name: Install sophios 🔧 run: | pip install .[test] @@ -32,7 +36,7 @@ jobs: python -m pip install twine build python -m build --wheel python -m build --sdist - + - name: Upload Artifact uses: actions/upload-artifact@v3 with: From e9ae10a0689ea348956f8453653b8b66d046b5ec Mon Sep 17 00:00:00 2001 From: Vasu Jaganath Date: Wed, 31 Jul 2024 22:33:55 -0400 Subject: [PATCH 2/2] init sophios from first run from any folder --- src/sophios/config_basic.json | 25 +++++++++++ src/sophios/input_output.py | 80 +++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 src/sophios/config_basic.json diff --git a/src/sophios/config_basic.json b/src/sophios/config_basic.json new file mode 100644 index 00000000..1af43dd3 --- /dev/null +++ b/src/sophios/config_basic.json @@ -0,0 +1,25 @@ +{ + "search_paths_cwl": { + "global": [ + "wic/cwl_adapters" + ], + "gpu": [ + ] + }, + "search_paths_wic": { + "global": [ + "wic/examples" + ] + }, + "renaming_conventions": [ + ["energy_", "edr_"], + ["structure_", "tpr_"], + ["traj_", "trr_"] + ], + "inference_rules": { + "edam:format_3881": "continue", + "edam:format_3987": "continue", + "edam:format_3878": "break", + "edam:format_2033": "break" + } +} \ No newline at end of file diff --git a/src/sophios/input_output.py b/src/sophios/input_output.py index 45137ba1..7c9c6852 100644 --- a/src/sophios/input_output.py +++ b/src/sophios/input_output.py @@ -1,5 +1,6 @@ import argparse import copy +from shutil import copytree, ignore_patterns import json from pathlib import Path import sys @@ -151,16 +152,26 @@ def get_config(config_file: Path, default_config_file: Path) -> Json: Json: The config json object with absolute filepaths """ global_config: Json = {} + proj_root_dir = 'workflow-inference-compiler' if not config_file.exists(): - if config_file == default_config_file: - global_config = get_default_config() - # write the default config object to the 'global_config.json' file in user's ~/wic directory + # check if sophios is run from 'project root' dir + if str(Path.cwd()).endswith(proj_root_dir): + if config_file == default_config_file: + global_config = get_default_config() + # write the default config object to the 'global_config.json' file in user's ~/wic directory + # for user to inspect and or modify the config json file + write_config_to_disk(global_config, default_config_file) + print(f'default config file : {default_config_file} generated') + else: + print(f"Error user specified config file {config_file} doesn't exist") + sys.exit() + else: + global_config = get_basic_config() + # write the basic config object to the 'global_config.json' file in user's ~/wic directory # for user to inspect and or modify the config json file write_config_to_disk(global_config, default_config_file) + move_adapters_and_examples(global_config) print(f'default config file : {default_config_file} generated') - else: - print(f"Error user specified config file {config_file} doesn't exist") - sys.exit() else: # reading user specified config file only if it exists # never overwrite user's config file or generate another file in user's non-default directory @@ -169,7 +180,25 @@ def get_config(config_file: Path, default_config_file: Path) -> Json: return global_config -def read_config_from_disk(config_file: Path) -> Json: +def move_adapters_and_examples(config: Json) -> None: + """Copies all the adapters and examples into the given search paths + + Args: + config (Json): Json containing search path information + """ + adapters_dir = Path(__file__).parent.parent.parent / 'cwl_adapters' + examples_dir = Path(__file__).parent.parent.parent / 'docs' / 'tutorials' + + extlist = ['*.png', '*.md', '*.rst', '*.pyc', '__pycache__', '*.json'] + # the default search paths will be the first entry in the 'global' namespace + # but we also want to preserve the ability of the users to add more search paths + # so we keep the namespace tag as a list of paths rather than a single path + copytree(adapters_dir, Path(config['search_paths_cwl']['global'][0])) + copytree(examples_dir, Path(config['search_paths_wic']['global'][0]), + ignore=ignore_patterns(*extlist)) + + +def read_config_from_disk(config_file: Path, abspath: bool = True) -> Json: """Returns the config json object from config_file with absolute paths Args: @@ -184,7 +213,10 @@ def read_config_from_disk(config_file: Path) -> Json: config = json.load(f) conf_tags = ['search_paths_cwl', 'search_paths_wic'] for tag in conf_tags: - config[tag] = get_absolute_paths(config[tag]) + if abspath: + config[tag] = get_absolute_paths(config[tag]) + else: # this is a hacky way to fix global paths wrt ~/home/wic/ + config[tag] = get_home_paths(config[tag]) return config @@ -196,12 +228,26 @@ def get_default_config() -> Json: """ src_dir = Path(__file__).parent default_config: Json = {} - # config.json can contain absolute or relative paths # read_config_from_disk handles converting them to absolute paths default_config = read_config_from_disk(src_dir/'config.json') return default_config +def get_basic_config() -> Json: + """Returns the (default) basic config with absolute paths + + Returns: + Json: The config json object with absolute filepaths + """ + # basic config doesn't contain mm-workflows or other + # domain cwl or wic files search paths + src_dir = Path(__file__).parent + basic_config: Json = {} + # read_config_from_disk handles converting them to absolute paths + basic_config = read_config_from_disk(src_dir/'config_basic.json', False) + return basic_config + + def get_absolute_paths(sub_config: Json) -> Json: """Update the paths within the sub_config json object as absolute paths @@ -218,6 +264,22 @@ def get_absolute_paths(sub_config: Json) -> Json: return abs_sub_config +def get_home_paths(sub_config: Json) -> Json: + """Update the paths within the sub_config json object as absolute paths + + Args: + sub_config (dict): The json (sub)object where filepaths are stored + + Returns: + Json: The json (sub)object with absolute filepaths + """ + abs_sub_config = copy.deepcopy(sub_config) + for ns in abs_sub_config: + abs_paths = [str(Path.home() / path) for path in abs_sub_config[ns]] + abs_sub_config[ns] = abs_paths + return abs_sub_config + + def write_absolute_yaml_tags(args: argparse.Namespace, in_dict_in: Yaml, namespaces: Namespaces, step_name_i: str, explicit_edge_calls_copy: ExplicitEdgeCalls) -> None: """cwl_subinterpreter requires all paths to be absolute.