Skip to content

Commit

Permalink
Merge pull request #18 from Knox-AAU/architecture_fix
Browse files Browse the repository at this point in the history
Architecture fix
  • Loading branch information
JonasGLund99 authored Nov 30, 2023
2 parents 2dbbe70 + dbd32f7 commit 62d10c8
Show file tree
Hide file tree
Showing 16 changed files with 123 additions and 88 deletions.
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"python.testing.unittestArgs": [
"-v",
"-s",
".",
"-p",
"test_*.py"
],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true
}
17 changes: 17 additions & 0 deletions relation_extraction/API_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

from abc import ABCMeta, abstractmethod

class APIHandler(metaclass=ABCMeta):
@property
@classmethod
@abstractmethod
def API_endpoint():
"""Property used to define the API_endpoint for the subclass of APIHandler"""
pass

@classmethod
@abstractmethod
def send_request(request):
pass


8 changes: 4 additions & 4 deletions relation_extraction/LessNaive/lessNaive.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from relation_extraction.ontology_messenger import OntologyMessenger
from relation_extraction.knowledge_graph_messenger import KnowledgeGraphMessenger
from .openie import POST_corenlp
import json
import sys

import urllib.parse
from strsimpy.normalized_levenshtein import NormalizedLevenshtein
from rapidfuzz.distance import Levenshtein
from relation_extraction.output import format_output
from relation_extraction.get_relations import extract_specific_relations


def find_best_ontology_match(api_relation, ontology_relations):
Expand Down Expand Up @@ -68,11 +68,11 @@ def do_relation_extraction(data, ontology_relations):
relations.extend(val["relations"])

tuples = [[r["subject"], r["relation"], r["object"]] for r in relations]
format_output(tuples)
KnowledgeGraphMessenger.format_output(tuples)
return tuples

def main():
ontology_relations = extract_specific_relations()
ontology_relations = OntologyMessenger.send_request()
do_relation_extraction(json.load(open("inputSentences.json")), ontology_relations)


Expand Down
12 changes: 6 additions & 6 deletions relation_extraction/NaiveMVP/main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
from relation_extraction.knowledge_graph_messenger import KnowledgeGraphMessenger
import strsimpy
import sys
from strsimpy.normalized_levenshtein import NormalizedLevenshtein
from relation_extraction.output import send_to_database_component
from relation_extraction.get_relations import extract_specific_relations
from relation_extraction.ontology_messenger import OntologyMessenger
import datetime
import multiprocessing as mp
from functools import partial
Expand Down Expand Up @@ -71,7 +71,7 @@ def parse_data(data, relations):

def handle_relation_post_request(data):
try:
relations = extract_specific_relations()
relations = OntologyMessenger.send_request()
except Exception as E:
print(f"Exception during retrieval of relations: {str(E)}")
raise Exception(f"Exception during retrieval of relations")
Expand All @@ -83,19 +83,19 @@ def handle_relation_post_request(data):
raise Exception("Incorrectly formatted input. Exception during parsing")

try:
send_to_database_component(parsed_data)
KnowledgeGraphMessenger.send_request(parsed_data)
except Exception as E:
print(f"Exception during request to database. {str(E)}")
raise Exception("Data was not sent to database due to connection error")


def main():
relations = extract_specific_relations()
relations = OntologyMessenger.send_request()
# Opening JSON file
with open('inputSentences.json', 'r') as f:
# returns JSON object as a dictionary
data = json.load(f)
send_to_database_component(parse_data(data, relations))
KnowledgeGraphMessenger.send_request(parse_data(data, relations))

if __name__ == "__main__":
main()
5 changes: 3 additions & 2 deletions relation_extraction/evaluation/evaluation.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import sys
import xml.etree.ElementTree as ET
from relation_extraction.ontology_messenger import OntologyMessenger
from relation_extraction.LessNaive.lessNaive import do_relation_extraction
from relation_extraction.NaiveMVP.main import parse_data
import re
from relation_extraction.get_relations import extract_specific_relations
import datetime
import json



def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 3, length = 100, fill = '█', printEnd = "\r"):
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
Expand Down Expand Up @@ -54,7 +55,7 @@ def calculate_metrics(data):
def main():
input_objs = convert_testdata_to_input_format()
print("testdata converted successfully")
ontology_relations = extract_specific_relations()
ontology_relations = OntologyMessenger.send_request()


solutions_to_test = {
Expand Down
43 changes: 0 additions & 43 deletions relation_extraction/get_relations.py

This file was deleted.

24 changes: 24 additions & 0 deletions relation_extraction/knowledge_graph_messenger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import requests

from relation_extraction.API_handler import APIHandler

class KnowledgeGraphMessenger(APIHandler):
def API_endpoint():
return "http://130.225.57.13/knox-api/triples"

def send_request(output):
HEADERS = {"Access-Authorization":"internal_key"}
PARAMS={"g": "http://knox_database"}
FORMATTED_OUTPUT = KnowledgeGraphMessenger.format_output(output)
response = requests.post(url=KnowledgeGraphMessenger.API_endpoint(), json=FORMATTED_OUTPUT, params=PARAMS, headers=HEADERS)
print(f"db component response: {response.text}")
return response.text

@classmethod
def format_output(self, output):
formatted_output = {"triples": output}
return formatted_output




8 changes: 8 additions & 0 deletions relation_extraction/meta_data_messenger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from relation_extraction.API_handler import APIHandler

class MetaDataMessenger(APIHandler):
def API_endpoint():
pass

def send_request(request_content):
pass
30 changes: 30 additions & 0 deletions relation_extraction/ontology_messenger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import requests
import re

from relation_extraction.API_handler import APIHandler

class OntologyMessenger(APIHandler):
def API_endpoint():
return "http://130.225.57.13/knox-api/triples"

def send_request():
"Function to extract relations based on the specified pattern"
print("Getting relations from online ontology...")
relations = []
query_string_s = 'http://dbpedia.org/ontology/'
query_string_o = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Property'
PARAMS = {"g":"http://knox_ontology", "s": query_string_s, "o": query_string_o}
HEADERS = {"Access-Authorization":"internal_key"}
r = requests.get(url=OntologyMessenger.API_endpoint(), params=PARAMS, headers=HEADERS)
print(f"db component response: {r.text}")

data = r.json()

for triple in data["triples"]:
relation = re.split("http://dbpedia.org/ontology/", triple["s"]["Value"])[1]
relations.append(relation)

return relations

if __name__ == "__main__":
OntologyMessenger.send_request()
13 changes: 0 additions & 13 deletions relation_extraction/output.py

This file was deleted.

7 changes: 7 additions & 0 deletions relation_extraction/relation_extractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from relation_extraction.NaiveMVP.main import handle_relation_post_request


class RelationExtractor():
@classmethod
def begin_extraction(self, data):
handle_relation_post_request(data)
3 changes: 2 additions & 1 deletion server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import os
from relation_extraction.NaiveMVP.main import handle_relation_post_request
from relation_extraction.relation_extractor import RelationExtractor

class PreProcessingHandler(BaseHTTPRequestHandler):
def do_POST(self):
Expand All @@ -23,7 +24,7 @@ def do_POST(self):

if self.path == '/tripleconstruction':
try:
handle_relation_post_request(post_content["post_json"])
RelationExtractor.begin_extraction(post_content["post_json"])
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
Expand Down
12 changes: 2 additions & 10 deletions test/test_server/test_get_relations.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import unittest
from relation_extraction.ontology_messenger import OntologyMessenger
from server.server import *
from unittest.mock import patch, Mock, MagicMock, mock_open
from relation_extraction.get_relations import *

class TestGetRelations(unittest.TestCase):

Expand All @@ -18,22 +18,14 @@ def test_extract_specific_relations(self, mock_get):
mock_get.return_value.json.return_value = response
mock_get.return_value.text.return_value = "request response"

relations = extract_specific_relations()
relations = OntologyMessenger.send_request()

self.assertEqual(len(relations), 2)
self.assertEqual(relations[0], "test")
self.assertEqual(relations[1], "another_test")
mock_get.assert_called_once_with(url='http://130.225.57.13/knox-api/triples', params={'g': 'http://knox_ontology', 's': 'http://dbpedia.org/ontology/', 'o': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Property'}, headers={'Access-Authorization': 'internal_key'})


@patch("builtins.open", new_callable=mock_open, read_data=":testline\na rdf:Property, owl:ObjectProperty ;")
def test_extract_specific_relations_offline(self, mock_open):
res = extract_specific_relations_offline()
mock_open.assert_called_once()

self.assertEqual(res, ["testline"])



if __name__ == "__main__":
unittest.main()
6 changes: 3 additions & 3 deletions test/test_server/test_output.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import unittest
from relation_extraction.output import *
from relation_extraction.knowledge_graph_messenger import KnowledgeGraphMessenger
from unittest.mock import patch, Mock, MagicMock

class TestOutput(unittest.TestCase):

def test_format_output(self):
input = [["this", "is", "triples"]]
res = format_output(input)
res = KnowledgeGraphMessenger.format_output(input)
self.assertTrue("triples" in res.keys())
self.assertEqual(res["triples"], input)

Expand All @@ -15,7 +15,7 @@ def test_send_to_database(self, mock_request):
mock_response = MagicMock()
mock_response.text = "response"
mock_request.return_value = mock_response
res = send_to_database_component("test_output")
res = KnowledgeGraphMessenger.send_request("test_output")

mock_request.assert_called_once_with(url='http://130.225.57.13/knox-api/triples', json={'triples': 'test_output'}, params={'g': 'http://knox_database'}, headers={'Access-Authorization': 'internal_key'})
self.assertEqual(res, "response")
4 changes: 2 additions & 2 deletions test/test_server/test_pre_processing_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class TestPreProcessingHandler(unittest.TestCase):
@patch("os.getenv")
@patch('server.server.handle_relation_post_request', return_value=Mock())
@patch('relation_extraction.relation_extractor.RelationExtractor.begin_extraction', return_value=Mock())
@patch.object(PreProcessingHandler, 'wrongly_formatted_request_response')
@patch.object(PreProcessingHandler, 'handled_request_body', return_value=True)
@patch.object(PreProcessingHandler, '__init__', return_value=None)
Expand Down Expand Up @@ -57,7 +57,7 @@ def test_do_post_invalid_endpoint(self, mock_init, mock_handled_body, mock_wrong
handler.end_headers.assert_called_once()

@patch("os.getenv")
@patch('server.server.handle_relation_post_request', return_value=Mock())
@patch('relation_extraction.relation_extractor.RelationExtractor.begin_extraction', return_value=Mock())
@patch.object(PreProcessingHandler, 'wrongly_formatted_request_response')
@patch.object(PreProcessingHandler, 'handled_request_body', return_value=True)
@patch.object(PreProcessingHandler, '__init__', return_value=None)
Expand Down
8 changes: 4 additions & 4 deletions test/test_server/test_relation_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


class TestHandleRelationPostRequest(unittest.TestCase):
@mock.patch('relation_extraction.NaiveMVP.main.extract_specific_relations')
@mock.patch('relation_extraction.ontology_messenger.OntologyMessenger.send_request')
def test_handle_post_request_raises_exception_if_relations_fail(self, mock_extract_specific_relations):
mock_extract_specific_relations.side_effect = Exception()
data = dict()
Expand All @@ -15,7 +15,7 @@ def test_handle_post_request_raises_exception_if_relations_fail(self, mock_extra


@mock.patch('relation_extraction.NaiveMVP.main.parse_data')
@mock.patch('relation_extraction.NaiveMVP.main.extract_specific_relations')
@mock.patch('relation_extraction.ontology_messenger.OntologyMessenger.send_request')
def test_handle_post_request_raises_exception_if_parse_fail(self, mock_extract_specific_relations, mock_parse_data):
mock_extract_specific_relations.return_value = []
mock_parse_data.side_effect = Exception()
Expand All @@ -28,9 +28,9 @@ def test_handle_post_request_raises_exception_if_parse_fail(self, mock_extract_s
mock_parse_data.assert_called_once()


@mock.patch('relation_extraction.NaiveMVP.main.send_to_database_component')
@mock.patch('relation_extraction.knowledge_graph_messenger.KnowledgeGraphMessenger.send_request')
@mock.patch('relation_extraction.NaiveMVP.main.parse_data')
@mock.patch('relation_extraction.NaiveMVP.main.extract_specific_relations')
@mock.patch('relation_extraction.ontology_messenger.OntologyMessenger.send_request')
def test_handle_post_request_raises_exception_if_db_component_fail(self, mock_extract_specific_relations, mock_parse_data, mock_send_to_db):
mock_extract_specific_relations.return_value = []
mock_parse_data.return_value = dict()
Expand Down

0 comments on commit 62d10c8

Please sign in to comment.