Recipe Conditions - ngageoint/scale-ui GitHub Wiki
The following is a sample recipe type definition.
{
"input": {
"files": [
{
"name": "foo",
"media_types": [
"image/tiff"
],
"required": true,
"multiple": true
}
],
"json": [
{
"name": "bar",
"type": "integer",
"required": false
}
]
},
"nodes": {
"node_a": {
"dependencies": [],
"input": {
"input_1": {
"type": "recipe",
"input": "foo"
}
},
"node_type": {
"node_type": "job",
"job_type_name": "job-type-1",
"job_type_version": "1.0",
"job_type_revision": 1
}
},
"node_b": {
"dependencies": [
{
"name": "node_a",
"acceptance": true
}
],
"input": {
"input_1": {
"type": "recipe",
"input": "foo"
},
"input_2": {
"type": "dependency",
"node": "node_a",
"output": "output_1"
}
},
"node_type": {
"node_type": "job",
"job_type_name": "job-type-2",
"job_type_version": "2.0",
"job_type_revision": 1
}
},
"node_c": {
"dependencies": [
{
"name": "node_b"
}
],
"input": {
"input_1": {
"type": "recipe",
"input": "bar"
},
"input_2": {
"type": "dependency",
"node": "node_b",
"output": "output_1"
}
},
"node_type": {
"node_type": "condition",
"interface": {
"files": [
{
"name": "input_2",
"media_types": [
"image/tiff"
],
"required": true,
"multiple": true
}
],
"json": [{
"name": "input_1",
"type": "integer",
"required": false
}]
},
"data_filter": {
"filters": [
{
"name": "input_2",
"type": "media-type",
"condition": "==",
"values": [
"image/tiff"
]
}
]
}
}
}
},
"node_d": {
"dependencies": [
{
"name": "node_c",
"acceptance": true
}
],
"input": {
"input_1": {
"type": "recipe",
"input": "bar"
},
"input_2": {
"type": "dependency",
"node": "node_c",
"output": "input_2"
}
},
"node_type": {
"node_type": "recipe",
"recipe_type_name": "recipe-type-1",
"recipe_type_revision": 5
}
}
}
This definition takes a required file input named 'foo' and an optional json integer input named 'bar'.
"input": {
"files": [{'name': 'foo', 'media_types': ['image/tiff'], 'required': True, 'multiple': True}],
"json": [{'name': 'bar', 'type': 'integer', 'required': False}]
}
The first node in the recipe is a job node named 'node_a'. It has a job type with a file input creatively named 'input_1'. It gets this input from the recipe's 'foo' input.
"node_a": {
"dependencies": [],
"input": {
"input_1": {"type": "recipe", "input": "foo"}
},
"node_type": {
"node_type": "job",
"job_type_name": "job-type-1",
"job_type_version": "1.0",
"job_type_revision": 1
}
}
The job-type specified in 'node_a' produces an output named 'output_1' which is passed to the second node, 'node_b'. This node has a job type that takes two inputs, 'input_1' and 'input_2'. The former is connected to 'foo' from the recipe again and the latter is passed from 'output_1' of 'node_a'. The job for 'node_b' will not be queued until the job for 'node_a' completes as it is dependent on that node.
"node_b": {
"dependencies": [{"name": "node_a"}],
"input": {
"input_1": {"type": "recipe", "input": "foo"},
"input_2": {"type": "dependency", "node": "node_a", "output": "output_1"}
},
"node_type": {
"node_type": "job",
"job_type_name": "job-type-2",
"job_type_version": "2.0",
"job_type_revision": 1
}
}
The condition node 'node_c' is dependent on 'node_b' and has two inputs. If the condition passes, both of these inputs will be passed through to dependent nodes. The output interface is a copy of the input interface. The example condition takes the 'bar' input from the recipe and the output 'output_1' from 'node_b' but only filters based on the latter. If the media_type equals "image/tiff" the condition will return true.
"node_c": {
"dependencies": [{"name": "node_b"}],
"input": {
"input_1": {"type": "recipe", "input": "bar"},
"input_2": {"type": "dependency", "node": "node_b", "output": "output_1"}
},
"node_type": {
"node_type": "condition",
"interface": {"files": [{"name": "input_2",
"media_types": ["image/tiff"],
"required": true,
"multiple": true}],
"json": [{"name": "input_1",
"type": "integer",
"required": false}]},
"data_filter": {"filters": [{"name": "input_2",
"type": "media-type",
"condition": "==",
"values": ["image/tiff"]}]}}},
}
}
We can add an additional filter for 'input_1' that will pass if either 'output_1' from 'node_b' has a media-type of "image/tiff" or the recipe input 'bar' is greater than or equal to 100 as follows:
"data_filter": {"filters": [{"name": "input_2",
"type": "media-type",
"condition": "==",
"values": ["image/tiff"]},
{"name": "input_1",
"type": "integer",
"condition": ">=",
"values": [100],
"all": false },]}}}
Finally, the last node depends on the result of the 'node_c'. Because 'acceptance' is set to "true", the sub-recipe specified in 'node_d' will only run if the condition passes. An 'else' branch could be created by having a node that depends on 'node_c' with 'acceptance' set to false. Note the name of the output from 'node_c' is "input_2". This is because the output interface of a condition is exactly the same as the input interface.
"node_d": {
"dependencies": [
{
"name": "node_c",
"acceptance": true
}
],
"input": {
"input_1": {
"type": "recipe",
"input": "bar"
},
"input_2": {
"type": "dependency",
"node": "node_c",
"output": "input_2"
}
},
"node_type": {
"node_type": "recipe",
"recipe_type_name": "recipe-type-1",
"recipe_type_revision": 5
}
}
More details on conditions can be found here