# -*- coding: utf-8 -*-
"""High-level API for alternative identifiers."""
import logging
from functools import lru_cache
from typing import List, Mapping, Optional
from .utils import get_version
from ..getters import get_ontology
from ..identifier_utils import normalize_curie, wrap_norm_prefix
from ..utils.cache import cached_multidict
from ..utils.path import prefix_cache_join
__all__ = [
"get_id_to_alts",
"get_alts_to_id",
"get_primary_curie",
"get_primary_identifier",
]
logger = logging.getLogger(__name__)
NO_ALTS = {
"ncbigene",
}
[docs]@lru_cache()
@wrap_norm_prefix
def get_id_to_alts(prefix: str, force: bool = False) -> Mapping[str, List[str]]:
"""Get alternate identifiers."""
if prefix in NO_ALTS:
return {}
version = get_version(prefix)
path = prefix_cache_join(prefix, name="alt_ids.tsv", version=version)
header = [f"{prefix}_id", "alt_id"]
@cached_multidict(path=path, header=header, force=force)
def _get_mapping() -> Mapping[str, List[str]]:
if force:
logger.info(f"[{prefix}] forcing reload for alts")
else:
logger.info("[%s] no cached alts found. getting from OBO loader", prefix)
ontology = get_ontology(prefix, force=force, version=version)
return ontology.get_id_alts_mapping()
return _get_mapping()
[docs]@lru_cache()
@wrap_norm_prefix
def get_alts_to_id(prefix: str, force: bool = False) -> Mapping[str, str]:
"""Get alternative id to primary id mapping."""
return {
alt: primary
for primary, alts in get_id_to_alts(prefix, force=force).items()
for alt in alts
}
[docs]def get_primary_curie(curie: str) -> Optional[str]:
"""Get the primary curie for an entity."""
prefix, identifier = normalize_curie(curie)
primary_identifier = get_primary_identifier(prefix, identifier)
if primary_identifier is not None:
return f"{prefix}:{primary_identifier}"
return None
[docs]@wrap_norm_prefix
def get_primary_identifier(prefix: str, identifier: str) -> str:
"""Get the primary identifier for an entity.
:param prefix: The name of the resource
:param identifier: The identifier to look up
:returns: the canonical identifier based on alt id lookup
Returns the original identifier if there are no alts available or if there's no mapping.
"""
if prefix in NO_ALTS: # TODO later expand list to other namespaces with no alts
return identifier
alts_to_id = get_alts_to_id(prefix)
if alts_to_id and identifier in alts_to_id:
return alts_to_id[identifier]
return identifier