feat: Update to new CleverSwarm ontology loading capabilities

ISSUES CLOSED: #8
This commit is contained in:
CoreRasurae
2026-01-05 21:39:25 +00:00
committed by Luis Mendes
parent cd808dc3dd
commit ae871db488
3 changed files with 92 additions and 48 deletions
@@ -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,11 +629,14 @@ 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",
self._base_url + ("unstructured/with_ontology" if ontology_file else
"unstructured/with_ontology_simple"),
headers=headers,
params=params,
files=files,
@@ -669,7 +667,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 +677,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 +692,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,12 +709,15 @@ 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",
self._base_url + ("unstructured/with_wildcards" if ontology_file else
"unstructured/with_wildcards_simple"),
headers=headers,
params=params,
files=files,
+65 -8
View File
@@ -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."""