Skip to content
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
48 changes: 19 additions & 29 deletions src/pyobo/cli/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import inspect
import json
import sys
from collections.abc import Iterable, Mapping
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -166,17 +165,27 @@ def typedefs(**kwargs: Unpack[LookupKwargs]) -> None:
echo_df(df)


def _help_page_mapping(id_to_name: Mapping[str, str], *, identifier: str | None = None) -> None:
def _help_page_mapping(
id_to_name: Mapping[str, str | list[str]], *, identifier: str | None = None
) -> None:
if not id_to_name:
click.secho("no data", fg="red")
elif identifier:
value = id_to_name.get(identifier)
if value:
if isinstance(value, str):
click.echo(value)
elif isinstance(value, list):
click.echo("\n".join(value))
else:
click.secho(f"no data for {identifier}", fg="red")
else:
click.echo_via_pager("\n".join("\t".join(item) for item in id_to_name.items()))
click.echo_via_pager(
"\n".join(
f"{key}\t{value}"
for key, values in id_to_name.items()
for value in ([values] if isinstance(values, str) else values)
)
)


@lookup_annotate
Expand Down Expand Up @@ -206,43 +215,24 @@ def synonyms(identifier: str | None, **kwargs: Unpack[LookupKwargs]) -> None:
@click.option(
"--relation", help="CURIE for the relationship or just the ID if local to the ontology"
)
@click.option("--target", help="Prefix for the target")
@click.option("--summarize", is_flag=True)
def relations(
relation: str,
target: str,
target: str | None,
summarize: bool,
**kwargs: Unpack[LookupKwargs],
) -> None:
"""Page through the relations for entities in the given namespace."""
import bioregistry

from ..api import get_filtered_relations_df, get_relations_df
from ..struct.reference import _parse_str_or_curie_or_uri

if relation is None:
relations_df = get_relations_df(**kwargs)
if summarize:
click.echo(relations_df[relations_df.columns[2]].value_counts())
else:
echo_df(relations_df)
else:
relation_reference = _parse_str_or_curie_or_uri(relation, strict=False)
if relation_reference is None:
click.secho(f"not a valid curie: {relation}", fg="red")
raise sys.exit(1)

if target is not None:
norm_target = bioregistry.normalize_prefix(target)
if norm_target is None:
raise ValueError
relations_df = get_filtered_relations_df(
relation=relation_reference,
target=norm_target,
**kwargs,
)
else:
raise NotImplementedError(f"can not filter by target prefix {target}")
relations_df = get_filtered_relations_df(relation=relation, **kwargs)
if summarize:
click.echo(relations_df[relations_df.columns[2]].value_counts())
else:
echo_df(relations_df)


@lookup_annotate
Expand Down
3 changes: 2 additions & 1 deletion src/pyobo/struct/functional/obo_to_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def get_ontology_axioms(obo_ontology: Obo) -> Iterable[f.Box]:
used_has_scope = False
for synonym_typedef in obo_ontology.synonym_typedefs:
yield f.Declaration(synonym_typedef, type="AnnotationProperty")
yield m.LabelMacro(synonym_typedef, synonym_typedef.name)
if synonym_typedef.name is not None:
yield m.LabelMacro(synonym_typedef, synonym_typedef.name)
yield f.SubAnnotationPropertyOf(synonym_typedef, "oboInOwl:SynonymTypeProperty")
if synonym_typedef.specificity:
used_has_scope = True
Expand Down
14 changes: 8 additions & 6 deletions src/pyobo/struct/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,20 @@ def __eq__(self, other: Any) -> bool:
return self.prefix == other.prefix and self.identifier == other.identifier
raise TypeError

def __lt__(self, other: Referenced) -> bool:
if not isinstance(other, curies.Reference | Referenced):
raise TypeError
return self.reference < other.reference
def __lt__(self, other: curies.Reference | Referenced) -> bool:
if isinstance(other, curies.Reference):
return self.reference < other
if isinstance(other, Referenced):
return self.reference < other.reference
raise TypeError

@property
def prefix(self):
def prefix(self) -> str:
"""The prefix of the typedef."""
return self.reference.prefix

@property
def name(self):
def name(self) -> str | None:
"""The name of the typedef."""
return self.reference.name

Expand Down
11 changes: 6 additions & 5 deletions src/pyobo/struct/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,7 @@ def to_obonet(self: Obo, *, use_tqdm: bool = False) -> nx.MultiDiGraph:
)
return rv

def get_metadata(self) -> Mapping[str, Any]:
def get_metadata(self) -> dict[str, Any]:
"""Get metadata."""
return {
"version": self.data_version,
Expand Down Expand Up @@ -1568,14 +1568,14 @@ def get_typedef_df(self, use_tqdm: bool = False) -> pd.DataFrame:
]
return pd.DataFrame(rows, columns=["prefix", "identifier", "name"])

def iter_typedef_id_name(self) -> Iterable[tuple[str, str]]:
def iter_typedef_id_name(self) -> Iterable[tuple[str, str | None]]:
"""Iterate over typedefs' identifiers and their respective names."""
for typedef in self.typedefs or []:
yield typedef.identifier, typedef.name

def get_typedef_id_name_mapping(self) -> Mapping[str, str]:
"""Get a mapping from typedefs' identifiers to names."""
return dict(self.iter_typedef_id_name())
return {identifier: name for identifier, name in self.iter_typedef_id_name() if name}

#########
# PROPS #
Expand Down Expand Up @@ -1906,11 +1906,12 @@ def get_relation_multimapping(

def get_id_multirelations_mapping(
self,
typedef: TypeDef,
typedef: ReferenceHint,
*,
use_tqdm: bool = False,
) -> Mapping[str, list[Reference]]:
"""Get a mapping from identifiers to a list of all references for the given relation."""
typedef = _ensure_ref(typedef, ontology_prefix=self.ontology)
return multidict(
(stanza.identifier, reference)
for stanza in self._iter_stanzas(
Expand Down Expand Up @@ -2030,7 +2031,7 @@ def get_literal_mappings_df(self) -> pd.DataFrame:

def iterate_mapping_rows(
self, *, use_tqdm: bool = False
) -> Iterable[tuple[str, str, str, str, str, float | None, str | None]]:
) -> Iterable[tuple[str, str | None, str, str, str, float | None, str | None]]:
"""Iterate over SSSOM rows for mappings."""
for stanza in self._iter_stanzas(use_tqdm=use_tqdm):
for predicate, obj_ref, context in stanza.get_mappings(
Expand Down
Loading