mcpField
D
ddinter-database

ddinter-database

github.com/jaechang-hitsデータ・データベース38470 回インストール6 日前に更新
リポジトリ

ddinter-database について

ddinter-databaseは、薬物相互作用を検索するスキルで、服薬安全性の評価や薬剤レビューに利用できます。認証不要のJSON REST APIから、重症度、機序、臨床管理の推奨を取得します。

主な機能

  1. 01薬剤名検索とDDInter IDの特定
  2. 02単剤または薬剤ペアの相互作用検索
  3. 03重症度・機序・臨床上の推奨の取得
  4. 04薬剤リストの相互作用スクリーニング
  5. 05薬物相互作用ネットワークの作成

活用シーン

  1. 012剤併用時の相互作用と重症度の確認
  2. 02多剤併用レジメンの相互作用リスク評価
  3. 03重症度による相互作用の絞り込み
  4. 04薬剤群の相互作用ネットワーク分析

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill ddinter-database

インストール後、Claude Code で/ddinter-databaseを入力して読み込まれたか確認します。

詳細

DDInter 薬物間相互作用データベース

概要

DDInter は、2,400 種以上の薬物と 170 万件以上のペアごとの相互作用を収録した、オープンなキュレーション済み薬物間相互作用(DDI)データベースです。構造化された重症度レベル(重大、中等度、軽度)、作用機序の注釈、臨床管理に関する推奨事項を備えています。認証や登録は不要で、https://ddinter.scbdd.com/api/ の JSON REST API から利用できます。

使用する場面

  • 併用する 2 種類の薬物に既知の相互作用があるか、その重症度(重大/中等度/軽度)を確認する
  • 多剤併用リスクの評価に役立てるため、特定の薬物に関する既知の相互作用をすべて取得する
  • 薬物間相互作用の作用機序(薬物動態学的か薬力学的か)を特定する
  • 臨床意思決定支援の前に、薬物の併用リストをスクリーニングし、重大な相互作用の可能性を調べる
  • 服薬レビューやドラッグリポジショニングのワークフロー向けに、DDI チェックを自動化するパイプラインを構築する
  • ある薬物クラスの DDI ネットワークを解析する(例:CYP3A4 基質に関するすべての重大な相互作用)
  • FDA 承認薬のラベル文書(効能、用量、禁忌)には dailymed-database を使用してください
  • 薬理ゲノミクスに関する相互作用(CYP 遺伝子型と薬物の関連)には clinpgx-database を使用してください。DDInter が扱うのは薬物間の相互作用であり、遺伝子と薬物のペアではありません
  • FAERS の薬物有害事象報告には fda-database を使用してください

前提条件

  • Python パッケージ:requests、pandas、matplotlib、networkx
  • データ要件:薬物名または DDInter の薬物 ID
  • 環境:インターネット接続。API キーは不要です
  • レート制限:公式に公開されたレート制限はありません。バッチ処理のループでは、適切なアクセスのためリクエスト間に time.sleep(0.3) を使用してください
pip install requests pandas matplotlib networkx

クイックスタート

import requests

BASE = "https://ddinter.scbdd.com/api"

# Search for a drug by name
r = requests.get(f"{BASE}/drug/", params={"drug_name": "warfarin", "format": "json"}, timeout=15)
r.raise_for_status()
data = r.json()
print(f"Results for 'warfarin': {data['count']} drugs found")
for drug in data["results"][:3]:
    print(f"  ID={drug['ddinter_id']}  Name={drug['drug_name']}")
# Results for 'warfarin': 1 drugs found
#   ID=DDInter_D00001  Name=Warfarin

コア API

クエリ 1:名前で薬物を検索する

薬物名で検索し、DDInter ID を取得します。すべての相互作用クエリで DDInter ID が必要です。

import requests
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

def search_drug(drug_name):
    """Search DDInter for a drug by name. Returns list of matching drug records."""
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": drug_name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    return r.json()

# Search for warfarin
result = search_drug("warfarin")
print(f"Matches: {result['count']}")
if result["results"]:
    drug = result["results"][0]
    print(f"DDInter ID: {drug['ddinter_id']}")
    print(f"Drug name: {drug['drug_name']}")
    # Store DDInter ID for interaction queries
    warfarin_id = drug["ddinter_id"]
    print(f"\nWarfarin DDInter ID: {warfarin_id}")

# Batch name lookup
drugs_to_find = ["warfarin", "aspirin", "atorvastatin", "metformin", "amiodarone"]
id_map = {}
for name in drugs_to_find:
    res = search_drug(name)
    if res["results"]:
        id_map[name] = res["results"][0]["ddinter_id"]
        print(f"  {name:20s} → {res['results'][0]['ddinter_id']}")
クエリ 2:薬物の相互作用をすべて取得する

DDInter ID を使用して、薬物に関する既知の DDI をすべて取得します。相互作用する薬物、重症度、臨床情報が返されます。

import requests
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

def get_drug_interactions(drug_id, page_size=100):
    """Get all DDIs for a drug by DDInter ID. Handles pagination automatically."""
    all_interactions = []
    url = f"{BASE}/interaction/"
    params = {"drug_id": drug_id, "format": "json", "page_size": page_size}

    while url:
        r = requests.get(url, params=params, timeout=20)
        r.raise_for_status()
        data = r.json()
        all_interactions.extend(data.get("results", []))
        url = data.get("next")   # None when last page
        params = {}              # next URL already includes params

    return all_interactions

# Get all interactions for warfarin (DDInter_D00001)
interactions = get_drug_interactions("DDInter_D00001")
print(f"Warfarin total interactions: {len(interactions)}")

# Summarize by severity
df = pd.DataFrame(interactions)
if not df.empty and "level" in df.columns:
    severity_counts = df["level"].value_counts()
    print("\nInteractions by severity:")
    for level, count in severity_counts.items():
        print(f"  {level:15s}: {count:4d}")
    # Major: 45
    # Moderate: 312
    # Minor: 198
クエリ 3:相互作用 ID で詳細を取得する

特定の薬物間相互作用について、作用機序や臨床上の推奨事項を含む詳細情報を取得します。

import requests

BASE = "https://ddinter.scbdd.com/api"

def get_interaction_detail(interaction_id):
    """Get full details for a specific interaction by its DDInter interaction ID."""
    r = requests.get(f"{BASE}/interaction/{interaction_id}/",
                     params={"format": "json"},
                     timeout=15)
    r.raise_for_status()
    return r.json()

# Example interaction ID (format: DDInter_I_XXXXXX)
interaction_id = "DDInter_I_000001"   # example
try:
    detail = get_interaction_detail(interaction_id)
    print(f"Interaction: {detail.get('interaction_id')}")
    print(f"Drug A: {detail.get('drug_a')}")
    print(f"Drug B: {detail.get('drug_b')}")
    print(f"Severity: {detail.get('level')}")
    print(f"Mechanism: {detail.get('mechanism', 'Not specified')[:200]}")
    print(f"Recommendation: {detail.get('recommendation', 'Not specified')[:200]}")
    print(f"PK type: {detail.get('pharmacokinetic_type', 'N/A')}")
    print(f"PD type: {detail.get('pharmacodynamic_type', 'N/A')}")
except Exception as e:
    print(f"Note: Use a valid interaction ID from get_drug_interactions() results. Error: {e}")
クエリ 4:指定した 2 種類の薬物間の相互作用を確認する

DDInter ID を使用して、指定した 2 種類の薬物間の相互作用を検索します。

import requests

BASE = "https://ddinter.scbdd.com/api"

def check_drug_pair(drug_id_1, drug_id_2):
    """Check interactions between two specific drugs by their DDInter IDs."""
    r = requests.get(f"{BASE}/between/",
                     params={"drug1": drug_id_1, "drug2": drug_id_2, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    return r.json()

def find_drug_id(drug_name):
    """Helper: resolve drug name to DDInter ID."""
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": drug_name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    results = r.json()["results"]
    return results[0]["ddinter_id"] if results else None

# Check warfarin + aspirin interaction
warfarin_id = find_drug_id("warfarin")
aspirin_id = find_drug_id("aspirin")

if warfarin_id and aspirin_id:
    interactions = check_drug_pair(warfarin_id, aspirin_id)
    count = interactions.get("count", 0)
    print(f"Warfarin + Aspirin: {count} interaction(s) found")
    for ix in interactions.get("results", []):
        print(f"  Severity: {ix.get('level')}")
        print(f"  Mechanism: {ix.get('mechanism', 'N/A')[:200]}")
        print(f"  Recommendation: {ix.get('recommendation', 'N/A')[:200]}")
else:
    print(f"Could not resolve drug IDs: warfarin={warfarin_id}, aspirin={aspirin_id}")
クエリ 5:重症度レベルで相互作用を絞り込む

薬物に関する重症度の高い(重大な)相互作用のみを取得します。迅速な臨床リスクスクリーニングに不可欠です。

import requests
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

def get_major_interactions(drug_id):
    """Get only major-severity interactions for a drug."""
    all_interactions = []
    r = requests.get(f"{BASE}/interaction/",
                     params={"drug_id": drug_id, "format": "json", "page_size": 200},
                     timeout=20)
    r.raise_for_status()
    data = r.json()
    all_interactions.extend(data.get("results", []))

    # Filter to major severity
    major = [ix for ix in all_interactions
             if ix.get("level", "").lower() == "major"]
    return major

# Get major interactions for amiodarone (known high-interaction drug)
drug_id = "DDInter_D00023"   # example amiodarone ID; resolve with search_drug()
major_ixs = get_major_interactions(drug_id)
print(f"Major interactions: {len(major_ixs)}")

if major_ixs:
    df = pd.DataFrame(major_ixs)
    # Show drug partners and mechanism type
    for col in ["drug_a", "drug_b", "level", "pharmacokinetic_type"]:
        if col in df.columns:
            print(f"  {col}: {df[col].value_counts().head(3).to_dict()}")
    df.to_csv("amiodarone_major_interactions.csv", index=False)
    print("Saved: amiodarone_major_interactions.csv")
クエリ 6:薬物リストの多剤併用スクリーニング

服薬リストをスクリーニングし、ペアごとの重大および中等度の相互作用をすべて調べます。

import requests
import time
import itertools
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

def find_drug_id(drug_name):
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": drug_name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    results = r.json()["results"]
    return (results[0]["ddinter_id"], results[0]["drug_name"]) if results else (None, None)

def check_pair(id1, id2):
    r = requests.get(f"{BASE}/between/",
                     params={"drug1": id1, "drug2": id2, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    return r.json().get("results", [])

# Medication list to screen
medication_names = ["warfarin", "aspirin", "atorvastatin", "metformin", "amiodarone"]

# Resolve to DDInter IDs
id_map = {}
for name in medication_names:
    ddid, resolved_name = find_drug_id(name)
    if ddid:
        id_map[name] = (ddid, resolved_name)
        print(f"  {name:20s} → {ddid}")
    time.sleep(0.3)

# Check all pairs
flagged = []
for (n1, (id1, rn1)), (n2, (id2, rn2)) in itertools.combinations(id_map.items(), 2):
    ixs = check_pair(id1, id2)
    for ix in ixs:
        level = ix.get("level", "unknown")
        if level.lower() in ("major", "moderate"):
            flagged.append({
                "drug_1": rn1,
                "drug_2": rn2,
                "severity": level,
                "mechanism": ix.get("mechanism", "")[:100],
            })
    time.sleep(0.3)

df = pd.DataFrame(flagged)
print(f"\nFlagged interactions: {len(df)}")
if not df.empty:
    print(df.to_string(index=False))
    df.to_csv("polypharmacy_screening.csv", index=False)
    print("Saved: polypharmacy_screening.csv")
クエリ 7:相互作用ネットワークを可視化する

薬物のセットを対象に薬物間相互作用ネットワークを構築して可視化し、エッジを重症度別に色分けします。

import requests
import time
import itertools
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

BASE = "https://ddinter.scbdd.com/api"

def find_drug_id(drug_name):
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": drug_name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    results = r.json()["results"]
    return (results[0]["ddinter_id"], results[0]["drug_name"]) if results else (None, None)

def check_pair(id1, id2):
    r = requests.get(f"{BASE}/between/",
                     params={"drug1": id1, "drug2": id2, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    return r.json().get("results", [])

SEVERITY_COLORS = {"major": "#D32F2F", "moderate": "#F57C00", "minor": "#388E3C"}

# Drug list
drugs = ["warfarin", "aspirin", "atorvastatin", "fluconazole", "amiodarone"]
id_map = {}
for name in drugs:
    ddid, rname = find_drug_id(name)
    if ddid:
        id_map[name] = (ddid, rname)
    time.sleep(0.3)

# Build network
G = nx.Graph()
for name, (ddid, rname) in id_map.items():
    G.add_node(rname)

edge_colors = []
for (n1, (id1, rn1)), (n2, (id2, rn2)) in itertools.combinations(id_map.items(), 2):
    ixs = check_pair(id1, id2)
    for ix in ixs:
        level = ix.get("level", "minor").lower()
        G.add_edge(rn1, rn2, severity=level, weight=3 if level == "major" else 1)
    time.sleep(0.3)

# Visualize
fig, ax = plt.subplots(figsize=(9, 7))
pos = nx.spring_layout(G, seed=42, k=2)

for level, color in SEVERITY_COLORS.items():
    edges = [(u, v) for u, v, d in G.edges(data=True) if d.get("severity") == level]
    if edges:
        width = 4 if level == "major" else 2
        nx.draw_networkx_edges(G, pos, edgelist=edges, edge_color=color, width=width, alpha=0.8, ax=ax)

nx.draw_networkx_nodes(G, pos, node_color="#1565C0", node_size=1200, alpha=0.9, ax=ax)
nx.draw_networkx_labels(G, pos, font_color="white", font_size=8, font_weight="bold", ax=ax)

# Legend
from matplotlib.patches import Patch
legend = [Patch(color=c, label=l.capitalize()) for l, c in SEVERITY_COLORS.items()]
ax.legend(handles=legend, title="Severity", loc="upper right")
ax.set_title("Drug-Drug Interaction Network\n(DDInter)")
ax.axis("off")
plt.tight_layout()
plt.savefig("ddi_network.png", dpi=150, bbox_inches="tight")
print(f"Saved: ddi_network.png  ({G.number_of_nodes()} drugs, {G.number_of_edges()} interactions)")

主な概念

重症度の分類

DDInter は、確立された臨床薬理学の基準に従って、相互作用を 3 つの重症度レベルに分類します。

重症度コード臨床上の意味対応
重大major生命を脅かす可能性、または恒久的な損傷を引き起こす可能性があります併用を避け、代替薬を使用してください
中等度moderate臨床状態を悪化させる可能性があり、モニタリングの強化が必要です注意して使用し、注意深くモニタリングしてください
軽度minor臨床的影響は限定的です。相互作用は記録されていますが、重大な影響を及ぼすことはまれです通常は安全です。症状がある場合はモニタリングしてください
作用機序の種類

相互作用は作用機序によって分類されます。

  • 薬物動態学的(PK):一方の薬物が、もう一方の薬物の吸収、分布、代謝、または排泄(ADME)に影響します(例:CYP 酵素の阻害)
  • 薬力学的(PD):薬理学的標的レベルで、薬物が相加作用、相乗作用、または拮抗作用を示します(例:出血リスクの相加)
  • 混合型:薬物動態学的作用と薬力学的作用の両方が寄与します
薬剤の識別

DDInter では独自の連番識別子スキームを使用しています(例:Warfarin の場合は DDInter_D00001)。事前に名前を検索しない限り、ChEMBL ID、PubChem CID、RxCUI への直接的な対応付けはありません。相互作用を照会する前に、必ず /drug/ エンドポイントを使用して薬剤名を DDInter ID に解決してください。

一般的なワークフロー

ワークフロー 1:薬剤の包括的な DDI プロファイル

目的:薬剤のすべての相互作用を取得し、重症度別に分類して、構造化されたレポートをエクスポートします。

import requests
import time
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

def find_drug_id(name):
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    res = r.json()["results"]
    return (res[0]["ddinter_id"], res[0]["drug_name"]) if res else (None, None)

def get_all_interactions(drug_id, page_size=200):
    all_results = []
    url = f"{BASE}/interaction/"
    params = {"drug_id": drug_id, "format": "json", "page_size": page_size}
    while url:
        r = requests.get(url, params=params, timeout=30)
        r.raise_for_status()
        data = r.json()
        all_results.extend(data.get("results", []))
        url = data.get("next")
        params = {}
    return all_results

# Build DDI profile for clopidogrel
drug_name = "clopidogrel"
drug_id, resolved_name = find_drug_id(drug_name)

if drug_id:
    print(f"Drug: {resolved_name} ({drug_id})")
    ixs = get_all_interactions(drug_id)
    df = pd.DataFrame(ixs)

    print(f"Total interactions: {len(df)}")
    if "level" in df.columns:
        print("\nSeverity breakdown:")
        for level, grp in df.groupby("level"):
            print(f"  {level:15s}: {len(grp):4d} interactions")

        # Major interactions table
        major = df[df["level"].str.lower() == "major"].copy()
        print(f"\nMajor interactions ({len(major)}):")
        for _, row in major.head(10).iterrows():
            partner = row.get("drug_b") if row.get("drug_a") == resolved_name else row.get("drug_a")
            mech = str(row.get("mechanism", ""))[:80]
            print(f"  + {partner}: {mech}")

    df.to_csv(f"{drug_name}_ddi_profile.csv", index=False)
    print(f"\nSaved: {drug_name}_ddi_profile.csv")
ワークフロー 2:薬剤パネルのペアごとの相互作用マトリックス

目的:選定した薬剤パネルのすべてのペアごとの相互作用を示す重症度マトリックスを作成します。臨床薬理学や医薬品集のレビューに役立ちます。

import requests
import time
import itertools
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

BASE = "https://ddinter.scbdd.com/api"

SEVERITY_SCORE = {"major": 3, "moderate": 2, "minor": 1, "none": 0}

def find_drug_id(name):
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    res = r.json()["results"]
    return (res[0]["ddinter_id"], res[0]["drug_name"]) if res else (None, None)

def check_pair(id1, id2):
    r = requests.get(f"{BASE}/between/",
                     params={"drug1": id1, "drug2": id2, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    return r.json().get("results", [])

# Drug panel
drug_names = ["warfarin", "aspirin", "atorvastatin", "fluconazole", "metformin"]
id_map = {}
for name in drug_names:
    ddid, rname = find_drug_id(name)
    if ddid:
        id_map[name] = (ddid, rname)
    time.sleep(0.3)

resolved = {name: rname for name, (ddid, rname) in id_map.items()}
n = len(id_map)
names = list(id_map.keys())
rnames = [resolved[n] for n in names]

# Build matrix
matrix = np.zeros((n, n), dtype=int)
for i, (n1, (id1, _)) in enumerate(id_map.items()):
    for j, (n2, (id2, _)) in enumerate(id_map.items()):
        if i < j:
            ixs = check_pair(id1, id2)
            if ixs:
                worst = max(SEVERITY_SCORE.get(ix.get("level", "none").lower(), 0) for ix in ixs)
                matrix[i, j] = matrix[j, i] = worst
            time.sleep(0.3)

# Heatmap
fig, ax = plt.subplots(figsize=(7, 6))
im = ax.imshow(matrix, cmap="RdYlGn_r", vmin=0, vmax=3)
ax.set_xticks(range(n))
ax.set_yticks(range(n))
ax.set_xticklabels(rnames, rotation=30, ha="right", fontsize=9)
ax.set_yticklabels(rnames, fontsize=9)
for i in range(n):
    for j in range(n):
        text = ["None", "Minor", "Mod", "Major"][matrix[i, j]]
        ax.text(j, i, text, ha="center", va="center", fontsize=7)
plt.colorbar(im, ax=ax, label="Severity (0=None, 3=Major)")
ax.set_title("Drug-Drug Interaction Severity Matrix\n(DDInter)")
plt.tight_layout()
plt.savefig("ddi_severity_matrix.png", dpi=150, bbox_inches="tight")
print("Saved: ddi_severity_matrix.png")

主なパラメーター

パラメーターエンドポイントデフォルト範囲/オプション効果
drug_name/drug/—任意の薬剤名文字列薬剤名の検索に使用する語句
drug_id/interaction/—DDInter_DXXXXX 文字列相互作用照会用の DDInter 薬剤 ID
drug1、drug2/between/—DDInter_DXXXXX 文字列特定の薬剤ペアを確認するには両方が必要です
formatすべてのエンドポイントjsonjson応答形式。API では JSON のみ
page_size/interaction/、/drug/10正の整数1 ページあたりの結果数。一括取得には 200 を使用します
level応答フィールド—major、moderate、minor相互作用の重症度。クライアント側で絞り込みます
pharmacokinetic_type応答フィールド—PK、PD、mixedメカニズムの分類

ベストプラクティス

  1. 必ず先に薬剤名を DDInter ID に解決します:API は相互作用の照会で自由入力の薬剤名を受け付けません。/drug/?drug_name= を使用して ddinter_id を取得し、その後 /interaction/ または /between/ に渡します。

  2. 相互作用リスト全体を取得するにはページネーションを処理します:デフォルトでは 1 ページに最大 10 件まで返されます。warfarin や amiodarone などの薬剤には数百件の相互作用があります。next URL が null になるまで繰り返し取得してください:

    while url:
        data = requests.get(url, params=params).json()
        results.extend(data["results"])
        url = data.get("next")
        params = {}   # clear params after first request
    
  3. 対象を絞った照会には check_pair()、全体のプロファイルには get_interactions() を使用します:1 つのペアを確認する場合は /between/ エンドポイントの方が高速です。包括的な DDI プロファイルには /interaction/ エンドポイントが必要です。

  4. 一括処理のループに time.sleep(0.3) を追加します:DDInter は公開されたレート制限を設けていませんが、適切な間隔を設けることで、一般公開されている研究用データベースのサーバー側スロットリングを防げます。

  5. 重症度でクライアント側から絞り込みます:API は /interaction/ エンドポイントでサーバー側の重症度による絞り込みをサポートしていません。すべての相互作用を取得し、pandas で絞り込んでください:

    df = pd.DataFrame(interactions)
    major_only = df[df["level"].str.lower() == "major"]
    
  6. 意思決定支援のために臨床データベースと相互参照します:DDInter はエビデンスに基づく相互作用レコードを提供しますが、臨床上の判断にあたっては、必ず dailymed-database の最新の処方情報や、施設内の薬物相互作用ツールで確認してください。

よく使われるレシピ

レシピ:薬剤ペアの迅速な安全性確認

使用するタイミング:2 種類の薬剤を併用する前に、単一のペアの相互作用をすばやく調べます。

import requests

BASE = "https://ddinter.scbdd.com/api"

def quick_check(drug1_name, drug2_name):
    """Check interaction between two drugs by name. Returns severity or 'No interaction found'."""
    def get_id(name):
        r = requests.get(f"{BASE}/drug/",
                         params={"drug_name": name, "format": "json"},
                         timeout=15)
        r.raise_for_status()
        results = r.json()["results"]
        return (results[0]["ddinter_id"], results[0]["drug_name"]) if results else (None, name)

    id1, rn1 = get_id(drug1_name)
    id2, rn2 = get_id(drug2_name)

    if not id1 or not id2:
        return f"Drug not found: {drug1_name if not id1 else drug2_name}"

    r = requests.get(f"{BASE}/between/",
                     params={"drug1": id1, "drug2": id2, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    ixs = r.json().get("results", [])

    if not ixs:
        return f"{rn1} + {rn2}: No interaction found in DDInter"

    worst = max(ixs, key=lambda x: {"major": 3, "moderate": 2, "minor": 1}.get(x.get("level", "minor").lower(), 0))
    return f"{rn1} + {rn2}: {worst.get('level', 'unknown').upper()} — {worst.get('mechanism', 'N/A')[:120]}"

print(quick_check("warfarin", "aspirin"))
print(quick_check("metformin", "atorvastatin"))
print(quick_check("warfarin", "fluconazole"))
レシピ:複数の薬剤について重症度別に相互作用を数える

使用するタイミング:複数の薬剤の DDI 負荷を比較するサマリーテーブルを作成します。

import requests
import time
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

def get_severity_summary(drug_name):
    """Return severity counts (major/moderate/minor) for a drug."""
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": drug_name, "format": "json"},
                     timeout=15)
    r.raise_for_status()
    results = r.json()["results"]
    if not results:
        return None
    drug_id = results[0]["ddinter_id"]

    # Get all interactions
    all_ixs = []
    url = f"{BASE}/interaction/"
    params = {"drug_id": drug_id, "format": "json", "page_size": 200}
    while url:
        r2 = requests.get(url, params=params, timeout=20)
        r2.raise_for_status()
        data = r2.json()
        all_ixs.extend(data.get("results", []))
        url = data.get("next")
        params = {}

    from collections import Counter
    counts = Counter(ix.get("level", "unknown").lower() for ix in all_ixs)
    return {
        "drug": results[0]["drug_name"],
        "total": len(all_ixs),
        "major": counts.get("major", 0),
        "moderate": counts.get("moderate", 0),
        "minor": counts.get("minor", 0),
    }

drugs = ["warfarin", "amiodarone", "metformin", "atorvastatin"]
records = []
for name in drugs:
    summary = get_severity_summary(name)
    if summary:
        records.append(summary)
        print(f"  {name:20s} total={summary['total']:4d}  major={summary['major']:3d}  mod={summary['moderate']:3d}  minor={summary['minor']:3d}")
    time.sleep(0.5)

df = pd.DataFrame(records)
df = df.sort_values("major", ascending=False)
df.to_csv("ddi_severity_summary.csv", index=False)
print(f"\nSaved: ddi_severity_summary.csv")
レシピ:薬剤リスト全体のすべての重大な相互作用をエクスポートする

使用するタイミング:医薬品集のレビューや臨床意思決定支援向けに、優先順位を付けた相互作用アラートリストを作成します。

import requests
import time
import pandas as pd

BASE = "https://ddinter.scbdd.com/api"

drug_list = ["warfarin", "aspirin", "clopidogrel", "amiodarone", "fluconazole"]
all_major = []

for drug_name in drug_list:
    r = requests.get(f"{BASE}/drug/",
                     params={"drug_name": drug_name, "format": "json"}, timeout=15)
    r.raise_for_status()
    res = r.json()["results"]
    if not res:
        continue
    drug_id, resolved = res[0]["ddinter_id"], res[0]["drug_name"]

    r2 = requests.get(f"{BASE}/interaction/",
                      params={"drug_id": drug_id, "format": "json", "page_size": 200}, timeout=30)
    r2.raise_for_status()
    for ix in r2.json().get("results", []):
        if ix.get("level", "").lower() == "major":
            all_major.append({
                "query_drug": resolved,
                "interaction_partner": ix.get("drug_a") if ix.get("drug_b") == resolved else ix.get("drug_b"),
                "severity": "major",
                "mechanism": str(ix.get("mechanism", ""))[:200],
                "recommendation": str(ix.get("recommendation", ""))[:200],
            })
    time.sleep(0.5)

df = pd.DataFrame(all_major).drop_duplicates()
print(f"Total major interactions across {len(drug_list)} drugs: {len(df)}")
df.to_csv("major_interactions_alert_list.csv", index=False)
print("Saved: major_interactions_alert_list.csv")

トラブルシューティング

問題原因解決策
/interaction/ で 404 Not Found が発生するDDInter の薬剤 ID が無効、または形式が正しくない/drug/?drug_name= を再度検索して有効な ID を取得します。形式は DDInter_DXXXXX である必要があります
/drug/ の検索結果が count: 0 になる薬剤名が DDInter の命名規則に一致しないINN 名を試します(例:"aspirin" ではなく "acetylsalicylic acid")。部分一致する名前も試します
相互作用リストが不完全デフォルトの page_size=10 によって結果が省略されるpage_size=200 を設定し、next の URL が null になるまで順に取得します
/between/ の結果が空その薬剤ペアについて、DDInter にキュレーション済みの相互作用がない相互作用がないとは限りません。dailymed-database のラベルテキストを確認してください
ConnectionError またはタイムアウトが発生するサーバーが一時的に利用できないtimeout=30 を指定して再試行します。一括リクエストには指数バックオフを使用してください
一括エクスポートに相互作用が重複して含まれる同じ相互作用が両方の薬剤の観点から表示される薬剤 ID をアルファベット順に並べ替えた後、(drug_a, drug_b) のペアで重複を除去します
JSONDecodeError が発生するサーバーから JSON 以外のエラーページが返されたHTTP ステータスコードを確認します。解析の前に r.raise_for_status() を実行してください

関連スキル

  • dailymed-database — FDA 承認薬のラベルテキスト。薬物相互作用のセクションを含みます(非構造化データ)
  • fda-database — 有害事象報告および医薬品リコールデータを扱う openFDA
  • drugbank-database-access — 構造化された DDI および標的データを含む、DrugBank のローカル XML
  • clinpgx-database — 薬物と遺伝子の相互作用データ(薬理ゲノミクス)を扱う PharmGKB
  • pytdc-therapeutics-data-commons — ML モデルのトレーニングに利用する TDC DDI ベンチマークデータセット

参考資料

コメント