diff --git a/src/sophios/api/http/restapi.py b/src/sophios/api/http/restapi.py index 1a803b95..f2bb950f 100644 --- a/src/sophios/api/http/restapi.py +++ b/src/sophios/api/http/restapi.py @@ -40,21 +40,6 @@ def remove_dot_dollar(tree: Cwl) -> Cwl: return tree_no_dd -def get_yaml_tree(req: Json) -> Json: - """ - Get the Sophios yaml tree from incoming JSON - Args: - req (JSON): A raw JSON content of incoming JSON object - Returns: - Cwl: A Cwl document with . and $ removed from $namespaces and $schemas - """ - wkflw_name = "generic_workflow" - # args = converter.get_args(wkflw_name) - # yaml_tree_json: Json = converter.wfb_to_wic(req) - yaml_tree_json: Json = {} - return yaml_tree_json - - def run_workflow(compiler_info: CompilerInfo, args: argparse.Namespace) -> int: """ Get the Sophios yaml tree from incoming JSON @@ -116,8 +101,8 @@ async def compile_wf(request: Request) -> Json: wkflw_name = "generic_workflow" args = get_args(wkflw_name, ['--inline_cwl_runtag']) + # Build canonical workflow object workflow_can = utils_cwl.desugar_into_canonical_normal_form(workflow_temp) - print(yaml.safe_dump(workflow_can, default_flow_style=False)) # ========= BUILD WIC COMPILE INPUT ========= # Build a list of CLTs diff --git a/src/sophios/api/utils/converter.py b/src/sophios/api/utils/converter.py index 7258dbf8..8a1e5ba6 100644 --- a/src/sophios/api/utils/converter.py +++ b/src/sophios/api/utils/converter.py @@ -4,7 +4,6 @@ from jsonschema import Draft202012Validator from sophios.utils_yaml import wic_loader -# from sophios import cli from sophios.wic_types import Json, Cwl SCHEMA: Json = { diff --git a/tests/rest_wfb_objects/multi_node.json b/tests/rest_wfb_objects/multi_node.json new file mode 100644 index 00000000..ffe42014 --- /dev/null +++ b/tests/rest_wfb_objects/multi_node.json @@ -0,0 +1,76 @@ +{ + "nodes": [ + { + "id": 7, + "x": 462, + "y": 206, + "z": 2, + "name": "touch", + "pluginId": "touch", + "height": 50, + "width": 250, + "settings": { + "inputs": { + "filename": "empty.txt" + }, + "outputs": { + "file": "file_touch" + } + }, + "internal": false + }, + { + "id": 18, + "x": 155, + "y": 195, + "z": 1, + "name": "append", + "pluginId": "append", + "height": 50, + "width": 250, + "settings": { + "inputs": { + "str": "Hello", + "file": "file_touch" + }, + "outputs": { + "file": "file_append1" + } + }, + "internal": false + }, + { + "id": 9, + "x": 790.3254637299812, + "y": 449.8103498684344, + "z": 5, + "name": "append", + "pluginId": "append", + "height": 50, + "width": 250, + "settings": { + "inputs": { + "str": "World!", + "file": "file_append1" + }, + "outputs": { + "file": "file_append2" + } + }, + "internal": false + } + ], + "links": [ + { + "sourceId": 7, + "targetId": 18, + "id": 1 + }, + { + "sourceId": 18, + "targetId": 9, + "id": 5 + } + ], + "selection": [] +} \ No newline at end of file diff --git a/tests/rest_wfb_objects/multi_node_inline_cwl.json b/tests/rest_wfb_objects/multi_node_inline_cwl.json new file mode 100644 index 00000000..c972ee36 --- /dev/null +++ b/tests/rest_wfb_objects/multi_node_inline_cwl.json @@ -0,0 +1,181 @@ +{ + "nodes": [ + { + "id": 7, + "x": 462, + "y": 206, + "z": 2, + "name": "touch", + "pluginId": "touch", + "height": 50, + "width": 250, + "settings": { + "inputs": { + "filename": "empty.txt" + }, + "outputs": { + "file": "file_touch" + } + }, + "run": { + "cwlVersion": "v1.0", + "class": "CommandLineTool", + "requirements": { + "DockerRequirement": { + "dockerPull": "docker.io/bash:4.4" + }, + "InlineJavascriptRequirement": {} + }, + "baseCommand": "touch", + "inputs": { + "filename": { + "type": "string", + "inputBinding": { + "position": 1 + } + } + }, + "outputs": { + "file": { + "type": "File", + "outputBinding": { + "glob": "$(inputs.filename)" + } + } + } + }, + "internal": false + }, + { + "id": 18, + "x": 155, + "y": 195, + "z": 1, + "name": "append", + "pluginId": "append", + "height": 50, + "width": 250, + "settings": { + "inputs": { + "str": "Hello", + "file": "file_touch" + }, + "outputs": { + "file": "file_append1" + } + }, + "run": { + "class": "CommandLineTool", + "cwlVersion": "v1.0", + "requirements": { + "ShellCommandRequirement": {}, + "InlineJavascriptRequirement": {}, + "InitialWorkDirRequirement": { + "listing": [ + "$(inputs.file)" + ] + } + }, + "inputs": { + "str": { + "type": "string", + "inputBinding": { + "shellQuote": false, + "position": 1, + "prefix": "echo" + } + }, + "file": { + "type": "File", + "inputBinding": { + "shellQuote": false, + "position": 2, + "prefix": ">>" + } + } + }, + "outputs": { + "file": { + "type": "File", + "outputBinding": { + "glob": "$(inputs.file.basename)" + } + } + } + }, + "internal": false + }, + { + "id": 9, + "x": 790.3254637299812, + "y": 449.8103498684344, + "z": 5, + "name": "append", + "pluginId": "append", + "height": 50, + "width": 250, + "settings": { + "inputs": { + "str": "World!", + "file": "file_append1" + }, + "outputs": { + "file": "file_append2" + } + }, + "run": { + "class": "CommandLineTool", + "cwlVersion": "v1.0", + "requirements": { + "ShellCommandRequirement": {}, + "InlineJavascriptRequirement": {}, + "InitialWorkDirRequirement": { + "listing": [ + "$(inputs.file)" + ] + } + }, + "inputs": { + "str": { + "type": "string", + "inputBinding": { + "shellQuote": false, + "position": 1, + "prefix": "echo" + } + }, + "file": { + "type": "File", + "inputBinding": { + "shellQuote": false, + "position": 2, + "prefix": ">>" + } + } + }, + "outputs": { + "file": { + "type": "File", + "outputBinding": { + "glob": "$(inputs.file.basename)" + } + } + } + }, + "internal": false + } + ], + "links": [ + { + "sourceId": 7, + "targetId": 18, + "id": 1 + }, + { + "sourceId": 18, + "targetId": 9, + "id": 5 + } + ], + "selection": [] +} \ No newline at end of file diff --git a/tests/single_node_helloworld.json b/tests/rest_wfb_objects/single_node.json similarity index 100% rename from tests/single_node_helloworld.json rename to tests/rest_wfb_objects/single_node.json diff --git a/tests/test_rest_core.py b/tests/test_rest_core.py index f85bf2e9..54639d02 100644 --- a/tests/test_rest_core.py +++ b/tests/test_rest_core.py @@ -1,12 +1,6 @@ import json -# import subprocess as sub from pathlib import Path -# import signal -# import sys -# from typing import List -# import argparse import asyncio -from jsonschema import Draft202012Validator from fastapi import Request @@ -16,141 +10,61 @@ from sophios.api.http import restapi -SCHEMA = { - "$schema": "http://json-schema.org/draft-07/schema#", - "definitions": { - "Link": { - "properties": { - "id": { - "type": "number" - }, - "inletIndex": { - "type": "number" - }, - "outletIndex": { - "type": "number" - }, - "sourceId": { - "type": "number" - }, - "targetId": { - "type": "number" - }, - "x1": { - "type": "number" - }, - "x2": { - "type": "number" - }, - "y1": { - "type": "number" - }, - "y2": { - "type": "number" - } - }, - "type": "object", - "required": ["id", "inletIndex", "outletIndex", "sourceId", "targetId"] - }, - "NodeSettings": { - "properties": { - "inputs": { - "additionalProperties": { - "$ref": "#/definitions/T" - }, - "type": "object" - }, - "outputs": { - "additionalProperties": { - "$ref": "#/definitions/T" - }, - "type": "object" - } - }, - "type": "object" - }, - "NodeX": { - "properties": { - "expanded": { - "type": "boolean" - }, - "height": { - "type": "number" - }, - "id": { - "type": "number" - }, - "internal": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "pluginId": { - "type": "string" - }, - "settings": { - "$ref": "#/definitions/NodeSettings" - }, - "width": { - "type": "number" - }, - "x": { - "type": "number" - }, - "y": { - "type": "number" - }, - "z": { - "type": "number" - }, - }, - "type": "object", - "required": ["id", "name", "pluginId", "settings", "internal"] - }, - "T": { - "type": "object" - } - }, - "properties": { - "links": { - "items": { - "$ref": "#/definitions/Link" - }, - "type": "array" - }, - "nodes": { - "items": { - "$ref": "#/definitions/NodeX" - }, - "type": "array" - }, - "selection": { - "items": { - "type": "number" - }, - "type": "array" - } - }, - "type": "object", - "required": ["links", "nodes"] -} - @pytest.mark.fast def test_rest_core_single_node() -> None: - """A simple single node 'hello world' test""" - # validate schema - Draft202012Validator.check_schema(SCHEMA) - df2012 = Draft202012Validator(SCHEMA) - inp_file = "single_node_helloworld.json" + """A simple single node sophios/restapi test""" + inp_file = "single_node.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) + 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 + assert int(res['retval']) == 0 + + +@pytest.mark.fast +def test_rest_core_multi_node() -> None: + """A simple multi node sophios/restapi test""" + inp_file = "multi_node.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) + 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 + assert int(res['retval']) == 0 + + +@pytest.mark.fast +def test_rest_core_multi_node_inline_cwl() -> None: + """A simple multi node (inline cwl) sophios/restapi test""" + inp_file = "multi_node_inline_cwl.json" inp: Json = {} - yaml_path = "workflow.json" - inp_path = Path(__file__).with_name(inp_file) + inp_path = Path(__file__).parent / 'rest_wfb_objects' / inp_file with open(inp_path, 'r', encoding='utf-8') as f: inp = json.load(f) - # check if object is conformant with our schema - df2012.is_valid(inp) print('----------- from rest api ----------- \n\n') scope = {} scope['type'] = 'http'