Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Handle Update - path_finder #262

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -676,6 +681,10 @@ async def get(self, *args, **kwargs):
bte=self.args.bte
)

# # 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:
raw_query_output = self.setup_pathfinder_rawquery(expanded_fields)
Expand Down
3 changes: 2 additions & 1 deletion src/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__":
Expand Down
72 changes: 41 additions & 31 deletions src/utils/metakg/path_finder.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -102,43 +104,51 @@ 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.
"""

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

return all_paths_with_edges
try:
# 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"Subject node {subject} is not found in the MetaKG" }
if object not in self.G:
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):
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.exception.NodeNotFound as node_err:
return { "error": node_err }
return all_paths_with_edges

except Exception as e:
return { "error": e }