gtopdb-database について
gtopdb-databaseは、Guide to Pharmacology REST APIで薬物標的、リガンド、相互作用を調べるスキルです。薬理学や創薬研究向けに、親和性、構造記述子、外部データベースへのリンクを取得できます。
主な機能
- 01遺伝子シンボルやアクセッションで標的検索
- 02標的とリガンドの相互作用検索
- 03リガンド構造記述子の取得
- 04リガンドの承認状況確認
- 05標的ファミリー階層の参照
活用シーン
- 01標的に対するリガンド親和性の確認
- 02受容体に注釈されたリガンドの一覧
- 03承認薬とデータベースリンクの検索
- 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 ファミリーのリスト |
ベストプラクティス
- 正規の検索には
geneSymbol=/accession=を使用し、name=は決して使用しないでください。あいまい検索のname=はすべてのフィールドを対象とするため、誤った標的が通知なく返されることがあります。 - ID 以外の情報はすべてサブリソースから取得してください。 基本の
/targets/{id}および/ligands/{id}レコードには、遺伝子シンボル、UniProt、SMILES、ChEMBL などが含まれていません。これらは/databaseLinks、/synonyms、/structureの下にあります。 - 相互作用の絞り込みには
/targets/{id}/interactionsまたは/ligands/{id}/interactionsを使用してください。フィルターが通知なく無視される/interactions?targetId=…は使用しないでください。 - 承認済み医薬品を取得するには、サーバーのエイリアス
type=Approvedを使用してください。クエリパラメーターapproved=trueは無視されます。 affinityは必ずerrors="coerce"を指定して数値に変換してください。このフィールドは文字列で、範囲、修飾付きの値、または欠損値の場合があります。- ファミリーのエンドポイントは
/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 アクセッションを解決
参考資料
- Guide to Pharmacology のホーム
- Web サービス API リファレンス
- 命名法とキュレーション
- Harding SD et al. 「The IUPHAR/BPS Guide to PHARMACOLOGY in 2024.」 Nucleic Acids Research 52(D1): D1438–D1449(2024). https://doi.org/10.1093/nar/gkad944