Files
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

9.8 KiB

Basic Usage

This section covers the fundamental operations of CleverRDFLib: loading ontologies from local files and web URLs.

Loading from a Local File

The simplest way to load an ontology is from a local file:

from cleverrdf_lib import OntologyLoader, LoadingResult

# Create a loader with default configuration
loader = OntologyLoader()

# Load from a local file path
result: LoadingResult = loader.load_ontology("path/to/ontology.ttl")

Supported File Formats

CleverRDFLib supports all RDF serialization formats that RDFLib can parse:

  • Turtle (.ttl)
  • RDF/XML (.rdf, .owl)
  • N3 (.n3)
  • N-Triples (.nt)
  • JSON-LD (.jsonld)
  • TriG (.trig)
  • N-Quads (.nq)

The format is automatically detected from the file extension, or you can specify it explicitly (see below).

File Path Formats

You can provide file paths in several formats:

# Relative path
result = loader.load_ontology("data/ontology.ttl")

# Absolute path
result = loader.load_ontology("/absolute/path/to/ontology.ttl")

# File URI
result = loader.load_ontology("file:///absolute/path/to/ontology.ttl")

Loading from the Web

Loading from HTTP or HTTPS URLs is equally straightforward:

from cleverrdf_lib import OntologyLoader

loader = OntologyLoader()

# Load from HTTP URL
result = loader.load_ontology("http://example.com/ontology.owl")

# Load from HTTPS URL
result = loader.load_ontology("https://example.com/ontology.ttl")

URL Handling

The framework automatically handles:

  • HTTP/HTTPS requests: Uses standard HTTP requests to fetch ontology files
  • Content-Type detection: Automatically detects the RDF format from HTTP headers
  • Redirects: Follows HTTP redirects automatically
  • Error handling: Provides detailed error information for failed requests

Specifying Serialization Format

If the format cannot be automatically detected, you can specify it explicitly using the GraphLoader utility:

from cleverrdf_lib.utils.graph_loader import GraphLoader

loader = GraphLoader()
graph = loader.load_from_uri("path/to/ontology", serialization_format="turtle")

Supported format strings: "xml", "turtle", "n3", "nt", "json-ld", "trig", "nquads".

Custom Graph Loading Handlers

The framework uses a Chain of Responsibility pattern for graph loading, allowing you to add custom handlers for specific URI schemes or repositories.

Creating a Custom Handler

To create a custom handler for fetching ontologies from a custom repository or redirecting web requests to local files:

Example 1: Handling a Custom URI Scheme

from cleverrdf_lib.core.interfaces.interfaces import GraphLoaderHandler
from cleverrdf_lib.utils.graph_loader_base_handler import GraphLoaderBaseHandler
from rdflib import Graph
import os

class CustomRepositoryHandler(GraphLoaderBaseHandler):
    """Custom handler for fetching ontologies from a custom repository."""
    
    def __init__(self, repository_path: str):
        """
        Initialize the custom handler.
        
        Args:
            repository_path: Base path to the custom repository
        """
        super().__init__()
        self._repository_path = repository_path
    
    def handle_graph_load(
        self,
        uri_scheme: str,
        uri_netloc: str,
        uri_path: str,
        serialization_format: str | None = None,
    ) -> Graph:
        """Handle loading from custom repository scheme."""
        # Check if this handler can handle the scheme
        if uri_scheme == "custom":
            # Load from custom repository
            # uri_path would be something like "ontology/example.owl"
            local_path = os.path.join(self._repository_path, uri_path)
            
            # Load the graph from the local file
            graph = Graph()
            graph.parse(local_path, format=serialization_format)
            return graph
        else:
            # Delegate to next handler in chain
            return super().handle_graph_load(uri_scheme, uri_netloc, uri_path, serialization_format)
    
    def get_id(self) -> str:
        """Return unique identifier for this handler."""
        return "custom_repository_handler"

Example 2: Redirecting HTTP URLs to Local Files

from cleverrdf_lib.core.interfaces.interfaces import GraphLoaderHandler
from cleverrdf_lib.utils.graph_loader_base_handler import GraphLoaderBaseHandler
from rdflib import Graph
import os

class LocalFileRedirectHandler(GraphLoaderBaseHandler):
    """Handler that redirects HTTP/HTTPS URLs to local files."""
    
    def __init__(self, url_to_file_map: dict[str, str]):
        """
        Initialize the redirect handler.
        
        Args:
            url_to_file_map: Dictionary mapping URLs to local file paths
        """
        super().__init__()
        self._url_map = url_to_file_map
    
    def handle_graph_load(
        self,
        uri_scheme: str,
        uri_netloc: str,
        uri_path: str,
        serialization_format: str | None = None,
    ) -> Graph:
        """Redirect HTTP/HTTPS URLs to local files if mapped."""
        # Construct the full URI from components for lookup
        uri_full = f"{uri_scheme}://{uri_netloc}{uri_path}"
        
        # Check if this is an HTTP/HTTPS URL that should be redirected
        if uri_scheme in ("http", "https") and uri_full in self._url_map:
            # Redirect to local file
            local_path = self._url_map[uri_full]
            graph = Graph()
            graph.parse(local_path, format=serialization_format)
            return graph
        else:
            # Delegate to next handler (e.g., DefaultGraphLoaderHTTPHandler)
            return super().handle_graph_load(uri_scheme, uri_netloc, uri_path, serialization_format)
    
    def get_id(self) -> str:
        """Return unique identifier for this handler."""
        return "local_file_redirect_handler"

Registering a Custom Handler

Example 1: Using a Custom Scheme Handler

from cleverrdf_lib.utils.graph_loader import GraphLoader
# Assuming CustomRepositoryHandler is defined as shown in the previous example

# Create a custom handler for "custom://" scheme
custom_handler = CustomRepositoryHandler(repository_path="/path/to/repository")

# Create a GraphLoader and insert the custom handler at the beginning
graph_loader = GraphLoader()
graph_loader.insert_handler_in_chain(custom_handler, position=0)

# Now you can load using the custom scheme
graph = graph_loader.load_from_uri("custom://ontology/example.owl")

Example 2: Redirecting Web Requests to Local Files

from cleverrdf_lib import OntologyLoader, LoadingResult
from cleverrdf_lib.utils.graph_loader import GraphLoader

# Assuming LocalFileRedirectHandler is defined as shown in the previous example

# Create a mapping of URLs to local files
url_map = {
    "http://example.com/ontology.owl": "/local/path/to/ontology.owl",
    "https://example.org/schema.ttl": "/local/path/to/schema.ttl"
}

# Create redirect handler
redirect_handler = LocalFileRedirectHandler(url_map)

# Create GraphLoader and insert redirect handler before HTTP handler
graph_loader = GraphLoader()
graph_loader.insert_handler_in_chain(redirect_handler, position=0)

# Now HTTP requests will be redirected to local files
loader = OntologyLoader(graph_loader=graph_loader)

result: LoadingResult = loader.load_ontology("http://example.com/ontology.owl")
# This will actually load from /local/path/to/ontology.owl

!!! note "Handler Chain Order" The order of handlers matters. Handlers are checked in sequence, so place your custom handler before the default handlers if you want it to take precedence. For redirect handlers, place them before the HTTP handler so redirects happen before network requests.

Loading with Custom Configuration

Setting Maximum Depth

Limit the depth of recursive ontology loading:

from cleverrdf_lib import OntologyLoader, LoadingResult

# Limit to 3 levels of imports
loader = OntologyLoader(max_depth=3)
result = loader.load_ontology("ontology.ttl")

Disabling Validation

Skip OWL validation for faster loading:

from cleverrdf_lib import OntologyLoader, LoadingResult

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

Custom Loading Strategy

Use a different loading strategy (depth-first is default):

from cleverrdf_lib import OntologyLoader, LoadingResult
from cleverrdf_lib.factories.strategy_factory import StrategyFactory

# Use breadth-first strategy
strategy = StrategyFactory.create("breadth-first")
loader = OntologyLoader(strategy=strategy)
result = loader.load_ontology("ontology.ttl")

Custom Reference Resolver

Use a custom resolver for reference resolution:

from cleverrdf_lib.factories.resolver_factory import ResolverFactory

# Use OWL-only resolver (ignores RDFS references)
resolver = ResolverFactory.create_owl_only()
loader = OntologyLoader(resolver=resolver)
result = loader.load_ontology("ontology.ttl")

Accessing the Loaded Graph

After loading, you can access the merged graph:

result: LoadingResult = loader.load_ontology("ontology.ttl")

# 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.

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

Next Steps