Skip to content

client

RDF4J client module.

Classes:

Attributes:

ObjectType module-attribute

ObjectType = Union[URIRef, Literal, None]

PredicateType module-attribute

PredicateType = Union[URIRef, None]

SubjectType module-attribute

SubjectType = Union[URIRef, None]

GraphStoreManager

GraphStoreManager(identifier: str, http_client: Client)

An RDF4J Graph Store Protocol Client.

Parameters:

  • identifier

    (str) –

    The identifier of the repository.

  • http_client

    (Client) –

    The httpx.Client instance.

Methods:

  • add

    Add statements to the specified graph.

  • clear

    Clear all statements in the specified graph.

  • get

    Fetch all statements in the specified graph.

  • overwrite

    Overwrite statements in the specified graph.

Attributes:

Source code in rdflib/contrib/rdf4j/client.py
def __init__(self, identifier: str, http_client: httpx.Client):
    self._identifier = identifier
    self._http_client = http_client
    self._content_type = "application/n-triples"

http_client property

http_client

identifier property

identifier

Repository identifier.

add

add(graph_name: URIRef | str, data: str | bytes | BinaryIO | Graph)

Add statements to the specified graph.

Parameters:

  • graph_name

    (URIRef | str) –

    The graph name of the graph.

    For the default graph, use DATASET_DEFAULT_GRAPH_ID.

  • data

    (str | bytes | BinaryIO | Graph) –

    The RDF data to add.

Source code in rdflib/contrib/rdf4j/client.py
def add(self, graph_name: URIRef | str, data: str | bytes | BinaryIO | Graph):
    """Add statements to the specified graph.

    Parameters:
        graph_name: The graph name of the graph.

            For the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

        data: The RDF data to add.
    """
    if not graph_name:
        raise ValueError("Graph name must be provided.")
    validate_graph_name(graph_name)
    stream, should_close = rdf_payload_to_stream(data)
    headers = {
        "Content-Type": self._content_type,
    }
    params = self._build_graph_name_params(graph_name) or None
    try:
        response = self.http_client.post(
            self._build_url(graph_name),
            headers=headers,
            params=params,
            content=stream,
        )
        response.raise_for_status()
    finally:
        if should_close:
            stream.close()

clear

clear(graph_name: URIRef | str)

Clear all statements in the specified graph.

Parameters:

Source code in rdflib/contrib/rdf4j/client.py
def clear(self, graph_name: URIRef | str):
    """Clear all statements in the specified graph.

    Parameters:
        graph_name: The graph name of the graph.

            For the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].
    """
    if not graph_name:
        raise ValueError("Graph name must be provided.")
    validate_graph_name(graph_name)
    params = self._build_graph_name_params(graph_name) or None
    response = self.http_client.delete(self._build_url(graph_name), params=params)
    response.raise_for_status()

get

get(graph_name: URIRef | str) -> Graph

Fetch all statements in the specified graph.

Parameters:

Returns:

  • Graph

    A Graph object containing all statements in the graph.

Source code in rdflib/contrib/rdf4j/client.py
def get(self, graph_name: URIRef | str) -> Graph:
    """Fetch all statements in the specified graph.

    Parameters:
        graph_name: The graph name of the graph.

            For the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

    Returns:
        A [`Graph`][rdflib.graph.Graph] object containing all statements in the
            graph.
    """
    if not graph_name:
        raise ValueError("Graph name must be provided.")
    validate_graph_name(graph_name)
    headers = {
        "Accept": self._content_type,
    }
    params = self._build_graph_name_params(graph_name) or None

    response = self.http_client.get(
        self._build_url(graph_name),
        headers=headers,
        params=params,
    )
    response.raise_for_status()

    return Graph(identifier=graph_name).parse(
        data=response.text, format=self._content_type
    )

overwrite

overwrite(graph_name: URIRef | str, data: str | bytes | BinaryIO | Graph)

Overwrite statements in the specified graph.

Parameters:

  • graph_name

    (URIRef | str) –

    The graph name of the graph.

    For the default graph, use DATASET_DEFAULT_GRAPH_ID.

  • data

    (str | bytes | BinaryIO | Graph) –

    The RDF data to overwrite with.

Source code in rdflib/contrib/rdf4j/client.py
def overwrite(self, graph_name: URIRef | str, data: str | bytes | BinaryIO | Graph):
    """Overwrite statements in the specified graph.

    Parameters:
        graph_name: The graph name of the graph.

            For the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

        data: The RDF data to overwrite with.
    """
    if not graph_name:
        raise ValueError("Graph name must be provided.")
    validate_graph_name(graph_name)
    stream, should_close = rdf_payload_to_stream(data)
    headers = {
        "Content-Type": self._content_type,
    }
    params = self._build_graph_name_params(graph_name) or None
    try:
        response = self.http_client.put(
            self._build_url(graph_name),
            headers=headers,
            params=params,
            content=stream,
        )
        response.raise_for_status()
    finally:
        if should_close:
            stream.close()

NamespaceListingResult dataclass

NamespaceListingResult(prefix: str, namespace: str)

RDF4J namespace and prefix name result.

Attributes:

namespace instance-attribute

namespace: str

prefix instance-attribute

prefix: str

RDF4JClient

RDF4JClient(base_url: str, auth: tuple[str, str] | None = None, timeout: float = 30.0, **kwargs: Any)

RDF4J client.

Parameters:

  • base_url

    (str) –

    The base URL of the RDF4J server.

  • auth

    (tuple[str, str] | None, default: None ) –

    Authentication tuple (username, password).

  • timeout

    (float, default: 30.0 ) –

    Request timeout in seconds (default: 30.0).

  • kwargs

    (Any, default: {} ) –

    Additional keyword arguments to pass to the httpx.Client.

Methods:

Attributes:

Source code in rdflib/contrib/rdf4j/client.py
def __init__(
    self,
    base_url: str,
    auth: tuple[str, str] | None = None,
    timeout: float = 30.0,
    **kwargs: Any,
):
    if not base_url.endswith("/"):
        base_url += "/"
    self._http_client = httpx.Client(
        base_url=base_url, auth=auth, timeout=timeout, **kwargs
    )
    self._repository_manager: RepositoryManager | None = None
    try:
        protocol_version = self.protocol
    except httpx.RequestError as err:
        self.close()
        raise RDF4JUnsupportedProtocolError(
            f"Failed to check protocol version: {err}"
        ) from err
    if protocol_version < 12:
        self.close()
        raise RDF4JUnsupportedProtocolError(
            f"RDF4J server protocol version {protocol_version} is not supported. Minimum required version is 12."
        )

http_client property

http_client

protocol property

protocol: float

The RDF4J REST API protocol version.

Returns:

  • float

    The protocol version number.

repositories property

repositories: RepositoryManager

Server-level repository management operations.

__enter__

__enter__()
Source code in rdflib/contrib/rdf4j/client.py
def __enter__(self):
    return self

__exit__

__exit__(exc_type, exc_val, exc_tb)
Source code in rdflib/contrib/rdf4j/client.py
def __exit__(self, exc_type, exc_val, exc_tb):
    self.close()

close

close()

Close the underlying httpx.Client.

Source code in rdflib/contrib/rdf4j/client.py
def close(self):
    """Close the underlying httpx.Client."""
    self.http_client.close()

RDF4JNamespaceManager

RDF4JNamespaceManager(identifier: str, http_client: Client)

A namespace manager for RDF4J repositories.

Parameters:

  • identifier

    (str) –

    The identifier of the repository.

  • http_client

    (Client) –

    The httpx.Client instance.

Methods:

  • clear

    Clear all namespace declarations in the repository.

  • get

    Get the namespace URI for a given prefix.

  • list

    List all namespace declarations in the repository.

  • remove

    Remove the namespace declaration for a given prefix.

  • set

    Set the namespace URI for a given prefix.

Attributes:

Source code in rdflib/contrib/rdf4j/client.py
def __init__(self, identifier: str, http_client: httpx.Client):
    self._identifier = identifier
    self._http_client = http_client

http_client property

http_client

identifier property

identifier

Repository identifier.

clear

clear()

Clear all namespace declarations in the repository.

Source code in rdflib/contrib/rdf4j/client.py
def clear(self):
    """Clear all namespace declarations in the repository."""
    headers = {
        "Accept": "application/sparql-results+json",
    }
    response = self.http_client.delete(
        f"/repositories/{self.identifier}/namespaces", headers=headers
    )
    response.raise_for_status()

get

get(prefix: str) -> str | None

Get the namespace URI for a given prefix.

Parameters:

  • prefix

    (str) –

    The prefix to lookup.

Returns:

  • str | None

    The namespace URI or None if not found.

Source code in rdflib/contrib/rdf4j/client.py
def get(self, prefix: str) -> str | None:
    """Get the namespace URI for a given prefix.

    Parameters:
        prefix: The prefix to lookup.

    Returns:
        The namespace URI or `None` if not found.
    """
    if not prefix:
        raise ValueError("Prefix cannot be empty.")
    headers = {
        "Accept": "text/plain",
    }
    try:
        response = self.http_client.get(
            f"/repositories/{self.identifier}/namespaces/{prefix}", headers=headers
        )
        response.raise_for_status()
        return response.text
    except httpx.HTTPStatusError as err:
        if err.response.status_code == 404:
            return None
        raise

list

List all namespace declarations in the repository.

Returns:

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def list(self) -> list[NamespaceListingResult]:
    """List all namespace declarations in the repository.

    Returns:
        list[NamespaceListingResult]: List of namespace and prefix name results.

    Raises:
        RepositoryFormatError: If the response format is unrecognized.
    """
    headers = {
        "Accept": "application/sparql-results+json",
    }
    response = self.http_client.get(
        f"/repositories/{self.identifier}/namespaces", headers=headers
    )
    response.raise_for_status()

    try:
        data = response.json()
        results = data["results"]["bindings"]
        return [
            NamespaceListingResult(
                prefix=row["prefix"]["value"],
                namespace=row["namespace"]["value"],
            )
            for row in results
        ]
    except (KeyError, ValueError) as err:
        raise RepositoryFormatError(f"Unrecognised response format: {err}")

remove

remove(prefix: str)

Remove the namespace declaration for a given prefix.

Parameters:

  • prefix

    (str) –

    The prefix to remove.

Source code in rdflib/contrib/rdf4j/client.py
def remove(self, prefix: str):
    """Remove the namespace declaration for a given prefix.

    Parameters:
        prefix: The prefix to remove.
    """
    if not prefix:
        raise ValueError("Prefix cannot be empty.")
    response = self.http_client.delete(
        f"/repositories/{self.identifier}/namespaces/{prefix}"
    )
    response.raise_for_status()

set

set(prefix: str, namespace: str)

Set the namespace URI for a given prefix.

Note

If the prefix was previously mapped to a different namespace, this will be overwritten.

Parameters:

  • prefix

    (str) –

    The prefix to set.

  • namespace

    (str) –

    The namespace URI to set.

Source code in rdflib/contrib/rdf4j/client.py
def set(self, prefix: str, namespace: str):
    """Set the namespace URI for a given prefix.

    !!! note
        If the prefix was previously mapped to a different namespace, this will be
        overwritten.

    Parameters:
        prefix: The prefix to set.
        namespace: The namespace URI to set.
    """
    if not prefix:
        raise ValueError("Prefix cannot be empty.")
    if not namespace:
        raise ValueError("Namespace cannot be empty.")
    headers = {
        "Content-Type": "text/plain",
    }
    response = self.http_client.put(
        f"/repositories/{self.identifier}/namespaces/{prefix}",
        headers=headers,
        content=namespace,
    )
    response.raise_for_status()

Repository

Repository(identifier: str, http_client: Client)

RDF4J repository client.

Parameters:

  • identifier

    (str) –

    The identifier of the repository.

  • http_client

    (Client) –

    The httpx.Client instance.

Methods:

  • delete

    Deletes statements from the repository matching the filtering parameters.

  • get

    Get RDF statements from the repository matching the filtering parameters.

  • graph_names

    Get a list of all graph names in the repository.

  • health

    Repository health check.

  • overwrite

    Upload and overwrite statements in the repository.

  • query

    Execute a SPARQL query against the repository.

  • size

    The number of statements in the repository or in the specified graph name.

  • transaction

    Create a new transaction for the repository.

  • update

    Execute a SPARQL update operation on the repository.

  • upload

    Upload and append statements to the repository.

Attributes:

Source code in rdflib/contrib/rdf4j/client.py
def __init__(self, identifier: str, http_client: httpx.Client):
    self._identifier = identifier
    self._http_client = http_client
    self._namespace_manager: RDF4JNamespaceManager | None = None
    self._graph_store_manager: GraphStoreManager | None = None

graphs property

Graph store manager for the repository.

http_client property

http_client

identifier property

identifier

Repository identifier.

namespaces property

Namespace manager for the repository.

delete

delete(subj: SubjectType = None, pred: PredicateType = None, obj: ObjectType = None, graph_name: URIRef | Iterable[URIRef] | str | None = None) -> None

Deletes statements from the repository matching the filtering parameters.

Note

The terms for subj, pred, obj or graph_name cannot be BNodes.

Parameters:

  • subj

    (SubjectType, default: None ) –

    Subject of the statement to filter by, or None to match all.

  • pred

    (PredicateType, default: None ) –

    Predicate of the statement to filter by, or None to match all.

  • obj

    (ObjectType, default: None ) –

    Object of the statement to filter by, or None to match all.

  • graph_name

    (URIRef | Iterable[URIRef] | str | None, default: None ) –

    Graph name(s) to restrict to.

    The default value None queries all graphs.

    To query just the default graph, use DATASET_DEFAULT_GRAPH_ID.

Source code in rdflib/contrib/rdf4j/client.py
def delete(
    self,
    subj: SubjectType = None,
    pred: PredicateType = None,
    obj: ObjectType = None,
    graph_name: URIRef | Iterable[URIRef] | str | None = None,
) -> None:
    """Deletes statements from the repository matching the filtering parameters.

    !!! Note
        The terms for `subj`, `pred`, `obj` or `graph_name` cannot be
        [`BNodes`][rdflib.term.BNode].

    Parameters:
        subj: Subject of the statement to filter by, or `None` to match all.
        pred: Predicate of the statement to filter by, or `None` to match all.
        obj: Object of the statement to filter by, or `None` to match all.
        graph_name: Graph name(s) to restrict to.

            The default value `None` queries all graphs.

            To query just the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].
    """
    validate_no_bnodes(subj, pred, obj, graph_name)
    params: dict[str, str] = {}
    build_context_param(params, graph_name)
    build_spo_param(params, subj, pred, obj)

    response = self.http_client.delete(
        f"/repositories/{self.identifier}/statements",
        params=params,
    )
    response.raise_for_status()

get

get(subj: SubjectType = None, pred: PredicateType = None, obj: ObjectType = None, graph_name: URIRef | Iterable[URIRef] | str | None = None, infer: bool = True, content_type: str | None = None) -> Graph | Dataset

Get RDF statements from the repository matching the filtering parameters.

Note

The terms for subj, pred, obj or graph_name cannot be BNodes.

Parameters:

  • subj

    (SubjectType, default: None ) –

    Subject of the statement to filter by, or None to match all.

  • pred

    (PredicateType, default: None ) –

    Predicate of the statement to filter by, or None to match all.

  • obj

    (ObjectType, default: None ) –

    Object of the statement to filter by, or None to match all.

  • graph_name

    (URIRef | Iterable[URIRef] | str | None, default: None ) –

    Graph name(s) to restrict to.

    The default value None queries all graphs.

    To query just the default graph, use DATASET_DEFAULT_GRAPH_ID.

  • infer

    (bool, default: True ) –

    Specifies whether inferred statements should be included in the result.

  • content_type

    (str | None, default: None ) –

    The content type of the response. A triple-based format returns a Graph, while a quad-based format returns a Dataset.

Returns:

Source code in rdflib/contrib/rdf4j/client.py
def get(
    self,
    subj: SubjectType = None,
    pred: PredicateType = None,
    obj: ObjectType = None,
    graph_name: URIRef | Iterable[URIRef] | str | None = None,
    infer: bool = True,
    content_type: str | None = None,
) -> Graph | Dataset:
    """Get RDF statements from the repository matching the filtering parameters.

    !!! Note
        The terms for `subj`, `pred`, `obj` or `graph_name` cannot be
        [`BNodes`][rdflib.term.BNode].

    Parameters:
        subj: Subject of the statement to filter by, or `None` to match all.
        pred: Predicate of the statement to filter by, or `None` to match all.
        obj: Object of the statement to filter by, or `None` to match all.
        graph_name: Graph name(s) to restrict to.

            The default value `None` queries all graphs.

            To query just the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

        infer: Specifies whether inferred statements should be included in the
            result.
        content_type: The content type of the response.
            A triple-based format returns a [Graph][rdflib.graph.Graph], while a
            quad-based format returns a [`Dataset`][rdflib.graph.Dataset].

    Returns:
        A [`Graph`][rdflib.graph.Graph] or [`Dataset`][rdflib.graph.Dataset] object
            with the repository namespace prefixes bound to it.
    """
    validate_no_bnodes(subj, pred, obj, graph_name)
    if content_type is None:
        content_type = "application/n-quads"
    headers = {"Accept": content_type}
    params: dict[str, str] = {}
    build_context_param(params, graph_name)
    build_spo_param(params, subj, pred, obj)
    build_infer_param(params, infer=infer)

    response = self.http_client.get(
        f"/repositories/{self.identifier}/statements",
        headers=headers,
        params=params,
    )
    response.raise_for_status()
    triple_formats = [
        "application/n-triples",
        "text/turtle",
        "application/rdf+xml",
    ]
    try:
        if content_type in triple_formats:
            retval = Graph().parse(data=response.text, format=content_type)
        else:
            retval = Dataset().parse(data=response.text, format=content_type)
        for result in self.namespaces.list():
            retval.bind(result.prefix, result.namespace, replace=True)
        return retval
    except Exception as err:
        raise RDFLibParserError(f"Error parsing RDF: {err}") from err

graph_names

graph_names() -> list[IdentifiedNode]

Get a list of all graph names in the repository.

Returns:

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def graph_names(self) -> list[IdentifiedNode]:
    """Get a list of all graph names in the repository.

    Returns:
        A list of graph names.

    Raises:
        RepositoryFormatError: Fails to parse the repository graph names.
    """
    headers = {
        "Accept": "application/sparql-results+json",
    }
    response = self.http_client.get(
        f"/repositories/{self.identifier}/contexts", headers=headers
    )
    response.raise_for_status()
    try:
        values: list[IdentifiedNode] = []
        for row in response.json()["results"]["bindings"]:
            value = row["contextID"]["value"]
            value_type = row["contextID"]["type"]
            if value_type == "uri":
                values.append(URIRef(value))
            elif value_type == "bnode":
                values.append(BNode(value))
            else:
                raise ValueError(f"Invalid graph name type: {value_type}")
        return values
    except Exception as err:
        raise RepositoryFormatError(
            f"Failed to parse repository graph names: {err}"
        ) from err

health

health() -> bool

Repository health check.

Returns:

  • bool ( bool ) –

    True if the repository is healthy, otherwise an error is raised.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def health(self) -> bool:
    """Repository health check.

    Returns:
        bool: True if the repository is healthy, otherwise an error is raised.

    Raises:
        RepositoryNotFoundError: If the repository is not found.
        RepositoryNotHealthyError: If the repository is not healthy.
    """
    headers = {
        "Content-Type": "application/sparql-query",
        "Accept": "application/sparql-results+json",
    }
    try:
        response = self.http_client.post(
            f"/repositories/{self._identifier}", headers=headers, content="ASK {}"
        )
        response.raise_for_status()
        return True
    except httpx.HTTPStatusError as err:
        if err.response.status_code == 404:
            raise RepositoryNotFoundError(
                f"Repository {self._identifier} not found."
            )
        raise RepositoryNotHealthyError(
            f"Repository {self._identifier} is not healthy. {err.response.status_code} - {err.response.text}"
        )

overwrite

overwrite(data: str | bytes | BinaryIO | Graph | Dataset, graph_name: URIRef | Iterable[URIRef] | str | None = None, base_uri: str | None = None, content_type: str | None = None)

Upload and overwrite statements in the repository.

Parameters:

  • data

    (str | bytes | BinaryIO | Graph | Dataset) –

    The RDF data to upload.

  • graph_name

    (URIRef | Iterable[URIRef] | str | None, default: None ) –

    Graph name(s) to restrict to.

    The default value None applies to all graphs.

    To apply to just the default graph, use DATASET_DEFAULT_GRAPH_ID.

  • base_uri

    (str | None, default: None ) –

    The base URI to resolve against for any relative URIs in the data.

  • content_type

    (str | None, default: None ) –

    The content type of the data. Defaults to application/n-quads when the value is None.

Source code in rdflib/contrib/rdf4j/client.py
def overwrite(
    self,
    data: str | bytes | BinaryIO | Graph | Dataset,
    graph_name: URIRef | Iterable[URIRef] | str | None = None,
    base_uri: str | None = None,
    content_type: str | None = None,
):
    """Upload and overwrite statements in the repository.

    Parameters:
        data: The RDF data to upload.
        graph_name: Graph name(s) to restrict to.

            The default value `None` applies to all graphs.

            To apply to just the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

        base_uri: The base URI to resolve against for any relative URIs in the data.
        content_type: The content type of the data. Defaults to
            `application/n-quads` when the value is `None`.
    """
    stream, should_close = rdf_payload_to_stream(data)
    validate_graph_name(graph_name)
    try:
        headers = {"Content-Type": content_type or "application/n-quads"}
        params: dict[str, str] = {}
        build_context_param(params, graph_name)
        if base_uri is not None:
            params["baseURI"] = base_uri
        response = self.http_client.put(
            f"/repositories/{self.identifier}/statements",
            headers=headers,
            params=params,
            content=stream,
        )
        response.raise_for_status()
    finally:
        if should_close:
            stream.close()

query

query(query: str, **kwargs)

Execute a SPARQL query against the repository.

Note

A POST request is used by default. If any keyword arguments are provided, a GET request is used instead, and the arguments are passed as query parameters.

Parameters:

  • query

    (str) –

    The SPARQL query to execute.

  • **kwargs

    Additional keyword arguments to include as query parameters in the request. See RDF4J REST API - Execute SPARQL query for the list of supported query parameters.

Source code in rdflib/contrib/rdf4j/client.py
def query(self, query: str, **kwargs):
    """Execute a SPARQL query against the repository.

    !!! note
        A POST request is used by default. If any keyword arguments are provided,
        a GET request is used instead, and the arguments are passed as query parameters.

    Parameters:
        query: The SPARQL query to execute.
        **kwargs: Additional keyword arguments to include as query parameters
            in the request. See
            [RDF4J REST API - Execute SPARQL query](https://rdf4j.org/documentation/reference/rest-api/#tag/SPARQL/paths/~1repositories~1%7BrepositoryID%7D/get)
            for the list of supported query parameters.
    """
    headers = {"Content-Type": "application/sparql-query"}
    build_sparql_query_accept_header(query, headers)

    if not kwargs:
        response = self.http_client.post(
            f"/repositories/{self.identifier}", headers=headers, content=query
        )
    else:
        response = self.http_client.get(
            f"/repositories/{self.identifier}",
            headers=headers,
            params={"query": query, **kwargs},
        )
    response.raise_for_status()
    try:
        return Result.parse(
            io.BytesIO(response.content),
            content_type=response.headers["Content-Type"].split(";")[0],
        )
    except KeyError as err:
        raise RDFLibParserError(
            f"Failed to parse SPARQL query result {response.headers.get('Content-Type')}: {err}"
        ) from err

size

size(graph_name: URIRef | Iterable[URIRef] | str | None = None) -> int

The number of statements in the repository or in the specified graph name.

Parameters:

  • graph_name

    (URIRef | Iterable[URIRef] | str | None, default: None ) –

    Graph name(s) to restrict to.

    The default value None queries all graphs.

    To query just the default graph, use DATASET_DEFAULT_GRAPH_ID.

Returns:

  • int

    The number of statements.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def size(self, graph_name: URIRef | Iterable[URIRef] | str | None = None) -> int:
    """The number of statements in the repository or in the specified graph name.

    Parameters:
        graph_name: Graph name(s) to restrict to.

            The default value `None` queries all graphs.

            To query just the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

    Returns:
        The number of statements.

    Raises:
        RepositoryFormatError: Fails to parse the repository size.
    """
    validate_graph_name(graph_name)
    params: dict[str, str] = {}
    build_context_param(params, graph_name)
    response = self.http_client.get(
        f"/repositories/{self.identifier}/size", params=params
    )
    response.raise_for_status()
    return self._to_size(response.text)

transaction

transaction()

Create a new transaction for the repository.

Source code in rdflib/contrib/rdf4j/client.py
@contextlib.contextmanager
def transaction(self):
    """Create a new transaction for the repository."""
    with Transaction(self) as txn:
        yield txn

update

update(query: str)

Execute a SPARQL update operation on the repository.

Parameters:

  • query

    (str) –

    The SPARQL update query to execute.

Source code in rdflib/contrib/rdf4j/client.py
def update(self, query: str):
    """Execute a SPARQL update operation on the repository.

    Parameters:
        query: The SPARQL update query to execute.
    """
    headers = {"Content-Type": "application/sparql-update"}
    response = self.http_client.post(
        f"/repositories/{self.identifier}/statements",
        headers=headers,
        content=query,
    )
    response.raise_for_status()

upload

upload(data: str | bytes | BinaryIO | Graph | Dataset, base_uri: str | None = None, content_type: str | None = None)

Upload and append statements to the repository.

Parameters:

  • data

    (str | bytes | BinaryIO | Graph | Dataset) –

    The RDF data to upload.

  • base_uri

    (str | None, default: None ) –

    The base URI to resolve against for any relative URIs in the data.

  • content_type

    (str | None, default: None ) –

    The content type of the data. Defaults to application/n-quads when the value is None.

Source code in rdflib/contrib/rdf4j/client.py
def upload(
    self,
    data: str | bytes | BinaryIO | Graph | Dataset,
    base_uri: str | None = None,
    content_type: str | None = None,
):
    """Upload and append statements to the repository.

    Parameters:
        data: The RDF data to upload.
        base_uri: The base URI to resolve against for any relative URIs in the data.
        content_type: The content type of the data. Defaults to
            `application/n-quads` when the value is `None`.
    """
    stream, should_close = rdf_payload_to_stream(data)
    try:
        headers = {"Content-Type": content_type or "application/n-quads"}
        params = {}
        if base_uri is not None:
            params["baseURI"] = base_uri
        response = self.http_client.post(
            f"/repositories/{self.identifier}/statements",
            headers=headers,
            params=params,
            content=stream,
        )
        response.raise_for_status()
    finally:
        if should_close:
            stream.close()

RepositoryListingResult dataclass

RepositoryListingResult(identifier: str, uri: str, readable: bool, writable: bool, title: str | None = None)

RDF4J repository listing result.

Parameters:

  • identifier

    (str) –

    Repository identifier.

  • uri

    (str) –

    Repository URI.

  • readable

    (bool) –

    Whether the repository is readable by the client.

  • writable

    (bool) –

    Whether the repository is writable by the client.

  • title

    (str | None, default: None ) –

    Repository title.

Attributes:

identifier instance-attribute

identifier: str

readable instance-attribute

readable: bool

title class-attribute instance-attribute

title: str | None = None

uri instance-attribute

uri: str

writable instance-attribute

writable: bool

RepositoryManager

RepositoryManager(http_client: Client)

A client to manage server-level repository operations.

Parameters:

  • http_client

    (Client) –

    The httpx.Client instance.

Methods:

  • create

    Create a new repository.

  • delete

    Delete a repository.

  • get

    Get a repository by ID.

  • list

    List all available repositories.

Attributes:

Source code in rdflib/contrib/rdf4j/client.py
def __init__(self, http_client: httpx.Client):
    self._http_client = http_client

http_client property

http_client

create

create(repository_id: str, data: str, content_type: str = 'text/turtle') -> Repository

Create a new repository.

Parameters:

  • repository_id

    (str) –

    The identifier of the repository.

  • data

    (str) –

    The repository configuration in RDF.

  • content_type

    (str, default: 'text/turtle' ) –

    The repository configuration content type.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def create(
    self, repository_id: str, data: str, content_type: str = "text/turtle"
) -> Repository:
    """Create a new repository.

    Parameters:
        repository_id: The identifier of the repository.
        data: The repository configuration in RDF.
        content_type: The repository configuration content type.

    Raises:
        RepositoryAlreadyExistsError: If the repository already exists.
        RepositoryNotHealthyError: If the repository is not healthy.
    """
    try:
        headers = {"Content-Type": content_type}
        response = self.http_client.put(
            f"/repositories/{repository_id}", headers=headers, content=data
        )
        response.raise_for_status()
        return self.get(repository_id)
    except httpx.HTTPStatusError as err:
        if err.response.status_code == 409:
            raise RepositoryAlreadyExistsError(
                f"Repository {repository_id} already exists."
            )
        raise

delete

delete(repository_id: str) -> None

Delete a repository.

Parameters:

  • repository_id

    (str) –

    The identifier of the repository.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def delete(self, repository_id: str) -> None:
    """Delete a repository.

    Parameters:
        repository_id: The identifier of the repository.

    Raises:
        RepositoryNotFoundError: If the repository is not found.
        RepositoryError: If the repository is not deleted successfully.
    """
    try:
        response = self.http_client.delete(f"/repositories/{repository_id}")
        response.raise_for_status()
        if response.status_code != 204:
            raise RepositoryError(
                f"Unexpected response status code when deleting repository {repository_id}: {response.status_code} - {response.text.strip()}"
            )
    except httpx.HTTPStatusError as err:
        if err.response.status_code == 404:
            raise RepositoryNotFoundError(f"Repository {repository_id} not found.")
        raise

get

Get a repository by ID.

Note

This performs a health check before returning the repository object.

Parameters:

  • repository_id

    (str) –

    The identifier of the repository.

Returns:

  • Repository ( Repository ) –

    The repository instance.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def get(self, repository_id: str) -> Repository:
    """Get a repository by ID.

    !!! Note
        This performs a health check before returning the repository object.

    Parameters:
        repository_id: The identifier of the repository.

    Returns:
        Repository: The repository instance.

    Raises:
        RepositoryNotFoundError: If the repository is not found.
        RepositoryNotHealthyError: If the repository is not healthy.
    """
    repo = Repository(repository_id, self.http_client)
    repo.health()
    return repo

list

List all available repositories.

Returns:

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def list(self) -> list[RepositoryListingResult]:
    """List all available repositories.

    Returns:
        list[RepositoryListingResult]: List of repository results.

    Raises:
        RepositoryFormatError: If the response format is unrecognized.
    """
    headers = {
        "Accept": "application/sparql-results+json",
    }
    response = self.http_client.get("/repositories", headers=headers)
    response.raise_for_status()

    try:
        data = response.json()
        results = data["results"]["bindings"]
        return [
            RepositoryListingResult(
                identifier=repo["id"]["value"],
                uri=repo["uri"]["value"],
                readable=repo["readable"]["value"],
                writable=repo["writable"]["value"],
                title=repo.get("title", {}).get("value"),
            )
            for repo in results
        ]
    except (KeyError, ValueError) as err:
        raise RepositoryFormatError(f"Unrecognised response format: {err}")

Transaction

Transaction(repo: Repository)

An RDF4J transaction.

Parameters:

Methods:

  • __enter__
  • __exit__
  • commit

    Commit the transaction.

  • delete

    Delete statements from the repository.

  • get

    Get RDF statements from the repository matching the filtering parameters.

  • open

    Opens a transaction.

  • ping

    Ping the transaction.

  • query

    Execute a SPARQL query against the repository.

  • rollback

    Roll back the transaction.

  • size

    The number of statements in the repository or in the specified graph name.

  • update

    Execute a SPARQL update operation on the repository.

  • upload

    Upload and append statements to the repository.

Attributes:

  • is_closed (bool) –

    Whether the transaction is closed.

  • repo

    The repository instance.

  • url

    The transaction URL.

Source code in rdflib/contrib/rdf4j/client.py
def __init__(self, repo: Repository):
    self._repo = repo
    self._url: str | None = None

is_closed property

is_closed: bool

Whether the transaction is closed.

repo property

repo

The repository instance.

url property

url

The transaction URL.

__enter__

__enter__()
Source code in rdflib/contrib/rdf4j/client.py
def __enter__(self):
    self._url = self._start_transaction()
    return self

__exit__

__exit__(exc_type, exc_val, exc_tb)
Source code in rdflib/contrib/rdf4j/client.py
def __exit__(self, exc_type, exc_val, exc_tb):
    if not self.is_closed:
        if exc_type is None:
            self.commit()
        else:
            try:
                self.rollback()
            except Exception:
                pass

    # Propagate errors.
    return False

commit

commit()

Commit the transaction.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def commit(self):
    """Commit the transaction.

    Raises:
        TransactionCommitError: If the transaction commit fails.
        TransactionClosedError: If the transaction is closed.
    """
    self._raise_for_closed()
    params = {"action": "COMMIT"}
    response = self.repo.http_client.put(self.url, params=params)
    if response.status_code != 200:
        raise TransactionCommitError(
            f"Transaction commit failed: {response.status_code} - {response.text}"
        )
    self._close_transaction()

delete

delete(data: str | bytes | BinaryIO | Graph | Dataset, base_uri: str | None = None, content_type: str | None = None) -> None

Delete statements from the repository.

Note

This function operates differently to Repository.delete as it does not use filter parameters. Instead, it expects a data payload. See the notes from graphdb.js#Deleting for more information.

Parameters:

  • data

    (str | bytes | BinaryIO | Graph | Dataset) –

    The RDF data to upload.

  • base_uri

    (str | None, default: None ) –

    The base URI to resolve against for any relative URIs in the data.

  • content_type

    (str | None, default: None ) –

    The content type of the data. Defaults to application/n-quads when the value is None.

Source code in rdflib/contrib/rdf4j/client.py
def delete(
    self,
    data: str | bytes | BinaryIO | Graph | Dataset,
    base_uri: str | None = None,
    content_type: str | None = None,
) -> None:
    """Delete statements from the repository.

    !!! Note
        This function operates differently to
        [`Repository.delete`][rdflib.contrib.rdf4j.client.Repository.delete]
        as it does not use filter parameters. Instead, it expects a data payload.
        See the notes from
        [graphdb.js#Deleting](https://github.com/Ontotext-AD/graphdb.js?tab=readme-ov-file#deleting-1)
        for more information.

    Parameters:
        data: The RDF data to upload.
        base_uri: The base URI to resolve against for any relative URIs in the data.
        content_type: The content type of the data. Defaults to
            `application/n-quads` when the value is `None`.
    """
    params: dict[str, str] = {"action": "DELETE"}
    stream, should_close = rdf_payload_to_stream(data)
    headers = {"Content-Type": content_type or "application/n-quads"}
    if base_uri is not None:
        params["baseURI"] = base_uri
    try:
        response = self.repo.http_client.put(
            self.url,
            headers=headers,
            params=params,
            content=stream,
        )
        response.raise_for_status()
    finally:
        if should_close:
            stream.close()

get

get(subj: SubjectType = None, pred: PredicateType = None, obj: ObjectType = None, graph_name: URIRef | Iterable[URIRef] | str | None = None, infer: bool = True, content_type: str | None = None) -> Graph | Dataset

Get RDF statements from the repository matching the filtering parameters.

Note

The terms for subj, pred, obj or graph_name cannot be BNodes.

Parameters:

  • subj

    (SubjectType, default: None ) –

    Subject of the statement to filter by, or None to match all.

  • pred

    (PredicateType, default: None ) –

    Predicate of the statement to filter by, or None to match all.

  • obj

    (ObjectType, default: None ) –

    Object of the statement to filter by, or None to match all.

  • graph_name

    (URIRef | Iterable[URIRef] | str | None, default: None ) –

    Graph name(s) to restrict to.

    The default value None queries all graphs.

    To query just the default graph, use DATASET_DEFAULT_GRAPH_ID.

  • infer

    (bool, default: True ) –

    Specifies whether inferred statements should be included in the result.

  • content_type

    (str | None, default: None ) –

    The content type of the response. A triple-based format returns a Graph, while a quad-based format returns a Dataset.

Returns:

Source code in rdflib/contrib/rdf4j/client.py
def get(
    self,
    subj: SubjectType = None,
    pred: PredicateType = None,
    obj: ObjectType = None,
    graph_name: URIRef | Iterable[URIRef] | str | None = None,
    infer: bool = True,
    content_type: str | None = None,
) -> Graph | Dataset:
    """Get RDF statements from the repository matching the filtering parameters.

    !!! Note
        The terms for `subj`, `pred`, `obj` or `graph_name` cannot be
        [`BNodes`][rdflib.term.BNode].

    Parameters:
        subj: Subject of the statement to filter by, or `None` to match all.
        pred: Predicate of the statement to filter by, or `None` to match all.
        obj: Object of the statement to filter by, or `None` to match all.
        graph_name: Graph name(s) to restrict to.

            The default value `None` queries all graphs.

            To query just the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

        infer: Specifies whether inferred statements should be included in the
            result.
        content_type: The content type of the response.
            A triple-based format returns a [Graph][rdflib.graph.Graph], while a
            quad-based format returns a [`Dataset`][rdflib.graph.Dataset].

    Returns:
        A [`Graph`][rdflib.graph.Graph] or [`Dataset`][rdflib.graph.Dataset] object
            with the repository namespace prefixes bound to it.
    """
    validate_no_bnodes(subj, pred, obj, graph_name)
    if content_type is None:
        content_type = "application/n-quads"
    headers = {"Accept": content_type}
    params: dict[str, str] = {"action": "GET"}
    build_context_param(params, graph_name)
    build_spo_param(params, subj, pred, obj)
    build_infer_param(params, infer=infer)

    response = self.repo.http_client.put(
        self.url,
        headers=headers,
        params=params,
    )
    response.raise_for_status()
    triple_formats = [
        "application/n-triples",
        "text/turtle",
        "application/rdf+xml",
    ]
    try:
        if content_type in triple_formats:
            retval = Graph().parse(data=response.text, format=content_type)
        else:
            retval = Dataset().parse(data=response.text, format=content_type)
        for result in self.repo.namespaces.list():
            retval.bind(result.prefix, result.namespace, replace=True)
        return retval
    except Exception as err:
        raise RDFLibParserError(f"Error parsing RDF: {err}") from err

open

open()

Opens a transaction.

Source code in rdflib/contrib/rdf4j/client.py
def open(self):
    """Opens a transaction."""
    self._url = self._start_transaction()

ping

ping()

Ping the transaction.

Raises:

  • RepositoryTransactionPingError

    If the transaction ping fails.

  • TransactionClosedError

    If the transaction is closed.

Source code in rdflib/contrib/rdf4j/client.py
def ping(self):
    """Ping the transaction.

    Raises:
        RepositoryTransactionPingError: If the transaction ping fails.
        TransactionClosedError: If the transaction is closed.
    """
    self._raise_for_closed()
    params = {"action": "PING"}
    response = self.repo.http_client.put(self.url, params=params)
    if response.status_code != 200:
        raise TransactionPingError(
            f"Transaction ping failed: {response.status_code} - {response.text}"
        )

query

query(query: str, **kwargs)

Execute a SPARQL query against the repository.

Parameters:

  • query

    (str) –

    The SPARQL query to execute.

  • **kwargs

    Additional keyword arguments to include as query parameters in the request. See RDF4J REST API - Execute SPARQL query for the list of supported query parameters.

Source code in rdflib/contrib/rdf4j/client.py
def query(self, query: str, **kwargs):
    """Execute a SPARQL query against the repository.

    Parameters:
        query: The SPARQL query to execute.
        **kwargs: Additional keyword arguments to include as query parameters
            in the request. See
            [RDF4J REST API - Execute SPARQL query](https://rdf4j.org/documentation/reference/rest-api/#tag/SPARQL/paths/~1repositories~1%7BrepositoryID%7D/get)
            for the list of supported query parameters.
    """
    headers: dict[str, str] = {}
    build_sparql_query_accept_header(query, headers)
    params = {"action": "QUERY", "query": query}
    response = self.repo.http_client.put(
        self.url, headers=headers, params={**params, **kwargs}
    )
    response.raise_for_status()
    try:
        return Result.parse(
            io.BytesIO(response.content),
            content_type=response.headers["Content-Type"].split(";")[0],
        )
    except KeyError as err:
        raise RDFLibParserError(
            f"Failed to parse SPARQL query result {response.headers.get('Content-Type')}: {err}"
        ) from err

rollback

rollback()

Roll back the transaction.

Source code in rdflib/contrib/rdf4j/client.py
def rollback(self):
    """Roll back the transaction."""
    response = self.repo.http_client.delete(self.url)
    if response.status_code != 204:
        raise TransactionRollbackError(
            f"Transaction rollback failed: {response.status_code} - {response.text}"
        )
    self._close_transaction()

size

size(graph_name: URIRef | Iterable[URIRef] | str | None = None)

The number of statements in the repository or in the specified graph name.

Parameters:

  • graph_name

    (URIRef | Iterable[URIRef] | str | None, default: None ) –

    Graph name(s) to restrict to.

    The default value None queries all graphs.

    To query just the default graph, use DATASET_DEFAULT_GRAPH_ID.

Returns:

  • The number of statements.

Raises:

Source code in rdflib/contrib/rdf4j/client.py
def size(self, graph_name: URIRef | Iterable[URIRef] | str | None = None):
    """The number of statements in the repository or in the specified graph name.

    Parameters:
        graph_name: Graph name(s) to restrict to.

            The default value `None` queries all graphs.

            To query just the default graph, use
            [`DATASET_DEFAULT_GRAPH_ID`][rdflib.graph.DATASET_DEFAULT_GRAPH_ID].

    Returns:
        The number of statements.

    Raises:
        RepositoryFormatError: Fails to parse the repository size.
    """
    self._raise_for_closed()
    validate_graph_name(graph_name)
    params = {"action": "SIZE"}
    build_context_param(params, graph_name)
    response = self.repo.http_client.put(self.url, params=params)
    response.raise_for_status()
    return self.repo._to_size(response.text)

update

update(query: str, **kwargs)

Execute a SPARQL update operation on the repository.

Parameters:

Source code in rdflib/contrib/rdf4j/client.py
def update(self, query: str, **kwargs):
    """Execute a SPARQL update operation on the repository.

    Parameters:
        query: The SPARQL update query to execute.
        **kwargs: Additional keyword arguments to include as query parameters
            See [RDF4J REST API - Execute a transaction action](https://rdf4j.org/documentation/reference/rest-api/#tag/Transactions/paths/~1repositories~1%7BrepositoryID%7D~1transactions~1%7BtransactionID%7D/put)
            for the list of supported query parameters.
    """
    params = {"action": "UPDATE", "update": query}
    response = self.repo.http_client.put(
        self.url,
        params={**params, **kwargs},
    )
    response.raise_for_status()

upload

upload(data: str | bytes | BinaryIO | Graph | Dataset, base_uri: str | None = None, content_type: str | None = None)

Upload and append statements to the repository.

Parameters:

  • data

    (str | bytes | BinaryIO | Graph | Dataset) –

    The RDF data to upload.

  • base_uri

    (str | None, default: None ) –

    The base URI to resolve against for any relative URIs in the data.

  • content_type

    (str | None, default: None ) –

    The content type of the data. Defaults to application/n-quads when the value is None.

Source code in rdflib/contrib/rdf4j/client.py
def upload(
    self,
    data: str | bytes | BinaryIO | Graph | Dataset,
    base_uri: str | None = None,
    content_type: str | None = None,
):
    """Upload and append statements to the repository.

    Parameters:
        data: The RDF data to upload.
        base_uri: The base URI to resolve against for any relative URIs in the data.
        content_type: The content type of the data. Defaults to
            `application/n-quads` when the value is `None`.
    """
    stream, should_close = rdf_payload_to_stream(data)
    headers = {"Content-Type": content_type or "application/n-quads"}
    params = {"action": "ADD"}
    if base_uri is not None:
        params["baseURI"] = base_uri
    try:
        response = self.repo.http_client.put(
            self.url,
            headers=headers,
            params=params,
            content=stream,
        )
        response.raise_for_status()
    finally:
        if should_close:
            stream.close()