feat: Update to new CleverSwarm ontology loading capabilities
ISSUES CLOSED: #8
This commit is contained in:
@@ -76,7 +76,10 @@ class TextoToKGCLI(object):
|
||||
force_filetype: FileTypeAPI = FileTypeAPI.AutoDetect,
|
||||
):
|
||||
input_text_path: Path = self._input_prefix / input_text
|
||||
ontology_json_path: Path = self._input_prefix / ontology_json
|
||||
# Ontology JSON file is optional - only create path if it was provided
|
||||
ontology_json_path: Path | None = (
|
||||
self._input_prefix / ontology_json if ontology_json else None
|
||||
)
|
||||
ontology_owl_path: Path = self._input_prefix / ontology_owl
|
||||
wildcards_path: Path = Path(wildcards) if wildcards else None
|
||||
|
||||
@@ -85,11 +88,15 @@ class TextoToKGCLI(object):
|
||||
f"Unstructured input text does not exist or is not a file: {str(input_text_path)}"
|
||||
)
|
||||
|
||||
if not ontology_json_path.exists() or not ontology_json_path.is_file():
|
||||
# If ontology_json was provided, validate that the file exists
|
||||
if ontology_json and ontology_json_path and (not ontology_json_path.exists() or not ontology_json_path.is_file()):
|
||||
raise ClientException(
|
||||
f"Input ontology JSON file does not exist or is not a file: {str(ontology_json_path)}"
|
||||
f"Specified optional Ontology JSON file does not exist or is not a file: {str(ontology_json_path)}"
|
||||
)
|
||||
|
||||
# Ontology JSON file is optional - use the path if it was provided and exists
|
||||
ontology_json_path_final: Path | None = ontology_json_path
|
||||
|
||||
if not ontology_owl_path.exists() or not ontology_owl_path.is_file():
|
||||
raise ClientException(
|
||||
f"Input ontology OWL file does not exist or is not a file: {str(ontology_owl_path)}"
|
||||
@@ -106,7 +113,7 @@ class TextoToKGCLI(object):
|
||||
if wildcards_job:
|
||||
job_id: str = self._client.create_unstructured_to_kg_wildcards_job(
|
||||
input_text_path,
|
||||
ontology_json_path,
|
||||
ontology_json_path_final,
|
||||
ontology_owl_path,
|
||||
wildcards_path,
|
||||
force_filetype=force_filetype,
|
||||
@@ -114,7 +121,7 @@ class TextoToKGCLI(object):
|
||||
else:
|
||||
job_id: str = self._client.create_unstructured_to_kg_job(
|
||||
input_text_path,
|
||||
ontology_json_path,
|
||||
ontology_json_path_final,
|
||||
ontology_owl_path,
|
||||
force_filetype=force_filetype,
|
||||
)
|
||||
@@ -272,7 +279,7 @@ def main():
|
||||
parser.add_argument(
|
||||
"--ontology_json",
|
||||
type=str,
|
||||
help="Enriched ontology file with descriptions in JSON format",
|
||||
help="Optional enriched ontology file with descriptions in JSON format",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ontology_owl",
|
||||
@@ -306,10 +313,6 @@ def main():
|
||||
print("create-and-exit action requires --unstructured_text argument.\n")
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if args.ontology_json is None:
|
||||
print("create-and-exit action requires --ontology_json argument.\n")
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if args.ontology_owl is None:
|
||||
print("create-and-exit action requires --ontology_owl argument.\n")
|
||||
parser.print_help()
|
||||
@@ -339,12 +342,6 @@ def main():
|
||||
)
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if args.ontology_json is None:
|
||||
print(
|
||||
"create-download-kg-delete action requires --ontology_json argument.\n"
|
||||
)
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if args.ontology_owl is None:
|
||||
print(
|
||||
"create-download-kg-delete action requires --ontology_owl argument.\n"
|
||||
@@ -361,12 +358,6 @@ def main():
|
||||
)
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if args.ontology_json is None:
|
||||
print(
|
||||
"create-download-kg-delete action requires --ontology_json argument.\n"
|
||||
)
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if args.ontology_owl is None:
|
||||
print(
|
||||
"create-download-kg-delete action requires --ontology_owl argument.\n"
|
||||
|
||||
@@ -595,7 +595,7 @@ class CleverSwarmClient(object):
|
||||
def create_unstructured_to_kg_job(
|
||||
self,
|
||||
unstructured_text_file: Path,
|
||||
ontology_file: Path,
|
||||
ontology_file: Path | None,
|
||||
ontology_spec_file: Path,
|
||||
force_filetype: FileTypeAPI = FileTypeAPI.AutoDetect,
|
||||
):
|
||||
@@ -604,7 +604,7 @@ class CleverSwarmClient(object):
|
||||
Login is requested if required by the server.
|
||||
If the upload is successful, it returns a job ID.
|
||||
:param unstructured_text_file: a valid file path containing unstructured text for conversion
|
||||
:param ontology_file: a valid file containing an ontology in JSON format.
|
||||
:param ontology_file: optional file containing an ontology in JSON format.
|
||||
:param ontology_spec_file: a valid file path containing the ontology spec in OWL/XML format.
|
||||
:param force_filetype: indicate the file type to force for the input file
|
||||
:return: the job ID where the files were placed.
|
||||
@@ -618,11 +618,6 @@ class CleverSwarmClient(object):
|
||||
f"{str(unstructured_text_file)}"
|
||||
)
|
||||
|
||||
if not ontology_file.exists() or not ontology_file.is_file():
|
||||
raise InvalidFileException(
|
||||
f"Ontology files does not exist or is not a file: {str(ontology_file)}"
|
||||
)
|
||||
|
||||
if not ontology_spec_file.exists() or not ontology_spec_file.is_file():
|
||||
raise InvalidFileException(
|
||||
f"OWL/XML ontology file does not exist or is not a file: "
|
||||
@@ -634,9 +629,11 @@ class CleverSwarmClient(object):
|
||||
params = {"file_type": force_filetype}
|
||||
files = [
|
||||
("unstructured", open(unstructured_text_file, "rb")),
|
||||
("ontology", open(ontology_file, "rb")),
|
||||
("ontology_spec", open(ontology_spec_file, "rb")),
|
||||
]
|
||||
if ontology_file:
|
||||
files.append(("ontology", open(ontology_file, "rb")))
|
||||
|
||||
response = requests.post(
|
||||
self._base_url + "unstructured/with_ontology",
|
||||
headers=headers,
|
||||
@@ -669,7 +666,7 @@ class CleverSwarmClient(object):
|
||||
def create_unstructured_to_kg_wildcards_job(
|
||||
self,
|
||||
unstructured_text_file: Path,
|
||||
ontology_file: Path,
|
||||
ontology_file: Path | None,
|
||||
ontology_spec_file: Path,
|
||||
wildcards_query_file: Path,
|
||||
force_filetype: FileTypeAPI = FileTypeAPI.AutoDetect,
|
||||
@@ -679,7 +676,7 @@ class CleverSwarmClient(object):
|
||||
Login is requested if required by the server.
|
||||
If the upload is successful, it returns a job ID.
|
||||
:param unstructured_text_file: a valid file path containing unstructured text for conversion
|
||||
:param ontology_file: a valid file containing an ontology in JSON format.
|
||||
:param ontology_file: optional file containing an ontology in JSON format.
|
||||
:param ontology_spec_file: a valid file path containing the ontology spec in OWL/XML format.
|
||||
:param wildcards_query_file: a valid file path containing wildcard queries in JSON.
|
||||
:param force_filetype: indicate the file type to force for the input file
|
||||
@@ -694,11 +691,6 @@ class CleverSwarmClient(object):
|
||||
f"{str(unstructured_text_file)}"
|
||||
)
|
||||
|
||||
if not ontology_file.exists() or not ontology_file.is_file():
|
||||
raise InvalidFileException(
|
||||
f"Ontology files does not exist or is not a file: {str(ontology_file)}"
|
||||
)
|
||||
|
||||
if not ontology_spec_file.exists() or not ontology_spec_file.is_file():
|
||||
raise InvalidFileException(
|
||||
f"OWL/XML ontology file does not exist or is not a file: "
|
||||
@@ -716,10 +708,12 @@ class CleverSwarmClient(object):
|
||||
params = {"file_type": force_filetype}
|
||||
files = [
|
||||
("unstructured", open(unstructured_text_file, "rb")),
|
||||
("ontology", open(ontology_file, "rb")),
|
||||
("ontology_spec", open(ontology_spec_file, "rb")),
|
||||
("wildcards", open(wildcards_query_file, "rb")),
|
||||
]
|
||||
if ontology_file:
|
||||
files.append(("ontology", open(ontology_file, "rb")))
|
||||
|
||||
response = requests.post(
|
||||
self._base_url + "unstructured/with_wildcards",
|
||||
headers=headers,
|
||||
|
||||
@@ -214,18 +214,75 @@ class TestTextoToKGCLIJobCreation:
|
||||
"test.owl"
|
||||
)
|
||||
|
||||
def test_create_job_invalid_json_file(self):
|
||||
"""Test job creation with invalid JSON file."""
|
||||
def test_create_job_with_invalid_json_file(self):
|
||||
"""Test job creation with invalid (non-existent) JSON file - should raise exception if JSON is provided."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as text_file:
|
||||
text_file.write("Test text content")
|
||||
text_file.flush()
|
||||
|
||||
with pytest.raises(ClientException, match="Input ontology JSON file does not exist"):
|
||||
self.cli.create_job(
|
||||
text_file.name,
|
||||
"nonexistent.json",
|
||||
"test.owl"
|
||||
)
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.owl') as owl_file:
|
||||
owl_file.write('<rdf:RDF>test</rdf:RDF>')
|
||||
owl_file.flush()
|
||||
|
||||
# If ontology_json is provided but file doesn't exist, should raise exception
|
||||
with pytest.raises(ClientException, match="Specified optional Ontology JSON file does not exist"):
|
||||
self.cli.create_job(
|
||||
text_file.name,
|
||||
"nonexistent.json", # Non-existent JSON file - should raise exception
|
||||
owl_file.name
|
||||
)
|
||||
|
||||
def test_create_job_without_json_file(self):
|
||||
"""Test job creation without JSON file - should work since JSON is optional."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as text_file:
|
||||
text_file.write("Test text content")
|
||||
text_file.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.owl') as owl_file:
|
||||
owl_file.write('<rdf:RDF>test</rdf:RDF>')
|
||||
owl_file.flush()
|
||||
|
||||
with patch.object(self.cli._client, 'create_unstructured_to_kg_job') as mock_create:
|
||||
mock_create.return_value = "test_job_123"
|
||||
|
||||
# Job creation should work without JSON file since it's optional
|
||||
result = self.cli.create_job(
|
||||
text_file.name,
|
||||
None, # No JSON file provided - should work
|
||||
owl_file.name
|
||||
)
|
||||
|
||||
assert result == "test_job_123"
|
||||
mock_create.assert_called_once()
|
||||
# Verify that None was passed for ontology_file since it wasn't provided
|
||||
call_args = mock_create.call_args
|
||||
assert call_args[0][1] is None # ontology_file parameter should be None
|
||||
|
||||
def test_create_job_with_empty_json_file_string(self):
|
||||
"""Test job creation with empty string for JSON file - should work since JSON is optional."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as text_file:
|
||||
text_file.write("Test text content")
|
||||
text_file.flush()
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.owl') as owl_file:
|
||||
owl_file.write('<rdf:RDF>test</rdf:RDF>')
|
||||
owl_file.flush()
|
||||
|
||||
with patch.object(self.cli._client, 'create_unstructured_to_kg_job') as mock_create:
|
||||
mock_create.return_value = "test_job_123"
|
||||
|
||||
# Job creation should work with empty string for JSON file since it's optional
|
||||
result = self.cli.create_job(
|
||||
text_file.name,
|
||||
"", # Empty string for JSON file - should work
|
||||
owl_file.name
|
||||
)
|
||||
|
||||
assert result == "test_job_123"
|
||||
mock_create.assert_called_once()
|
||||
# Verify that None was passed for ontology_file since empty string is falsy
|
||||
call_args = mock_create.call_args
|
||||
assert call_args[0][1] is None # ontology_file parameter should be None
|
||||
|
||||
def test_create_job_invalid_owl_file(self):
|
||||
"""Test job creation with invalid OWL file."""
|
||||
|
||||
Reference in New Issue
Block a user