Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/curies/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .api import Converter

__all__ = [
"ReverseSemanticallyProcessable",
"SemanticallyProcessable",
"SemanticallyStandardizable",
]
Expand Down Expand Up @@ -50,6 +51,36 @@ def process(self, converter: Converter) -> X:
raise NotImplementedError


class ReverseSemanticallyProcessable(ABC, Generic[X]):
"""A class that can be processed with a converter.

The goal of this class is to standardize objects that come with
unprocessed URIs that can be processed into references with
respect to a :class:`curies.Converter`. For example, this is
useful for :mod:`obographs` and :mod:`jskos`.

.. code-block:: python

from pydantic import BaseModel
from curies import ReverseSemanticallyProcessable


class RawEntity(BaseModel):
uri: str


class ProcessedEntity(BaseModel, ReverseSemanticallyProcessable[RawEntity]):
reference: Reference

def unprocess(self, converter: Converter) -> RawEntity:
return RawEntity(uri=converter.expand_reference(self.reference, strict=True))
"""

@abstractmethod
def unprocess(self, converter: Converter) -> X:
"""Process this raw instance."""


class SemanticallyStandardizable(ABC):
"""An object that can be standardized.

Expand Down
29 changes: 28 additions & 1 deletion tests/test_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

import curies
from curies import Converter, Reference
from curies.mixins import SemanticallyProcessable, SemanticallyStandardizable
from curies.mixins import (
ReverseSemanticallyProcessable,
SemanticallyProcessable,
SemanticallyStandardizable,
)


class TestMixins(unittest.TestCase):
Expand Down Expand Up @@ -36,6 +40,29 @@ def process(self, converter: Converter) -> Processed:
self.assertIsInstance(p, Processed)
self.assertEqual(Reference(prefix="GO", identifier="1234567"), p.reference)

def test_reversesemantically_processable(self) -> None:
"""Test processing."""

class Raw(BaseModel):
"""A raw model, with a URI."""

uri: str

class Processed(BaseModel, ReverseSemanticallyProcessable[Raw]):
"""A processed model, with a reference."""

reference: Reference

def unprocess(self, converter: Converter) -> Raw:
"""Convert to raw."""
return Raw(uri=converter.expand_reference(self.reference, strict=True))

c = Converter.from_prefix_map({"GO": "http://purl.obolibrary.org/obo/GO_"})

p = Processed(reference=Reference(prefix="GO", identifier="1234567"))
r = p.unprocess(c)
self.assertEqual("http://purl.obolibrary.org/obo/GO_1234567", r.uri)

def test_standardizable(self) -> None:
"""Test standardizable."""

Expand Down
Loading