More work on converting tool inputs to json.

- Drop version requirement per commends by @bgruening.
 - Add examples for conditionals, repeats, sections, colors, and booleans specified truevalue/falsevalue.
 - Various bug fixes unearthed by new test cases.
This commit is contained in:
John Chilton
2015-12-30 11:17:13 +00:00
parent d5d404c912
commit de0c913b8b
4 changed files with 113 additions and 59 deletions
+1 -5
View File
@@ -646,11 +646,7 @@ class Tool( object, Dictifiable ):
name = inputs_elem.get( "name" )
filename = inputs_elem.get( "filename", None )
format = inputs_elem.get("format", "json")
version_str = inputs_elem.get("version", "1")
if not version_str:
raise ValueError("inputs configfile tag must define a version attribute")
version = int(version_str)
content = dict(format=format, version=version)
content = dict(format=format)
self.config_files.append( ( name, filename, content ) )
for conf_elem in conf_parent_elem.findall( "configfile" ):
name = conf_elem.get( "name" )
+5 -2
View File
@@ -533,8 +533,11 @@ class ToolEvaluator( object ):
if isinstance( content, basestring ):
return content, True
assert content["format"] == "json"
assert content["version"] == 1
content_format = content["format"]
if content_format != "json":
template = "Galaxy can only currently convert inputs to json, format [%s] is unhandled"
message = template % content_format
raise Exception(message)
return json.dumps(wrapped_json.json_wrap(self.tool.inputs, self.param_dict)), False
+57 -49
View File
@@ -2,65 +2,73 @@ import logging
log = logging.getLogger(__name__)
SKIP_INPUT = object()
def json_wrap(inputs, input_values, as_dict=None, handle_files="SKIP"):
if as_dict is None:
as_dict = {}
for input in inputs.itervalues():
input_name = input.name
input_type = input.type
value = input_values[input_name]
if input_type == "repeat":
repeat_job_value = []
for d in input_values[input.name]:
repeat_instance_job_value = {}
json_wrap(input.inputs, d, repeat_instance_job_value)
repeat_job_value.append(repeat_instance_job_value)
as_dict[input_name] = repeat_job_value
if input_type == "conditional":
values = input_values[input_name]
current = values["__current_case__"]
conditional_job_value = {}
json_wrap(input.cases[current].inputs, values, conditional_job_value)
as_dict[input_name] = conditional_job_value
if input_type == "section":
values = input_values[input_name]
section_job_value = {}
json_wrap(input.inputs, values, section_job_value)
as_dict[input_name] = section_job_value
elif input_type == "data" and input.multiple:
if handle_files == "SKIP":
continue
raise NotImplementedError()
elif input_type == "data":
if handle_files == "SKIP":
continue
raise NotImplementedError()
elif input_type == "data_collection":
if handle_files == "SKIP":
continue
raise NotImplementedError()
elif input_type == "select" or input_type == "text":
value = input_values[input_name]
json_value = _cast_if_not_none(value, str)
as_dict[input_name] = json_value
elif input_type == "float":
value = input_values[input_name]
json_value = _cast_if_not_none(value, float, empty_to_none=True)
as_dict[input_name] = json_value
elif input_type == "integer":
value = input_values[input_name]
json_value = _cast_if_not_none(value, int, empty_to_none=True)
as_dict[input_name] = json_value
elif input_type == "boolean":
value = input_values[input_name]
json_value = _cast_if_not_none(value, bool)
as_dict[input_name] = json_value
else:
raise NotImplementedError("input_type [%s] not implemented" % input_type)
json_value = _json_wrap_input(input, value, handle_files=handle_files)
if json_value is SKIP_INPUT:
continue
as_dict[input_name] = json_value
return as_dict
def _json_wrap_input(input, value, handle_files="SKIP"):
input_type = input.type
if input_type == "repeat":
repeat_job_value = []
for d in value:
repeat_instance_job_value = {}
json_wrap(input.inputs, d, repeat_instance_job_value)
repeat_job_value.append(repeat_instance_job_value)
json_value = repeat_job_value
elif input_type == "conditional":
values = value
current = values["__current_case__"]
conditional_job_value = {}
json_wrap(input.cases[current].inputs, values, conditional_job_value)
test_param = input.test_param
test_param_name = test_param.name
test_value = _json_wrap_input(test_param, values[test_param_name])
conditional_job_value[test_param_name] = test_value
json_value = conditional_job_value
elif input_type == "section":
values = value
section_job_value = {}
json_wrap(input.inputs, values, section_job_value)
json_value = section_job_value
elif input_type == "data" and input.multiple:
if handle_files == "SKIP":
return SKIP_INPUT
raise NotImplementedError()
elif input_type == "data":
if handle_files == "SKIP":
return SKIP_INPUT
raise NotImplementedError()
elif input_type == "data_collection":
if handle_files == "SKIP":
return SKIP_INPUT
raise NotImplementedError()
elif input_type == "select" or input_type == "text" or input_type == "color":
json_value = _cast_if_not_none(value, str)
elif input_type == "float":
json_value = _cast_if_not_none(value, float, empty_to_none=True)
elif input_type == "integer":
json_value = _cast_if_not_none(value, int, empty_to_none=True)
elif input_type == "boolean":
json_value = _cast_if_not_none(value, bool)
else:
raise NotImplementedError("input_type [%s] not implemented" % input_type)
return json_value
def _cast_if_not_none(value, cast_to, empty_to_none=False):
# log.debug("value [%s], type[%s]" % (value, type(value)))
if value is None or (empty_to_none and str(value) == ''):
+50 -3
View File
@@ -1,4 +1,7 @@
<tool id="inputs_as_json" name="inputs_as_json" version="1.0.0">
<command detect_errors="exit_code">
python $check_inputs $inputs $test_case
</command>
<configfiles>
<inputs name="inputs" format="json" version="1" />
<configfile name="check_inputs"><![CDATA[
@@ -17,28 +20,36 @@ if test_case == "1":
assert_equals(as_dict["test_case"], 1)
assert_equals(as_dict["text_test"], "foo")
assert_equals(as_dict["booltest"], True)
assert_equals(as_dict["booltest2"], True)
assert_equals(as_dict["inttest"], 12456)
assert_equals(as_dict["floattest"], 6.789)
assert_equals(as_dict["radio_select"], "a_radio")
assert_equals(as_dict["repeat"][0]["r"], "000000")
assert_equals(as_dict["repeat"][1]["r"], "FFFFFF")
assert_equals(as_dict["cond"]["more_text"], "fdefault")
assert_equals(as_dict["section_example"]["section_text"], "section_default")
elif test_case == "2":
assert_equals(as_dict["test_case"], 2)
assert_equals(as_dict["text_test"], "bar")
assert_equals(as_dict["booltest"], False)
assert_equals(as_dict["booltest2"], False)
assert_equals(as_dict["inttest"], None)
assert_equals(as_dict["floattest"], 1.0)
assert_equals(as_dict["radio_select"], "a_radio")
assert_equals(as_dict["repeat"][0]["r"], "000000")
assert_equals(as_dict["cond"]["cond_test"], "second")
assert_equals(as_dict["cond"]["more_text"], "sdefault")
assert_equals(as_dict["section_example"]["section_text"], "section_default")
with open("output", "w") as f:
f.write("okay\n")
]]></configfile>
</configfiles>
<command>
python $check_inputs $inputs $test_case
</command>
<inputs>
<param name="test_case" type="integer" value="0" />
<param name="text_test" type="text" />
<param name="booltest" truevalue="booltrue" falsevalue="boolfalse" checked="false" type="boolean" />
<param name="booltest2" truevalue="booltrue" falsevalue="boolfalse" checked="false" type="boolean" />
<param name="inttest" type="integer" optional="true" />
<param name="floattest" value="1.0" type="float" />
<param name="radio_select" type="select" display="radio">
@@ -46,6 +57,24 @@ with open("output", "w") as f:
<option value="b_radio">B Radio</option>
<option value="c_radio">C Radio</option>
</param>
<repeat name="repeat" title="Repeat" min="1">
<param name="r" type="color" />
</repeat>
<conditional name="cond">
<param name="cond_test" type="select">
<option value="first" selected="true">First</option>
<option value="second">Second</option>
</param>
<when value="first">
<param name="more_text" type="text" value="fdefault" />
</when>
<when value="second">
<param name="more_text" type="text" value="sdefault" />
</when>
</conditional>
<section name="section_example">
<param name="section_text" type="text" value="section_default" />
</section>
</inputs>
<outputs>
<data name="out_file1" from_work_dir="output" format="txt" />
@@ -55,8 +84,18 @@ with open("output", "w") as f:
<param name="test_case" value="1" />
<param name="text_test" value="foo" />
<param name="booltest" value="true" />
<param name="booltest2" value="booltrue" />
<param name="inttest" value="12456" />
<param name="floattest" value="6.789" />
<repeat name="repeat">
<param name="r" value="000000"/>
</repeat>
<repeat name="repeat">
<param name="r" value="FFFFFF"/>
</repeat>
<conditional name="cond">
<param name="cond_test" value="first" />
</conditional>
<output name="out_file1">
<assert_contents>
<has_line line="okay" />
@@ -67,8 +106,13 @@ with open("output", "w") as f:
<param name="test_case" value="2" />
<param name="text_test" value="bar" />
<param name="booltest" value="false" />
<param name="booltest2" value="boolfalse" />
<!-- Testing null integers -->
<!-- <param name="inttest" value="12456" /> -->
<param name="r" value="000000" />
<conditional name="cond">
<param name="cond_test" value="second" />
</conditional>
<output name="out_file1">
<assert_contents>
<has_line line="okay" />
@@ -76,4 +120,7 @@ with open("output", "w") as f:
</output>
</test>
</tests>
<help>
Test tool demonstrating the special inputs config file.
</help>
</tool>