Skip to content

Commit 4af8def

Browse files
authored
Add RDFLib functionality (#36)
This PR adds the ability to extract a `curies.Converter` from an RDFLib object ```python import rdflib, curies # Build an RDFLib graph and populate its namespace manager graph = rdflib.Graph() graph.bind("hgnc", "https://bioregistry.io/hgnc:") # Convert to a converter converter = curies.Converter.from_rdflib(graph) converter.expand("hgnc:1234") assert converter.expand("hgnc:1234") == "https://bioregistry.io/hgnc:" # This also works if you have a namespace manager directly converter = curies.Converter.from_rdflib(graph.namespace_manager) assert converter.expand("hgnc:1234") == "https://bioregistry.io/hgnc:"
1 parent 61d957a commit 4af8def

5 files changed

Lines changed: 51 additions & 0 deletions

File tree

.readthedocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ python:
1919
- pandas
2020
- flask
2121
- fastapi
22+
- rdflib

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ flask =
8282
fastapi =
8383
fastapi
8484
httpx
85+
rdflib =
86+
rdflib
8587
docs =
8688
sphinx
8789
sphinx-rtd-theme

src/curies/api.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
if TYPE_CHECKING: # pragma: no cover
3434
import pandas
35+
import rdflib
3536

3637
__all__ = [
3738
"Converter",
@@ -538,6 +539,39 @@ def from_jsonld_github(
538539
url = f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{rest}"
539540
return cls.from_jsonld(url)
540541

542+
@classmethod
543+
def from_rdflib(
544+
cls,
545+
graph_or_manager: Union["rdflib.Graph", "rdflib.namespace.NamespaceManager"],
546+
**kwargs: Any,
547+
) -> "Converter":
548+
"""Get a converter from an RDFLib graph or namespace manager.
549+
550+
:param graph_or_manager: A RDFLib graph or manager object
551+
:param kwargs: Keyword arguments to pass to :meth:`from_prefix_map`
552+
:return: A converter
553+
554+
In the following example, a :class:`rdflib.Graph` is created, a namespace
555+
is bound to it, then a converter is made:
556+
557+
>>> import rdflib, curies
558+
>>> graph = rdflib.Graph()
559+
>>> graph.bind("hgnc", "https://bioregistry.io/hgnc:")
560+
>>> converter = curies.Converter.from_rdflib(graph)
561+
>>> converter.expand("hgnc:1234")
562+
'https://bioregistry.io/hgnc:1234'
563+
564+
This also works if you directly start with a :class:`rdflib.namespace.NamespaceManager`:
565+
566+
>>> converter = curies.Converter.from_rdflib(graph.namespace_manager)
567+
>>> converter.expand("hgnc:1234")
568+
'https://bioregistry.io/hgnc:1234'
569+
"""
570+
# it's required to stringify namespace since it's a rdflib.URIRef
571+
# object, which acts funny if not coerced into a string
572+
prefix_map = {prefix: str(namespace) for prefix, namespace in graph_or_manager.namespaces()}
573+
return cls.from_prefix_map(prefix_map, **kwargs)
574+
541575
def get_prefixes(self) -> Set[str]:
542576
"""Get the set of prefixes covered by this converter."""
543577
return {record.prefix for record in self.records}

tests/test_api.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from tempfile import TemporaryDirectory
1010

1111
import pandas as pd
12+
import rdflib
1213
from bioregistry.export.prefix_maps import EXTENDED_PREFIX_MAP_PATH
1314

1415
from curies.api import Converter, DuplicatePrefixes, DuplicateURIPrefixes, Record, chain
@@ -373,6 +374,17 @@ def test_incremental(self):
373374
with self.assertRaises(ValueError):
374375
converter.add_prefix("...", "...", prefix_synonyms=["GO"])
375376

377+
def test_rdflib(self):
378+
"""Test parsing a converter from an RDFLib object."""
379+
graph = rdflib.Graph()
380+
for prefix, uri_prefix in self.simple_obo_prefix_map.items():
381+
graph.bind(prefix, uri_prefix)
382+
converter = Converter.from_rdflib(graph)
383+
self._assert_convert(converter)
384+
385+
converter_2 = Converter.from_rdflib(graph.namespace_manager)
386+
self._assert_convert(converter_2)
387+
376388

377389
class TestVersion(unittest.TestCase):
378390
"""Trivially test a version."""

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ extras =
4141
bioregistry
4242
flask
4343
fastapi
44+
rdflib
4445

4546
[testenv:doctests]
4647
commands =
@@ -135,6 +136,7 @@ extras =
135136
pandas
136137
flask
137138
fastapi
139+
rdflib
138140
commands =
139141
python -m sphinx -W -b html -d docs/build/doctrees docs/source docs/build/html
140142

0 commit comments

Comments
 (0)