|
|
|
"""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 `<repo_root>/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" |
|
|
|
|
|
|
|
|
|
|
|
@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: |
|
|
|
index[row["Name"].lower()] = row |
|
return index |
|
|
|
|
|
|
|
|
|
|
|
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()) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
hit = lookup_drug("Temozolomide") |
|
print(hit or "Drug not found – ensure TSV downloaded.") |
|
|