Source code for mkt.databases.hgnc

"""Client for the HGNC (HUGO Gene Nomenclature Committee) REST API.

Provides :class:`HGNC`, a REST client that resolves gene symbols and cross-references
via the HGNC service.
"""

import logging
from dataclasses import dataclass

import requests
from mkt.databases import requests_wrapper, utils_requests
from mkt.databases.api_schema import RESTAPIClient

logger = logging.getLogger(__name__)


[docs] @dataclass class HGNC(RESTAPIClient): """Class to interact with the HGNC API.""" input_symbol_or_id: str """Gene symbol or Ensembl gene ID.""" input_is_hgnc_symbol: bool = True """If True, input_symbol_or_id is a gene symbol, otherwise it is an Ensembl gene ID.""" url: str = "https://rest.genenames.org" """HGNC API URL.""" def __post_init__(self): """Post-initialization to set HGNC gene symbol or Ensembl gene ID.""" if self.input_is_hgnc_symbol: self.hgnc = self.input_symbol_or_id self.ensembl = None else: self.hgnc = None self.ensembl = self.input_symbol_or_id
[docs] def query_api(self, **kwargs) -> list[str] | None: """Default HGNC query: forwards to maybe_get_symbol_from_hgnc_search. Parameters: ----------- **kwargs Forwarded to maybe_get_symbol_from_hgnc_search. Returns: -------- list[str] | None Result of the search; see maybe_get_symbol_from_hgnc_search for details. """ return self.maybe_get_symbol_from_hgnc_search(**kwargs)
[docs] def maybe_get_info_from_hgnc_fetch( self, list_to_extract: list[str] | None = None, bool_verbose: bool = False, ) -> dict | None: """Get gene information for a given HGNC gene name from gene symbol report using HGNC REST API. Parameters ---------- hgnc_gene_symbol : str HGNC gene symbol list_to_extract : list[str] | None List of fields to extract from the response; if None, defaults to ["locus_type"] bool_verbose : bool, optional Whether to log verbose messages, by default False. Returns ------- dict | None Dictionary of gene information; empty list if no match and None if request fails or field not found Notes ----- The list of extractable fields can be found at https://www.genenames.org/help/rest/ \ under "storedFields" in the JSON or XML outputs. """ if self.hgnc is not None: url = f"https://rest.genenames.org/fetch/symbol/{self.hgnc}" res = requests_wrapper.get_cached_session().get( url, headers={"Accept": "application/json"} ) self._stamp_from_response(res) if list_to_extract is None: list_to_extract = ["locus_type"] list_out = [] if res.ok: set_keys = self._generate_key_set_hgnc_response_docs(res) for entry in list_to_extract: if entry not in set_keys: list_out.append(None) else: list_entry = self._extract_list_from_hgnc_response_docs( res, entry ) list_out.append(list_entry) else: list_out = [None for _ in list_to_extract] utils_requests.print_status_code_if_res_not_ok(res) dict_out = dict(zip(list_to_extract, list_out)) else: if bool_verbose: logger.warning( "No HGNC gene symbol provided; cannot fetch gene information " f"from HGNC API with Ensembl gene ID {self.ensembl}" ) dict_out = None return dict_out
[docs] @staticmethod def _extract_list_from_hgnc_response_docs( res_input: requests.models.Response, str_to_extract: str, ) -> list[str]: """Extract a list of values from the response documents of an HGNC REST API request. Parameters ---------- res_input : requests.models.Response Response object from an HGNC REST API request str_to_extract : str Key to extract from the response documents Returns ------- list[str] List of values extracted from the response documents """ if res_input.json()["response"]["numFound"] >= 1: list_output = [ doc[str_to_extract] for doc in res_input.json()["response"]["docs"] ] else: list_output = [] return list_output
[docs] @staticmethod def _generate_key_set_hgnc_response_docs( res_input: requests.models.Response, ) -> set[str]: """Generate a set of keys present in the response documents of an HGNC REST API request. Parameters ---------- res_input : requests.models.Response Response object from an HGNC REST API request Returns ------- set[str] Set of keys present in the response documents """ try: list_keys = [ set(doc.keys()) for doc in res_input.json()["response"]["docs"] ] set_keys = set.union(*list_keys) except TypeError: set_keys = set() return set_keys