Пример #1
0
    def build_workflow_from_dict(
        self,
        trans,
        data,
        source=None,
        add_to_menu=False,
        publish=False,
        create_stored_workflow=True,
        exact_tools=False,
    ):
        # Put parameters in workflow mode
        trans.workflow_building_mode = True
        # If there's a source, put it in the workflow name.
        if source:
            name = "%s (imported from %s)" % (data['name'], source)
        else:
            name = data['name']
        workflow, missing_tool_tups = self._workflow_from_dict(
            trans,
            data,
            name=name,
            exact_tools=exact_tools,
        )
        if 'uuid' in data:
            workflow.uuid = data['uuid']

        if create_stored_workflow:
            # Connect up
            stored = model.StoredWorkflow()
            stored.name = workflow.name
            workflow.stored_workflow = stored
            stored.latest_workflow = workflow
            stored.user = trans.user
            stored.published = publish
            if data['annotation']:
                annotation = sanitize_html(data['annotation'], 'utf-8',
                                           'text/html')
                self.add_item_annotation(trans.sa_session, stored.user, stored,
                                         annotation)

            # Persist
            trans.sa_session.add(stored)

            if add_to_menu:
                if trans.user.stored_workflow_menu_entries is None:
                    trans.user.stored_workflow_menu_entries = []
                menuEntry = model.StoredWorkflowMenuEntry()
                menuEntry.stored_workflow = stored
                trans.user.stored_workflow_menu_entries.append(menuEntry)

        else:
            stored = None
            # Persist
            trans.sa_session.add(workflow)

        trans.sa_session.flush()

        return CreatedWorkflow(stored_workflow=stored,
                               workflow=workflow,
                               missing_tools=missing_tool_tups)
Пример #2
0
    def update( self, trans, id, payload, **kwds ):
        """
        * PUT /api/workflows/{id}
            updates the workflow stored with ``id``

        :type   id:      str
        :param  id:      the encoded id of the workflow to update
        :type   payload: dict
        :param  payload: a dictionary containing any or all the
            * workflow   the json description of the workflow as would be
                         produced by GET workflows/<id>/download or
                         given to `POST workflows`

                         The workflow contents will be updated to target
                         this.

            * name       optional string name for the workflow, if not present in payload,
                         name defaults to existing name
            * annotation optional string annotation for the workflow, if not present in payload,
                         annotation defaults to existing annotation
            * menu_entry optional boolean marking if the workflow should appear in the user's menu,
                         if not present, workflow menu entries are not modified

        :rtype:     dict
        :returns:   serialized version of the workflow
        """
        stored_workflow = self.__get_stored_workflow( trans, id )
        if 'workflow' in payload:
            stored_workflow.name = sanitize_html(payload['name']) if ('name' in payload) else stored_workflow.name

            if 'annotation' in payload:
                newAnnotation = sanitize_html(payload['annotation'])
                self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, newAnnotation)

            if 'menu_entry' in payload:
                if payload['menu_entry']:
                    menuEntry = model.StoredWorkflowMenuEntry()
                    menuEntry.stored_workflow = stored_workflow
                    trans.get_user().stored_workflow_menu_entries.append(menuEntry)
                else:
                    # remove if in list
                    entries = {x.stored_workflow_id: x for x in trans.get_user().stored_workflow_menu_entries}
                    if (trans.security.decode_id(id) in entries):
                        trans.get_user().stored_workflow_menu_entries.remove(entries[trans.security.decode_id(id)])

            try:
                workflow, errors = self.workflow_contents_manager.update_workflow_from_dict(
                    trans,
                    stored_workflow,
                    payload[ 'workflow' ],
                )
            except workflows.MissingToolsException:
                raise exceptions.MessageException( "This workflow contains missing tools. It cannot be saved until they have been removed from the workflow or installed." )
        else:
            message = "Updating workflow requires dictionary containing 'workflow' attribute with new JSON description."
            raise exceptions.RequestParameterInvalidException( message )
        return self.workflow_contents_manager.workflow_to_dict( trans, stored_workflow, style="instance" )
Пример #3
0
 def set_workflow_menu(self, trans, **kwd):
     """
     Save workflow menu to be shown in the tool panel
     PUT /api/workflows/menu
     """
     payload = kwd.get('payload')
     user = trans.get_user()
     workflow_ids = payload.get('workflow_ids')
     if workflow_ids is None:
         workflow_ids = []
     elif type(workflow_ids) != list:
         workflow_ids = [workflow_ids]
     workflow_ids_decoded = []
     # Decode the encoded workflow ids
     for ids in workflow_ids:
         workflow_ids_decoded.append(trans.security.decode_id(ids))
     sess = trans.sa_session
     # This explicit remove seems like a hack, need to figure out
     # how to make the association do it automatically.
     for m in user.stored_workflow_menu_entries:
         sess.delete(m)
     user.stored_workflow_menu_entries = []
     q = sess.query(model.StoredWorkflow)
     # To ensure id list is unique
     seen_workflow_ids = set()
     for wf_id in workflow_ids_decoded:
         if wf_id in seen_workflow_ids:
             continue
         else:
             seen_workflow_ids.add(wf_id)
         m = model.StoredWorkflowMenuEntry()
         m.stored_workflow = q.get(wf_id)
         user.stored_workflow_menu_entries.append(m)
     sess.flush()
     message = "Menu updated."
     trans.set_message(message)
     return {'message': message, 'status': 'done'}
Пример #4
0
    def update(self, trans, id, payload, **kwds):
        """
        * PUT /api/workflows/{id}
            updates the workflow stored with ``id``

        :type   id:      str
        :param  id:      the encoded id of the workflow to update
        :type   payload: dict
        :param  payload: a dictionary containing any or all the
            * workflow   the json description of the workflow as would be
                         produced by GET workflows/<id>/download or
                         given to `POST workflows`

                         The workflow contents will be updated to target
                         this.

            * name       optional string name for the workflow, if not present in payload,
                         name defaults to existing name
            * annotation optional string annotation for the workflow, if not present in payload,
                         annotation defaults to existing annotation
            * menu_entry optional boolean marking if the workflow should appear in the user's menu,
                         if not present, workflow menu entries are not modified

        :rtype:     dict
        :returns:   serialized version of the workflow
        """
        stored_workflow = self.__get_stored_workflow(trans, id)
        workflow_dict = payload.get('workflow') or payload
        if workflow_dict:
            raw_workflow_description = self.__normalize_workflow(
                trans, workflow_dict)
            workflow_dict = raw_workflow_description.as_dict
            new_workflow_name = workflow_dict.get('name') or workflow_dict.get(
                'name')
            if new_workflow_name and new_workflow_name != stored_workflow.name:
                sanitized_name = sanitize_html(new_workflow_name)
                workflow = stored_workflow.latest_workflow.copy()
                workflow.stored_workflow = stored_workflow
                workflow.name = sanitized_name
                stored_workflow.name = sanitized_name
                stored_workflow.latest_workflow = workflow
                trans.sa_session.add(workflow, stored_workflow)
                trans.sa_session.flush()

            if 'annotation' in workflow_dict:
                newAnnotation = sanitize_html(workflow_dict['annotation'])
                self.add_item_annotation(trans.sa_session, trans.get_user(),
                                         stored_workflow, newAnnotation)

            if 'menu_entry' in workflow_dict or 'show_in_tool_panel' in workflow_dict:
                if workflow_dict.get('menu_entry') or workflow_dict.get(
                        'show_in_tool_panel'):
                    menuEntry = model.StoredWorkflowMenuEntry()
                    menuEntry.stored_workflow = stored_workflow
                    trans.get_user().stored_workflow_menu_entries.append(
                        menuEntry)
                else:
                    # remove if in list
                    entries = {
                        x.stored_workflow_id: x
                        for x in trans.get_user().stored_workflow_menu_entries
                    }
                    if (trans.security.decode_id(id) in entries):
                        trans.get_user().stored_workflow_menu_entries.remove(
                            entries[trans.security.decode_id(id)])
            # set tags
            trans.app.tag_handler.set_tags_from_list(
                user=trans.user,
                item=stored_workflow,
                new_tags_list=workflow_dict.get('tags', []))

            if 'steps' in workflow_dict:
                try:
                    from_dict_kwds = self.__import_or_update_kwds(payload)
                    workflow, errors = self.workflow_contents_manager.update_workflow_from_raw_description(
                        trans, stored_workflow, raw_workflow_description,
                        **from_dict_kwds)
                except workflows.MissingToolsException:
                    raise exceptions.MessageException(
                        "This workflow contains missing tools. It cannot be saved until they have been removed from the workflow or installed."
                    )
            else:
                # We only adjusted tags and menu entry
                return payload
        else:
            message = "Updating workflow requires dictionary containing 'workflow' attribute with new JSON description."
            raise exceptions.RequestParameterInvalidException(message)
        return self.workflow_contents_manager.workflow_to_dict(
            trans, stored_workflow, style="instance")
Пример #5
0
    def build_workflow_from_dict(self,
                                 trans,
                                 data,
                                 source=None,
                                 add_to_menu=False,
                                 publish=False):
        # Put parameters in workflow mode
        trans.workflow_building_mode = True
        # Create new workflow from incoming dict
        workflow = model.Workflow()
        # If there's a source, put it in the workflow name.
        if source:
            name = "%s (imported from %s)" % (data['name'], source)
        else:
            name = data['name']
        workflow.name = name
        if 'uuid' in data:
            workflow.uuid = data['uuid']
        # 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 = {}
        # Keep track of tools required by the workflow that are not available in
        # the local Galaxy instance.  Each tuple in the list of missing_tool_tups
        # will be ( tool_id, tool_name, tool_version ).
        missing_tool_tups = []
        for step_dict in self.__walk_step_dicts(data):
            module, step = self.__module_from_dict(trans,
                                                   step_dict,
                                                   secure=False)
            steps.append(step)
            steps_by_external_id[step_dict['id']] = step

            if module.type == 'tool' and module.tool is None:
                # A required tool is not available in the local Galaxy instance.
                missing_tool_tup = (step_dict['tool_id'], step_dict['name'],
                                    step_dict['tool_version'])
                if missing_tool_tup not in missing_tool_tups:
                    missing_tool_tups.append(missing_tool_tup)
                # Save the entire step_dict in the unused config field, be parsed later
                # when we do have the tool
                step.config = json.dumps(step_dict)
            if step.tool_errors:
                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
        stored = model.StoredWorkflow()
        stored.name = workflow.name
        workflow.stored_workflow = stored
        stored.latest_workflow = workflow
        stored.user = trans.user
        stored.published = publish
        if data['annotation']:
            annotation = sanitize_html(data['annotation'], 'utf-8',
                                       'text/html')
            self.add_item_annotation(trans.sa_session, stored.user, stored,
                                     annotation)

        # Persist
        trans.sa_session.add(stored)
        trans.sa_session.flush()

        if add_to_menu:
            if trans.user.stored_workflow_menu_entries is None:
                trans.user.stored_workflow_menu_entries = []
            menuEntry = model.StoredWorkflowMenuEntry()
            menuEntry.stored_workflow = stored
            trans.user.stored_workflow_menu_entries.append(menuEntry)
            trans.sa_session.flush()

        return CreatedWorkflow(stored_workflow=stored,
                               missing_tools=missing_tool_tups)