Files
CleverRDFlib/docs/loading_result.md
CoreRasurae f14c0bad8c
CI / lint (pull_request) Successful in 1m35s
CI / typecheck (pull_request) Successful in 1m38s
CI / behave (3.11) (pull_request) Successful in 1m48s
CI / behave (3.12) (pull_request) Successful in 1m47s
CI / behave (3.13) (pull_request) Successful in 1m43s
CI / build (pull_request) Successful in 1m33s
CI / lint (push) Successful in 1m31s
CI / typecheck (push) Successful in 1m29s
CI / behave (3.11) (push) Successful in 1m37s
CI / behave (3.12) (push) Successful in 1m44s
CI / behave (3.13) (push) Successful in 1m36s
CI / build (push) Successful in 1m31s
docs: Initial documentation of CleverRDFLib
ISSUES CLOSED: #2
2025-12-22 10:50:03 +00:00

11 KiB

Loading Result API

The LoadingResult class encapsulates the result of an ontology loading operation, providing access to the merged graph, loaded URIs, errors, warnings, and OWL-specific features.

Overview

After loading an ontology, OntologyLoader.load_ontology() returns a LoadingResult object that contains:

  • Merged graph: The combined RDF graph containing all loaded ontologies
  • Loaded URIs: Set of successfully loaded ontology URIs
  • Errors: List of errors encountered during loading
  • Warnings: List of warnings encountered during loading
  • OWL features: Lazy-loaded OWL-specific features (validation, consistency, metadata, version management)

Basic Usage

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Check if loading was successful
if result.is_successful_for_main_ontology:
    print("Loading succeeded!")
else:
    print("Loading failed!")
    for error in result.errors:
        print(f"Error: {error['message']}")

Accessing the Merged Graph

!!! warning "Graph Access Warning" Direct access to the merged_graph property introduces a direct dependency on RDFLib and its SPARQL queries and iterators. For general client applications, prefer using the class_hierarchy API for navigating the ontology structure.

# Access the merged graph
graph = result.merged_graph

# NOTE: Direct graph access is discouraged for general client applications
# as it introduces a direct dependency on RDFLib and its SPARQL/iterators.
# Prefer using the class_hierarchy API instead.

When to Use the Graph Directly

Direct graph access should only be used when:

  • You need to perform custom SPARQL queries
  • You need to access RDF triples directly
  • You need to work with RDFLib-specific features
  • You are building framework extensions

For most use cases, use the class_hierarchy API instead.

Loaded URIs

Get the set of successfully loaded ontology URIs:

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Get loaded URIs
loaded_uris = result.loaded_uris
print(f"Loaded {len(loaded_uris)} ontologies:")
for uri in loaded_uris:
    print(f"  - {uri}")

# Get count
count = result.loaded_count
print(f"Total loaded: {count}")

Errors

Access errors encountered during loading:

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Check for errors
if not result.is_successful_for_main_ontology:
    print("Errors encountered:")
    for error in result.errors:
        print(f"URI: {error['uri']}")
        print(f"Message: {error['message']}")
        if 'exception' in error:
            print(f"Exception: {error['exception']}")

Error Structure

Each error is a dictionary:

{
    "uri": str,           # The URI that failed to load
    "message": str,       # Human-readable error message
    "exception": Exception # The underlying exception (if available)
}

Adding Errors

You can add errors programmatically (though this is typically done internally):

result.add_error({
    "uri": "http://example.org/failed.owl",
    "message": "Failed to load ontology",
    "exception": some_exception
})

Warnings

Access warnings encountered during loading:

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Check for warnings
if result.warnings:
    print("Warnings:")
    for warning in result.warnings:
        print(f"  - {warning}")

Adding Warnings

Warnings can be added programmatically:

result.add_warning("OWL Validation Warning: Circular class definition detected")

Warnings are typically added by:

  • OWL validation (validation warnings)
  • Consistency checking (consistency warnings)
  • Build observers (build inconsistency warnings)

Class Hierarchy

Access the class hierarchy (lazy-loaded):

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Access the hierarchy (automatically builds if not already built)
hierarchy = result.class_hierarchy

# Navigate the hierarchy (iterate over dictionary values)
for class_node in hierarchy.get_all_classes().values():
    print(f"Class: {class_node.iri}")
    print(f"  Parents: {[p.iri for p in class_node.parents]}")
    print(f"  Children: {[c.iri for c in class_node.children]}")

The hierarchy is built automatically on first access. See Class Hierarchy Navigation for details.

Setting Build Observers

You can set observers for the class hierarchy build process:

from cleverrdf_lib import OntologyLoader
from cleverrdf_lib.observers.base_hierarchy_oberver import BaseClassHierarchyBuildObserver

class MyBuildObserver(BaseClassHierarchyBuildObserver):
    def on_build_started(self, iri: str) -> None:
        print(f"Building hierarchy for: {iri}")
    
    def on_build_completed(self, iri: str) -> None:
        print(f"Hierarchy build completed for: {iri}")

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Set observer before accessing hierarchy
observer = MyBuildObserver()
result.set_class_hierarchy_build_observer(observer)

# Or set multiple observers
observer1 = MyBuildObserver()
observer2 = MyBuildObserver()
result.set_class_hierarchy_build_observers([observer1, observer2])

# Now access hierarchy (observer will be notified)
hierarchy = result.class_hierarchy

OWL Features

The LoadingResult provides lazy-loaded access to OWL-specific features:

Validation Result

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Access validation result (lazy-loaded)
validation_result = result.owl_validation_result

if validation_result.is_valid:
    print("Ontology is valid!")
else:
    print("Validation errors:")
    for error in validation_result.errors:
        print(f"  - {error}")
    
    print("Validation warnings:")
    for warning in validation_result.warnings:
        print(f"  - {warning}")

Consistency Result

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Access consistency result (lazy-loaded)
consistency_result = result.owl_consistency_result

if consistency_result.is_consistent:
    print("Ontology is consistent!")
else:
    print("Consistency issues:")
    for issue in consistency_result.issues:
        print(f"  - {issue.message}")
        print(f"    Element: {issue.element_iri}")

Metadata

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Access metadata (lazy-loaded)
metadata = result.owl_metadata

print(f"Version IRI: {metadata.get('version_iri')}")
print(f"Prior Version: {metadata.get('prior_version')}")
print(f"Imports: {metadata.get('imports')}")

Version Manager

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()
result = loader.load_ontology("ontology.ttl")

# Access version manager (lazy-loaded)
version_manager = result.owl_version_manager

version_info = version_manager.extract_version_info()
print(f"Version: {version_info.version_info}")
print(f"Version IRI: {version_info.version_iri}")

Lazy Loading

All OWL features are lazy-loaded, meaning they are only computed when first accessed:

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()

# Validation is not performed until accessed
result = loader.load_ontology("ontology.ttl")

# Validation happens here (first access)
validation_result = result.owl_validation_result

# Subsequent accesses return the cached result
validation_result2 = result.owl_validation_result  # No recomputation

This provides:

  • Performance: Features are only computed when needed
  • Flexibility: You can skip expensive operations if not needed
  • Efficiency: Results are cached after first computation

Result Properties Summary

Property Type Description
merged_graph Graph Merged RDF graph (use with caution)
loaded_uris set[str] Set of loaded ontology URIs
loaded_count int Number of loaded ontologies
errors list[dict] List of error dictionaries
warnings list[str] List of warning messages
is_successful_for_all_ontologies bool Whether loading succeeded for all ontologies (no errors at all)
is_successful_for_main_ontology bool Whether the main ontology loaded successfully
class_hierarchy ClassHierarchy Class hierarchy (lazy-loaded)
owl_validation_result OWLValidationResult Validation result (lazy-loaded)
owl_consistency_result ConsistencyResult Consistency result (lazy-loaded)
owl_metadata dict OWL metadata (lazy-loaded)
owl_version_manager VersionManager Version manager (lazy-loaded)

Success Checking Methods

The LoadingResult provides two methods for checking loading success:

is_successful_for_main_ontology

Recommended for most use cases. Checks if the main ontology (the one you requested to load) was successfully loaded. Returns True if:

  • The main ontology URI is in the loaded_uris set
  • There are no errors specifically for the main ontology

This is the method you should use in most scenarios, as it verifies that the ontology you requested was successfully loaded, even if some imported ontologies failed to load.

if result.is_successful_for_main_ontology:
    # Main ontology loaded successfully
    hierarchy = result.class_hierarchy
else:
    # Main ontology failed to load
    print("Failed to load main ontology")

is_successful_for_all_ontologies

Checks if all ontologies (main + all imports) loaded successfully. Returns True only if:

  • There are no errors at all in the loading process

Use this method when you require that all imported ontologies must load successfully. If any import fails, this will return False even if the main ontology loaded successfully.

if result.is_successful_for_all_ontologies:
    # All ontologies (main + imports) loaded successfully
    print("All ontologies loaded")
else:
    # At least one ontology failed to load
    # Check result.errors to see which ones failed
    for error in result.errors:
        print(f"Failed: {error['uri']}")

When to Use Which

  • Use is_successful_for_main_ontology (recommended): When you want to proceed if the main ontology loaded, even if some imports failed
  • Use is_successful_for_all_ontologies: When you require all ontologies (including all imports) to load successfully before proceeding

Best Practices

  1. Check is_successful_for_main_ontology: Always verify loading succeeded before accessing results (recommended for most cases)
  2. Prefer class_hierarchy: Use the class hierarchy API instead of direct graph access
  3. Handle errors: Check and handle errors appropriately
  4. Review warnings: Review warnings to identify potential issues
  5. Lazy loading: Be aware that OWL features are lazy-loaded

Next Steps