File size: 2,117 Bytes
864cb28
 
 
 
 
 
 
 
c5b2751
864cb28
c5b2751
 
864cb28
c5b2751
 
 
864cb28
 
 
 
 
 
c5b2751
864cb28
c5b2751
 
864cb28
 
 
 
 
 
 
 
c5b2751
864cb28
 
c5b2751
 
864cb28
 
 
c5b2751
 
864cb28
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/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  `<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"

# ---------------------------------------------------------------------
# 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.")