diff --git a/src/curies/triples/__init__.py b/src/curies/triples/__init__.py index fb71288..e440777 100644 --- a/src/curies/triples/__init__.py +++ b/src/curies/triples/__init__.py @@ -146,7 +146,7 @@ keep_subject_prefixes, keep_triples_by_hash, ) -from .hash_utils import encode_uri_triple, hash_triple +from .hash_utils import encode_curie_triple, encode_uri_triple, hash_triple from .io import read_triples, write_triples from .model import StrTriple, Triple, TriplePredicate @@ -154,6 +154,7 @@ "StrTriple", "Triple", "TriplePredicate", + "encode_curie_triple", "encode_uri_triple", "exclude_object_prefixes", "exclude_prefixes_both", diff --git a/src/curies/triples/hash_utils.py b/src/curies/triples/hash_utils.py index 0957c97..8309035 100644 --- a/src/curies/triples/hash_utils.py +++ b/src/curies/triples/hash_utils.py @@ -8,6 +8,7 @@ from ..api import Converter __all__ = [ + "encode_curie_triple", "encode_uri_triple", "hash_triple", ] @@ -45,8 +46,47 @@ def hash_triple(converter: Converter, triple: Triple, *, negate: bool = False) - return encode_uri_triple(triple.as_uri_triple(converter), negate=negate) +def encode_curie_triple( + curie_triple: tuple[str, str, str], converter: Converter, *, negate: bool = False +) -> str: + """Encode a subject-predicate-object CURIE triple. + + :param curie_triple: A triple of CURIEs represented as strings + :param converter: A converter + :param negate: If true, considers the triple as "negative" and postpends a ``~`` to + the hash + + :returns: An encoded triple of URIs + + .. seealso:: + + https://ts4nfdi.github.io/mapping-sameness-identifier/ + + >>> import curies + >>> from curies.triples import Triple + >>> converter = curies.load_prefix_map( + ... { + ... "mesh": "http://id.nlm.nih.gov/mesh/", + ... "skos": "http://www.w3.org/2004/02/skos/core#", + ... "CHEBI": "http://purl.obolibrary.org/obo/CHEBI_", + ... } + ... ) + >>> triple = ("mesh:C000089", "skos:exactMatch", "CHEBI:28646") + >>> encode_curie_triple(triple) + '36a1f9244ea7641a90987c82f33c25c0c13712ee8f48207b2a0825f8a4e4e26a' + >>> encode_curie_triple(triple, negate=True) + '36a1f9244ea7641a90987c82f33c25c0c13712ee8f48207b2a0825f8a4e4e26a~' + """ + uri_triple = ( + converter.expand(curie_triple[0], strict=True), + converter.expand(curie_triple[1], strict=True), + converter.expand(curie_triple[2], strict=True), + ) + return encode_uri_triple(uri_triple, negate=negate) + + def encode_uri_triple(uri_triple: tuple[str, str, str], *, negate: bool = False) -> str: - """Encode a subject-predicate-object triple. + """Encode a subject-predicate-object URI triple. :param uri_triple: A triple of URIs represented as strings :param negate: If true, considers the triple as "negative" and postpends a ``~`` to diff --git a/tests/test_triples/test_models.py b/tests/test_triples/test_models.py index 6a60474..4d0cc72 100644 --- a/tests/test_triples/test_models.py +++ b/tests/test_triples/test_models.py @@ -9,7 +9,7 @@ import curies from curies import Reference, Triple -from curies.triples import encode_uri_triple, read_triples, write_triples +from curies.triples import encode_curie_triple, encode_uri_triple, read_triples, write_triples T1 = Triple.from_curies("a:1", "a:2", "a:3") T2 = Triple.from_curies("a:1", "a:2", "a:4") @@ -51,7 +51,7 @@ def test_sort(self) -> None: self.assertEqual([T1, T2], sorted([T2, T1])) def test_hash_uri_triple(self) -> None: - """Test URL-safe base64 encoding and decoding of triples.""" + """Test encoding triples of URI strings.""" examples: list[tuple[str, str, str, str]] = [ ( # example 1 from https://ts4nfdi.github.io/mapping-sameness-identifier/ "95a088082ab2b2a68638aebbcc3fe3e0f229da75a8b5bdbb9f3f8cd5e1e4286e", @@ -70,8 +70,25 @@ def test_hash_uri_triple(self) -> None: with self.subTest(): self.assertEqual(expected, encode_uri_triple((s, p, o))) + def test_encode_curie_triple(self) -> None: + """Test encoding triples of CURIE strings.""" + converter = curies.load_prefix_map( + { + "mesh": "http://id.nlm.nih.gov/mesh/", + "skos": "http://www.w3.org/2004/02/skos/core#", + "CHEBI": "http://purl.obolibrary.org/obo/CHEBI_", + } + ) + triple = ("mesh:C000089", "skos:exactMatch", "CHEBI:28646") + triple_id = encode_curie_triple(triple, converter) + + self.assertEqual( + "36a1f9244ea7641a90987c82f33c25c0c13712ee8f48207b2a0825f8a4e4e26a", + triple_id, + ) + def test_hash_triple(self) -> None: - """Test URL-safe base64 encoding and decoding of triples.""" + """Test encoding Triple model.""" converter = curies.load_prefix_map( { "mesh": "http://id.nlm.nih.gov/mesh/",