#!/usr/bin/env python3 """MedGenesis – lightweight **DrugBank Open Data** TSV helper. * Loads the DrugBank TSV once into an in‑memory dict (lazy, cached). * Case‑insensitive lookup via `lookup_drug(name)`. * Raises actionable `FileNotFoundError` if the TSV is missing and provides official download URL in the error message. * TSV expected at `/mcp/data/drugbank_open_structured_drug_links.tsv`. """ from __future__ import annotations import csv from functools import lru_cache from pathlib import Path from typing import Dict, Optional _DATA = Path(__file__).with_suffix("").parent / "data" / "drugbank_open_structured_drug_links.tsv" _DOWNLOAD_URL = "https://go.drugbank.com/releases/latest#open-data" # --------------------------------------------------------------------- # Lazy index loader # --------------------------------------------------------------------- @lru_cache(maxsize=1) def _load_index() -> Dict[str, Dict]: if not _DATA.exists(): raise FileNotFoundError( f"DrugBank TSV not found at {_DATA}. Download the open-data TSV from\n" f"{_DOWNLOAD_URL} and place it in the same path." ) index: Dict[str, Dict] = {} with _DATA.open(newline="", encoding="utf-8") as fh: reader = csv.DictReader(fh, delimiter="\t") for row in reader: # Primary key is lower‑cased `Name`; keep original row otherwise untouched. index[row["Name"].lower()] = row return index # --------------------------------------------------------------------- # Public lookup # --------------------------------------------------------------------- def lookup_drug(name: str) -> Optional[Dict]: """Return DrugBank row dict for *name* (case‑insensitive) or `None`.""" idx = _load_index() return idx.get(name.lower()) # --------------------------------------------------------------------- # CLI demo # --------------------------------------------------------------------- if __name__ == "__main__": hit = lookup_drug("Temozolomide") print(hit or "Drug not found – ensure TSV downloaded.")