Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed representation according to ogcapi (fixes #263) #272

Merged
merged 6 commits into from
Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 60 additions & 58 deletions tests/functional/test_wps_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ def test_literal_io_from_package(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 1
assert desc["process"]["inputs"][0]["id"] == "url"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert "format" not in desc["process"]["inputs"][0]
assert isinstance(desc["process"]["outputs"], list)
assert len(desc["process"]["outputs"]) == 1
Expand Down Expand Up @@ -223,11 +223,11 @@ def test_literal_io_from_package_and_offering(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 2
assert desc["process"]["inputs"][0]["id"] == "literal_input_only_cwl_minimal"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert desc["process"]["inputs"][1]["id"] == "literal_input_both_cwl_and_wps"
assert desc["process"]["inputs"][1]["minOccurs"] == "1"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 1
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert desc["process"]["inputs"][1]["title"] == "Extra detail for I/O both in CWL and WPS", \
"Additional details defined only in WPS matching CWL I/O by ID should be preserved"
assert isinstance(desc["process"]["outputs"], list)
Expand Down Expand Up @@ -549,32 +549,32 @@ def test_complex_io_with_multiple_formats_and_defaults(self):

# process description input validation
assert desc["process"]["inputs"][0]["id"] == "single_value_single_format"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][0]["formats"]) == 1
assert desc["process"]["inputs"][0]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][0]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][1]["id"] == "multi_value_single_format"
assert desc["process"]["inputs"][1]["minOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 1
assert desc["process"]["inputs"][1]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][1]["formats"]) == 1
assert desc["process"]["inputs"][1]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
assert desc["process"]["inputs"][1]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][2]["id"] == "single_value_single_format_default"
assert desc["process"]["inputs"][2]["minOccurs"] == "0"
assert desc["process"]["inputs"][2]["maxOccurs"] == "1"
assert desc["process"]["inputs"][2]["minOccurs"] == 0
assert desc["process"]["inputs"][2]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][2]["formats"]) == 1
assert desc["process"]["inputs"][2]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][2]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][3]["id"] == "multi_value_single_format_default"
assert desc["process"]["inputs"][3]["minOccurs"] == "0"
assert desc["process"]["inputs"][3]["minOccurs"] == 0
assert desc["process"]["inputs"][3]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][3]["formats"]) == 1
assert desc["process"]["inputs"][3]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
assert desc["process"]["inputs"][3]["formats"][0]["default"] is True # only format available, auto default
assert desc["process"]["inputs"][4]["id"] == "single_value_multi_format"
assert desc["process"]["inputs"][4]["minOccurs"] == "1"
assert desc["process"]["inputs"][4]["maxOccurs"] == "1"
assert desc["process"]["inputs"][4]["minOccurs"] == 1
assert desc["process"]["inputs"][4]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][4]["formats"]) == 3
assert desc["process"]["inputs"][4]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][4]["formats"][0]["default"] is True # no explicit default, uses first
Expand All @@ -583,7 +583,7 @@ def test_complex_io_with_multiple_formats_and_defaults(self):
assert desc["process"]["inputs"][4]["formats"][2]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][4]["formats"][2]["default"] is False
assert desc["process"]["inputs"][5]["id"] == "multi_value_multi_format"
assert desc["process"]["inputs"][5]["minOccurs"] == "1"
assert desc["process"]["inputs"][5]["minOccurs"] == 1
assert desc["process"]["inputs"][5]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][5]["formats"]) == 3
assert desc["process"]["inputs"][5]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_NETCDF
Expand All @@ -593,8 +593,8 @@ def test_complex_io_with_multiple_formats_and_defaults(self):
assert desc["process"]["inputs"][5]["formats"][2]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][5]["formats"][2]["default"] is False
assert desc["process"]["inputs"][6]["id"] == "single_value_multi_format_default"
assert desc["process"]["inputs"][6]["minOccurs"] == "0"
assert desc["process"]["inputs"][6]["maxOccurs"] == "1"
assert desc["process"]["inputs"][6]["minOccurs"] == 0
assert desc["process"]["inputs"][6]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][6]["formats"]) == 3
assert desc["process"]["inputs"][6]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
assert desc["process"]["inputs"][6]["formats"][0]["default"] is True # no explicit default, uses first
Expand All @@ -603,7 +603,7 @@ def test_complex_io_with_multiple_formats_and_defaults(self):
assert desc["process"]["inputs"][6]["formats"][2]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][6]["formats"][2]["default"] is False
assert desc["process"]["inputs"][7]["id"] == "multi_value_multi_format_default"
assert desc["process"]["inputs"][7]["minOccurs"] == "0"
assert desc["process"]["inputs"][7]["minOccurs"] == 0
assert desc["process"]["inputs"][7]["maxOccurs"] == "unbounded"
assert len(desc["process"]["inputs"][7]["formats"]) == 3
assert desc["process"]["inputs"][7]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_JSON
Expand Down Expand Up @@ -780,51 +780,51 @@ def test_resolution_io_min_max_occurs(self):
desc, pkg = self.deploy_process(body)

assert desc["process"]["inputs"][0]["id"] == "required_literal"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert desc["process"]["inputs"][1]["id"] == "required_literal_default"
assert desc["process"]["inputs"][1]["minOccurs"] == "0"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 0
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert desc["process"]["inputs"][2]["id"] == "optional_literal_shortcut"
assert desc["process"]["inputs"][2]["minOccurs"] == "0"
assert desc["process"]["inputs"][2]["maxOccurs"] == "1"
assert desc["process"]["inputs"][2]["minOccurs"] == 0
assert desc["process"]["inputs"][2]["maxOccurs"] == 1
assert desc["process"]["inputs"][3]["id"] == "optional_literal_explicit"
assert desc["process"]["inputs"][3]["minOccurs"] == "0"
assert desc["process"]["inputs"][3]["maxOccurs"] == "1"
assert desc["process"]["inputs"][3]["minOccurs"] == 0
assert desc["process"]["inputs"][3]["maxOccurs"] == 1
assert desc["process"]["inputs"][4]["id"] == "required_array_shortcut"
assert desc["process"]["inputs"][4]["minOccurs"] == "1"
assert desc["process"]["inputs"][4]["minOccurs"] == 1
assert desc["process"]["inputs"][4]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][5]["id"] == "required_array_explicit"
assert desc["process"]["inputs"][5]["minOccurs"] == "1"
assert desc["process"]["inputs"][5]["minOccurs"] == 1
assert desc["process"]["inputs"][5]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][6]["id"] == "optional_array_shortcut"
assert desc["process"]["inputs"][6]["minOccurs"] == "0"
assert desc["process"]["inputs"][6]["minOccurs"] == 0
assert desc["process"]["inputs"][6]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][7]["id"] == "optional_array_explicit"
assert desc["process"]["inputs"][7]["minOccurs"] == "0"
assert desc["process"]["inputs"][7]["minOccurs"] == 0
assert desc["process"]["inputs"][7]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][8]["id"] == "required_literal_min_fixed_by_wps"
assert desc["process"]["inputs"][8]["minOccurs"] == "1"
assert desc["process"]["inputs"][8]["maxOccurs"] == "1"
assert desc["process"]["inputs"][8]["minOccurs"] == 1
assert desc["process"]["inputs"][8]["maxOccurs"] == 1
assert desc["process"]["inputs"][9]["id"] == "optional_literal_min_fixed_by_wps"
assert desc["process"]["inputs"][9]["minOccurs"] == "0"
assert desc["process"]["inputs"][9]["maxOccurs"] == "1"
assert desc["process"]["inputs"][9]["minOccurs"] == 0
assert desc["process"]["inputs"][9]["maxOccurs"] == 1
assert desc["process"]["inputs"][10]["id"] == "required_array_min_fixed_by_wps"
# FIXME: https://github.com/crim-ca/weaver/issues/50
# `maxOccurs=1` not updated to `maxOccurs="unbounded"` as it is evaluated as a single value,
# but it should be considered an array since `minOccurs>1`
# (see: https://github.com/crim-ca/weaver/issues/17)
assert desc["process"]["inputs"][10]["minOccurs"] == "2"
assert desc["process"]["inputs"][10]["minOccurs"] == 2
# assert desc["process"]["inputs"][10]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][11]["id"] == "required_array_min_optional_fixed_by_wps"
assert desc["process"]["inputs"][11]["minOccurs"] == "2"
assert desc["process"]["inputs"][11]["minOccurs"] == 2
# assert desc["process"]["inputs"][11]["maxOccurs"] == "unbounded"
assert desc["process"]["inputs"][12]["id"] == "required_array_max_fixed_by_wps"
assert desc["process"]["inputs"][12]["minOccurs"] == "1"
assert desc["process"]["inputs"][12]["maxOccurs"] == "10"
assert desc["process"]["inputs"][12]["minOccurs"] == 1
assert desc["process"]["inputs"][12]["maxOccurs"] == 10
assert desc["process"]["inputs"][13]["id"] == "optional_array_max_fixed_by_wps"
assert desc["process"]["inputs"][13]["minOccurs"] == "0"
assert desc["process"]["inputs"][13]["maxOccurs"] == "10"
assert desc["process"]["inputs"][13]["minOccurs"] == 0
assert desc["process"]["inputs"][13]["maxOccurs"] == 10

assert pkg["inputs"][0]["id"] == "required_literal"
assert pkg["inputs"][0]["type"] == "string"
Expand Down Expand Up @@ -920,8 +920,10 @@ def test_valid_io_min_max_occurs_as_str_or_int(self):
assert desc["process"]["inputs"][i]["id"] == process_input["id"]
for field in ["minOccurs", "maxOccurs"]:
proc_in_res = desc["process"]["inputs"][i][field]
proc_in_exp = process_input[field]
assert proc_in_res in (proc_in_exp, str(proc_in_exp)), \
proc_in_exp = (
int(process_input[field]) if str(process_input[field]).isnumeric() else process_input[field]
)
assert proc_in_res == proc_in_exp, \
"Field '{}' of input '{}'({}) is expected to be '{}' but was '{}'" \
.format(field, process_input, i, proc_in_exp, proc_in_res)

Expand Down Expand Up @@ -1009,8 +1011,8 @@ def test_complex_io_from_package(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 1
assert desc["process"]["inputs"][0]["id"] == "url"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert isinstance(desc["process"]["inputs"][0]["formats"], list)
assert len(desc["process"]["inputs"][0]["formats"]) == 1
assert isinstance(desc["process"]["inputs"][0]["formats"][0], dict)
Expand Down Expand Up @@ -1104,15 +1106,15 @@ def test_complex_io_from_package_and_offering(self):
assert isinstance(desc["process"]["inputs"], list)
assert len(desc["process"]["inputs"]) == 2
assert desc["process"]["inputs"][0]["id"] == "complex_input_only_cwl_minimal"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][0]["formats"]) == 1, \
"Default format should be added to process definition when omitted from both CWL and WPS"
assert desc["process"]["inputs"][0]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
assert desc["process"]["inputs"][0]["formats"][0]["default"] is True
assert desc["process"]["inputs"][1]["id"] == "complex_input_both_cwl_and_wps"
assert desc["process"]["inputs"][1]["minOccurs"] == "1"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 1
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert len(desc["process"]["inputs"][1]["formats"]) == 1, \
"Default format should be added to process definition when omitted from both CWL and WPS"
assert desc["process"]["inputs"][1]["formats"][0]["mimeType"] == CONTENT_TYPE_TEXT_PLAIN
Expand Down Expand Up @@ -1210,17 +1212,17 @@ def test_literal_and_complex_io_from_wps_xml_reference(self):
assert desc["process"]["inputs"][0]["id"] == "tasmax"
assert desc["process"]["inputs"][0]["title"] == "Resource"
assert desc["process"]["inputs"][0]["abstract"] == "NetCDF Files or archive (tar/zip) containing netCDF files."
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "1000"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 1000
assert len(desc["process"]["inputs"][0]["formats"]) == 1
assert desc["process"]["inputs"][0]["formats"][0]["default"] is True
assert desc["process"]["inputs"][0]["formats"][0]["mimeType"] == CONTENT_TYPE_APP_NETCDF
assert desc["process"]["inputs"][0]["formats"][0]["encoding"] == "base64"
assert desc["process"]["inputs"][1]["id"] == "freq"
assert desc["process"]["inputs"][1]["title"] == "Frequency"
assert desc["process"]["inputs"][1]["abstract"] == "Resampling frequency"
assert desc["process"]["inputs"][1]["minOccurs"] == "0"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 0
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert "formats" not in desc["process"]["inputs"][1]
assert len(desc["process"]["outputs"]) == 2
assert desc["process"]["outputs"][0]["id"] == "output_netcdf"
Expand Down Expand Up @@ -1307,21 +1309,21 @@ def test_enum_array_and_multi_format_inputs_from_wps_xml_reference(self):
assert desc["process"]["inputs"][0]["id"] == "region"
assert desc["process"]["inputs"][0]["title"] == "Region"
assert desc["process"]["inputs"][0]["abstract"] == "Country code, see ISO-3166-3"
assert desc["process"]["inputs"][0]["minOccurs"] == "1"
assert desc["process"]["inputs"][0]["maxOccurs"] == "220"
assert desc["process"]["inputs"][0]["minOccurs"] == 1
assert desc["process"]["inputs"][0]["maxOccurs"] == 220
assert "formats" not in desc["process"]["inputs"][0]
assert desc["process"]["inputs"][1]["id"] == "mosaic"
assert desc["process"]["inputs"][1]["title"] == "Union of multiple regions"
assert desc["process"]["inputs"][1]["abstract"] == \
"If True, selected regions will be merged into a single geometry." # noqa
assert desc["process"]["inputs"][1]["minOccurs"] == "0"
assert desc["process"]["inputs"][1]["maxOccurs"] == "1"
assert desc["process"]["inputs"][1]["minOccurs"] == 0
assert desc["process"]["inputs"][1]["maxOccurs"] == 1
assert "formats" not in desc["process"]["inputs"][1]
assert desc["process"]["inputs"][2]["id"] == "resource"
assert desc["process"]["inputs"][2]["title"] == "Resource"
assert desc["process"]["inputs"][2]["abstract"] == "NetCDF Files or archive (tar/zip) containing NetCDF files."
assert desc["process"]["inputs"][2]["minOccurs"] == "1"
assert desc["process"]["inputs"][2]["maxOccurs"] == "1000"
assert desc["process"]["inputs"][2]["minOccurs"] == 1
assert desc["process"]["inputs"][2]["maxOccurs"] == 1000
# note: TAR should remain as literal format in the WPS context (not mapped/added as GZIP when resolved for CWL)
assert len(desc["process"]["inputs"][2]["formats"]) == 3
assert desc["process"]["inputs"][2]["formats"][0]["default"] is True
Expand Down
4 changes: 2 additions & 2 deletions tests/wps_restapi/test_processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,8 @@ def assert_deployed_wps3(response_json, expected_process_id):
assert expected_process_id in response_json["process"]["id"]
assert len(response_json["process"]["inputs"]) == 1
assert response_json["process"]["inputs"][0]["id"] == "input-1"
assert response_json["process"]["inputs"][0]["minOccurs"] == "1"
assert response_json["process"]["inputs"][0]["maxOccurs"] == "1"
assert response_json["process"]["inputs"][0]["minOccurs"] == 1
assert response_json["process"]["inputs"][0]["maxOccurs"] == 1
assert "formats" not in response_json["process"]["inputs"][0] # literal data doesn't have "formats"
assert len(response_json["process"]["outputs"]) == 1
assert response_json["process"]["outputs"][0]["id"] == "output"
Expand Down
11 changes: 10 additions & 1 deletion weaver/datatype.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,16 @@ def version(self):
@property
def inputs(self):
# type: () -> Optional[List[Dict[str, Any]]]
return self.get("inputs")
inputs = self.get("inputs")
if inputs is not None:
for input_ in inputs:
maxOccurs = input_.get("maxOccurs", False)
minOccurs = input_.get("minOccurs", False)
if minOccurs:
input_["minOccurs"] = int(minOccurs)
if maxOccurs and maxOccurs != "unbounded":
input_["maxOccurs"] = int(maxOccurs)
trapsidanadir marked this conversation as resolved.
Show resolved Hide resolved
return inputs

@property
def outputs(self):
Expand Down