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确认已加载。

详细介绍

药理学指南(GtoPdb)数据库

概述

IUPHAR/BPS 药理学指南(GtoPdb)收录了受体药理学领域的药物靶点、配体及定量相互作用。其 Web 服务 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 靶点/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 会匹配 PLC β2 和 GABA_A β2,以及 β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. 始终使用 errors="coerce" 将 affinity 转换为数值——该字段是字符串,可能包含范围、限定词或缺失值。
  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 登录号

参考资料

评论

支持 Markdown