关于 alterlab-bindingdb
alterlab-bindingdb 是面向药物发现、药理学和计算化学研究的 BindingDB 数据查询与分析技能,可通过 REST API 或下载文件获取蛋白质与化合物的实测亲和力。它支持按 UniProt 靶点或 SMILES 查询,并提供 SAR、多靶点分析和机器学习数据准备方法。
主要功能
- 01通过 REST API 查询结合数据
- 02按 UniProt ID 搜索靶点配体
- 03按 SMILES 进行结构相似性搜索
- 04下载 TSV 进行批量分析
- 05分析 SAR 与多靶点结合
适用场景
- 01为蛋白靶点查找已知配体
- 02比较类似物的结合亲和力
- 03分析化合物的选择性与脱靶
- 04准备亲和力机器学习数据集
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ alterlab-ieu/ alterlab-academic-skills --skill alterlab-bindingdb安装后在 Claude Code 中输入/alterlab-bindingdb确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonreferences/affinity_queries.mdscripts/query_bindingdb.py详细介绍
BindingDB 数据库
概述
BindingDB(https://www.bindingdb.org/)是主要的公开药物-蛋白质结合亲和力实测数据库。它包含约 320 万条结合数据记录,涉及约 140 万种化合物对约 11,500 个蛋白质靶标的测试结果(主页数据,2026-09),数据整理自科学文献和专利文献。BindingDB 存储定量结合测量值(Ki、Kd、IC50、EC50),这些数据对药物发现、药理学和计算化学研究至关重要。
关键资源:
- BindingDB 网站:https://www.bindingdb.org/
- REST API 基础 URL:https://bindingdb.org/rest/(无需密钥;默认响应格式为 XML,附加
response=application/json) - 下载页面:https://www.bindingdb.org/rwd/bind/chemsearch/marvin/Download.jsp(完整 TSV 文件为带日期的
BindingDB_All_<YYYYMM>_tsv.zip,压缩后约 560 MB,每月更新)
何时使用此工具
在以下情况下使用 BindingDB:
- 基于靶标的药物发现:哪些已知化合物能与某个蛋白质靶标结合?它们的亲和力如何?
- SAR 分析:结构修饰会如何影响一系列类似物的结合亲和力?
- 先导化合物分析:某个化合物会与哪些靶标结合(选择性/多药理学)?
- 基准数据集:获取经过整理的蛋白质-配体亲和力数据,用于 ML 模型训练
- 药物再利用分析:已获批药物是否会与非预期靶标结合?
- 竞品分析:某类靶标报道的最佳亲和力是多少?
- 片段筛选:查找针对某个靶标的片段验证结合数据
不适用场景
| 场景 | 请改用 |
|---|---|
| 大规模整理生物活性数据、检测元数据、药物作用机制 | alterlab-chembl |
| 按名称或 CID 查询化合物标识符/属性、PubChem BioAssay | alterlab-pubchem |
| 可购买的类似物或可用于对接的 3D 化合物库 | alterlab-zinc-db |
| 将配体对接到受体结构中 | alterlab-diffdock |
核心功能
1. BindingDB REST API
基础 URL:https://bindingdb.org/rest
import requests
BASE_URL = "https://bindingdb.org/rest"
def bindingdb_query(method, params):
"""Query the BindingDB REST API."""
url = f"{BASE_URL}/{method}"
response = requests.get(url, params=params, headers={"Accept": "application/json"})
response.raise_for_status()
return response.json()
2. 按靶标查询(UniProt ID)
getLigandsByUniprot 端点接受一个 uniprot 参数,格式为
<UniProt accession>;<cutoff in nM>,例如 P00519;10000。
def get_ligands_for_target(uniprot_id, cutoff=10000):
"""
Get all ligands with measured affinity for a UniProt target.
Args:
uniprot_id: UniProt accession (e.g., "P00519" for ABL1)
cutoff: Maximum affinity value to return (in nM)
"""
params = {
"uniprot": f"{uniprot_id};{cutoff}",
"response": "application/json",
}
return bindingdb_query("getLigandsByUniprot", params)
# Example: Get all compounds binding ABL1 (imatinib target) at <=100 nM
ligands = get_ligands_for_target("P00519", cutoff=100)
# Response shape (verified 2026-09): one top-level key, spelled
# "getLindsByUniprotResponse" (sic — getTargetByCompound uses the same key),
# holding "bdb.hit" (count, as a string) and "bdb.affinities": a list of
# {"bdb.monomerid", "bdb.smile", "bdb.affinity_type", "bdb.affinity"}.
# Affinities are strings, may carry leading spaces or ">"/"<" qualifiers.
resp = next(iter(ligands.values()))
rows = resp.get("bdb.affinities", [])
3. 按 SMILES 查询(结构相似性)
def search_by_smiles(smiles, cutoff=0.85):
"""
Search BindingDB by SMILES string (structural-similarity search).
Args:
smiles: SMILES string of the compound
cutoff: Tanimoto similarity threshold (0.0-1.0; e.g. 0.85)
"""
params = {
"smiles": smiles,
"cutoff": cutoff,
"response": "application/json",
}
return bindingdb_query("getTargetByCompound", params)
# Example: structural-similarity search for imatinib's binding targets
result = search_by_smiles("Cc1ccc(NC(=O)c2ccc(CN3CCN(C)CC3)cc2)cc1Nc1nccc(-c2cccnc2)n1")
若要按 PubChem CID 查询,先通过 PubChem
PUG-REST 将 CID 转换为 SMILES 字符串,再将其传递给 search_by_smiles。BindingDB REST 没有按名称或 CID 查询的端点。
4. 基于下载的数据分析(大型查询推荐)
如需进行全面分析,可直接下载 BindingDB 数据:
import pandas as pd
def load_bindingdb(filepath="BindingDB_All.tsv"):
"""
Load BindingDB TSV file (the unzipped BindingDB_All_<YYYYMM>.tsv).
Download the dated BindingDB_All_<YYYYMM>_tsv.zip from:
https://www.bindingdb.org/rwd/bind/chemsearch/marvin/Download.jsp
"""
# Key columns
usecols = [
"BindingDB Reactant_set_id",
"Ligand SMILES",
"Ligand InChI",
"Ligand InChI Key",
"BindingDB Target Chain Sequence",
"PDB ID(s) for Ligand-Target Complex",
"UniProt (SwissProt) Entry Name of Target Chain",
"UniProt (SwissProt) Primary ID of Target Chain",
"UniProt (TrEMBL) Primary ID of Target Chain",
"Ki (nM)",
"IC50 (nM)",
"Kd (nM)",
"EC50 (nM)",
"kon (M-1-s-1)",
"koff (s-1)",
"Target Name",
"Target Source Organism According to Curator or DataSource",
"Number of Protein Chains in Target (>1 implies a multichain complex)",
"PubChem CID",
"PubChem SID",
"ChEMBL ID of Ligand",
"DrugBank ID of Ligand",
]
# Exact TSV headers drift between monthly releases (some contain double
# spaces), so intersect with the actual header rather than hard-failing.
header = pd.read_csv(filepath, sep="\t", nrows=0).columns
keep = [c for c in usecols if c in header]
df = pd.read_csv(filepath, sep="\t", usecols=keep,
low_memory=False, on_bad_lines='skip')
# Convert affinity columns to numeric
for col in ["Ki (nM)", "IC50 (nM)", "Kd (nM)", "EC50 (nM)"]:
if col in df.columns:
df[col] = pd.to_numeric(df[col], errors='coerce')
return df
def query_target_affinity(df, uniprot_id, affinity_types=None, max_nm=10000):
"""Query loaded BindingDB for a specific target."""
if affinity_types is None:
affinity_types = ["Ki (nM)", "IC50 (nM)", "Kd (nM)"]
# Filter by UniProt ID
mask = df["UniProt (SwissProt) Primary ID of Target Chain"] == uniprot_id
target_df = df[mask].copy()
# Filter by affinity cutoff
has_affinity = pd.Series(False, index=target_df.index)
for col in affinity_types:
if col in target_df.columns:
has_affinity |= target_df[col] <= max_nm
result = target_df[has_affinity][["Ligand SMILES"] + affinity_types +
["PubChem CID", "ChEMBL ID of Ligand"]].dropna(how='all')
return result.sort_values(affinity_types[0])
5. SAR 分析
import pandas as pd
def sar_analysis(df, target_uniprot, affinity_col="IC50 (nM)"):
"""
Structure-activity relationship analysis for a target.
Retrieves all compounds with affinity data and ranks by potency.
"""
target_data = query_target_affinity(df, target_uniprot, [affinity_col])
if target_data.empty:
return target_data
# Add pIC50 (negative log of IC50 in molar)
if affinity_col in target_data.columns:
target_data = target_data[target_data[affinity_col].notna()].copy()
target_data["pAffinity"] = -((target_data[affinity_col] * 1e-9).apply(
lambda x: __import__('math').log10(x)
))
target_data = target_data.sort_values("pAffinity", ascending=False)
return target_data
# Most potent compounds against EGFR (P00533)
# sar = sar_analysis(df, "P00533", "IC50 (nM)")
# print(sar.head(20))
6. 多药理学概况
def polypharmacology_profile(df, ligand_smiles, affinity_cutoff_nM=1000):
"""
Find all targets a compound binds to, by exact SMILES match.
For tolerance to tautomers/salts/charge states, match on the InChIKey
skeleton (first 14 chars of "Ligand InChI Key") instead of raw SMILES.
"""
# Search by ligand SMILES (exact string match)
mask = df["Ligand SMILES"] == ligand_smiles
ligand_data = df[mask].copy()
# Filter by affinity
aff_cols = ["Ki (nM)", "IC50 (nM)", "Kd (nM)"]
has_aff = pd.Series(False, index=ligand_data.index)
for col in aff_cols:
if col in ligand_data.columns:
has_aff |= ligand_data[col] <= affinity_cutoff_nM
result = ligand_data[has_aff][
["Target Name", "UniProt (SwissProt) Primary ID of Target Chain"] + aff_cols
].dropna(how='all')
# Rank by the tightest measured constant per row (NaNs ignored)
result = result.assign(best_nM=result[aff_cols].min(axis=1))
return result.sort_values("best_nM")
查询工作流
工作流 1:查找某个靶标的最佳抑制剂
import pandas as pd
def find_best_inhibitors(uniprot_id, affinity_type="IC50 (nM)", top_n=20):
"""Find the most potent inhibitors for a target in BindingDB."""
df = load_bindingdb("BindingDB_All.tsv") # Load once and reuse
result = query_target_affinity(df, uniprot_id, [affinity_type])
if result.empty:
print(f"No data found for {uniprot_id}")
return result
result = result.sort_values(affinity_type).head(top_n)
print(f"Top {top_n} inhibitors for {uniprot_id} by {affinity_type}:")
for _, row in result.iterrows():
print(f" {row['PubChem CID']}: {row[affinity_type]:.1f} nM | SMILES: {row['Ligand SMILES'][:40]}...")
return result
工作流 2:选择性分析
- 获取化合物针对所有靶标的亲和力数据
- 比较目标靶标与脱靶靶标之间的亲和力比值
- 找出选择性差异显著的情况(可提高选择性的结构变化)
- 交叉参照 ChEMBL,获取更多选择性数据
工作流 3:机器学习数据集准备
def prepare_ml_dataset(df, uniprot_ids, affinity_col="IC50 (nM)",
max_affinity_nM=100000, min_count=50):
"""Prepare BindingDB data for ML model training."""
records = []
for uid in uniprot_ids:
target_df = query_target_affinity(df, uid, [affinity_col], max_affinity_nM)
if len(target_df) >= min_count:
target_df = target_df.copy()
target_df["target"] = uid
records.append(target_df)
if not records:
return pd.DataFrame()
combined = pd.concat(records)
# Add pAffinity (normalized)
combined["pAffinity"] = -((combined[affinity_col] * 1e-9).apply(
lambda x: __import__('math').log10(max(x, 1e-12))
))
return combined[["Ligand SMILES", "target", "pAffinity", affinity_col]].dropna()
关键数据字段
| 字段 | 说明 |
|---|---|
Ligand SMILES | 化合物的 2D 结构 |
Ligand InChI Key | 唯一化学标识符 |
Ki (nM) | 抑制常数(平衡态,功能性) |
Kd (nM) | 解离常数(热力学,结合) |
IC50 (nM) | 半数最大抑制浓度 |
EC50 (nM) | 半数最大有效浓度 |
kon (M-1-s-1) | 结合速率常数 |
koff (s-1) | 解离速率常数 |
UniProt (SwissProt) Primary ID | 靶标 UniProt 登录号 |
Target Name | 蛋白质名称 |
PDB ID(s) for Ligand-Target Complex | 晶体结构 |
PubChem CID | PubChem 化合物 ID |
ChEMBL ID of Ligand | ChEMBL 化合物 ID |
亲和力解读
| 亲和力 | 分类 | 类药性 |
|---|---|---|
| < 1 nM | 亚纳摩尔级 | 活性极强(皮摩尔级) |
| 1–10 nM | 纳摩尔级 | 活性强,已获批药物的典型范围 |
| 10–100 nM | 中等 | 常见的先导化合物 |
| 100–1000 nM | 弱 | 片段/起始点 |
| > 1000 nM | 极弱 | 通常低于药物相关性阈值 |
最佳实践
- 直接结合时使用 Ki:Ki 反映真实结合亲和力,不受酶机制影响
- IC50 取决于具体条件:IC50 值取决于底物浓度(Cheng-Prusoff 方程)
- 留意限定符前缀:TSV 亲和力单元格通常带有
>、<或>=前缀(例如>10000),表示测量值受到删失。pd.to_numeric(errors='coerce')会将这些值静默转换为 NaN — 先去除前缀(例如df[col].astype(str).str.lstrip("<>= ")),并在建模前明确决定是保留、丢弃,还是将删失值视为不等式 - 统一单位:BindingDB 使用 nM 报告数据;跨研究比较时请核实单位
- 按目标生物筛选:使用
Target Source Organism确保数据来自人类蛋白质 - 处理缺失值:并非所有化合物都具备所有类型的测量数据
- 与 ChEMBL 交叉参考:ChEMBL 收录了更多经过整理的药物化学活性数据
其他资源
- BindingDB 网站:https://www.bindingdb.org/
- 数据下载:https://www.bindingdb.org/rwd/bind/chemsearch/marvin/Download.jsp
- REST API 文档:https://www.bindingdb.org/rwd/bind/BindingDBRESTfulAPI.jsp(REST 基础地址:https://bindingdb.org/rest)
- 引用文献:Liu T 等。《BindingDB in 2024: a FAIR knowledgebase of protein-small molecule binding data》。Nucleic Acids Research 2025;53(D1):D1633-D1644。doi:10.1093/nar/gkae1075(较早文献:Gilson MK 等,NAR 2016;44(D1):D1045-53,doi:10.1093/nar/gkv1072)
- 相关资源:ChEMBL(https://www.ebi.ac.uk/chembl/)、PubChem BioAssay
脚本
scripts/query_bindingdb.py — 可运行的 BindingDB REST API 辅助脚本(无需密钥):
python scripts/query_bindingdb.py uniprot P00519 --cutoff 10000
python scripts/query_bindingdb.py pdb 1Q0L,3ANM --cutoff 100 --identity 92
python scripts/query_bindingdb.py compound "<SMILES>" --cutoff 0.85