def _make_schema_def_dict(self): """ Make dictionary from SchemaDefRequirement to populate inputs parameters fully. :param schema_def_requirement: SchemaDefRequirement attribute_value. :return: keys are input names, values are input parameter fields to drop into inputs section. :rtype: dict """ schema_def_types = self.types # list of InputRecordSchema | InputArraySchema | InputEnumSchema objects. if not isinstance(schema_def_types, list): raise NotImplementedError schema_def_dict = {} for type_def in schema_def_types: type_def_name = get_shortened_id(type_def.name) schema_def_dict[type_def_name] = type_def.save() schema_def_dict[type_def_name]['name'] = get_shortened_id( schema_def_dict[type_def_name]['name']) if type_def.type == 'record': pass elif type_def.type == 'array': pass elif type_def.type == 'enum': raise NotImplementedError( "EnumRecordSchema puts long id's in for symbols. Make sure this is handled." ) else: raise ValueError( f"Unexpected InputSchema type {repr(type_def)}") return schema_def_dict
def get_shortened_source_ids( self): # Might need to rename this if it needs to do more. if isinstance(self.source, str): source_shortname = get_shortened_id(self.source) elif isinstance(self.source, list): source_shortname = [ get_shortened_id(source) for source in self.source ] else: raise NotImplementedError( f"Deal with WorflowStepInput.source of {self.source}") return source_shortname
def to_dict_with_id_key(self): step_dict = CommentedMap() step_id = get_shortened_id(self.id) step_dict[step_id] = CommentedMap() step_dict[step_id]['run'] = get_shortened_id(self.run) step_dict[step_id]['in'] = CommentedMap() for step_input in self.in_: # list of WorkflowStepInput instances. step_dict[step_id]['in'].update( step_input.get_workflow_step_inputs( )) # WorkflowStepInput class # step_dict[step_id]['in'] = [step_input.return_workflow_step_input_dict() for step_input in self.in_] step_dict[step_id]['out'] = [ get_shortened_id(output) for output in self.out ] return step_dict
def get_output_parameter_by_short_id(self, id_): output_parameter = None for command_output_parameter in self.outputs: if get_shortened_id(command_output_parameter.id) == id_: output_parameter = command_output_parameter break return output_parameter
def get_outputs_dict(self): """ Transform CommandLineTool.outputs into a nested dict. """ outputs_dict = CommentedMap() for output in self.outputs: output_id = get_shortened_id(output.id) outputs_dict[output_id] = output.get_ordered_output() return outputs_dict
def to_dict_with_id_key(self): output_dict = CommentedMap() output_id = get_shortened_id(self.id) output_dict[output_id] = CommentedMap() output_dict[output_id]['type'] = self.type output_source_id = self.outputSource rel_output_source_id = '/'.join( output_source_id.split('#')[-1].split('/')[1:]) output_dict[output_id]['outputSource'] = rel_output_source_id return output_dict
def make_template(self): """ Make a cwl job file template. Inspired by cwl-tool --make-template (calls cwl-tool.main.generate_input_template https://github.com/common-workflow-language/cwltool/blob/main/cwltool/main.py) :return: """ template = CommentedMap() for input in self.cwl_inputs: input_name = get_shortened_id(input.id) template_param_value, comment = self._make_input_value_field( input, self._cwl_schema_def_requirement) template.insert(0, input_name, template_param_value, comment) return template
def get_workflow_step_inputs(self): step_input_dict = CommentedMap() input_id = get_shortened_id(self.id) step_input_attrs = list(self.attrs) step_input_attrs.remove('id') # Handled explicitly step_input_attrs.remove('source') # Handled explicitly step_input_dict[input_id] = CommentedMap() step_input_dict[input_id]['source'] = self.get_shortened_source_ids() step_input_dict[input_id].update({ step_input_attr: getattr(self, step_input_attr) for step_input_attr in step_input_attrs if getattr(self, step_input_attr) }) return step_input_dict
def _make_inputs_schema_dict(self): """ Make the schema from inputs to validate job file with. :return (dict): """ inputs_fields = {} for input in self.cwl_inputs: # inputs is a list of CommandInputParameter inputs_fields[get_shortened_id(input.id)] = { 'type': input._handle_input_type_field(self.cwl_schema_def_requirement) } schema_dict = deepcopy(InputsSchema.template_dict) _, inputs_field_index = get_dict_from_list(schema_dict['$graph'], 'name', 'InputsField') schema_dict['$graph'][inputs_field_index]['fields'] = inputs_fields return schema_dict
def _handle_str_input_type(self, type_, schema_def_requirement): """ Should be the terminating function of walking CommandInputParameter.type fields. The value of _type must be a string here. Return type if type is CWLType, otherwise return type from SchemaDefRequirement dict. :param _type: :param schema_def_dict: :return: """ if type_ in cwl_types: type_ = type_ else: schema_def_dict = schema_def_requirement._make_schema_def_dict() schema_def_name = get_shortened_id(type_) type_ = schema_def_dict[schema_def_name] return type_
def get_sorted_inputs_dict(self): """ Transform CommandLineTool.inputs into a nested dict attribute_value sorted based on CommandLineBinding. CommandInputParameter objects cannot be represented by yaml (I could register it I guess???). """ clt_inputs_list = self.inputs unsorted_inputs_dict = {} sort_keys_list = self._make_sorted_input_names(clt_inputs_list) schema_def_requirement = self.get_schema_def_requirement() for command_input in clt_inputs_list: input_id = get_shortened_id(command_input.id) ordered_input_field = command_input.get_ordered_input_map( schema_def_requirement) unsorted_inputs_dict[input_id] = ordered_input_field sorted_inputs_dict = CommentedMap( (input_name, unsorted_inputs_dict[input_name]) for input_name in sort_keys_list) return sorted_inputs_dict
def _make_sorted_input_names(inputs_list): """ Sort inputs according to their command line binding order. :return: list of input ids (names) sorted by command line binding order order. :rtype: list """ sort_key_dict = {} for input in inputs_list: command_line_binding = input.inputBinding if not command_line_binding: # Will not appear on command line. continue position = command_line_binding.position # Will be None if not specified. if not position: position = 999 input_id = get_shortened_id(input.id) sort_key = [position, input_id] sort_key_dict[input_id] = sort_key sorted_ids = sorted( sort_key_dict.keys(), key=lambda sort_key: (sort_key_dict[sort_key][0], sort_key_dict[sort_key][1])) return sorted_ids
def to_dict_with_id_key(self): input_dict = CommentedMap() input_id = get_shortened_id(self.id) input_dict[input_id] = CommentedMap() input_dict[input_id]['type'] = self.type return input_dict
def get_input_parameter_by_short_id(self, id_): for input_parameter in self.inputs: if get_shortened_id(input_parameter.id) == id_: return input_parameter return