Skip to content

Commit 85fe915

Browse files
author
Vasu Jaganath
committed
remove args from core sophios 3/3
1 parent 6907bff commit 85fe915

File tree

8 files changed

+257
-81
lines changed

8 files changed

+257
-81
lines changed

src/sophios/apis/python/api.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,30 @@ def compile(self, write_to_disk: bool = False) -> CompilerInfo:
720720
steps_config = extract_tools_paths_NONPORTABLE(self.flatten_steps())
721721
global_config = merge(steps_config, global_config, strategy=Strategy.TYPESAFE_REPLACE)
722722

723+
# core compiler options for transformation into CWL
724+
compiler_options: Dict[str, bool] = {}
725+
compiler_options['partial_failure_enable'] = args.partial_failure_enable
726+
compiler_options['inference_use_naming_conventions'] = args.inference_use_naming_conventions
727+
compiler_options['insert_steps_automatically'] = args.insert_steps_automatically
728+
compiler_options['inference_disable'] = args.inference_disable
729+
compiler_options['allow_raw_cwl'] = args.allow_raw_cwl
730+
731+
# to be given to graph util functions
732+
graph_settings: Dict[str, Any] = {}
733+
graph_settings['graph_dark_theme'] = args.graph_dark_theme
734+
graph_settings['graph_inline_depth'] = args.graph_inline_depth
735+
graph_settings['graph_label_edges'] = args.graph_label_edges
736+
graph_settings['graph_show_outputs'] = args.graph_show_outputs
737+
738+
# to be given to io absolute_yaml_tags function
739+
yaml_tag_paths: Dict[str, str] = {}
740+
yaml_tag_paths['cachedir'] = args.cachedir
741+
yaml_tag_paths['yaml'] = args.yaml
742+
yaml_tag_paths['homedir'] = args.homedir
743+
723744
# The compile_workflow function is 100% in-memory
724-
compiler_info = compiler.compile_workflow(yaml_tree, args, [], [graph], {}, {}, {}, {},
745+
compiler_info = compiler.compile_workflow(yaml_tree, compiler_options, graph_settings, yaml_tag_paths,
746+
[], [graph], {}, {}, {}, {},
725747
global_config, True, relative_run_path=True, testing=False)
726748

727749
if write_to_disk:

src/sophios/apis/rest/api.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pathlib import Path
22
import copy
33
import yaml
4+
from typing import Dict, Any
45

56

67
import uvicorn
@@ -111,8 +112,30 @@ async def compile_wf(request: Request) -> Json:
111112
graph = get_graph_reps(wkflw_name)
112113
yaml_tree: YamlTree = YamlTree(StepId(wkflw_name, plugin_ns), workflow_can)
113114

115+
# core compiler options for transformation into CWL
116+
compiler_options: Dict[str, bool] = {}
117+
compiler_options['partial_failure_enable'] = args.partial_failure_enable
118+
compiler_options['inference_use_naming_conventions'] = args.inference_use_naming_conventions
119+
compiler_options['insert_steps_automatically'] = args.insert_steps_automatically
120+
compiler_options['inference_disable'] = args.inference_disable
121+
compiler_options['allow_raw_cwl'] = args.allow_raw_cwl
122+
123+
# to be given to graph util functions
124+
graph_settings: Dict[str, Any] = {}
125+
graph_settings['graph_dark_theme'] = args.graph_dark_theme
126+
graph_settings['graph_inline_depth'] = args.graph_inline_depth
127+
graph_settings['graph_label_edges'] = args.graph_label_edges
128+
graph_settings['graph_show_outputs'] = args.graph_show_outputs
129+
130+
# to be given to io absolute_yaml_tags function
131+
yaml_tag_paths: Dict[str, str] = {}
132+
yaml_tag_paths['cachedir'] = args.cachedir
133+
yaml_tag_paths['yaml'] = args.yaml
134+
yaml_tag_paths['homedir'] = args.homedir
135+
114136
# ========= COMPILE WORKFLOW ================
115-
compiler_info: CompilerInfo = compiler.compile_workflow(yaml_tree, args, [], [graph], {}, {}, {}, {},
137+
compiler_info: CompilerInfo = compiler.compile_workflow(yaml_tree, compiler_options, graph_settings, yaml_tag_paths,
138+
[], [graph], {}, {}, {}, {},
116139
tools_cwl, True, relative_run_path=True, testing=False)
117140

118141
rose_tree = compiler_info.rose

src/sophios/compiler.py

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import argparse
21
import copy
32
import json
43
import os
@@ -11,7 +10,6 @@
1110
import networkx as nx
1211
import yaml
1312

14-
1513
from . import input_output as io
1614
from . import inference, utils, utils_cwl, utils_graphs
1715
from .wic_types import (CompilerInfo, EnvData, ExplicitEdgeCalls,
@@ -24,7 +22,9 @@
2422

2523

2624
def compile_workflow(yaml_tree_ast: YamlTree,
27-
args: argparse.Namespace,
25+
compiler_options: Dict[str, bool],
26+
graph_settings: Dict[str, Any],
27+
yaml_tag_paths: Dict[str, str],
2828
namespaces: Namespaces,
2929
subgraphs_: List[GraphReps],
3030
explicit_edge_defs: ExplicitEdgeDefs,
@@ -40,7 +40,9 @@ def compile_workflow(yaml_tree_ast: YamlTree,
4040
4141
Args:
4242
yaml_tree_ast (YamlTree): A tuple of name and yml AST
43-
args (Any): all of the other positional arguments for compile_workflow_once
43+
compiler_options (Dict[str, bool]): The core flags needed for compilation and transformation into CWL
44+
graph_settings (Dict[str, Any]): The settings dict for graphpviz graphs
45+
yaml_tag_paths (Dict[str,str]): The paths that need to be included in (generated) yaml tags
4446
kwargs (Any): all of the other keyword arguments for compile_workflow_once
4547
4648
Returns:
@@ -58,8 +60,8 @@ def compile_workflow(yaml_tree_ast: YamlTree,
5860
i = 0
5961
while ast_modified and i < max_iters:
6062
subgraphs = copy.deepcopy(subgraphs_) # See comment below!
61-
compiler_info = compile_workflow_once(yaml_tree, args, namespaces, subgraphs,
62-
explicit_edge_defs, explicit_edge_calls,
63+
compiler_info = compile_workflow_once(yaml_tree, compiler_options, graph_settings, yaml_tag_paths,
64+
namespaces, subgraphs, explicit_edge_defs, explicit_edge_calls,
6365
input_mapping, output_mapping,
6466
tools, is_root, relative_run_path, testing)
6567
node_data: NodeData = compiler_info.rose.data
@@ -95,14 +97,15 @@ def compile_workflow(yaml_tree_ast: YamlTree,
9597
subgraph_.networkx.update(subgraphs[i].networkx.edges, subgraphs[i].networkx.nodes)
9698

9799
if i == max_iters:
98-
import yaml
99100
print(yaml.dump(node_data.yml))
100101
raise Exception(f'Error! Maximum number of iterations ({max_iters}) reached in compile_workflow!')
101102
return compiler_info
102103

103104

104105
def compile_workflow_once(yaml_tree_ast: YamlTree,
105-
args: argparse.Namespace,
106+
compiler_options: Dict[str, bool],
107+
graph_settings: Dict[str, Any],
108+
yaml_tag_paths: Dict[str, str],
106109
namespaces: Namespaces,
107110
subgraphs: List[GraphReps],
108111
explicit_edge_defs: ExplicitEdgeDefs,
@@ -118,7 +121,9 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
118121
119122
Args:
120123
yaml_tree_ast (YamlTree): A tuple of name and yml AST
121-
args (argparse.Namespace): The command line arguments
124+
graph_settings (Dict[str, Any]): The settings dict for graphpviz graphs
125+
yaml_tag_paths (Dict[str,str]): The paths that need to be included in (generated) yaml tags
126+
compiler_options (Dict[str, bool]): The core flags needed for compilation and transformation into CWL
122127
namespaces (Namespaces): Specifies the path in the yml AST to the current subworkflow
123128
subgraphs (List[Graph]): The graphs associated with the parent workflows of the current subworkflow
124129
explicit_edge_defs (ExplicitEdgeDefs): Stores the (path, value) of the explicit edge definition sites
@@ -209,19 +214,6 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
209214

210215
tools_lst: List[Tool] = []
211216

212-
# to be given to graph util functions
213-
graph_settings = {}
214-
graph_settings['graph_dark_theme'] = args.graph_dark_theme
215-
graph_settings['graph_inline_depth'] = args.graph_inline_depth
216-
graph_settings['graph_label_edges'] = args.graph_label_edges
217-
graph_settings['graph_show_outputs'] = args.graph_show_outputs
218-
219-
# to be gieven io absolute_yaml_tags function
220-
yaml_tag_paths: Dict[str, str] = {}
221-
yaml_tag_paths['cachedir'] = args.cachedir
222-
yaml_tag_paths['yaml'] = args.yaml
223-
yaml_tag_paths['homedir'] = args.homedir
224-
225217
for i, step_key in enumerate(steps_keys):
226218
step_name_i = utils.step_name_str(yaml_stem, i, step_key)
227219
stem = Path(step_key).stem
@@ -254,9 +246,9 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
254246
graphdata = GraphData(step_key)
255247
subgraph = GraphReps(subgraph_gv, subgraph_nx, graphdata)
256248

257-
sub_compiler_info = compile_workflow(sub_yaml_tree, args, namespaces + [step_name_or_key],
258-
subgraphs + [subgraph], explicit_edge_defs_copy,
259-
explicit_edge_calls_copy,
249+
sub_compiler_info = compile_workflow(sub_yaml_tree, compiler_options, graph_settings, yaml_tag_paths,
250+
namespaces + [step_name_or_key], subgraphs + [subgraph],
251+
explicit_edge_defs_copy, explicit_edge_calls_copy,
260252
input_mapping_copy, output_mapping_copy,
261253
tools, False, relative_run_path, testing)
262254

@@ -340,14 +332,6 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
340332
rose_tree_list.append(rose_tree_base_case)
341333
tools_lst.append(tool_i)
342334

343-
if not testing:
344-
# Disable for testing because when testing in parallel, the *.gv Graphviz files
345-
# can be written/read to/from disk simultaneously, which results in
346-
# intermittent 'syntax errors'.
347-
pass
348-
# Actually, this is a significant performance bottleneck and isn't really necessary.
349-
# utils_graphs.make_tool_dag(stem, tool_i, args.graph_dark_theme)
350-
351335
# Add run tag, using relative or flat-directory paths
352336
# NOTE: run: path issues were causing test_cwl_embedding_independence()
353337
# to fail, so I simply ignore the run tag in that test.
@@ -419,13 +403,11 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
419403
# (Solution: refactor all required arguments out of config and list
420404
# them as explicit inputs in the cwl files, then modify the python
421405
# files accordingly.)
422-
# print(args_required)
423406

424407
sub_args_provided = [arg for arg in args_required if arg in explicit_edge_calls_copy]
425-
# print(sub_args_provided)
426408

427409
label = step_key
428-
if args.graph_label_stepname:
410+
if graph_settings['graph_label_stepname']:
429411
label = step_name_or_key
430412
step_node_name = '___'.join(namespaces + [step_name_or_key])
431413

@@ -439,11 +421,11 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
439421
graph_gv.node(step_node_name, **attrs)
440422
graph_nx.add_node(step_node_name)
441423
graphdata.nodes.append((step_node_name, attrs))
442-
elif not (step_key in subkeys and len(namespaces) < args.graph_inline_depth):
424+
elif not (step_key in subkeys and len(namespaces) < graph_settings['graph_inline_depth']):
443425
nssnode = namespaces + [step_name_or_key]
444426
# Just like in add_graph_edge(), here we can hide all of the details
445427
# below a given depth by simply truncating the node's namespaces.
446-
nssnode = nssnode[:(1 + args.graph_inline_depth)]
428+
nssnode = nssnode[:(1 + graph_settings['graph_inline_depth'])]
447429
step_node_name = '___'.join(nssnode)
448430
# NOTE: NOT wic_graphviz_step_i
449431
# get the label (if any) from the subworkflow
@@ -633,11 +615,11 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
633615
new_val = {'source': in_name}
634616
steps[i]['in'][arg_key] = new_val
635617

636-
if args.graph_show_inputs:
618+
if graph_settings['graph_show_inputs']:
637619
input_node_name = '___'.join(namespaces + [step_name_or_key, arg_key])
638620
attrs = {'label': arg_key, 'shape': 'box', 'style': 'rounded, filled', 'fillcolor': 'lightgreen'}
639621
graph_gv.node(input_node_name, **attrs)
640-
font_edge_color = 'black' if args.graph_dark_theme else 'white'
622+
font_edge_color = 'black' if graph_settings['graph_dark_theme'] else 'white'
641623
graph_gv.edge(input_node_name, step_node_name, color=font_edge_color)
642624
graph_nx.add_node(input_node_name)
643625
graph_nx.add_edge(input_node_name, step_node_name)
@@ -668,18 +650,10 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
668650
except Exception:
669651
pass
670652

671-
if not args.allow_raw_cwl and (not hashable or arg_var not in yaml_tree.get('inputs', {})):
672-
if not args.allow_raw_cwl:
673-
print(f"Warning! Did you forget to use !ii before {arg_var} in {yaml_stem}.wic?")
674-
print('If you want to compile the workflow anyway, use --allow_raw_cwl')
675-
sys.exit(1)
676-
677-
inputs = yaml_tree.get('inputs', {})
678-
unbound_lit_var = 'Error! Unbound literal variable'
679-
if inputs == {}:
680-
raise Exception(f"{unbound_lit_var}{arg_var} not in inputs: tag in {yaml_stem}.wic")
681-
inputs_dump = yaml.dump({'inputs': inputs})
682-
raise Exception(f"{unbound_lit_var}{arg_var} not in\n{inputs_dump}\nin {yaml_stem}.wic")
653+
if not compiler_options['allow_raw_cwl'] and (not hashable or arg_var not in yaml_tree.get('inputs', {})):
654+
print(f"Warning! Did you forget to use !ii before {arg_var} in {yaml_stem}.wic?")
655+
print('If you want to compile the workflow anyway, use --allow_raw_cwl')
656+
sys.exit(1)
683657

684658
if 'doc' in inputs_key_dict:
685659
inputs_key_dict['doc'] += '\\n' + in_dict.get('doc', '')
@@ -757,22 +731,24 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
757731
# NOTE: We already added an edge to the appropriate subgraph above.
758732
# TODO: vars_workflow_output_internal?
759733
else:
760-
if args.inference_disable:
734+
if compiler_options['inference_disable']:
761735
continue
762736
insertions: List[StepId] = []
763737
in_name_in_inputs_file_workflow: bool = (in_name in inputs_file_workflow)
764738
arg_key_in_yaml_tree_inputs: bool = (arg_key in yaml_tree.get('inputs', {}))
765-
inference_use_naming_conventions = args.inference_use_naming_conventions
766-
steps[i] = inference.perform_edge_inference(inference_use_naming_conventions, graph_settings, tools, tools_lst, steps_keys,
767-
yaml_stem, i, steps, arg_key, graph, is_root, namespaces,
768-
vars_workflow_output_internal, input_mapping_copy, output_mapping_copy, inputs_workflow, in_name,
769-
in_name_in_inputs_file_workflow, arg_key_in_yaml_tree_inputs, insertions, wic_steps, testing)
739+
steps[i] = inference.perform_edge_inference(compiler_options['inference_use_naming_conventions'],
740+
graph_settings, tools, tools_lst, steps_keys,
741+
yaml_stem, i, steps, arg_key, graph,
742+
is_root, namespaces, vars_workflow_output_internal,
743+
input_mapping_copy, output_mapping_copy, inputs_workflow,
744+
in_name, in_name_in_inputs_file_workflow,
745+
arg_key_in_yaml_tree_inputs, insertions, wic_steps, testing)
770746
# NOTE: For now, perform_edge_inference mutably appends to
771747
# inputs_workflow and vars_workflow_output_internal.
772748

773749
# Automatically insert steps
774750
insertions = list(set(insertions)) # Remove duplicates
775-
if len(insertions) != 0 and args.insert_steps_automatically:
751+
if len(insertions) != 0 and compiler_options['insert_steps_automatically']:
776752
insertion = insertions[0]
777753
print('Automaticaly inserting step', insertion, i)
778754
if len(insertions) != 1:
@@ -802,7 +778,7 @@ def compile_workflow_once(yaml_tree_ast: YamlTree,
802778

803779
steps[i] = utils_cwl.add_yamldict_keyval_out(steps[i], step_key, list(tool_i.cwl['outputs'].keys()))
804780

805-
if args.partial_failure_enable:
781+
if compiler_options['partial_failure_enable']:
806782
when_null_clauses = []
807783
for arg_in in args_required:
808784
when_null_clauses.append(f'inputs["{arg_in}"] != null')

src/sophios/cwl_subinterpreter.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import sys
77
import time
88
from pathlib import Path
9-
from typing import Dict, List
9+
from typing import Dict, List, Any
1010

1111
import graphviz
1212
import networkx as nx
@@ -116,7 +116,28 @@ def rerun_cwltool(homedir: str, _directory_realtime: Path, cachedir_path: Path,
116116
stepid = StepId(yaml_path, plugin_ns)
117117
yaml_tree = YamlTree(stepid, yml)
118118
subgraph = GraphReps(graphviz.Digraph(name=yaml_path), nx.DiGraph(), GraphData(yaml_path))
119-
compiler_info = compiler.compile_workflow(yaml_tree, args, [], [subgraph], {}, {}, {}, {},
119+
# core compiler options for transformation into CWL
120+
compiler_options: Dict[str, bool] = {}
121+
compiler_options['partial_failure_enable'] = args.partial_failure_enable
122+
compiler_options['inference_use_naming_conventions'] = args.inference_use_naming_conventions
123+
compiler_options['insert_steps_automatically'] = args.insert_steps_automatically
124+
compiler_options['inference_disable'] = args.inference_disable
125+
compiler_options['allow_raw_cwl'] = args.allow_raw_cwl
126+
127+
# to be given to graph util functions
128+
graph_settings: Dict[str, Any] = {}
129+
graph_settings['graph_dark_theme'] = args.graph_dark_theme
130+
graph_settings['graph_inline_depth'] = args.graph_inline_depth
131+
graph_settings['graph_label_edges'] = args.graph_label_edges
132+
graph_settings['graph_show_outputs'] = args.graph_show_outputs
133+
134+
# to be given to io absolute_yaml_tags function
135+
yaml_tag_paths: Dict[str, str] = {}
136+
yaml_tag_paths['cachedir'] = args.cachedir
137+
yaml_tag_paths['yaml'] = args.yaml
138+
yaml_tag_paths['homedir'] = args.homedir
139+
compiler_info = compiler.compile_workflow(yaml_tree, compiler_options, graph_settings, yaml_tag_paths,
140+
[], [subgraph], {}, {}, {}, {},
120141
tools_cwl, True, relative_run_path=False, testing=False)
121142
rose_tree = compiler_info.rose
122143
working_dir = Path('.') / Path('autogenerated/') # Use a new working directory.

0 commit comments

Comments
 (0)