# api_clients/umls_client.py """ Client for the NLM Unified Medical Language System (UMLS) API. Handles the complex ticket-based authentication. """ import aiohttp from lxml import html from .config import UMLS_API_KEY, UMLS_AUTH_URL, UMLS_BASE_URL, REQUEST_HEADERS class UMLSClient: def __init__(self, session: aiohttp.ClientSession): self.session = session self.service_ticket = None async def authenticate(self): """Gets a single-use service ticket for API requests.""" if not UMLS_API_KEY: print("Warning: UMLS_API_KEY not found. UMLS features will be disabled.") return False params = {'apikey': UMLS_API_KEY} async with self.session.post(UMLS_AUTH_URL, data=params, headers=REQUEST_HEADERS) as resp: if resp.status == 201: response_text = await resp.text() self.service_ticket = html.fromstring(response_text).find('.//form').get('action') return True else: print(f"Error authenticating with UMLS: {resp.status}") return False async def get_cui_for_term(self, term: str): """Searches for a Concept Unique Identifier (CUI) for a given term.""" if not await self.authenticate(): return None query = {'string': term, 'ticket': self.service_ticket} url = f"{UMLS_BASE_URL}/search/current" async with self.session.get(url, params=query, headers=REQUEST_HEADERS) as resp: if resp.status == 200: data = await resp.json() results = data.get('result', {}).get('results', []) return results[0] if results else None else: print(f"Error searching UMLS for term '{term}': {resp.status}") return None