def prep_template_graph_get_req(prep_id, user_id): """Returns graph of all artifacts created from the prep base artifact Parameters ---------- prep_id : int Prep template ID to get graph for user_id : str User making the request Returns ------- dict of lists of tuples A dictionary containing the edge list representation of the graph, and the node labels. Formatted as: {'status': status, 'message': message, 'edge_list': [(0, 1), (0, 2)...], 'node_labels': [(0, 'label0'), (1, 'label1'), ...]} Notes ----- Nodes are identified by the corresponding Artifact ID. """ exists = _check_prep_template_exists(int(prep_id)) if exists['status'] != 'success': return exists prep = PrepTemplate(int(prep_id)) access_error = check_access(prep.study_id, user_id) if access_error: return access_error # We should filter for only the public artifacts if the user # doesn't have full access to the study full_access = Study(prep.study_id).can_edit(User(user_id)) artifact = prep.artifact if artifact is None: return {'edges': [], 'nodes': [], 'status': 'success', 'message': ''} G = artifact.descendants_with_jobs nodes, edges, wf_id = get_network_nodes_edges(G, full_access) # nodes returns [node_type, node_name, element_id]; here we are looking # for the node_type == artifact, and check by the element/artifact_id if # it's being deleted artifacts_being_deleted = [a[2] for a in nodes if a[0] == 'artifact' and Artifact(a[2]).being_deleted_by is not None] return {'edges': edges, 'nodes': nodes, 'workflow': wf_id, 'status': 'success', 'artifacts_being_deleted': artifacts_being_deleted, 'message': ''}
def test_get_network_nodes_edges(self): graph = Artifact(1).descendants_with_jobs obs_nodes, obs_edges, obs_wf = get_network_nodes_edges(graph, True) self.assertEqual(len(obs_nodes), 11) self.assertEqual(len([x for x in obs_nodes if x[0] == 'job']), 5) self.assertEqual(len([x for x in obs_nodes if x[0] == 'artifact']), 6) self.assertEqual(len([x for x in obs_nodes if x[0] == 'type']), 0) self.assertEqual(len(obs_edges), 10) self.assertIsNone(obs_wf) # This graph only contains one node - check added to make sure that # the graph gets extended accordingly graph = Artifact(6).descendants_with_jobs obs_nodes, obs_edges, obs_wf = get_network_nodes_edges( graph, True, nodes=obs_nodes, edges=obs_edges) self.assertEqual(len(obs_nodes), 12) self.assertEqual(len([x for x in obs_nodes if x[0] == 'job']), 5) self.assertEqual(len([x for x in obs_nodes if x[0] == 'artifact']), 7) self.assertEqual(len([x for x in obs_nodes if x[0] == 'type']), 0) self.assertEqual(len(obs_edges), 10) self.assertIsNone(obs_wf)
def test_get_network_nodes_edges(self): graph = Artifact(1).descendants_with_jobs obs_nodes, obs_edges, obs_wf = get_network_nodes_edges(graph, True) self.assertEqual(len(obs_nodes), 11) self.assertEqual(len([x for x in obs_nodes if x[0] == 'job']), 5) self.assertEqual(len([x for x in obs_nodes if x[0] == 'artifact']), 6) self.assertEqual(len([x for x in obs_nodes if x[0] == 'type']), 0) self.assertEqual(len(obs_edges), 10) self.assertIsNone(obs_wf) # This graph only contains one node - check added to make sure that # the graph gets extended accordingly graph = Artifact(6).descendants_with_jobs obs_nodes, obs_edges, obs_wf = get_network_nodes_edges( graph, True, nodes=obs_nodes, edges=obs_edges) self.assertEqual(len(obs_nodes), 12) self.assertEqual(len([x for x in obs_nodes if x[0] == 'job']), 5) self.assertEqual(len([x for x in obs_nodes if x[0] == 'artifact']), 7) self.assertEqual(len([x for x in obs_nodes if x[0] == 'type']), 0) self.assertEqual(len(obs_edges), 10) self.assertIsNone(obs_wf)
def prep_template_graph_get_req(prep_id, user_id): """Returns graph of all artifacts created from the prep base artifact Parameters ---------- prep_id : int Prep template ID to get graph for user_id : str User making the request Returns ------- dict of lists of tuples A dictionary containing the edge list representation of the graph, and the node labels. Formatted as: {'status': status, 'message': message, 'edge_list': [(0, 1), (0, 2)...], 'node_labels': [(0, 'label0'), (1, 'label1'), ...]} Notes ----- Nodes are identified by the corresponding Artifact ID. """ exists = _check_prep_template_exists(int(prep_id)) if exists['status'] != 'success': return exists prep = PrepTemplate(int(prep_id)) access_error = check_access(prep.study_id, user_id) if access_error: return access_error # We should filter for only the public artifacts if the user # doesn't have full access to the study full_access = Study(prep.study_id).can_edit(User(user_id)) artifact = prep.artifact if artifact is None: return {'edges': [], 'nodes': [], 'status': 'success', 'message': ''} G = artifact.descendants_with_jobs nodes, edges, wf_id = get_network_nodes_edges(G, full_access) return {'edges': edges, 'nodes': nodes, 'workflow': wf_id, 'status': 'success', 'message': ''}
def analyisis_graph_handler_get_request(analysis_id, user): """Returns the graph information of the analysis Parameters ---------- analysis_id : int The analysis id user : qiita_db.user.User The user performing the request Returns ------- dict with the graph information Raises ------ ValueError If there is more than one workflow in a single analysis """ analysis = Analysis(analysis_id) # Check if the user actually has access to the analysis check_analysis_access(user, analysis) # A user has full access to the analysis if it is one of its private # analyses, the analysis has been shared with the user or the user is a # superuser or admin full_access = (analysis in (user.private_analyses | user.shared_analyses) or user.level in {'superuser', 'admin'}) nodes = [] edges = [] wf_id = None # Loop through all the initial artifacts of the analysis for a in analysis.artifacts: if a.processing_parameters is None: g = a.descendants_with_jobs nodes, edges, a_wf_id = get_network_nodes_edges(g, full_access, nodes=nodes, edges=edges) if wf_id is None: wf_id = a_wf_id elif a_wf_id is not None and wf_id != a_wf_id: # This should never happen, but worth having a useful message raise ValueError('More than one workflow in a single analysis') return {'edges': edges, 'nodes': nodes, 'workflow': wf_id}
def analyisis_graph_handler_get_request(analysis_id, user): """Returns the graph information of the analysis Parameters ---------- analysis_id : int The analysis id user : qiita_db.user.User The user performing the request Returns ------- dict with the graph information Raises ------ ValueError If there is more than one workflow in a single analysis """ analysis = Analysis(analysis_id) # Check if the user actually has access to the analysis check_analysis_access(user, analysis) # A user has full access to the analysis if it is one of its private # analyses, the analysis has been shared with the user or the user is a # superuser or admin full_access = (analysis in (user.private_analyses | user.shared_analyses) or user.level in {'superuser', 'admin'}) nodes = [] edges = [] wf_id = None # Loop through all the initial artifacts of the analysis for a in analysis.artifacts: if a.processing_parameters is None: g = a.descendants_with_jobs nodes, edges, a_wf_id = get_network_nodes_edges( g, full_access, nodes=nodes, edges=edges) if wf_id is None: wf_id = a_wf_id elif a_wf_id is not None and wf_id != a_wf_id: # This should never happen, but worth having a useful message raise ValueError('More than one workflow in a single analysis') return {'edges': edges, 'nodes': nodes, 'workflow': wf_id}