def save_workflow(self, workflow): stored_workflow = model.StoredWorkflow() stored_workflow.latest_workflow = workflow stored_workflow.user = self.user self.sa_session.add(stored_workflow) self.sa_session.flush() return stored_workflow
def extract_workflow(trans, user, history=None, job_ids=None, dataset_ids=None, dataset_collection_ids=None, workflow_name=None): steps = extract_steps(trans, history=history, job_ids=job_ids, dataset_ids=dataset_ids, dataset_collection_ids=dataset_collection_ids) # Workflow to populate workflow = model.Workflow() workflow.name = workflow_name # Order the steps if possible attach_ordered_steps(workflow, steps) # And let's try to set up some reasonable locations on the canvas # (these are pretty arbitrary values) levorder = order_workflow_steps_with_levels(steps) base_pos = 10 for i, steps_at_level in enumerate(levorder): for j, index in enumerate(steps_at_level): step = steps[index] step.position = dict(top=(base_pos + 120 * j), left=(base_pos + 220 * i)) # Store it stored = model.StoredWorkflow() stored.user = user stored.name = workflow_name workflow.stored_workflow = stored stored.latest_workflow = workflow trans.sa_session.add(stored) trans.sa_session.flush() return stored
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)
def __workflow_fixure(trans): user = model.User(email="*****@*****.**", password="******") stored_workflow = model.StoredWorkflow() stored_workflow.user = user workflow = model.Workflow() workflow.stored_workflow = stored_workflow def add_step(**kwds): workflow_step = model.WorkflowStep() for key, value in kwds.items(): setattr(workflow_step, key, value) workflow.steps.append(workflow_step) trans.app.model.context.add(workflow, ) add_step(type="data_input", order_index=0, tool_inputs={"name": "input1"}) add_step(type="data_input", order_index=1, tool_inputs={"name": "input2"}) add_step( type="tool", tool_id="cat1", order_index=2, ) add_step( type="tool", tool_id="cat1", order_index=4, ) trans.app.model.context.flush() # Expunge and reload to ensure step state is as expected from database. workflow_id = workflow.id trans.app.model.context.expunge_all() return trans.app.model.context.query(model.Workflow).get(workflow_id)
def workflow_from_steps(steps): stored_workflow = model.StoredWorkflow() stored_workflow.user = user workflow = model.Workflow() workflow.steps = steps workflow.stored_workflow = stored_workflow return workflow
def test_annotations(self): model = self.model u = model.User(email="*****@*****.**", password="******") self.persist(u) def persist_and_check_annotation(annotation_class, **kwds): annotated_association = annotation_class() annotated_association.annotation = "Test Annotation" annotated_association.user = u for key, value in kwds.items(): setattr(annotated_association, key, value) self.persist(annotated_association) self.expunge() stored_annotation = self.query(annotation_class).all()[0] assert stored_annotation.annotation == "Test Annotation" assert stored_annotation.user.email == "*****@*****.**" sw = model.StoredWorkflow() sw.user = u self.persist(sw) persist_and_check_annotation(model.StoredWorkflowAnnotationAssociation, stored_workflow=sw) workflow = model.Workflow() workflow.stored_workflow = sw self.persist(workflow) ws = model.WorkflowStep() ws.workflow = workflow self.persist(ws) persist_and_check_annotation(model.WorkflowStepAnnotationAssociation, workflow_step=ws) h = model.History(name="History for Annotation", user=u) self.persist(h) persist_and_check_annotation(model.HistoryAnnotationAssociation, history=h) d1 = model.HistoryDatasetAssociation(extension="txt", history=h, create_dataset=True, sa_session=model.session) self.persist(d1) persist_and_check_annotation(model.HistoryDatasetAssociationAnnotationAssociation, hda=d1) page = model.Page() page.user = u self.persist(page) persist_and_check_annotation(model.PageAnnotationAssociation, page=page) visualization = model.Visualization() visualization.user = u self.persist(visualization) persist_and_check_annotation(model.VisualizationAnnotationAssociation, visualization=visualization) dataset_collection = model.DatasetCollection(collection_type="paired") history_dataset_collection = model.HistoryDatasetCollectionAssociation(collection=dataset_collection) self.persist(history_dataset_collection) persist_and_check_annotation(model.HistoryDatasetCollectionAssociationAnnotationAssociation, history_dataset_collection=history_dataset_collection) library_dataset_collection = model.LibraryDatasetCollectionAssociation(collection=dataset_collection) self.persist(library_dataset_collection) persist_and_check_annotation(model.LibraryDatasetCollectionAnnotationAssociation, library_dataset_collection=library_dataset_collection)
def save_workflow_as(self, trans, workflow_name, workflow_data, workflow_annotation="", from_tool_form=False): """ Creates a new workflow based on Save As command. It is a new workflow, but is created with workflow_data already present. """ user = trans.get_user() if workflow_name is not None: workflow_contents_manager = self.app.workflow_contents_manager stored_workflow = model.StoredWorkflow() stored_workflow.name = workflow_name stored_workflow.user = user self.slug_builder.create_item_slug(trans.sa_session, stored_workflow) workflow = model.Workflow() workflow.name = workflow_name workflow.stored_workflow = stored_workflow stored_workflow.latest_workflow = workflow # Add annotation. workflow_annotation = sanitize_html(workflow_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, workflow_annotation) # Persist session = trans.sa_session session.add(stored_workflow) session.flush() workflow_update_options = WorkflowUpdateOptions( update_stored_workflow_attributes=False, # taken care of above from_tool_form=from_tool_form, ) try: workflow, errors = workflow_contents_manager.update_workflow_from_raw_description( trans, stored_workflow, workflow_data, workflow_update_options, ) except MissingToolsException as e: return dict( name=e.workflow.name, message= ("This workflow includes missing or invalid tools. " "It cannot be saved until the following steps are removed or the missing tools are enabled." ), errors=e.errors, ) return (trans.security.encode_id(stored_workflow.id)) else: # This is an error state, 'save as' must have a workflow_name log.exception("Error in Save As workflow: no name.")
def __test_workflow( self ): stored_workflow = model.StoredWorkflow() workflow = model.Workflow() workflow.stored_workflow = stored_workflow stored_workflow.latest_workflow = workflow user = model.User() user.email = "*****@*****.**" user.password = "******" stored_workflow.user = user self.app.model.context.add( workflow ) self.app.model.context.add( stored_workflow ) self.app.model.context.flush() return stored_workflow
def test_ratings(self): model = self.model u = model.User(email="*****@*****.**", password="******") self.persist(u) def persist_and_check_rating(rating_class, **kwds): rating_association = rating_class() rating_association.rating = 5 rating_association.user = u for key, value in kwds.items(): setattr(rating_association, key, value) self.persist(rating_association) self.expunge() stored_annotation = self.query(rating_class).all()[0] assert stored_annotation.rating == 5 assert stored_annotation.user.email == "*****@*****.**" sw = model.StoredWorkflow() sw.user = u self.persist(sw) persist_and_check_rating(model.StoredWorkflowRatingAssociation, stored_workflow=sw) h = model.History(name="History for Rating", user=u) self.persist(h) persist_and_check_rating(model.HistoryRatingAssociation, history=h) d1 = model.HistoryDatasetAssociation(extension="txt", history=h, create_dataset=True, sa_session=model.session) self.persist(d1) persist_and_check_rating(model.HistoryDatasetAssociationRatingAssociation, hda=d1) page = model.Page() page.user = u self.persist(page) persist_and_check_rating(model.PageRatingAssociation, page=page) visualization = model.Visualization() visualization.user = u self.persist(visualization) persist_and_check_rating(model.VisualizationRatingAssociation, visualization=visualization) dataset_collection = model.DatasetCollection(collection_type="paired") history_dataset_collection = model.HistoryDatasetCollectionAssociation(collection=dataset_collection) self.persist(history_dataset_collection) persist_and_check_rating(model.HistoryDatasetCollectionRatingAssociation, history_dataset_collection=history_dataset_collection) library_dataset_collection = model.LibraryDatasetCollectionAssociation(collection=dataset_collection) self.persist(library_dataset_collection) persist_and_check_rating(model.LibraryDatasetCollectionRatingAssociation, library_dataset_collection=library_dataset_collection)
def create(self, trans, payload=None, **kwd): if trans.request.method == 'GET': return { 'title': 'Create Workflow', 'inputs': [{ 'name': 'workflow_name', 'label': 'Name', 'value': 'Unnamed workflow' }, { 'name': 'workflow_annotation', 'label': 'Annotation', 'help': 'A description of the workflow; annotation is shown alongside shared or published workflows.' }] } else: user = trans.get_user() workflow_name = payload.get('workflow_name') workflow_annotation = payload.get('workflow_annotation') if not workflow_name: return self.message_exception( trans, 'Please provide a workflow name.') # Create the new stored workflow stored_workflow = model.StoredWorkflow() stored_workflow.name = workflow_name stored_workflow.user = user self.slug_builder.create_item_slug(trans.sa_session, stored_workflow) # And the first (empty) workflow revision workflow = model.Workflow() workflow.name = workflow_name workflow.stored_workflow = stored_workflow stored_workflow.latest_workflow = workflow # Add annotation. workflow_annotation = sanitize_html(workflow_annotation) self.add_item_annotation(trans.sa_session, trans.get_user(), stored_workflow, workflow_annotation) # Persist session = trans.sa_session session.add(stored_workflow) session.flush() return { 'id': trans.security.encode_id(stored_workflow.id), 'message': f'Workflow {workflow_name} has been created.' }
def test_workflow_export(self): stored_workflow = model.StoredWorkflow() stored_workflow.name = "My Cool Workflow" workflow = model.Workflow() stored_workflow.latest_workflow = workflow workflow_step_0 = model.WorkflowStep() workflow.steps = [workflow_step_0] self.trans.app.workflow_manager.get_stored_accessible_workflow.return_value = stored_workflow example = """# Example ```galaxy workflow_display(workflow_id=1) ``` """ result = self._to_basic(example) assert "**Workflow:** My Cool Workflow\n" in result assert "**Steps:**\n" in result
def test_ratings(self): model = self.model user_email = "*****@*****.**" u = model.User(email=user_email, password="******") self.persist(u) def persist_and_check_rating(rating_class, item): rating = 5 rating_association = rating_class(u, item, rating) self.persist(rating_association) self.expunge() stored_rating = self.query(rating_class).all()[0] assert stored_rating.rating == rating assert stored_rating.user.email == user_email sw = model.StoredWorkflow() sw.user = u self.persist(sw) persist_and_check_rating(model.StoredWorkflowRatingAssociation, sw) h = model.History(name="History for Rating", user=u) self.persist(h) persist_and_check_rating(model.HistoryRatingAssociation, h) d1 = model.HistoryDatasetAssociation(extension="txt", history=h, create_dataset=True, sa_session=model.session) self.persist(d1) persist_and_check_rating(model.HistoryDatasetAssociationRatingAssociation, d1) page = model.Page() page.user = u self.persist(page) persist_and_check_rating(model.PageRatingAssociation, page) visualization = model.Visualization() visualization.user = u self.persist(visualization) persist_and_check_rating(model.VisualizationRatingAssociation, visualization) dataset_collection = model.DatasetCollection(collection_type="paired") history_dataset_collection = model.HistoryDatasetCollectionAssociation(collection=dataset_collection) self.persist(history_dataset_collection) persist_and_check_rating(model.HistoryDatasetCollectionRatingAssociation, history_dataset_collection) library_dataset_collection = model.LibraryDatasetCollectionAssociation(collection=dataset_collection) self.persist(library_dataset_collection) persist_and_check_rating(model.LibraryDatasetCollectionRatingAssociation, library_dataset_collection)
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
def test_tags(self): model = self.model my_tag = model.Tag(name="Test Tag") u = model.User(email="*****@*****.**", password="******") self.persist(my_tag, u) def tag_and_test(taggable_object, tag_association_class, backref_name): assert len(getattr(self.query(model.Tag).filter(model.Tag.name == "Test Tag").all()[0], backref_name)) == 0 tag_association = tag_association_class() tag_association.tag = my_tag taggable_object.tags = [tag_association] self.persist(tag_association, taggable_object) assert len(getattr(self.query(model.Tag).filter(model.Tag.name == "Test Tag").all()[0], backref_name)) == 1 sw = model.StoredWorkflow() sw.user = u tag_and_test(sw, model.StoredWorkflowTagAssociation, "tagged_workflows") h = model.History(name="History for Tagging", user=u) tag_and_test(h, model.HistoryTagAssociation, "tagged_histories") d1 = model.HistoryDatasetAssociation(extension="txt", history=h, create_dataset=True, sa_session=model.session) tag_and_test(d1, model.HistoryDatasetAssociationTagAssociation, "tagged_history_dataset_associations") page = model.Page() page.user = u tag_and_test(page, model.PageTagAssociation, "tagged_pages") visualization = model.Visualization() visualization.user = u tag_and_test(visualization, model.VisualizationTagAssociation, "tagged_visualizations") dataset_collection = model.DatasetCollection(collection_type="paired") history_dataset_collection = model.HistoryDatasetCollectionAssociation(collection=dataset_collection) tag_and_test(history_dataset_collection, model.HistoryDatasetCollectionTagAssociation, "tagged_history_dataset_collections") library_dataset_collection = model.LibraryDatasetCollectionAssociation(collection=dataset_collection) tag_and_test(library_dataset_collection, model.LibraryDatasetCollectionTagAssociation, "tagged_library_dataset_collections")
def copy(self, trans, id, save_as_name=None): # Get workflow to copy. stored = self.get_stored_workflow(trans, id, check_ownership=False) user = trans.get_user() if stored.user == user: owner = True else: 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") owner = False # Copy. new_stored = model.StoredWorkflow() if (save_as_name): new_stored.name = '%s' % save_as_name else: new_stored.name = "Copy of %s" % stored.name new_stored.latest_workflow = stored.latest_workflow # Copy annotation. annotation_obj = self.get_item_annotation_obj(trans.sa_session, stored.user, stored) if annotation_obj: self.add_item_annotation(trans.sa_session, trans.get_user(), new_stored, annotation_obj.annotation) new_stored.copy_tags_from(trans.user, stored) if not owner: new_stored.name += " shared by %s" % stored.user.email new_stored.user = user # Persist session = trans.sa_session session.add(new_stored) session.flush() # Display the management page message = 'Created new workflow with name: %s' % escape( new_stored.name) trans.set_message(message) return_url = url_for( '/') + 'workflow?status=done&message=%s' % escape(message) trans.response.send_redirect(return_url)
def _workflow_from_dict(self, trans, data, source=None): """ RPARK: copied from galaxy.webapps.galaxy.controllers.workflows.py Creates a workflow from a dict. Created workflow is stored in the database and returned. """ # 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 # 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 = [] # First pass to build step objects and populate basic values for key, step_dict in data['steps'].iteritems(): # Create the model class for the step step = model.WorkflowStep() steps.append(step) steps_by_external_id[step_dict['id']] = step # FIXME: Position should be handled inside module step.position = step_dict['position'] module = module_factory.from_dict(trans, step_dict, secure=False) 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) module.save_to_step(step) if step.tool_errors: workflow.has_errors = True # Stick this in the step temporarily step.temp_input_connections = step_dict['input_connections'] # Save step annotation. #annotation = step_dict[ 'annotation' ] #if annotation: #annotation = sanitize_html( annotation, 'utf-8', 'text/html' ) # ------------------------------------------ # # RPARK REMOVING: user annotation b/c of API #self.add_item_annotation( trans.sa_session, trans.get_user(), step, annotation ) # ------------------------------------------ # # Unpack and add post-job actions. post_job_actions = step_dict.get('post_job_actions', {}) for name, pja_dict in post_job_actions.items(): model.PostJobAction(pja_dict['action_type'], step, pja_dict['output_name'], pja_dict['action_arguments']) # Second pass to deal with connections between steps for step in steps: # Input connections for input_name, conn_dict in step.temp_input_connections.iteritems( ): if conn_dict: conn = model.WorkflowStepConnection() conn.input_step = step conn.input_name = input_name conn.output_name = conn_dict['output_name'] conn.output_step = steps_by_external_id[conn_dict['id']] del step.temp_input_connections # 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 # Persist trans.sa_session.add(stored) trans.sa_session.flush() return stored, missing_tool_tups
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)