1+ ################################################################################
2+ # ols_mcp/api.py
3+ # This module contains wrapper functions that interact with the OLS API endpoints
4+ ################################################################################
5+ import json
6+ from typing import Any , Dict , List , Optional , Union
7+ import requests
8+
9+
10+ def search_ontologies (
11+ query : str ,
12+ ontologies : Optional [List [str ]] = None ,
13+ max_results : int = 20 ,
14+ exact : bool = False ,
15+ verbose : bool = False ,
16+ ) -> List [Dict [str , Any ]]:
17+ """
18+ Search across all ontologies in the OLS.
19+
20+ Args:
21+ query: The search term
22+ ontologies: List of specific ontology IDs to search within (optional)
23+ max_results: Maximum number of results to return
24+ exact: Whether to perform exact matching
25+ verbose: If True, print progress information during retrieval
26+
27+ Returns:
28+ A list of dictionaries, where each dictionary represents a search result.
29+ """
30+ base_url = "https://www.ebi.ac.uk/ols/api/search"
31+
32+ params = {
33+ "q" : query ,
34+ "rows" : max_results ,
35+ "exact" : exact
36+ }
37+
38+ if ontologies :
39+ params ["ontology" ] = "," .join (ontologies )
40+
41+ if verbose :
42+ print (f"Searching OLS for: { query } " )
43+
44+ response = requests .get (base_url , params = params )
45+ response .raise_for_status ()
46+ data = response .json ()
47+
48+ # Extract the docs from the response
49+ results = data .get ("response" , {}).get ("docs" , [])
50+
51+ if verbose :
52+ print (f"Found { len (results )} results" )
53+
54+ return results
55+
56+
57+ def get_ontology_details (ontology_id : str , verbose : bool = False ) -> Dict [str , Any ]:
58+ """
59+ Get details about a specific ontology.
60+
61+ Args:
62+ ontology_id: The ID of the ontology (e.g., 'go', 'uberon')
63+ verbose: If True, print progress information
64+
65+ Returns:
66+ A dictionary containing ontology details.
67+ """
68+ base_url = f"https://www.ebi.ac.uk/ols/api/ontologies/{ ontology_id } "
69+
70+ if verbose :
71+ print (f"Fetching details for ontology: { ontology_id } " )
72+
73+ response = requests .get (base_url )
74+ response .raise_for_status ()
75+ data = response .json ()
76+
77+ if verbose :
78+ print (f"Retrieved details for { ontology_id } " )
79+
80+ return data
81+
82+
83+ def get_ontology_terms (
84+ ontology_id : str ,
85+ max_results : int = 20 ,
86+ page_size : int = 20 ,
87+ iri : Optional [str ] = None ,
88+ short_form : Optional [str ] = None ,
89+ obo_id : Optional [str ] = None ,
90+ verbose : bool = False ,
91+ ) -> List [Dict [str , Any ]]:
92+ """
93+ Get classes/terms from a specific ontology.
94+
95+ Args:
96+ ontology_id: The ID of the ontology (e.g., 'go', 'uberon')
97+ max_results: Maximum number of results to return
98+ page_size: Number of results per page
99+ iri: Filter by specific IRI
100+ short_form: Filter by short form
101+ obo_id: Filter by OBO ID
102+ verbose: If True, print progress information
103+
104+ Returns:
105+ A list of dictionaries, where each dictionary represents a term.
106+ """
107+ base_url = f"https://www.ebi.ac.uk/ols/api/ontologies/{ ontology_id } /terms"
108+
109+ params = {"size" : min (page_size , max_results )}
110+
111+ if iri :
112+ params ["iri" ] = iri
113+ if short_form :
114+ params ["short_form" ] = short_form
115+ if obo_id :
116+ params ["obo_id" ] = obo_id
117+
118+ all_terms = []
119+ page = 0
120+
121+ if verbose :
122+ print (f"Fetching terms from ontology: { ontology_id } " )
123+
124+ while len (all_terms ) < max_results :
125+ params ["page" ] = page
126+
127+ response = requests .get (base_url , params = params )
128+ response .raise_for_status ()
129+ data = response .json ()
130+
131+ terms = data .get ("_embedded" , {}).get ("terms" , [])
132+ if not terms :
133+ break
134+
135+ all_terms .extend (terms )
136+
137+ if verbose :
138+ print (f"Fetched page { page + 1 } , total terms so far: { len (all_terms )} " )
139+
140+ # Check if we have more pages
141+ if not data .get ("page" , {}).get ("number" , 0 ) < data .get ("page" , {}).get ("totalPages" , 0 ) - 1 :
142+ break
143+
144+ page += 1
145+
146+ # Truncate to max_results
147+ result = all_terms [:max_results ]
148+
149+ if verbose :
150+ print (f"Retrieved { len (result )} terms from { ontology_id } " )
151+
152+ return result
0 commit comments