# genesis/api_clients/bioportal_api.py import requests from typing import List, Dict, Optional BIOPORTAL_BASE_URL = "https://data.bioontology.org" BIOPORTAL_API_KEY = None # Load from secrets in Hugging Face or local .env def search_term(term: str, ontologies: Optional[List[str]] = None, max_results: int = 20) -> List[Dict]: """ Search BioPortal for a term across one or more ontologies. If no ontologies specified, searches all available ones. """ headers = {"Authorization": f"apikey token={BIOPORTAL_API_KEY}"} params = { "q": term, "pagesize": max_results } if ontologies: params["ontologies"] = ",".join(ontologies) r = requests.get(f"{BIOPORTAL_BASE_URL}/search", headers=headers, params=params) r.raise_for_status() data = r.json() results = [] for result in data.get("collection", []): results.append({ "pref_label": result.get("prefLabel"), "definition": result.get("definition", ["No definition found"])[0], "synonyms": result.get("synonym", []), "ontology": result.get("links", {}).get("ontology"), "iri": result.get("@id"), "score": result.get("score", 0) }) return results def get_concept_details(ontology_acronym: str, concept_id: str) -> Dict: """ Fetch detailed metadata for a specific ontology concept. """ headers = {"Authorization": f"apikey token={BIOPORTAL_API_KEY}"} r = requests.get(f"{BIOPORTAL_BASE_URL}/ontologies/{ontology_acronym}/classes/{concept_id}", headers=headers) r.raise_for_status() data = r.json() return { "pref_label": data.get("prefLabel"), "definition": data.get("definition", ["No definition found"])[0], "synonyms": data.get("synonym", []), "properties": data.get("properties", {}), "relations": data.get("links", {}) } def map_to_ontologies(term: str, ontologies: List[str]) -> Dict[str, List[str]]: """ Map a given term to equivalent terms in multiple ontologies. Returns a dictionary mapping ontology → list of equivalent labels. """ results = search_term(term, ontologies=ontologies) mapping = {} for res in results: onto_name = res.get("ontology", "Unknown") if onto_name not in mapping: mapping[onto_name] = [] mapping[onto_name].append(res.get("pref_label")) return mapping