mcpField
G
gtopdb-database

gtopdb-database

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

gtopdb-database について

gtopdb-databaseは、Guide to Pharmacology REST APIで薬物標的、リガンド、相互作用を調べるスキルです。薬理学や創薬研究向けに、親和性、構造記述子、外部データベースへのリンクを取得できます。

主な機能

  1. 01遺伝子シンボルやアクセッションで標的検索
  2. 02標的とリガンドの相互作用検索
  3. 03リガンド構造記述子の取得
  4. 04リガンドの承認状況確認
  5. 05標的ファミリー階層の参照

活用シーン

  1. 01標的に対するリガンド親和性の確認
  2. 02受容体に注釈されたリガンドの一覧
  3. 03承認薬とデータベースリンクの検索
  4. 04遺伝子シンボルからUniProtへの対応付け

インストール

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

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

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

詳細

Guide to Pharmacology(GtoPdb)データベース

概要

IUPHAR/BPS Guide to Pharmacology(GtoPdb)は、受容体薬理学における薬物標的、リガンド、定量的相互作用をカタログ化しています。ウェブサービス REST API(https://www.guidetopharmacology.org/services/)は、標的、リガンド、相互作用、ファミリー階層の JSON を返します。基本レコードは意図的に簡潔に保たれており、遺伝子シンボル、UniProt アクセッション、ChEMBL ID、SMILES/InChI はサブリソース(/targets/{id}/databaseLinks、/targets/{id}/synonyms、/ligands/{id}/structure、/ligands/{id}/databaseLinks)に格納されています。認証は不要です。

使用する場面

  • 特定の標的に対するリガンドの親和性(pKi/pIC50/pKd)を調べる
  • 受容体(例:μオピオイド受容体/OPRM1)について、注釈付きリガンドをすべて一覧表示する
  • リガンドの承認状況(approved=true)と相互参照(PubChem CID、ChEMBL ID、DrugBank ID)を確認する
  • 受容体分類に使う IUPHAR ファミリー階層(867 ファミリー)を取得する
  • ケモインフォマティクス用の構造記述子(SMILES、InChI、InChIKey)を取得する
  • HGNC シンボル → UniProt → GtoPdb 標的 ID をマッピングして、データベース間の統合に利用する
  • より大規模な生物活性データセット(240 万件以上の化合物)には chembl-database-bioactivity を使用してください。GtoPdb はキュレーション済みで規模は小さいものの、注釈がより詳細です
  • FDA 承認薬のラベル情報には dailymed-database を使用してください。GtoPdb は薬理学向けであり、規制関連のテキストを扱うものではありません

前提条件

  • Python パッケージ:requests、pandas、matplotlib
  • データ要件:HGNC シンボル、UniProt アクセッション、GtoPdb 標的/リガンド ID、または薬物 INN
  • 環境:インターネット接続が必要です。API キーは不要です
  • レート制限:公開された制限はありません。一括処理のループでは、リクエストの間に time.sleep(0.2) を使用してください
pip install requests pandas matplotlib

クイックスタート

import requests

BASE = "https://www.guidetopharmacology.org/services"

# Resolve HGNC symbol → GtoPdb target. geneSymbol= and accession= give an
# exact match. (name= matches across all fields and silently returns the
# wrong target — never use it for canonical lookups.)
r = requests.get(f"{BASE}/targets", params={"geneSymbol": "OPRM1"}, timeout=30)
targets = r.json()
print(f"OPRM1 hits: {len(targets)}")  # 1
t = targets[0]
print(f"targetId={t['targetId']}  name='{t['name']}'  type={t['type']}  family={t['familyIds']}")
# targetId=319  name='μ receptor'  type=GPCR  family=[50]

コア API

クエリ 1:標的の解決(HGNC シンボルまたは UniProt アクセッション)
import requests

BASE = "https://www.guidetopharmacology.org/services"

def find_target(*, geneSymbol=None, accession=None):
    """Exact-match target lookup. Pass ONE of geneSymbol or accession."""
    if geneSymbol:
        params = {"geneSymbol": geneSymbol}
    elif accession:
        params = {"accession": accession}
    else:
        raise ValueError("provide geneSymbol or accession")
    r = requests.get(f"{BASE}/targets", params=params, timeout=30)
    r.raise_for_status()
    hits = r.json()
    if not hits:
        return None
    return hits[0]

print(find_target(geneSymbol="OPRM1"))   # targetId 319 (μ receptor)
print(find_target(accession="P35372"))   # same — UniProt P35372 is OPRM1
# Base record has only IDs and family pointers — no gene symbol, UniProt, or
# synonym text. Read sub-resources to get those.
import requests
BASE = "https://www.guidetopharmacology.org/services"
print(requests.get(f"{BASE}/targets/319", timeout=30).json().keys())
# dict_keys(['targetId','name','type','familyIds','subunitIds','complexIds'])
クエリ 2:標的の相互参照と同義語
import requests, pandas as pd

BASE = "https://www.guidetopharmacology.org/services"

def target_xrefs(target_id):
    """Cross-database accessions: UniProt, HGNC, ChEMBL Target, Ensembl, etc."""
    r = requests.get(f"{BASE}/targets/{target_id}/databaseLinks", timeout=30)
    r.raise_for_status()
    return pd.DataFrame(r.json())

def target_synonyms(target_id):
    r = requests.get(f"{BASE}/targets/{target_id}/synonyms", timeout=30)
    r.raise_for_status()
    return [s.get("name") for s in r.json()]

df_links = target_xrefs(319)
print(df_links[["database", "accession", "species"]].head(8).to_string(index=False))
# database          accession    species
# ChEMBL Target     CHEMBL233    Human
# UniProtKB         P35372       Human
# HGNC              8156         Human
# ...
print("Synonyms:", target_synonyms(319))
クエリ 3:標的の相互作用と親和性
import requests, pandas as pd

BASE = "https://www.guidetopharmacology.org/services"

def target_interactions(target_id):
    """All ligand-target interaction records for a target.
    Each row carries ligandId, ligandName, type (Agonist/Antagonist/etc.),
    action, affinity (string), affinityParameter (pKi/pIC50/...), refs."""
    r = requests.get(f"{BASE}/targets/{target_id}/interactions", timeout=60)
    r.raise_for_status()
    rows = []
    for i in r.json():
        rows.append({
            "ligandId": i.get("ligandId"),
            "ligandName": i.get("ligandName"),
            "type": i.get("type"),                     # Agonist/Antagonist/Allosteric modulator/...
            "action": i.get("action"),
            "affinity": i.get("affinity"),             # string, may include "-" (range) or "~"
            "affinityParameter": i.get("affinityParameter"),  # pKi, pIC50, pKd, pEC50, pA2, pKB
            "species": i.get("targetSpecies"),
            "primary": i.get("primaryTarget"),
            "endogenous": i.get("endogenous"),
        })
    return pd.DataFrame(rows)

df_ints = target_interactions(319)  # μ receptor
print(f"OPRM1 interactions: {len(df_ints)}")
# Top pKi values (cast safely — affinity is a string; some are ranges like "8.5-9.0")
df_ints["pki"] = pd.to_numeric(df_ints["affinity"], errors="coerce")
print(df_ints[df_ints["affinityParameter"] == "pKi"]
      .sort_values("pki", ascending=False)
      .head(8)[["ligandName", "type", "pki"]].to_string(index=False))
クエリ 4:リガンドの検索と構造
import requests

BASE = "https://www.guidetopharmacology.org/services"

def ligand(ligand_id):
    """Base ligand record. Keys: ligandId, name, type, approved, approvalSource,
    abbreviation, inn, whoEssential, withdrawn, antibacterial, immuno, malaria,
    labelled, radioactive, activeDrugIds, prodrugIds, subunitIds, complexIds."""
    r = requests.get(f"{BASE}/ligands/{ligand_id}", timeout=30)
    r.raise_for_status()
    return r.json()

def ligand_structure(ligand_id):
    """Structure descriptors: smiles, inchi, inchiKey, iupacName."""
    r = requests.get(f"{BASE}/ligands/{ligand_id}/structure", timeout=30)
    r.raise_for_status()
    return r.json()

l = ligand(1627)            # morphine
s = ligand_structure(1627)
print(f"{l['name']:12s} approved={l['approved']}  type={l['type']}  inn={l.get('inn')}")
print(f"  SMILES   : {s['smiles']}")
print(f"  InChIKey : {s['inchiKey']}")
# Ligand cross-references: PubChem CID, ChEMBL, DrugBank, CAS, ChEBI, BindingDB
import requests
BASE = "https://www.guidetopharmacology.org/services"

def ligand_xrefs(ligand_id):
    r = requests.get(f"{BASE}/ligands/{ligand_id}/databaseLinks", timeout=30)
    r.raise_for_status()
    return r.json()

xrefs = ligand_xrefs(1627)
for x in xrefs[:10]:
    print(f"  {x['database']:25s}  {x['accession']}")
クエリ 5:ファミリー階層
import requests, pandas as pd

BASE = "https://www.guidetopharmacology.org/services"

# Correct endpoint is /targets/families (NOT /families, which is 404)
def list_families():
    r = requests.get(f"{BASE}/targets/families", timeout=30)
    r.raise_for_status()
    return pd.DataFrame(r.json())

df_fams = list_families()
print(f"Total families: {len(df_fams)}")  # ~867
print(df_fams[df_fams["name"].str.contains("opioid", case=False, na=False)]
      [["familyId", "name"]].to_string(index=False))
クエリ 6:承認済み薬剤(サーバー側エイリアス)
import requests, pandas as pd

BASE = "https://www.guidetopharmacology.org/services"

# Special: `type=Approved` is a server-side alias that returns all `approved=true`
# ligands. The `approved=true` query param is silently ignored — use type=.
def approved_ligands():
    r = requests.get(f"{BASE}/ligands", params={"type": "Approved"}, timeout=60)
    r.raise_for_status()
    return pd.DataFrame(r.json())

df = approved_ligands()
print(f"Approved ligands in GtoPdb: {len(df)}")  # ~2,197
print(df[df["name"].str.contains("morphine|fentanyl|naloxone", case=False, na=False)]
      [["ligandId", "name", "approvalSource"]].head(8).to_string(index=False))

重要な概念

基本レコードとサブリソース

GtoPdb では、基本レコードを意図的に簡潔に保っています。通常必要となるデータを取得するには、サブリソースを呼び出す必要があります。

項目エンドポイント
遺伝子シンボル/UniProt/HGNC/ChEMBL Target/targets/{id}/databaseLinks
標的の同義語/targets/{id}/synonyms
生物種の注釈/targets/{id}/databaseLinks(各行に species を含む)
標的の相互作用/親和性/targets/{id}/interactions
SMILES/InChI/InChIKey/ligands/{id}/structure
PubChem CID/ChEMBL/DrugBank/CAS/ChEBI/ligands/{id}/databaseLinks
リガンドの薬理学的概要/ligands/{id}/pharmacology(長いテキストフィールド)
geneSymbol= と accession= は完全一致です

name= フィルターはすべての標的フィールドを検索するため、誤検出が返されます(例:name=beta-2 は β2 アドレナリン受容体だけでなく、PLC β2 や GABA_A β2 にも一致します)。標準的な検索には、必ず geneSymbol=HGNC または accession=UniProt を優先してください。

暗黙のうちに無視されるフィルター
  • /interactions では、targetId、ligandId、targetType、ligandType は受け付けられますが、暗黙のうちに無視されます。どのフィルターを指定しても、エンドポイントは約 28 万件の行を返します。代わりに /targets/{id}/interactions または /ligands/{id}/interactions を使用してください。
  • /ligands では、approved=true は暗黙のうちに無視されます。フィルターには type=Approved(サーバー側エイリアス)を使用してください。
親和性パラメーター

affinityParameter は pKi、pKd、pIC50、pEC50、pA2、pKB のいずれかです。affinity フィールドは文字列で、数値("9.4")、範囲("8.5-9.0")、修飾付きの値("~7.5"、">8")が含まれることがあります。常に pd.to_numeric(..., errors="coerce") を使って型変換してください。

一般的なワークフロー

ワークフロー 1:標的のリガンドプロファイルを作成する

目的:HGNC で指定した標的について、親和性が pKi 7 以上の承認済み薬剤をすべて取得します。

import requests, pandas as pd

BASE = "https://www.guidetopharmacology.org/services"

def target_profile(gene_symbol, min_pki=7.0):
    t = requests.get(f"{BASE}/targets",
                     params={"geneSymbol": gene_symbol}, timeout=30).json()
    if not t:
        return None
    tid = t[0]["targetId"]
    ints = requests.get(f"{BASE}/targets/{tid}/interactions", timeout=60).json()
    rows = []
    for i in ints:
        # Skip rows without numeric pKi
        if i.get("affinityParameter") != "pKi":
            continue
        try:
            pki = float(i.get("affinity"))
        except (TypeError, ValueError):
            continue
        if pki < min_pki:
            continue
        # Check approval via the ligand base record
        lig = requests.get(f"{BASE}/ligands/{i['ligandId']}", timeout=30).json()
        rows.append({
            "ligand": i["ligandName"],
            "ligandId": i["ligandId"],
            "type": i.get("type"),
            "pki": pki,
            "approved": lig.get("approved"),
            "withdrawn": lig.get("withdrawn"),
        })
    return pd.DataFrame(rows).sort_values("pki", ascending=False)

df = target_profile("OPRM1", min_pki=8.0)
print(df.head(10).to_string(index=False))
df.to_csv("OPRM1_profile.csv", index=False)
ワークフロー 2:リガンド → 標的

目標:リガンドのオフターゲットを親和性とともに一覧表示します。

import requests, pandas as pd

BASE = "https://www.guidetopharmacology.org/services"

def ligand_targets(ligand_id):
    r = requests.get(f"{BASE}/ligands/{ligand_id}/interactions", timeout=60)
    r.raise_for_status()
    rows = []
    for i in r.json():
        rows.append({
            "targetId": i.get("targetId"),
            "targetName": i.get("targetName"),
            "type": i.get("type"),
            "affinity": pd.to_numeric(i.get("affinity"), errors="coerce"),
            "affinityParameter": i.get("affinityParameter"),
            "species": i.get("targetSpecies"),
            "primary": i.get("primaryTarget"),
        })
    return pd.DataFrame(rows).sort_values("affinity", ascending=False)

df = ligand_targets(1627)  # morphine
print(f"Morphine interactions across all targets: {len(df)}")
print(df.head(8).to_string(index=False))

主なパラメーター

パラメーターエンドポイントデフォルト範囲/オプション効果
geneSymbol/targets—HGNC シンボル標的を完全一致で検索
accession/targets—UniProt アクセッション標的を完全一致で検索
name/targets, /ligands—任意の文字列あいまい検索 — すべてのフィールドが対象となり、誤ったレコードが返されることがあります
type/ligands—Synthetic organic, Peptide, Natural product, Metabolite, Antibody, Nucleic acid, Inorganic, Approved(エイリアス)種類または承認状況でリガンドリストを絞り込み
(パス){targetId}/targets/{id}/{rel}必須整数標的のサブリソースを検索(databaseLinks/synonyms/interactions/…)
(パス){ligandId}/ligands/{id}/{rel}必須整数リガンドのサブリソースを検索(structure/databaseLinks/interactions/pharmacology)
(パス)families/targets/families——867 の IUPHAR ファミリーのリスト

ベストプラクティス

  1. 正規の検索には geneSymbol=/accession= を使用し、name= は決して使用しないでください。あいまい検索の name= はすべてのフィールドを対象とするため、誤った標的が通知なく返されることがあります。
  2. ID 以外の情報はすべてサブリソースから取得してください。 基本の /targets/{id} および /ligands/{id} レコードには、遺伝子シンボル、UniProt、SMILES、ChEMBL などが含まれていません。これらは /databaseLinks、/synonyms、/structure の下にあります。
  3. 相互作用の絞り込みには /targets/{id}/interactions または /ligands/{id}/interactions を使用してください。フィルターが通知なく無視される /interactions?targetId=… は使用しないでください。
  4. 承認済み医薬品を取得するには、サーバーのエイリアス type=Approved を使用してください。クエリパラメーター approved=true は無視されます。
  5. affinity は必ず errors="coerce" を指定して数値に変換してください。このフィールドは文字列で、範囲、修飾付きの値、または欠損値の場合があります。
  6. ファミリーのエンドポイントは /targets/families です。404 エラーになる /families ではありません。

よくあるレシピ

レシピ:遺伝子シンボル → GtoPdb 経由で UniProt を解決
import requests
BASE = "https://www.guidetopharmacology.org/services"

def gene_to_uniprot(symbol):
    t = requests.get(f"{BASE}/targets", params={"geneSymbol": symbol}, timeout=30).json()
    if not t:
        return None
    links = requests.get(f"{BASE}/targets/{t[0]['targetId']}/databaseLinks", timeout=30).json()
    for x in links:
        if x.get("database") == "UniProtKB" and x.get("species") == "Human":
            return x["accession"]
    return None

print(gene_to_uniprot("OPRM1"))   # P35372
print(gene_to_uniprot("ADRB2"))   # P07550
レシピ:受容体ファミリーの承認済み医薬品
import requests, pandas as pd
BASE = "https://www.guidetopharmacology.org/services"

def family_targets(family_id):
    fams = requests.get(f"{BASE}/targets/families", timeout=30).json()
    return next((f.get("targetIds", []) for f in fams if f["familyId"] == family_id), [])

def approved_drugs_for_family(family_id):
    rows = []
    for tid in family_targets(family_id):
        ints = requests.get(f"{BASE}/targets/{tid}/interactions", timeout=60).json()
        for i in ints:
            lig = requests.get(f"{BASE}/ligands/{i['ligandId']}", timeout=30).json()
            if not lig.get("approved"):
                continue
            rows.append({"targetId": tid, "drug": i["ligandName"],
                         "type": i.get("type"),
                         "affinity": pd.to_numeric(i.get("affinity"), errors="coerce"),
                         "param": i.get("affinityParameter")})
    return pd.DataFrame(rows).drop_duplicates(subset=["targetId", "drug"])

# family 50 = opioid receptors (example)
df = approved_drugs_for_family(50)
print(df.head(10).to_string(index=False))
レシピ:GtoPdb リガンド ID のリストから SMILES を検索
import requests, pandas as pd, time
BASE = "https://www.guidetopharmacology.org/services"

def smiles_table(ligand_ids):
    rows = []
    for lid in ligand_ids:
        s = requests.get(f"{BASE}/ligands/{lid}/structure", timeout=30).json()
        rows.append({"ligandId": lid, "smiles": s.get("smiles"),
                     "inchiKey": s.get("inchiKey")})
        time.sleep(0.2)
    return pd.DataFrame(rows)

print(smiles_table([1627, 1638, 5466]).to_string(index=False))  # morphine, naloxone, fentanyl

トラブルシューティング

問題原因解決策
name=... で誤った標的が返されるname= はすべてのフィールドを対象に検索する正規の検索には geneSymbol= または accession= を使用する
target["hgncSymbol"] / target["uniprotId"] で KeyError基本レコードには ID しか含まれない/targets/{id}/databaseLinks を呼び出す
ligand["smiles"] / inchikey / pubchemCid で KeyError基本のリガンドレコードにはフラグしか含まれない/ligands/{id}/structure と /ligands/{id}/databaseLinks を呼び出す
/interactions?targetId=... で約 28 万行が返されるフィルターが通知なく無視される/targets/{id}/interactions を使用する
?approved=true でリガンドリスト全体が返されるパラメーターが通知なく無視される?type=Approved(サーバーのエイリアス)を使用する
/families → HTTP 404パスが誤っている/targets/families を使用する
affinity で ValueError: could not convert string to floatフィールドは文字列で、範囲または修飾付きの値の場合があるpd.to_numeric(s, errors="coerce") を使用するか、範囲を手動で解析する
相互作用を ligandType="Approved" で絞り込むと結果が空になる相互作用に ligandType フィールドが存在しない代わりにリガンドレコードの approved フラグで絞り込む

関連スキル

  • chembl-database-bioactivity — 同じ標的クラスを対象とした、より大規模な生物活性データ(240 万種以上の化合物)
  • pubchem-compound-search — 化合物を中心としたケモインフォマティクス。/ligands/{id}/databaseLinks の PubChem CID を介して相互参照
  • dailymed-database — 市販医薬品の FDA 承認ラベルのテキスト(規制情報を補完)
  • uniprot-protein-database — GtoPdb が相互参照する UniProt アクセッションを解決

参考資料

コメント