From 3a88427b0f466cd923782dd431a653947522c647 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Tue, 23 Jul 2024 12:46:26 -0400 Subject: [PATCH 1/7] error handling updated for pathfinder --- src/utils/metakg/path_finder.py | 80 ++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/src/utils/metakg/path_finder.py b/src/utils/metakg/path_finder.py index 6829735..d8a8493 100644 --- a/src/utils/metakg/path_finder.py +++ b/src/utils/metakg/path_finder.py @@ -110,35 +110,55 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals all_paths_with_edges = [] - # Predicate Filter Setup - predicate_filter_set = set(predicate_filter) if predicate_filter else None - if 'predicate' in self.expanded_fields and self.expanded_fields['predicate']: - predicate_filter_set.update(self.expanded_fields['predicate']) - - # Graph iteration over subject-object pairs - for subject in self.expanded_fields["subject"]: - for object in self.expanded_fields["object"]: - try: - # Check if a path exists between the subject and object - if nx.has_path(self.G, subject, object): - raw_paths = nx.all_simple_paths(self.G, source=subject, target=object, cutoff=cutoff) - for path in raw_paths: - paths_data = {"path": path, "edges": []} - edge_added = False - for i in range(len(path) - 1): - source_node = path[i] - target_node = path[i + 1] - edge_key = f"{source_node}-{target_node}" - edge_data = self.predicates.get(edge_key, []) - - for data in edge_data: - if predicate_filter_set and data["predicate"] not in predicate_filter_set: - continue - paths_data = self.build_edge_results(paths_data, data, api_details, source_node, target_node, bte) - edge_added = True - if edge_added: - all_paths_with_edges.append(paths_data) - except Exception as e: - continue + try: + # Predicate Filter Setup + predicate_filter_set = set(predicate_filter) if predicate_filter else None + try: + if 'predicate' in self.expanded_fields and self.expanded_fields['predicate']: + predicate_filter_set.update(self.expanded_fields['predicate']) + except TypeError as te: + logger.error(f"TypeError encountered while updating predicate_filter_set: {te}") + except KeyError as ke: + logger.error(f"KeyError encountered while updating predicate_filter_set: {ke}") + + # Graph iteration over subject-object pairs + for subject in self.expanded_fields["subject"]: + for object in self.expanded_fields["object"]: + try: + # Check if a path exists between the subject and object + if nx.has_path(self.G, subject, object): + raw_paths = nx.all_simple_paths(self.G, source=subject, target=object, cutoff=cutoff) + for path in raw_paths: + paths_data = {"path": path, "edges": []} + edge_added = False + for i in range(len(path) - 1): + source_node = path[i] + target_node = path[i + 1] + edge_key = f"{source_node}-{target_node}" + edge_data = self.predicates.get(edge_key, []) + + for data in edge_data: + if predicate_filter_set and data["predicate"] not in predicate_filter_set: + continue + paths_data = self.build_edge_results(paths_data, data, api_details, source_node, target_node, bte) + edge_added = True + if edge_added: + all_paths_with_edges.append(paths_data) + except nx.NetworkXNoPath: + # No path found, continue to the next pair + continue + except nx.NetworkXError as e: + logger.error(f"NetworkX error while processing subject {subject} and object {object}: {e}") + continue + except KeyError as ke: + logger.error(f"Key error encountered while processing subject {subject} and object {object}. Missing key: {ke}") + continue + except Exception as e: + logger.error(f"Unexpected error while processing subject {subject} and object {object}: {e}") + continue + except KeyError as ke: + logger.error(f"Key error encountered in expanded_fields. Missing key: {ke}") + except Exception as e: + logger.error(f"Unexpected error in get_paths function: {e}") return all_paths_with_edges From b333880f726319601326587b54b0a02ca1dbc239 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Tue, 23 Jul 2024 12:50:59 -0400 Subject: [PATCH 2/7] update for logging import --- src/utils/metakg/path_finder.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/metakg/path_finder.py b/src/utils/metakg/path_finder.py index d8a8493..fc5da12 100644 --- a/src/utils/metakg/path_finder.py +++ b/src/utils/metakg/path_finder.py @@ -1,9 +1,11 @@ -import networkx as nx import logging + +import networkx as nx + from controller.metakg import MetaKG from model import ConsolidatedMetaKGDoc -logger=logging.basicConfig(level=logging.INFO, filename="missing_bte.log") +logging.basicConfig(level="INFO") class MetaKGPathFinder: def __init__(self, query_data=None, expanded_fields=None): From 5591e2620f903680bba35db722f0fb7b28514346 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Tue, 23 Jul 2024 12:51:21 -0400 Subject: [PATCH 3/7] added conditional for testing purposes --- src/index.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.py b/src/index.py index b8a3110..1008630 100644 --- a/src/index.py +++ b/src/index.py @@ -20,7 +20,8 @@ def run_routine(): class WebAppHandler(RequestHandler): def get(self): - self.render("../web-app/dist/index.html") + if os.path.exists("../web-app/dist/index.html"): + self.render("../web-app/dist/index.html") if __name__ == "__main__": From 83a356257c0fc8b58a6b8c432049a1ec03a45aa0 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Mon, 29 Jul 2024 15:52:05 -0400 Subject: [PATCH 4/7] update for error handle-cleaning up errors internally handled by biothings, pf errors added --- src/handlers/api.py | 15 ++++++++++--- src/utils/metakg/path_finder.py | 40 ++++++++++----------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/handlers/api.py b/src/handlers/api.py index b3849a0..45d2ece 100644 --- a/src/handlers/api.py +++ b/src/handlers/api.py @@ -561,14 +561,14 @@ def write(self, chunk): class MetaKGPathFinderHandler(QueryHandler): """ - A handler for querying paths in a knowledge graph using MetaKGPathFinder. + A handler for querying paths in a knowledge graph using the custom MetaKGPathFinder module. Attributes: - name: Unique identifier for this handler. - kwargs: Configuration for GET request parameters. - The primary GET method accepts 'subject', 'object', and 'cutoff' parameters, then retrieves - and returns paths in JSON format between the specified entities up to the given 'cutoff' length. + The primary GET method accepts the required 'subject', 'object', and 'cutoff'(default=3) parameters, then retrieves + and returns paths in JSON format between the specified nodes up to the given 'cutoff' length. """ name = "metakgpathfinder" @@ -633,6 +633,11 @@ def setup_pathfinder_rawquery(self, expanded_fields): @capture_exceptions async def get(self, *args, **kwargs): + + # Check if subject and object are the same - not allowed + if self.args.subject == self.args.object: + raise ValueError("Subject and object must be different.") + query_data = {"q": self.args.q} # Initialize with the original subject and object, and setup for expansion @@ -676,6 +681,10 @@ async def get(self, *args, **kwargs): bte=self.args.bte ) + # Error check path results + if isinstance(paths_with_edges, ValueError): + raise ValueError(str(paths_with_edges)) + # Check if rawquery parameter is true -- respond with correct output if self.args.rawquery: raw_query_output = self.setup_pathfinder_rawquery(expanded_fields) diff --git a/src/utils/metakg/path_finder.py b/src/utils/metakg/path_finder.py index fc5da12..21f9aaf 100644 --- a/src/utils/metakg/path_finder.py +++ b/src/utils/metakg/path_finder.py @@ -104,7 +104,8 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals If True, includes full details of the 'api' in the result. - predicate_filter: list (default=None) A list of predicates to filter the results by. - + - bte: bool (default=False) + If True, includes BTE information in the result. Returns: - all_paths_with_edges: list of dict A list containing paths and their edge information for all subject-object pairs. @@ -112,17 +113,12 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals all_paths_with_edges = [] - try: - # Predicate Filter Setup - predicate_filter_set = set(predicate_filter) if predicate_filter else None - try: - if 'predicate' in self.expanded_fields and self.expanded_fields['predicate']: - predicate_filter_set.update(self.expanded_fields['predicate']) - except TypeError as te: - logger.error(f"TypeError encountered while updating predicate_filter_set: {te}") - except KeyError as ke: - logger.error(f"KeyError encountered while updating predicate_filter_set: {ke}") + predicate_filter_set = set(predicate_filter) if predicate_filter else None + + if 'predicate' in self.expanded_fields and self.expanded_fields['predicate']: + predicate_filter_set.update(self.expanded_fields['predicate']) + try: # Graph iteration over subject-object pairs for subject in self.expanded_fields["subject"]: for object in self.expanded_fields["object"]: @@ -146,21 +142,9 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals edge_added = True if edge_added: all_paths_with_edges.append(paths_data) - except nx.NetworkXNoPath: - # No path found, continue to the next pair - continue - except nx.NetworkXError as e: - logger.error(f"NetworkX error while processing subject {subject} and object {object}: {e}") - continue - except KeyError as ke: - logger.error(f"Key error encountered while processing subject {subject} and object {object}. Missing key: {ke}") - continue - except Exception as e: - logger.error(f"Unexpected error while processing subject {subject} and object {object}: {e}") - continue - except KeyError as ke: - logger.error(f"Key error encountered in expanded_fields. Missing key: {ke}") - except Exception as e: - logger.error(f"Unexpected error in get_paths function: {e}") + except nx.exception.NodeNotFound as node_err: + raise ValueError(node_err) + return all_paths_with_edges - return all_paths_with_edges + except Exception as e: + return e From 9246154ad01ce43e929775ccc333275608e567e2 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Wed, 7 Aug 2024 12:19:14 -0400 Subject: [PATCH 5/7] update syntax from 500 to 400 error --- src/handlers/api.py | 6 +++--- src/utils/metakg/path_finder.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/handlers/api.py b/src/handlers/api.py index 45d2ece..e5be8bc 100644 --- a/src/handlers/api.py +++ b/src/handlers/api.py @@ -681,9 +681,9 @@ async def get(self, *args, **kwargs): bte=self.args.bte ) - # Error check path results - if isinstance(paths_with_edges, ValueError): - raise ValueError(str(paths_with_edges)) + # # Error check path results + if "error" in paths_with_edges: + raise HTTPError(400, reason=str(paths_with_edges["error"])) # Check if rawquery parameter is true -- respond with correct output if self.args.rawquery: diff --git a/src/utils/metakg/path_finder.py b/src/utils/metakg/path_finder.py index 21f9aaf..669cbc6 100644 --- a/src/utils/metakg/path_finder.py +++ b/src/utils/metakg/path_finder.py @@ -143,8 +143,8 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals if edge_added: all_paths_with_edges.append(paths_data) except nx.exception.NodeNotFound as node_err: - raise ValueError(node_err) + return { "error": node_err } return all_paths_with_edges except Exception as e: - return e + return { "error": e } From f8f51805788def8f2a720cec4bb57fb9bc80eb26 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Wed, 7 Aug 2024 13:57:30 -0400 Subject: [PATCH 6/7] specific error node output --- src/utils/metakg/path_finder.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/metakg/path_finder.py b/src/utils/metakg/path_finder.py index 669cbc6..67cbf31 100644 --- a/src/utils/metakg/path_finder.py +++ b/src/utils/metakg/path_finder.py @@ -122,6 +122,10 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals # Graph iteration over subject-object pairs for subject in self.expanded_fields["subject"]: for object in self.expanded_fields["object"]: + if subject not in self.G: + return { "error": f"Source node {subject} is not found in the MetaKG" } + if object not in self.G: + return { "error": f"Target node {object} is not found in the MetaKG" } try: # Check if a path exists between the subject and object if nx.has_path(self.G, subject, object): From 62073518b1af61109cfc18e8c4fb272c66c306d0 Mon Sep 17 00:00:00 2001 From: Nichollette Date: Wed, 7 Aug 2024 14:00:24 -0400 Subject: [PATCH 7/7] simple syntax update --- src/utils/metakg/path_finder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/metakg/path_finder.py b/src/utils/metakg/path_finder.py index 67cbf31..c1e9702 100644 --- a/src/utils/metakg/path_finder.py +++ b/src/utils/metakg/path_finder.py @@ -123,9 +123,9 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals for subject in self.expanded_fields["subject"]: for object in self.expanded_fields["object"]: if subject not in self.G: - return { "error": f"Source node {subject} is not found in the MetaKG" } + return { "error": f"Subject node {subject} is not found in the MetaKG" } if object not in self.G: - return { "error": f"Target node {object} is not found in the MetaKG" } + return { "error": f"Object node {object} is not found in the MetaKG" } try: # Check if a path exists between the subject and object if nx.has_path(self.G, subject, object):