ISSUES CLOSED: #2
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_urisset - 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
- Check
is_successful_for_main_ontology: Always verify loading succeeded before accessing results (recommended for most cases) - Prefer class_hierarchy: Use the class hierarchy API instead of direct graph access
- Handle errors: Check and handle errors appropriately
- Review warnings: Review warnings to identify potential issues
- Lazy loading: Be aware that OWL features are lazy-loaded
Next Steps
- Learn about Class Hierarchy Navigation
- Explore OWL Extensions and Validation
- Understand Error Handling