Skip to content

Commit 1c27db4

Browse files
authored
Error Handle Update - path_finder (#262)
* error handling updated for pathfinder * update for logging import * added conditional for testing purposes * update for error handle-cleaning up errors internally handled by biothings, pf errors added * update syntax from 500 to 400 error * specific error node output * simple syntax update * removed logging setter * added logger to admin * flake8 fix
1 parent 200a37d commit 1c27db4

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

src/handlers/api.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -560,14 +560,14 @@ def write(self, chunk):
560560

561561
class MetaKGPathFinderHandler(QueryHandler):
562562
"""
563-
A handler for querying paths in a knowledge graph using MetaKGPathFinder.
563+
A handler for querying paths in a knowledge graph using the custom MetaKGPathFinder module.
564564
565565
Attributes:
566566
- name: Unique identifier for this handler.
567567
- kwargs: Configuration for GET request parameters.
568568
569-
The primary GET method accepts 'subject', 'object', and 'cutoff' parameters, then retrieves
570-
and returns paths in JSON format between the specified entities up to the given 'cutoff' length.
569+
The primary GET method accepts the required 'subject', 'object', and 'cutoff'(default=3) parameters, then retrieves
570+
and returns paths in JSON format between the specified nodes up to the given 'cutoff' length.
571571
"""
572572

573573
name = "metakgpathfinder"
@@ -632,6 +632,11 @@ def setup_pathfinder_rawquery(self, expanded_fields):
632632

633633
@capture_exceptions
634634
async def get(self, *args, **kwargs):
635+
636+
# Check if subject and object are the same - not allowed
637+
if self.args.subject == self.args.object:
638+
raise ValueError("Subject and object must be different.")
639+
635640
query_data = {"q": self.args.q}
636641

637642
# Initialize with the original subject and object, and setup for expansion
@@ -675,6 +680,10 @@ async def get(self, *args, **kwargs):
675680
bte=self.args.bte
676681
)
677682

683+
# # Error check path results
684+
if "error" in paths_with_edges:
685+
raise HTTPError(400, reason=str(paths_with_edges["error"]))
686+
678687
# Check if rawquery parameter is true -- respond with correct output
679688
if self.args.rawquery:
680689
raw_query_output = self.setup_pathfinder_rawquery(expanded_fields)

src/index.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def run_routine():
2020

2121
class WebAppHandler(RequestHandler):
2222
def get(self):
23-
self.render("../web-app/dist/index.html")
23+
if os.path.exists("../web-app/dist/index.html"):
24+
self.render("../web-app/dist/index.html")
2425

2526

2627
if __name__ == "__main__":

src/utils/metakg/path_finder.py

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
import logging
2-
31
import networkx as nx
2+
43
from controller.metakg import MetaKG
54
from model import ConsolidatedMetaKGDoc
65

7-
logger = logging.basicConfig(level=logging.INFO, filename="missing_bte.log")
8-
9-
106
class MetaKGPathFinder:
117
def __init__(self, query_data=None, expanded_fields=None):
128
"""
@@ -104,43 +100,51 @@ def get_paths(self, cutoff=2, api_details=False, predicate_filter=None, bte=Fals
104100
If True, includes full details of the 'api' in the result.
105101
- predicate_filter: list (default=None)
106102
A list of predicates to filter the results by.
107-
103+
- bte: bool (default=False)
104+
If True, includes BTE information in the result.
108105
Returns:
109106
- all_paths_with_edges: list of dict
110107
A list containing paths and their edge information for all subject-object pairs.
111108
"""
112109

113110
all_paths_with_edges = []
114111

115-
# Predicate Filter Setup
116112
predicate_filter_set = set(predicate_filter) if predicate_filter else None
113+
117114
if 'predicate' in self.expanded_fields and self.expanded_fields['predicate']:
118115
predicate_filter_set.update(self.expanded_fields['predicate'])
119116

120-
# Graph iteration over subject-object pairs
121-
for subject in self.expanded_fields["subject"]:
122-
for object in self.expanded_fields["object"]:
123-
try:
124-
# Check if a path exists between the subject and object
125-
if nx.has_path(self.G, subject, object):
126-
raw_paths = nx.all_simple_paths(self.G, source=subject, target=object, cutoff=cutoff)
127-
for path in raw_paths:
128-
paths_data = {"path": path, "edges": []}
129-
edge_added = False
130-
for i in range(len(path) - 1):
131-
source_node = path[i]
132-
target_node = path[i + 1]
133-
edge_key = f"{source_node}-{target_node}"
134-
edge_data = self.predicates.get(edge_key, [])
135-
136-
for data in edge_data:
137-
if predicate_filter_set and data["predicate"] not in predicate_filter_set:
138-
continue
139-
paths_data = self.build_edge_results(paths_data, data, api_details, source_node, target_node, bte)
140-
edge_added = True
141-
if edge_added:
142-
all_paths_with_edges.append(paths_data)
143-
except Exception:
144-
continue
145-
146-
return all_paths_with_edges
117+
try:
118+
# Graph iteration over subject-object pairs
119+
for subject in self.expanded_fields["subject"]:
120+
for object in self.expanded_fields["object"]:
121+
if subject not in self.G:
122+
return { "error": f"Subject node {subject} is not found in the MetaKG" }
123+
if object not in self.G:
124+
return { "error": f"Object node {object} is not found in the MetaKG" }
125+
try:
126+
# Check if a path exists between the subject and object
127+
if nx.has_path(self.G, subject, object):
128+
raw_paths = nx.all_simple_paths(self.G, source=subject, target=object, cutoff=cutoff)
129+
for path in raw_paths:
130+
paths_data = {"path": path, "edges": []}
131+
edge_added = False
132+
for i in range(len(path) - 1):
133+
source_node = path[i]
134+
target_node = path[i + 1]
135+
edge_key = f"{source_node}-{target_node}"
136+
edge_data = self.predicates.get(edge_key, [])
137+
138+
for data in edge_data:
139+
if predicate_filter_set and data["predicate"] not in predicate_filter_set:
140+
continue
141+
paths_data = self.build_edge_results(paths_data, data, api_details, source_node, target_node, bte)
142+
edge_added = True
143+
if edge_added:
144+
all_paths_with_edges.append(paths_data)
145+
except nx.exception.NodeNotFound as node_err:
146+
return { "error": node_err }
147+
return all_paths_with_edges
148+
149+
except Exception as e:
150+
return { "error": e }

0 commit comments

Comments
 (0)