Пример #1
0
 def set_step_outputs(self, invocation_step, outputs, already_persisted=False):
     step = invocation_step.workflow_step
     if invocation_step.output_value:
         outputs[invocation_step.output_value.workflow_output.output_name] = invocation_step.output_value.value
     self.outputs[step.id] = outputs
     if not already_persisted:
         workflow_outputs_by_name = {wo.output_name: wo for wo in step.workflow_outputs}
         for output_name, output_object in outputs.items():
             if hasattr(output_object, "history_content_type"):
                 invocation_step.add_output(output_name, output_object)
             else:
                 # Add this non-data, non workflow-output output to the workflow outputs.
                 # This is required for recovering the output in the next scheduling iteration,
                 # and should be replaced with a WorkflowInvocationStepOutputValue ASAP.
                 if not workflow_outputs_by_name.get(output_name) and not output_object == modules.NO_REPLACEMENT:
                     workflow_output = model.WorkflowOutput(step, output_name=output_name)
                     step.workflow_outputs.append(workflow_output)
         for workflow_output in step.workflow_outputs:
             output_name = workflow_output.output_name
             if output_name not in outputs:
                 message = f"Failed to find expected workflow output [{output_name}] in step outputs [{outputs}]"
                 # raise KeyError(message)
                 # Pre-18.01 we would have never even detected this output wasn't configured
                 # and even in 18.01 we don't have a way to tell the user something bad is
                 # happening so I guess we just log a debug message and continue sadly for now.
                 # Once https://github.com/galaxyproject/galaxy/issues/5142 is complete we could
                 # at least tell the user what happened, give them a warning.
                 log.debug(message)
                 continue
             output = outputs[output_name]
             self._record_workflow_output(
                 step,
                 workflow_output,
                 output=output,
             )
Пример #2
0
    def update_workflow_from_dict(self, trans, stored_workflow, workflow_data, from_editor=False):
        # Put parameters in workflow mode
        trans.workflow_building_mode = True
        # Convert incoming workflow data from json if coming from editor
        data = json.loads(workflow_data) if from_editor else workflow_data
        # Create new workflow from incoming data
        workflow = model.Workflow()
        # Just keep the last name (user can rename later)
        workflow.name = stored_workflow.name
        # Assume no errors until we find a step that has some
        workflow.has_errors = False
        # Create each step
        steps = []
        # The editor will provide ids for each step that we don't need to save,
        # but do need to use to make connections
        steps_by_external_id = {}
        errors = []
        for key, step_dict in data['steps'].iteritems():
            is_tool = is_tool_module_type( step_dict[ 'type' ] )
            if is_tool and not trans.app.toolbox.has_tool( step_dict['tool_id'], exact=True ):
                errors.append("Step %s requires tool '%s'." % (step_dict['id'], step_dict['tool_id']))
        if errors:
            raise MissingToolsException(workflow, errors)

        # First pass to build step objects and populate basic values
        for step_dict in self.__walk_step_dicts( data ):
            module, step = self.__module_from_dict( trans, step_dict, secure=from_editor )
            # Create the model class for the step
            steps.append( step )
            steps_by_external_id[ step_dict['id' ] ] = step
            if 'workflow_outputs' in step_dict:
                for output_name in step_dict['workflow_outputs']:
                    m = model.WorkflowOutput(workflow_step=step, output_name=output_name)
                    trans.sa_session.add(m)
            if step.tool_errors:
                # DBTODO Check for conditional inputs here.
                workflow.has_errors = True

        # Second pass to deal with connections between steps
        self.__connect_workflow_steps( steps, steps_by_external_id )

        # Order the steps if possible
        attach_ordered_steps( workflow, steps )
        # Connect up
        workflow.stored_workflow = stored_workflow
        stored_workflow.latest_workflow = workflow
        # Persist
        trans.sa_session.flush()
        # Return something informative
        errors = []
        if workflow.has_errors:
            errors.append( "Some steps in this workflow have validation errors" )
        if workflow.has_cycles:
            errors.append( "This workflow contains cycles" )
        return workflow, errors
Пример #3
0
def example_invocation(trans):
    invocation = model.WorkflowInvocation()
    workflow = yaml_to_model(TEST_WORKFLOW_YAML)
    workflow.id = 342
    invocation.id = 44
    invocation.workflow = workflow

    # TODO: fix this to use workflow id and eliminate hack.
    stored_workflow = model.StoredWorkflow()
    stored_workflow.id = 342
    invocation.workflow.stored_workflow = stored_workflow

    hda = model.HistoryDatasetAssociation(create_dataset=True, sa_session=trans.sa_session)
    hda.id = 567
    invocation.add_input(hda, step=workflow.steps[0])
    out_hda = model.HistoryDatasetAssociation(create_dataset=True, sa_session=trans.sa_session)
    out_hda.id = 563
    wf_output = model.WorkflowOutput(workflow.steps[2], label="output_label")
    invocation.add_output(wf_output, workflow.steps[2], out_hda)
    return invocation
Пример #4
0
def _dict_to_workflow_output(workflow_step, as_dict):
    output = model.WorkflowOutput(workflow_step)
    for key, value in as_dict.items():
        setattr(output, key, value)
    return output
Пример #5
0
 def tag_outputs(self, trans, id, **kwargs):
     stored = self.get_stored_workflow(trans, id, check_ownership=False)
     user = trans.get_user()
     if stored.user != user:
         if trans.sa_session.query(model.StoredWorkflowUserShareAssociation) \
                 .filter_by(user=user, stored_workflow=stored).count() == 0:
             error("Workflow is not owned by or shared with current user")
     # Get the latest revision
     workflow = stored.latest_workflow
     # It is possible for a workflow to have 0 steps
     if len(workflow.steps) == 0:
         error(
             "Workflow cannot be tagged for outputs because it does not have any steps"
         )
     if workflow.has_cycles:
         error(
             "Workflow cannot be tagged for outputs because it contains cycles"
         )
     if workflow.has_errors:
         error(
             "Workflow cannot be tagged for outputs because of validation errors in some steps"
         )
     # Build the state for each step
     errors = {}
     has_upgrade_messages = False
     # has_errors is never used
     # has_errors = False
     if kwargs:
         # If kwargs were provided, the states for each step should have
         # been POSTed
         for step in workflow.steps:
             if step.type == 'tool':
                 # Extract just the output flags for this step.
                 p = "%s|otag|" % step.id
                 l = len(p)
                 outputs = [
                     k[l:] for (k, v) in kwargs.items() if k.startswith(p)
                 ]
                 if step.workflow_outputs:
                     for existing_output in step.workflow_outputs:
                         if existing_output.output_name not in outputs:
                             trans.sa_session.delete(existing_output)
                         else:
                             outputs.remove(existing_output.output_name)
                 for outputname in outputs:
                     m = model.WorkflowOutput(workflow_step_id=int(step.id),
                                              output_name=outputname)
                     trans.sa_session.add(m)
     # Prepare each step
     trans.sa_session.flush()
     module_injector = WorkflowModuleInjector(trans)
     for step in workflow.steps:
         step.upgrade_messages = {}
         # Contruct modules
         module_injector.inject(step)
         if step.upgrade_messages:
             has_upgrade_messages = True
         if step.type == 'tool' or step.type is None:
             # Error dict
             if step.tool_errors:
                 errors[step.id] = step.tool_errors
     # Render the form
     return trans.fill_template("workflow/tag_outputs.mako",
                                steps=workflow.steps,
                                workflow=stored,
                                has_upgrade_messages=has_upgrade_messages,
                                errors=errors,
                                incoming=kwargs)