fix: resolve TTL export alias failure and add RDF notebook example (#355)

- Add _format_aliases map in RDFExporter to accept 'ttl', 'nt', 'xml', 'rdf', 'json-ld' as shorthands for canonical format names
- Resolve alias at the start of export_to_rdf() before validation, leaving all existing callers unaffected
- Add TTL alias demo cell to cookbook/introduction/15_Export.ipynb
- Add tests/export/test_rdf_exporter.py covering alias parity, canonical formats, unsupported format error, and file export with format="ttl"

Closes #355

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
KaifAhmad1
2026-03-07 01:42:16 +05:30
co-authored by Claude Sonnet 4.6
parent 501142e8de
commit 8c4e5e5968
4 changed files with 91 additions and 1 deletions
+8 -1
View File
@@ -178,6 +178,13 @@
"rdf_exporter.export(kg, \"output.ttl\", format=\"turtle\")"
]
},
{
"cell_type": "code",
"source": "# TTL alias: format=\"ttl\" is equivalent to format=\"turtle\"\nrdf_data = {\n \"entities\": [\n {\"id\": \"e1\", \"text\": \"Apple Inc.\", \"type\": \"ORG\", \"confidence\": 0.95},\n {\"id\": \"e2\", \"text\": \"Steve Jobs\", \"type\": \"PERSON\", \"confidence\": 0.97},\n ],\n \"relationships\": [\n {\"source_id\": \"e2\", \"target_id\": \"e1\", \"type\": \"founded_by\", \"confidence\": 0.91},\n ],\n}\n\nrdf_exporter.export(rdf_data, \"output.ttl\", format=\"ttl\")\n\nresult = rdf_exporter.validate_rdf(rdf_data)\nprint(f\"Valid: {result['valid']}\")",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
@@ -363,4 +370,4 @@
},
"nbformat": 4,
"nbformat_minor": 2
}
}
+10
View File
@@ -851,6 +851,15 @@ class RDFExporter:
# Supported RDF formats
self.supported_formats = ["turtle", "rdfxml", "jsonld", "ntriples", "n3"]
# Format aliases (common extensions/shorthands → canonical names)
self._format_aliases = {
"ttl": "turtle",
"nt": "ntriples",
"xml": "rdfxml",
"rdf": "rdfxml",
"json-ld": "jsonld",
}
# Initialize progress tracker
self.progress_tracker = get_progress_tracker()
@@ -892,6 +901,7 @@ class RDFExporter:
)
try:
format = self._format_aliases.get(format.lower(), format.lower())
if format not in self.supported_formats:
raise ValidationError(
f"Unsupported RDF format: {format}. "
View File
+73
View File
@@ -0,0 +1,73 @@
"""Tests for RDFExporter format alias resolution (issue #355)."""
import pytest
from semantica.export import RDFExporter
RDF_DATA = {
"entities": [
{"id": "e1", "text": "Apple Inc.", "type": "ORG", "confidence": 0.95},
{"id": "e2", "text": "Steve Jobs", "type": "PERSON", "confidence": 0.97},
],
"relationships": [
{"source_id": "e2", "target_id": "e1", "type": "founded_by", "confidence": 0.91},
],
}
@pytest.fixture
def exporter():
return RDFExporter()
def test_ttl_alias_produces_same_output_as_turtle(exporter):
"""format='ttl' must produce identical output to format='turtle'."""
result_turtle = exporter.export_to_rdf(RDF_DATA, format="turtle")
result_ttl = exporter.export_to_rdf(RDF_DATA, format="ttl")
assert result_ttl == result_turtle
def test_nt_alias_produces_same_output_as_ntriples(exporter):
result_canonical = exporter.export_to_rdf(RDF_DATA, format="ntriples")
result_alias = exporter.export_to_rdf(RDF_DATA, format="nt")
assert result_alias == result_canonical
def test_xml_alias_produces_same_output_as_rdfxml(exporter):
result_canonical = exporter.export_to_rdf(RDF_DATA, format="rdfxml")
result_alias = exporter.export_to_rdf(RDF_DATA, format="xml")
assert result_alias == result_canonical
def test_rdf_alias_produces_same_output_as_rdfxml(exporter):
result_canonical = exporter.export_to_rdf(RDF_DATA, format="rdfxml")
result_alias = exporter.export_to_rdf(RDF_DATA, format="rdf")
assert result_alias == result_canonical
def test_json_ld_alias_produces_same_output_as_jsonld(exporter):
result_canonical = exporter.export_to_rdf(RDF_DATA, format="jsonld")
result_alias = exporter.export_to_rdf(RDF_DATA, format="json-ld")
assert result_alias == result_canonical
def test_canonical_formats_unaffected(exporter):
"""Existing canonical format names must continue to work."""
# n3 is listed in supported_formats but has no serializer implementation yet
for fmt in ("turtle", "rdfxml", "jsonld", "ntriples"):
result = exporter.export_to_rdf(RDF_DATA, format=fmt)
assert result is not None and len(result) > 0
def test_unsupported_format_raises(exporter):
from semantica.utils.exceptions import ValidationError
with pytest.raises(ValidationError):
exporter.export_to_rdf(RDF_DATA, format="parquet")
def test_ttl_export_to_file(exporter, tmp_path):
out = tmp_path / "output.ttl"
exporter.export(RDF_DATA, str(out), format="ttl")
assert out.exists()
assert out.stat().st_size > 0