Skip to content

Commit

Permalink
one step wfb payload test case with no basecommand/entrypoint in ICT
Browse files Browse the repository at this point in the history
  • Loading branch information
Vasu Jaganath committed Nov 7, 2024
1 parent 060a85b commit 00aed86
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 4 deletions.
18 changes: 16 additions & 2 deletions src/sophios/api/http/restapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,15 @@ async def compile_wf(request: Request) -> Json:
print('---------- Compile Workflow! ---------')
# ========= PROCESS REQUEST OBJECT ==========
req: Json = await request.json()
suppliedargs = ['--cwl_inline_runtag', '--generate_cwl_workflow']
# clean up and convert the incoming object
# schema preserving
req = converter.update_payload_missing_inputs_outputs(req)
wfb_payload = converter.raw_wfb_to_lean_wfb(req)
# schema non-preserving
workflow_temp = converter.wfb_to_wic(wfb_payload)
wkflw_name = "generic_workflow"
args = get_args(wkflw_name, ['--cwl_inline_runtag', '--generate_cwl_workflow'])
args = get_args(wkflw_name, suppliedargs)

# Build canonical workflow object
workflow_can = utils_cwl.desugar_into_canonical_normal_form(workflow_temp)
Expand All @@ -128,7 +129,10 @@ async def compile_wf(request: Request) -> Json:
yaml_tree: YamlTree = YamlTree(StepId(wkflw_name, plugin_ns), workflow_can)

# ========= COMPILE WORKFLOW ================
args.ignore_dir_path = True
if req.get('run_local_env') == 'true':
args.ignore_dir_path = False
else:
args.ignore_dir_path = True
compiler_info: CompilerInfo = compiler.compile_workflow(yaml_tree, args, [], [graph], {}, {}, {}, {},
tools_cwl, True, relative_run_path=True, testing=False)

Expand All @@ -141,11 +145,21 @@ async def compile_wf(request: Request) -> Json:
yaml_stem = sub_node_data.name
cwl_tree = sub_node_data.compiled_cwl
yaml_inputs = sub_node_data.workflow_inputs_file
# The following two conversions should be conditionalon the compute environment
# they are called from, removing dot and dollar won't make it run on compute-ci
cwl_tree_no_dd = remove_dot_dollar(cwl_tree)
yaml_inputs_no_dd = remove_dot_dollar(yaml_inputs)

# Convert the compiled yaml file to json for labshare Compute.
cwl_tree_run = copy.deepcopy(cwl_tree_no_dd)
for step in cwl_tree_run['steps']:
node_name = step['id']
step.pop('id', None)
step = {node_name: step}
cwl_tree_run['steps_dict'] = copy.deepcopy(step)

cwl_tree_run.pop('steps', None)
cwl_tree_run['steps'] = cwl_tree_run.pop('steps_dict', None)

compute_workflow: Json = {}
compute_workflow = {
Expand Down
1 change: 0 additions & 1 deletion src/sophios/api/pythonapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"""CLT utilities."""
import logging
from pathlib import Path
import subprocess as sub
from typing import Any, ClassVar, Optional, TypeVar, Union

import cwl_utils.parser as cu_parser
Expand Down
8 changes: 7 additions & 1 deletion src/sophios/api/utils/ict/ict_spec/tools/cwl_ict.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ def requirements(ict_: "ICT", network_access: bool) -> dict:
return reqs


def split_entrypoint_string(enrtypoint: str) -> list[str]:
"""Fix str to list of str for entrypoint/baseCommand"""
list_of_str_entry = enrtypoint.split(' ')
return list_of_str_entry


def clt_dict(ict_: "ICT", network_access: bool) -> dict:
"""Return a dict of a CommandLineTool from an ICT object."""

Expand All @@ -37,7 +43,7 @@ def clt_dict(ict_: "ICT", network_access: bool) -> dict:
for io in ict_.outputs
},
"requirements": requirements(ict_, network_access),
"baseCommand": ict_.entrypoint,
"baseCommand": '' if ict_.entrypoint == '' else split_entrypoint_string(str(ict_.entrypoint)),
"label": ict_.title,
"doc": str(ict_.documentation),
}
Expand Down
85 changes: 85 additions & 0 deletions tests/rest_wfb_objects/bbbc_download_wfb.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"state": {
"nodes": [
{
"id": 1,
"x": 259,
"y": 209,
"z": 1,
"name": "BBBC Download",
"expanded": true,
"pluginId": "polusai/bbbc-download-plugin@0.1.0-dev1",
"height": 50,
"width": 250,
"settings": {
"inputs": {
"name": "BBBC001",
"outDir": "bbbcdownload.outDir"
}
},
"internal": false
}
],
"links": [],
"selection": []
},
"plugins": [
{
"name": "polusai/bbbc-download-plugin:0.1.0-dev1",
"version": "0.1.0-dev1",
"title": "BBBC Download",
"description": "Downloads the datasets on the Broad Bioimage Benchmark Collection website",
"createdBy": "Serebryakov, Artem (NIH/NCATS) [C]",
"updatedBy": "Serebryakov, Artem (NIH/NCATS) [C]",
"author": [
"Hamdah Abbasi"
],
"contact": "hamdahshafqat.abbasi@nih.gov",
"container": "polusai/bbbc-download-plugin:0.1.0-dev1",
"entrypoint": "",
"inputs": [
{
"description": "The name of the dataset(s) to be downloaded (separate the datasets with a comma. eg BBBC001,BBBC002,BBBC003)",
"format": [
"collection"
],
"name": "name",
"required": true,
"type": "string"
}
],
"outputs": [
{
"description": "Output collection",
"name": "outDir",
"format": [
"directory"
],
"required": true,
"type": "path"
}
],
"repository": "https://github.com/LabShare/polus-plugins",
"specVersion": "1.0.0",
"ui": [
{
"description": "The name of the dataset(s) to be downloaded (separate the datasets with a comma. eg BBBC001,BBBC002,BBBC003)",
"format": [
"collection"
],
"name": "name",
"required": true,
"type": "string"
}
],
"path": "visualization",
"tags": [
"bbbc-download"
],
"createdAt": "2024-10-29T18:59:55.843Z",
"updatedAt": "2024-10-29T20:01:42.463Z",
"id": "672130abad801ccee7f5eaad",
"pid": "polusai/bbbc-download-plugin@0.1.0-dev1"
}
]
}
74 changes: 74 additions & 0 deletions tests/rest_wfb_objects/single_node_bbbc_download.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"state": {
"nodes": [
{
"id": 1,
"name": "bbbcdownload",
"pluginId": "",
"run": {
"baseCommand": ["python3", "-m", "polus.plugins.utils.bbbc_download"],
"class": "CommandLineTool",
"cwlVersion": "v1.2",
"inputs": {
"name": {
"label": "The name of the dataset(s) to be downloaded (separate the datasets with a comma. eg BBBC001,BBBC002,BBBC003)",
"doc": "The name of the dataset(s) to be downloaded (separate the datasets with a comma. eg BBBC001,BBBC002,BBBC003)",
"inputBinding": {
"prefix": "--name"
},
"type": "string"
},
"outDir": {
"label": "Output collection",
"doc": "Output collection",
"inputBinding": {
"prefix": "--outDir"
},
"type": "Directory"
}
},
"outputs": {
"outDir": {
"label": "Output collection",
"doc": "Output collection",
"type": "Directory",
"outputBinding": {
"glob": "$(inputs.outDir.basename)"
}
}
},
"stdout": "output",
"requirements": {
"DockerRequirement": {
"dockerPull": "polusai/bbbc-download-plugin:0.1.0-dev1"
},
"InitialWorkDirRequirement": {
"listing": [
{
"entry": "$(inputs.outDir)",
"writable": true
}
]
},
"InlineJavascriptRequirement": {},
"NetworkAccess": {
"networkAccess": true
}
}
},
"settings": {
"inputs": {
"name": "BBBC001",
"outDir": "bbbcdownload.outDir"
},
"outputs": {
"outDir": "bbbcdownload.outDir"
}
},
"internal": false
}
],
"links": []
},
"plugins": []
}
54 changes: 54 additions & 0 deletions tests/test_rest_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,60 @@ async def receive() -> Json:
assert retval == 0


def test_rest_core_single_node_bbbc() -> None:
"""A simple single node sophios/restapi test"""
inp_file = "single_node_bbbc_download.json"
inp: Json = {}
inp_path = Path(__file__).parent / 'rest_wfb_objects' / inp_file
with open(inp_path, 'r', encoding='utf-8') as f:
inp = json.load(f)
inp['run_local_env'] = 'true'
print('----------- from rest api ----------- \n\n')
scope = {}
scope['type'] = 'http'

async def receive() -> Json:
inp_byte = json.dumps(inp).encode('utf-8')
return {"type": "http.request", "body": inp_byte}

# create a request object and pack it with our json payload
req: Request = Request(scope)
req._receive = receive
res: Json = asyncio.run(restapi.compile_wf(req)) # call to rest api
workflow_name = inp_file.split('.', maxsplit=1)[0]
# write compiled_cwl and inputs_yml
write_out_to_disk(res, workflow_name)
retval = run_cwl_local(workflow_name, 'cwltool', 'docker', False)
assert retval == 0


def test_rest_core_bbbc_download_wfb() -> None:
"""A simple multi node (inline cwl) sophios/restapi test"""
inp_file = "bbbc_download_wfb.json"
inp: Json = {}
inp_path = Path(__file__).parent / 'rest_wfb_objects' / inp_file
with open(inp_path, 'r', encoding='utf-8') as f:
inp = json.load(f)
inp['run_local_env'] = 'true'
print('----------- from rest api ----------- \n\n')
scope = {}
scope['type'] = 'http'

async def receive() -> Json:
inp_byte = json.dumps(inp).encode('utf-8')
return {"type": "http.request", "body": inp_byte}

# create a request object and pack it with our json payload
req: Request = Request(scope)
req._receive = receive
res: Json = asyncio.run(restapi.compile_wf(req)) # call to rest api
workflow_name = inp_file.split('.', maxsplit=1)[0]
# write compiled_cwl and inputs_yml
write_out_to_disk(res, workflow_name)
retval = run_cwl_local(workflow_name, 'cwltool', 'docker', False)
assert retval == 0


@pytest.mark.fast
def test_rest_core_multi_node_file() -> None:
"""A simple multi node sophios/restapi test"""
Expand Down

0 comments on commit 00aed86

Please sign in to comment.