Skip to content

Commit 22e9a1a

Browse files
Merge pull request #20 from InformaticsMatters/options-processing
Workflow engine can now read and use (basic) options
2 parents d279ef6 + 13de59c commit 22e9a1a

File tree

3 files changed

+86
-43
lines changed

3 files changed

+86
-43
lines changed

tests/test_workflow_engine_examples.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ def test_workflow_engine_simple_python_molprops(basic_engine):
313313
assert project_file_exists(output_file_2)
314314

315315

316-
@pytest.mark.skip(reason="The engine does not currently create the required variables")
316+
# @pytest.mark.skip(reason="The engine does not currently create the required variables")
317317
def test_workflow_engine_simple_python_molprops_with_options(basic_engine):
318318
# Arrange
319319
da, md = basic_engine
@@ -380,7 +380,11 @@ def test_workflow_engine_simple_python_molprops_with_options(basic_engine):
380380
md,
381381
da,
382382
"simple-python-molprops-with-options",
383-
{"candidateMolecules": input_file_1},
383+
{
384+
"candidateMolecules": input_file_1,
385+
"rdkitPropertyName": "prop",
386+
"rdkitPropertyValue": 1.2,
387+
},
384388
)
385389

386390
# Assert

workflow/decoder.py

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def get_variable_names(definition: dict[str, Any]) -> list[str]:
8484

8585
def set_variables_from_options_for_step(
8686
definition: dict[str, Any], variables: dict[str, Any], step_name: str
87-
) -> tuple[dict[str, Any], str | None]:
87+
) -> dict[str, Any]:
8888
"""Given a Workflow definition, an existing map of variables and values,
8989
and a step name this function returns a new set of variables by adding
9090
variables and values that are required for the step that have been defined in the
@@ -109,13 +109,26 @@ def set_variables_from_options_for_step(
109109
"""
110110

111111
assert isinstance(definition, dict)
112-
assert isinstance(variables, dict)
113112
assert step_name
114113

115-
new_variables: dict[str, Any] = variables.copy()
114+
print("workflow", definition)
115+
print("workflow_variables", variables)
116+
117+
result = {}
118+
options = definition.get("variables", {}).get("options", [])
119+
print("options", options)
120+
print("variables", variables)
121+
122+
for opt in options:
123+
for step_alias in opt["as"]:
124+
if step_alias["step"] == step_name:
125+
result[step_alias["option"]] = variables[opt["name"]]
126+
# can break the loop because a variable can be a step
127+
# variable only once
128+
break
116129

117130
# Success...
118-
return new_variables, None
131+
return result
119132

120133

121134
def get_required_variable_names(definition: dict[str, Any]) -> list[str]:
@@ -138,3 +151,49 @@ def get_required_variable_names(definition: dict[str, Any]) -> list[str]:
138151
if "default" not in option_variable
139152
)
140153
return required_variables
154+
155+
156+
def set_step_variables(
157+
*,
158+
workflow: dict[str, Any],
159+
inputs: list[dict[str, Any]],
160+
outputs: list[dict[str, Any]],
161+
previous_step_outputs: list[dict[str, Any]],
162+
workflow_variables: dict[str, Any],
163+
step_name: str,
164+
) -> dict[str, Any]:
165+
"""Prepare input- and output variables for the following step.
166+
167+
Inputs are defined in step definition but their values may
168+
come from previous step outputs.
169+
"""
170+
result = {}
171+
172+
for item in inputs:
173+
p_key = item["input"]
174+
p_val = ""
175+
val = item["from"]
176+
if "workflow-input" in val.keys():
177+
p_val = workflow_variables[val["workflow-input"]]
178+
elif "step" in val.keys():
179+
for out in previous_step_outputs:
180+
if out["output"] == val["output"]:
181+
p_val = out["as"]
182+
break
183+
184+
result[p_key] = p_val
185+
186+
for item in outputs:
187+
p_key = item["output"]
188+
p_val = item["as"]
189+
result[p_key] = p_val
190+
191+
options = set_variables_from_options_for_step(
192+
definition=workflow,
193+
variables=workflow_variables,
194+
step_name=step_name,
195+
)
196+
197+
result |= options
198+
199+
return result

workflow/workflow_engine.py

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
WorkflowAPIAdapter,
3939
)
4040

41+
from .decoder import set_step_variables
42+
4143
_LOGGER: logging.Logger = logging.getLogger(__name__)
4244
_LOGGER.setLevel(logging.INFO)
4345
_LOGGER.addHandler(logging.StreamHandler(sys.stdout))
@@ -388,11 +390,25 @@ def _validate_step_command(
388390
running_workflow_step_id,
389391
previous_step_outputs,
390392
)
391-
step_vars = self._set_step_variables(
393+
394+
# there should probably be an easier way to access this
395+
running_wf_step, _ = self._wapi_adapter.get_running_workflow_step(
396+
running_workflow_step_id=running_workflow_step_id
397+
)
398+
running_wf_id = running_wf_step["running_workflow"]["id"]
399+
running_wf, _ = self._wapi_adapter.get_running_workflow(
400+
running_workflow_id=running_wf_id
401+
)
402+
workflow_id = running_wf["workflow"]["id"]
403+
workflow, _ = self._wapi_adapter.get_workflow(workflow_id=workflow_id)
404+
405+
step_vars = set_step_variables(
406+
workflow=workflow,
392407
workflow_variables=all_variables,
393408
inputs=inputs,
394409
outputs=outputs,
395410
previous_step_outputs=previous_step_outputs,
411+
step_name=running_wf_step["name"],
396412
)
397413
all_variables |= step_vars
398414
_LOGGER.debug(
@@ -506,39 +522,3 @@ def _set_step_error(
506522
error_num=error_num,
507523
error_msg=r_wf_error,
508524
)
509-
510-
def _set_step_variables(
511-
self,
512-
*,
513-
inputs: list[dict[str, Any]],
514-
outputs: list[dict[str, Any]],
515-
previous_step_outputs: list[dict[str, Any]],
516-
workflow_variables: dict[str, Any],
517-
) -> dict[str, Any]:
518-
"""Prepare input- and output variables for the following step.
519-
520-
Inputs are defined in step definition but their values may
521-
come from previous step outputs.
522-
"""
523-
result = {}
524-
525-
for item in inputs:
526-
p_key = item["input"]
527-
p_val = ""
528-
val = item["from"]
529-
if "workflow-input" in val.keys():
530-
p_val = workflow_variables[val["workflow-input"]]
531-
elif "step" in val.keys():
532-
for out in previous_step_outputs:
533-
if out["output"] == val["output"]:
534-
p_val = out["as"]
535-
break
536-
537-
result[p_key] = p_val
538-
539-
for item in outputs:
540-
p_key = item["output"]
541-
p_val = item["as"]
542-
result[p_key] = p_val
543-
544-
return result

0 commit comments

Comments
 (0)