Skip to content

Commit d95fb58

Browse files
author
Alan Christie
committed
refactor: Add support for simple python rdkit/butina example
1 parent 55fb660 commit d95fb58

File tree

8 files changed

+165
-12
lines changed

8 files changed

+165
-12
lines changed

tests/job-definitions/job-definitions.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,11 @@ jobs:
116116
type: string
117117
default: clustered.sdf
118118
pattern: "^[A-Za-z0-9_/\\.\\-]+\\.(smi|sdf)$"
119+
120+
rdkit-molprops:
121+
command: >-
122+
rdkit-molprops.py --inputFile {{ inputFile }} --outputFile {{ outputFile }} --name {{ name }} --value {{ value }}
123+
124+
cluster-butina:
125+
command: >-
126+
rdkit-molprops.py --inputFile {{ inputFile }} --outputFile {{ outputFile }} --name {{ name }} --value {{ value }}

tests/jobs/cluster-butina.py

Whitespace-only changes.

tests/jobs/rdkik-molprops.py

Whitespace-only changes.

tests/test_workflow_engine_examples.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,34 @@ def test_workflow_engine_shortcut_example_1(basic_engine):
214214
# This test should generate a file in the simulated project directory
215215
assert project_file_exists(output_file_a)
216216
assert project_file_exists(output_file_b)
217+
218+
219+
@pytest.mark.skip(reason="The engine does not currently create the required variables")
220+
def test_workflow_engine_simple_python_molprops(basic_engine):
221+
# Arrange
222+
da, md = basic_engine
223+
# Make sure files that should be generated by the test
224+
# do not exist before we run the test.
225+
output_file_a = "a.sdf"
226+
assert not project_file_exists(output_file_a)
227+
output_file_b = "b.sdf"
228+
assert not project_file_exists(output_file_b)
229+
230+
# Act
231+
r_wfid = start_workflow(
232+
md, da, "simple-python-molprops", {"candidateMolecules": "C"}
233+
)
234+
235+
# Assert
236+
wait_for_workflow(da, r_wfid)
237+
# Additional, detailed checks...
238+
# Check we only have one RunningWorkflowStep, and it succeeded
239+
response = da.get_running_workflow_steps(running_workflow_id=r_wfid)
240+
assert response["count"] == 2
241+
assert response["running_workflow_steps"][0]["done"]
242+
assert response["running_workflow_steps"][0]["success"]
243+
assert response["running_workflow_steps"][1]["done"]
244+
assert response["running_workflow_steps"][1]["success"]
245+
# This test should generate a file in the simulated project directory
246+
assert project_file_exists(output_file_a)
247+
assert project_file_exists(output_file_b)

tests/test_workflow_validator_for_create_level.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,23 @@ def test_validate_shortcut_example_1():
102102
# Assert
103103
assert error.error_num == 0
104104
assert error.error_msg is None
105+
106+
107+
def test_validate_simple_python_molprops():
108+
# Arrange
109+
workflow_file: str = os.path.join(
110+
os.path.dirname(__file__), "workflow-definitions", "simple-python-molprops.yaml"
111+
)
112+
with open(workflow_file, "r", encoding="utf8") as workflow_file:
113+
workflow: dict[str, Any] = yaml.load(workflow_file, Loader=yaml.FullLoader)
114+
assert workflow
115+
116+
# Act
117+
error = WorkflowValidator.validate(
118+
level=ValidationLevel.CREATE,
119+
workflow_definition=workflow,
120+
)
121+
122+
# Assert
123+
assert error.error_num == 0
124+
assert error.error_msg is None
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
kind: DataManagerWorkflow
3+
kind-version: "2024.1"
4+
name: python-workflow
5+
description: An simple python experimental workflow
6+
variables:
7+
inputs:
8+
- name: candidateMolecules
9+
- type: squonk/x-smiles
10+
outputs:
11+
- name: clusteredMolecules
12+
from:
13+
- step: step2
14+
output: outputFile
15+
as: clustered-molecules.smi
16+
17+
steps:
18+
- name: step1
19+
description: Add column 1
20+
specification: >-
21+
{
22+
"collection": "workflow-engine-unit-test-jobs",
23+
"job": "rdkit-molprops",
24+
"version": "1.0.0",
25+
"variables": {
26+
"name": "col1",
27+
"value": 123
28+
}
29+
}
30+
inputs:
31+
- input: inputFile
32+
from:
33+
workflow-input: candidateMolecules
34+
outputs:
35+
- output: outputFile
36+
as: __step1__out.smi
37+
38+
- name: step2
39+
Description: Add column 2
40+
specification: >-
41+
{
42+
"collection": "workflow-engine-unit-test-jobs",
43+
"job": "cluster-butina",
44+
"version":"1.0.0",
45+
"variables": {
46+
"name":"col2",
47+
"value":"999"
48+
}
49+
}
50+
inputs:
51+
- input: inputFile
52+
from:
53+
step: step1
54+
output: outputFile
55+
outputs:
56+
- output: outputFile
57+
as: __step2__out.smi

workflow/workflow-schema.yaml

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ properties:
2727
type: array
2828
items:
2929
$ref: "#/definitions/step"
30+
variables:
31+
type: object
32+
properties:
33+
inputs:
34+
type: array
35+
items:
36+
$ref: "#/definitions/workflow-input-parameter"
3037
required:
3138
- kind
3239
- kind-version
@@ -46,21 +53,35 @@ definitions:
4653
A value compatible with Kubernetes variables
4754
to allow it to be used ins Pod Label
4855
49-
variable-name:
56+
parameter-name:
5057
type: string
51-
pattern: ^[a-zA-Z_][a-zA-Z0-9_]{,63}$
52-
description: >-
53-
A Job/Step variable name, as used in the Data Manager Job Specification
58+
pattern: ^[a-zA-Z_][a-zA-Z0-9_-]*$
5459

55-
# Declaration of a step from anotehr step
60+
workflow-input-parameter:
61+
type: object
62+
properties:
63+
name:
64+
$ref: '#/definitions/parameter-name'
65+
66+
# Declaration of a value from a workflow input (variable)
67+
from-workflow-input:
68+
type: object
69+
additionalProperties: false
70+
properties:
71+
workflow-input:
72+
$ref: '#/definitions/parameter-name'
73+
required:
74+
- workflow-input
75+
76+
# Declaration of a value from another step
5677
from-step-output:
5778
type: object
5879
additionalProperties: false
5980
properties:
6081
step:
6182
$ref: '#/definitions/rfc1035-label-name'
6283
output:
63-
$ref: '#/definitions/variable-name'
84+
$ref: '#/definitions/parameter-name'
6485
required:
6586
- step
6687
- output
@@ -71,22 +92,33 @@ definitions:
7192
additionalProperties: false
7293
properties:
7394
input:
74-
$ref: '#/definitions/variable-name'
95+
$ref: '#/definitions/parameter-name'
7596
from:
7697
$ref: '#/definitions/from-step-output'
7798
required:
7899
- input
79100

101+
step-input-from-workflow:
102+
type: object
103+
additionalProperties: false
104+
properties:
105+
input:
106+
$ref: '#/definitions/parameter-name'
107+
from:
108+
$ref: '#/definitions/from-workflow-input'
109+
required:
110+
- input
111+
80112
# A Step output (with an 'as' - a declared value)
81113
step-output-as:
82114
type: object
83115
additionalProperties: false
84116
properties:
85117
output:
86-
$ref: '#/definitions/variable-name'
118+
$ref: '#/definitions/parameter-name'
87119
as:
88120
type: string
89-
description: The value to set the variable to
121+
description: The value to set the parameter to
90122
required:
91123
- output
92124
- as
@@ -105,12 +137,13 @@ definitions:
105137
inputs:
106138
type: array
107139
items:
108-
oneOf:
140+
anyOf:
109141
- $ref: "#/definitions/step-input-from-step"
142+
- $ref: "#/definitions/step-input-from-workflow"
110143
outputs:
111144
type: array
112145
items:
113-
oneOf:
146+
anyOf:
114147
- $ref: "#/definitions/step-output-as"
115148
required:
116149
- name

workflow/workflow_engine.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,20 @@ def _validate_step_command(
338338
#
339339
# 1. The RunningWorkflow
340340
# 2. The Workflow
341-
# 3. The Job Specification
341+
# 3. The Job Step Specification Variables
342342
#
343343
# If variable 'x' is defined in all three then the RunningWorkflow's
344344
# value must be used.
345345

346+
# Get any variables from the step specification.
346347
all_variables = step_spec.pop("variables") if "variables" in step_spec else {}
348+
# Merge workflow variables on top of these
347349
if workflow_variables:
348350
all_variables |= workflow_variables
351+
# Merge running workflow variables on top of these
349352
if running_workflow_variables:
350353
all_variables |= running_workflow_variables
354+
351355
message, success = decode(
352356
job["command"], all_variables, "command", TextEncoding.JINJA2_3_0
353357
)

0 commit comments

Comments
 (0)