Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Improvements #8

Merged
merged 9 commits into from
Nov 14, 2022
Merged
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
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ keywords =

[options]
install_requires =
bioregistry>=0.5.86
bioregistry>=0.6.13
curies>=0.3.0
requests
pydantic
Expand Down
8 changes: 7 additions & 1 deletion src/bioontologies/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

"""Tools for biomedical ontologies."""

from .robot import convert_to_obograph, get_obograph_by_iri, get_obograph_by_prefix
from .robot import (
convert_to_obograph,
get_obograph_by_iri,
get_obograph_by_path,
get_obograph_by_prefix,
)

__all__ = [
"convert_to_obograph",
"get_obograph_by_prefix",
"get_obograph_by_iri",
"get_obograph_by_path",
]
23 changes: 15 additions & 8 deletions src/bioontologies/obograph.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@
from operator import attrgetter
from typing import Any, Iterable, List, Mapping, Optional, Set, Tuple, Union

from bioregistry import curie_to_str, manager
from curies import Converter
from bioregistry import curie_to_str, get_default_converter, manager
from pydantic import BaseModel, Field
from tqdm.auto import tqdm
from typing_extensions import Literal

from . import upgrade
from .relations import ground_relation

__all__ = [
Expand All @@ -40,8 +38,6 @@

MaybeCURIE = Union[Tuple[str, str], Tuple[None, None]]

converter = Converter.from_reverse_prefix_map(manager.get_reverse_prefix_map(include_prefixes=True))


class StandardizeMixin:
"""A mixin for classes representing standardizable data."""
Expand Down Expand Up @@ -85,6 +81,7 @@ def val_curie(self) -> str:

def standardize(self):
"""Standardize this property."""
self.val = self.val.replace("\n", " ")
self.pred_prefix, self.pred_identifier = _parse_uri_or_curie_or_str(self.pred)
self.val_prefix, self.val_identifier = _parse_uri_or_curie_or_str(self.val)
self.standardized = True
Expand Down Expand Up @@ -273,6 +270,14 @@ def xrefs(self) -> List[Xref]:
return self.meta.xrefs
return []

@property
def properties(self) -> List[Property]:
"""Get the properties for this node."""
if not self.meta or self.meta.basicPropertyValues is None:
return []
# TODO filter out ones grabbed by other getters
return self.meta.basicPropertyValues

@property
def replaced_by(self) -> Optional[str]:
"""Get the identifier that this node was replaced by."""
Expand Down Expand Up @@ -565,13 +570,15 @@ def _parse_obo_rel(s: str, identifier: str) -> Union[Tuple[str, str], Tuple[None
def _compress_uri_or_curie_or_str(
s: str, *, debug: bool = False
) -> Union[Tuple[str, str], Tuple[None, str]]:
from .upgrade import insert, upgrade

s = s.replace(" ", "")

cv = upgrade.upgrade(s)
cv = upgrade(s)
if cv:
return cv

prefix, identifier = converter.parse_uri(s)
prefix, identifier = get_default_converter().parse_uri(s)
if prefix and identifier:
if prefix == "obo" and "#" in identifier:
return _parse_obo_rel(s, identifier)
Expand All @@ -587,7 +594,7 @@ def _compress_uri_or_curie_or_str(
if s.startswith(x):
prefix, identifier = ground_relation(s[len(x) :])
if prefix and identifier:
upgrade.insert(s, prefix, identifier)
insert(s, prefix, identifier)
return prefix, identifier
elif s not in WARNED:
tqdm.write(f"could not parse legacy RO: {s}")
Expand Down
51 changes: 42 additions & 9 deletions src/bioontologies/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
# Processors
"get_obograph_by_prefix",
"get_obograph_by_iri",
"get_obograph_by_path",
]

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -92,6 +93,15 @@ def guess(self, prefix: str) -> Graph:
return id_to_graph[CANONICAL[prefix]]
raise ValueError(f"Several graphs in {prefix}: {sorted(id_to_graph)}")

def guess_version(self, prefix: str) -> Optional[str]:
"""Guess the version."""
try:
graph = self.guess(prefix)
except ValueError:
return None
else:
return graph.version or graph.version_iri


def get_obograph_by_iri(
iri: str,
Expand All @@ -102,6 +112,16 @@ def get_obograph_by_iri(
return ParseResults(graph_document=graph_document, iri=iri)


def get_obograph_by_path(path: Union[str, Path], *, iri: Optional[str] = None) -> ParseResults:
"""Get an ontology by its OBO Graph JSON file path."""
res_json = json.loads(Path(path).resolve().read_text())
graph_document = GraphDocument(**res_json)
if iri is None:
if graph_document.graphs and len(graph_document.graphs) == 1:
iri = graph_document.graphs[0].id
return ParseResults(graph_document=graph_document, iri=iri)


def get_obograph_by_prefix(
prefix: str,
*,
Expand Down Expand Up @@ -205,6 +225,7 @@ def convert_to_obograph(
input_is_iri: bool = False,
extra_args: Optional[List[str]] = None,
from_iri: Optional[str] = None,
merge: bool = True,
) -> ParseResults:
"""Convert a local OWL file to a JSON file.

Expand All @@ -223,6 +244,7 @@ def convert_to_obograph(
:param extra_args:
Extra positional arguments to pass in the command line
:param from_iri: Use this parameter to say what IRI the graph came from
:param merge: Use ROBOT's merge command to squash all graphs together

:returns: An object with the parsed OBO Graph JSON and text
output from the ROBOT conversion program
Expand All @@ -243,6 +265,7 @@ def convert_to_obograph(
output_path=path,
fmt="json",
extra_args=extra_args,
merge=merge,
)
messages = ret.strip().splitlines()
graph_document_raw = json.loads(path.read_text())
Expand Down Expand Up @@ -301,21 +324,31 @@ def convert(
output_path: Union[str, Path],
input_flag: Optional[Literal["-i", "-I"]] = None,
*,
merge: bool = True,
fmt: Optional[str] = None,
extra_args: Optional[List[str]] = None,
) -> str:
"""Convert an OBO file to an OWL file with ROBOT."""
if input_flag is None:
input_flag = "-I" if _is_remote(input_path) else "-i"
args = [
"robot",
"convert",
input_flag,
str(input_path),
"-o",
str(output_path),
*(extra_args or []),
]
if merge:
args = [
"robot",
"merge",
input_flag,
str(input_path),
"convert",
]
else:
args = [
"robot",
"convert",
input_flag,
str(input_path),
]
args.extend(("-o", str(output_path)))
if extra_args:
args.extend(extra_args)
if fmt:
args.extend(("--format", fmt))
logger.debug("Running shell command: %s", args)
Expand Down
1 change: 1 addition & 0 deletions src/bioontologies/upgrade/data.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ http://purl.obolibrary.org/obo/nbo#has_participant ro 0000057
http://purl.obolibrary.org/obo/ncbitaxon#has_rank debio 0000023
http://purl.obolibrary.org/obo/ncbitaxon/subsets/taxslim#has_rank debio 0000023
http://purl.obolibrary.org/obo/obo#_PATO_0000047 pato 0000047
http://purl.obolibrary.org/obo/pato#seeAlso rdf seeAlso
http://purl.obolibrary.org/obo/so#has_origin debio 0000025
http://purl.obolibrary.org/obo/uberon/core#conduit_for ro 0002570
http://purl.obolibrary.org/obo/uberon/core#existence_starts_and_ends_during ro 0002491
Expand Down