mcpField
I
interpro-database

interpro-database

github.com/jaechang-hits数据与数据库38468 次安装1 周前更新
代码仓库

关于 interpro-database

interpro-database 是用于查询 EBI InterPro REST API 的技能,面向分析蛋白质家族、结构域和保守位点的研究人员。它涵盖统一条目搜索、蛋白质匹配、分类分布和关联的 PDB 结构。

主要功能

  1. 01按关键词或登录号搜索条目
  2. 02获取蛋白质结构域架构
  3. 03列出匹配条目的蛋白质
  4. 04查看分类群分布
  5. 05获取关联的 PDB 结构
  6. 06以 FASTA 获取家族蛋白序列

适用场景

  1. 01识别 UniProt 蛋白质中的结构域
  2. 02查找属于某个家族的蛋白质
  3. 03比较不同分类群的结构域覆盖
  4. 04定位与条目关联的 PDB 结构

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/interpro-database确认已加载。

详细介绍

InterPro 数据库

概述

InterPro 是 EBI 的蛋白质家族、结构域和功能位点综合数据库。它将 13 个成员数据库(Pfam、PANTHER、PIRSF、PRINTS、PROSITE、SMART、CDD、NCBIfam 等)的特征整合为统一的 InterPro 条目,每个条目描述一个同源超家族、结构域、家族、重复序列或保守位点。REST API 地址为 https://www.ebi.ac.uk/interpro/api/,免费且无需身份验证。

适用场景

  • 根据 UniProt 登录号识别蛋白质中包含的所有结构域和家族(结构域架构)
  • 搜索包含特定结构域或属于特定家族的蛋白质
  • 查找编码给定结构域或家族的生物体的分类分布
  • 将结构域与 PDB 中的实验 3D 结构关联
  • 检查哪些源数据库(Pfam、PANTHER、SMART 等)涵盖某个 InterPro 条目
  • 通过关键词(例如“激酶结构域”)发现 InterPro 条目;适用于尚不知道登录号的情况
  • 如需获取蛋白质序列、功能注释(GO、通路、活性位点)和 ID 映射,请使用 uniprot-protein-database
  • 如需下载结构域比对序列或构建 HMM profile,请直接使用 Pfam;InterPro 是元数据库

前提条件

  • Python 软件包:requests、pandas、matplotlib
  • 数据要求:UniProt 登录号(例如 P04637)或 InterPro 登录号(例如 IPR011009)
  • 环境:需要互联网连接;无需 API 密钥
  • 速率限制:未公布硬性限制;批量查询时,请在请求之间使用 time.sleep(1.0);使用 ?cursor= 或 ?page_size= 分页
pip install requests pandas matplotlib

快速入门

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def interpro_get(path: str, params: dict = None) -> dict:
    """Send a GET request to the InterPro API and return parsed JSON."""
    r = requests.get(
        f"{INTERPRO_BASE}/{path}",
        params=params,
        headers={"Accept": "application/json"},
        timeout=30
    )
    r.raise_for_status()
    return r.json()

# Get domain architecture for TP53 (P04637)
# Note: `protein/uniprot/{acc}/` returns only {metadata}; the entries-per-protein
# data lives at `entry/interpro/protein/uniprot/{acc}/` and is keyed `results`.
data = interpro_get("entry/interpro/protein/uniprot/P04637/")
entries = data.get("results", [])
print(f"InterPro entries for TP53: {data.get('count')}  (this page: {len(entries)})")
for e in entries[:4]:
    m = e["metadata"]
    print(f"  {m['accession']}  {m['type']:<25}  {m['name']}")
# InterPro entries for TP53: 9
#   IPR002117  family                     p53 tumour suppressor family
#   IPR036674  homologous_superfamily     p53-like tetramerisation domain superfamily

核心 API

查询 1:搜索条目

按名称关键词搜索 InterPro 条目,或通过登录号获取特定条目。

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def search_entries(query: str, entry_type: str = None,
                   page_size: int = 20) -> list:
    """Search InterPro entries by keyword; optionally filter by type."""
    params = {"search": query, "page_size": page_size}
    if entry_type:
        params["type"] = entry_type   # family, domain, homologous_superfamily, repeat, site
    r = requests.get(
        f"{INTERPRO_BASE}/entry/interpro/",
        params=params,
        headers={"Accept": "application/json"},
        timeout=30
    )
    r.raise_for_status()
    return r.json().get("results", [])

hits = search_entries("serine kinase", entry_type="domain")
print(f"InterPro domain entries matching 'serine kinase': {len(hits)}")
for h in hits[:5]:
    m = h["metadata"]
    print(f"  {m['accession']}  {m['type']:<10}  {m['name']}")
# InterPro domain entries matching 'serine kinase': 8
#   IPR000719  domain    Protein kinase domain
#   IPR008271  domain    Serine/threonine/tyrosine kinase, active site
# Fetch a specific InterPro entry by accession
r = requests.get(
    f"{INTERPRO_BASE}/entry/interpro/IPR000719/",
    headers={"Accept": "application/json"},
    timeout=30
)
r.raise_for_status()
meta = r.json()["metadata"]
print(f"Accession    : {meta['accession']}")
print(f"Name         : {meta['name']}")
print(f"Type         : {meta['type']}")
print(f"Member DBs   : {list(meta.get('member_databases', {}).keys())}")
go_terms = meta.get("go_terms", [])
print(f"GO terms     : {[g['identifier'] for g in go_terms[:3]]}")
# Accession    : IPR000719
# Name         : Protein kinase domain
# Type         : domain
# Member DBs   : ['pfam', 'smart', 'cdd', 'ncbifam', 'panther']
# GO terms     : ['GO:0004672', 'GO:0005524', 'GO:0006468']
查询 2:蛋白质结构域架构

根据 UniProt 登录号,获取蛋白质中匹配到的所有 InterPro 条目(结构域、家族、位点)。

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_protein_domain_architecture(uniprot_acc: str) -> dict:
    """Return all InterPro entry matches for a protein. Uses the
    `entry/interpro/protein/uniprot/{acc}/` endpoint, which returns
    {count, next, previous, results}. Each result has metadata + a
    nested `proteins[0].entry_protein_locations` for the per-protein match."""
    r = requests.get(
        f"{INTERPRO_BASE}/entry/interpro/protein/uniprot/{uniprot_acc}/",
        headers={"Accept": "application/json"},
        timeout=60
    )
    r.raise_for_status()
    return r.json()

data = get_protein_domain_architecture("P04637")   # TP53
results = data.get("results", [])
# Pull length/source from the first match's nested protein record
prot0 = results[0]["proteins"][0] if results and results[0].get("proteins") else {}
print(f"Protein length : {prot0.get('protein_length')}")
print(f"Source DB      : {prot0.get('source_database')}")
print(f"InterPro entries: {data.get('count')}")
for entry in results[:6]:
    m = entry["metadata"]
    # Locations are nested under proteins[0].entry_protein_locations
    locs = entry["proteins"][0].get("entry_protein_locations", []) if entry.get("proteins") else []
    loc_str = ", ".join(
        f"{frag['start']}-{frag['end']}"
        for loc in locs for frag in loc.get("fragments", [])
    )
    print(f"  {m['accession']}  {m['type']:<25}  {m['name'][:35]:<35}  [{loc_str}]")
# Compare domain architectures of two proteins side-by-side
import pandas as pd

def domain_set(uniprot_acc: str) -> set:
    data = get_protein_domain_architecture(uniprot_acc)
    return {e["metadata"]["accession"] for e in data.get("results", [])}

brca1_domains = domain_set("P38398")   # BRCA1
tp53_domains   = domain_set("P04637")  # TP53

shared = brca1_domains & tp53_domains
unique_brca1 = brca1_domains - tp53_domains
unique_tp53  = tp53_domains - brca1_domains
print(f"Shared InterPro entries: {len(shared)}")
print(f"BRCA1-unique           : {len(unique_brca1)}")
print(f"TP53-unique            : {len(unique_tp53)}")
查询 3:条目对应的蛋白质

列出包含特定 InterPro 条目(家族或结构域)的蛋白质。

import requests, time

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_entry_proteins(interpro_acc: str, reviewed_only: bool = True,
                       page_size: int = 50) -> list:
    """Return proteins (UniProt) containing a given InterPro entry.
    Path order is `/protein/{db}/entry/interpro/{IPR}/` — the inverse
    `entry/interpro/{IPR}/protein/{db}/` times out (408) on large families."""
    db = "reviewed" if reviewed_only else "uniprot"
    r = requests.get(
        f"{INTERPRO_BASE}/protein/{db}/entry/interpro/{interpro_acc}/",
        params={"page_size": page_size},
        headers={"Accept": "application/json"},
        timeout=60
    )
    r.raise_for_status()
    return r.json().get("results", [])

proteins = get_entry_proteins("IPR011009")   # Protein kinase-like domain SF
print(f"Reviewed proteins with IPR011009 (page 1): {len(proteins)}")
for p in proteins[:4]:
    m = p["metadata"]
    # metadata fields: accession, gene, length, name, source_database, source_organism
    print(f"  {m['accession']}  {(m.get('gene') or ''):<8}  "
          f"len={m.get('length', '?')}  "
          f"org={(m.get('source_organism') or {}).get('scientificName', '')[:30]}")
# Paginate all proteins for a family using cursor
def get_all_entry_proteins(interpro_acc: str,
                            reviewed_only: bool = True) -> list:
    INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"
    db = "reviewed" if reviewed_only else "uniprot"
    # Path-inverted: /protein/{db}/entry/interpro/{IPR}/ is the working order
    url = f"{INTERPRO_BASE}/protein/{db}/entry/interpro/{interpro_acc}/"
    all_proteins = []
    params = {"page_size": 200}
    while url:
        r = requests.get(url, params=params,
                         headers={"Accept": "application/json"}, timeout=60)
        r.raise_for_status()
        data = r.json()
        all_proteins.extend(data.get("results", []))
        url = data.get("next")
        params = None   # next URL already has params encoded
        if url:
            time.sleep(1.0)
    return all_proteins

proteins = get_all_entry_proteins("IPR000719")   # Protein kinase domain
print(f"Total reviewed proteins with protein kinase domain: {len(proteins)}")
查询 4:条目分类

获取带有指定 InterPro 条目注释的蛋白质的分类分布。

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_entry_taxonomy(interpro_acc: str,
                        page_size: int = 50) -> list:
    """Return taxonomic summary for proteins in a given InterPro entry.
    Path-inverted: `/taxonomy/uniprot/entry/interpro/{IPR}/`. Each result
    has `metadata` (taxon: accession=taxId, name, parent, children, rank)
    and `entries[]` (representative protein-match locations for that taxon)."""
    r = requests.get(
        f"{INTERPRO_BASE}/taxonomy/uniprot/entry/interpro/{interpro_acc}/",
        params={"page_size": page_size},
        headers={"Accept": "application/json"},
        timeout=90
    )
    r.raise_for_status()
    return r.json().get("results", [])

# Use a smaller entry (p53 DBD); IPR000719 (kinase) has ~270k taxa and times out.
taxa = get_entry_taxonomy("IPR011615")
print(f"Top taxa for IPR011615 (p53 DNA-binding domain):")
for t in taxa[:8]:
    m = t["metadata"]
    print(f"  taxId={m['accession']:>10}  {m.get('name', ''):<30}  "
          f"rank={m.get('rank') or 'n/a'}")
查询 5:结构整合

获取与 InterPro 条目关联的 PDB 结构。

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_entry_structures(interpro_acc: str, page_size: int = 25) -> list:
    """Return PDB structures that include a match to a given InterPro entry.
    Path-inverted: `/structure/pdb/entry/interpro/{IPR}/`. The flat form with
    `?entry_interpro=...` is silently slow / 408s on this resource."""
    r = requests.get(
        f"{INTERPRO_BASE}/structure/pdb/entry/interpro/{interpro_acc}/",
        params={"page_size": page_size},
        headers={"Accept": "application/json"},
        timeout=60
    )
    r.raise_for_status()
    return r.json().get("results", [])

structures = get_entry_structures("IPR011009")   # Protein kinase-like SF
print(f"PDB structures linked to IPR011009 (page 1): {len(structures)}")
for s in structures[:5]:
    m = s["metadata"]
    print(f"  {m['accession'].upper()}  resolution={m.get('resolution', 'N/A')} Å  "
          f"experiment={m.get('experiment_type', 'N/A')}")
# PDB structures linked to IPR011009: ~8,000+
#   1A06  resolution=2.5 Å  experiment=x-ray
#   ...
查询 6:结构域序列获取

下载 InterPro 家族中蛋白质的 FASTA 序列,用于序列比对或系统发育分析。

import requests, time

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_family_fasta(interpro_acc: str,
                      reviewed_only: bool = True,
                      max_sequences: int = 100) -> str:
    """Retrieve FASTA sequences for proteins in an InterPro entry."""
    db = "reviewed" if reviewed_only else "uniprot"
    proteins = []
    # Path-inverted: protein-list-for-entry is /protein/{db}/entry/interpro/{IPR}/
    url = f"{INTERPRO_BASE}/protein/{db}/entry/interpro/{interpro_acc}/"
    params = {"page_size": min(max_sequences, 200)}
    while url and len(proteins) < max_sequences:
        r = requests.get(url, params=params,
                         headers={"Accept": "application/json"}, timeout=60)
        r.raise_for_status()
        data = r.json()
        proteins.extend(data.get("results", []))
        url = data.get("next") if len(proteins) < max_sequences else None
        params = None
        if url:
            time.sleep(1.0)

    # Fetch FASTA from UniProt for each accession
    accessions = [p["metadata"]["accession"] for p in proteins[:max_sequences]]
    fasta_url = "https://rest.uniprot.org/uniprotkb/stream"
    query = " OR ".join(f"accession:{acc}" for acc in accessions)
    r = requests.get(fasta_url,
                     params={"query": query, "format": "fasta"},
                     timeout=120)
    r.raise_for_status()
    return r.text

fasta = get_family_fasta("IPR000719", reviewed_only=True, max_sequences=20)
seq_count = fasta.count(">")
print(f"FASTA sequences retrieved: {seq_count}")
print(fasta[:300])   # preview first sequence header + start

核心概念

InterPro 条目类型

InterPro 将条目分为五种类型。类型决定了匹配结果所代表的生物学关系:

类型说明示例
family具有共同祖先和功能的同源蛋白质群组IPR000719(蛋白激酶)
domain可出现在多种蛋白质背景中的独立结构和功能单元IPR011009(蛋白激酶样超家族)
homologous_superfamily结构相似、但序列可能已发生分化的结构域IPR011993(Pleckstrin 样)
repeat在蛋白质中多次出现的短重复序列单元IPR001440(TPR 重复序列)
site短保守基序:活性位点、结合位点或翻译后修饰位点IPR008271(丝氨酸/苏氨酸激酶活性位点)
成员数据库层级结构

每个 InterPro 条目都会整合一个或多个成员数据库的特征模型。InterPro 登录号(IPR...)是统一的元条目;成员数据库登录号则指向底层模型:

成员数据库登录号前缀建模方法
PfamPF隐马尔可夫模型(profile HMM)
PANTHERPTHR系统发育树 + HMM
PIRSFPIRSF全长 HMM
PRINTSPR指纹基序组
PROSITEPS模式和 profile
SMARTSM与数据库集成的 HMM
CDDcd位置特异性评分矩阵(PSSM)
NCBIfamNF由 NCBI 整理的 HMM
分页

InterPro API 在集合级别对结果分页。每个响应都包含一个 next URL(结果用尽时为 null)和一个 count 字段。对于大型家族(例如激酶:10,000+ 个蛋白质),请务必使用 next 游标逐页获取。

import requests, time

def iterate_interpro(url: str, page_size: int = 200) -> list:
    """Generic paginator for any InterPro list endpoint."""
    results = []
    params = {"page_size": page_size}
    while url:
        r = requests.get(url, params=params,
                         headers={"Accept": "application/json"}, timeout=60)
        r.raise_for_status()
        data = r.json()
        results.extend(data.get("results", []))
        url = data.get("next")
        params = None
        if url:
            time.sleep(1.0)
    return results

常见工作流

工作流 1:蛋白质集的结构域架构报告

目标:获取一组蛋白质的所有 InterPro 结构域,并生成汇总表,展示每个蛋白质包含哪些结构域。

import requests, time, pandas as pd

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_domains(uniprot_acc: str) -> list:
    """List InterPro entries for a protein. Uses the
    `entry/interpro/protein/uniprot/{acc}/` endpoint (keyed `results`)."""
    r = requests.get(
        f"{INTERPRO_BASE}/entry/interpro/protein/uniprot/{uniprot_acc}/",
        headers={"Accept": "application/json"}, timeout=60
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    data = r.json()
    return [
        {
            "protein": uniprot_acc,
            "accession": e["metadata"]["accession"],
            "name": e["metadata"]["name"],
            "type": e["metadata"]["type"],
            "source_db": list(e["metadata"].get("member_databases", {}).keys()),
        }
        for e in data.get("results", [])
    ]

proteins = ["P04637", "P38398", "Q00987", "P10415"]  # TP53, BRCA1, MDM2, BCL2
rows = []
for acc in proteins:
    rows.extend(get_domains(acc))
    time.sleep(1.0)

df = pd.DataFrame(rows)
print(f"Total domain matches: {len(df)}")
print(df.groupby(["protein", "type"])["accession"].count().unstack(fill_value=0))

# Pivot: proteins × domain accessions
pivot = df[df["type"] == "domain"].pivot_table(
    index="protein", columns="accession", aggfunc="size", fill_value=0
)
pivot.to_csv("domain_architecture_matrix.csv")
print(f"\nDomain × protein matrix: {pivot.shape}")
工作流 2:查找具有 PDB 结构的激酶家族成员

目标:获取激酶结构域家族中具有 PDB 实验结构的蛋白质,并按分辨率排序。

import requests, time, pandas as pd

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

# Step 1: Get PDB structures linked to the protein kinase-like SF entry.
# Use the path-inverted form; the flat `?entry_interpro=` filter 408s.
r = requests.get(
    f"{INTERPRO_BASE}/structure/pdb/entry/interpro/IPR011009/",
    params={"page_size": 200},
    headers={"Accept": "application/json"}, timeout=60
)
r.raise_for_status()
structures = r.json().get("results", [])
print(f"PDB structures with IPR011009 (kinase-like SF, page 1): {len(structures)}")

rows = []
for s in structures:
    m = s["metadata"]
    rows.append({
        "pdb_id": m["accession"],
        "resolution": m.get("resolution"),
        "experiment": m.get("experiment_type", ""),
        "name": m.get("name", ""),
    })

df = pd.DataFrame(rows)
df = df.dropna(subset=["resolution"]).sort_values("resolution")
print(f"\nTop 10 highest-resolution kinase structures:")
print(df[["pdb_id", "resolution", "experiment", "name"]].head(10).to_string(index=False))
df.to_csv("kinase_structures.csv", index=False)
print(f"\nSaved kinase_structures.csv ({len(df)} X-ray / cryo-EM structures)")
工作流 3:结构域的分类学覆盖率柱状图

目标:可视化各主要界中携带指定 InterPro 结构域的已审校蛋白质数量。

import requests, time
import pandas as pd
import matplotlib.pyplot as plt

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_taxonomy_counts(interpro_acc: str, page_size: int = 100,
                        max_pages: int = 5) -> pd.DataFrame:
    """Walk the taxonomy results for an InterPro entry. The API does not
    expose a per-taxon protein count at this endpoint — instead each
    paged record is one (taxon × representative protein-match) row.
    Aggregate client-side by taxon name to approximate frequency."""
    rows, url = [], f"{INTERPRO_BASE}/taxonomy/uniprot/entry/interpro/{interpro_acc}/"
    params = {"page_size": page_size}
    for _ in range(max_pages):
        if not url:
            break
        r = requests.get(url, params=params,
                         headers={"Accept": "application/json"}, timeout=90)
        r.raise_for_status()
        data = r.json()
        for t in data.get("results", []):
            m = t["metadata"]
            rows.append({
                "taxon_id": m["accession"],
                "name": m.get("name", ""),
                "rank": m.get("rank") or "",
            })
        url = data.get("next")
        params = None
        if url:
            time.sleep(1.0)
    return pd.DataFrame(rows)

IPR_ACC = "IPR011615"   # p53 DNA-binding domain (smaller; kinase 408s)
df = get_taxonomy_counts(IPR_ACC, max_pages=3)
print(f"Tax entries pulled for {IPR_ACC}: {len(df)}")

# Aggregate by name and take top 15 (each row = one rep. protein-match)
top = (df.groupby("name").size().sort_values(ascending=False).head(15)
       .reset_index(name="rep_matches"))
fig, ax = plt.subplots(figsize=(10, 5))
bars = ax.barh(top["name"], top["rep_matches"], color="#2171B5")
ax.bar_label(bars, fmt="%d", padding=3, fontsize=8)
ax.set_xlabel("Representative protein-matches")
ax.set_title(f"Taxonomic distribution of {IPR_ACC} (p53 DNA-binding domain)")
ax.invert_yaxis()
plt.tight_layout()
plt.savefig(f"{IPR_ACC}_taxonomy.png", dpi=150, bbox_inches="tight")
print(f"Saved {IPR_ACC}_taxonomy.png")

关键参数

参数端点默认值范围 / 选项作用
searchentry/interpro/—任意文本字符串按条目名称和简称筛选关键词
typeentry/interpro/所有类型family、domain、homologous_superfamily、repeat、site按 InterPro 类型筛选条目
page_size所有列表端点201–200每页返回的结果数
entry_interprostructure/pdb/—IPR######按关联的 InterPro 条目筛选结构
source_databaseprotein/—reviewed、uniprot、trembl按 UniProt 审校级别筛选蛋白质
reviewed(URL 路径)entry/{ipr}/{acc}/protein/uniprotreviewed、uniprot仅限 Swiss-Prot 已审校条目,或所有 UniProtKB 条目
relationsentry/interpro/{acc}/—contains、contained_by、child_of、parent_of浏览 InterPro 层级结构
next所有列表端点—响应中的 URL基于游标分页;使用 next 字段中的完整 URL

最佳实践

  1. 整理结构域列表时使用 reviewed 蛋白质:未经审校的 TrEMBL 数据集规模大 5–10 倍,并包含自动预测结果。对于基准测试、家族分析或训练集,请限制为 reviewed(Swiss-Prot)条目,以避免未经审校预测带来的噪声。

  2. 将大型分类群或蛋白质列表分块处理:获取蛋白激酶超家族等广泛家族的所有 10,000+ 个蛋白质可能耗时数分钟,并生成很大的响应数据。使用 page_size=200 和 next 游标限制查询;将中间结果保存到磁盘。

  3. 分页请求之间添加 time.sleep(1.0):InterPro API 使用 EBI 共享基础设施,未公布速率限制。批处理脚本中每页暂停 1 秒是安全的最低间隔。

  4. 跨数据库查询时优先使用 InterPro 登录号,而非成员数据库登录号:Pfam PF00069 和 PANTHER PTHR24340 都对激酶结构域建模,但覆盖的蛋白质不同。使用上级 InterPro IPR000719,即可通过一次查询获得所有成员数据库匹配结果的并集。

  5. 解读 entry_protein_locations 前检查 type:只有 domain、repeat 和 site 条目包含有意义的位置信息。family 和 homologous_superfamily 条目通常覆盖整个蛋白质,其坐标参考价值较低。

常用操作

配方:快速检查蛋白质的结构域

适用场景:给定一个 UniProt 登录号,快速列出它包含的 InterPro 结构域。

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def list_protein_domains(uniprot_acc: str) -> list:
    """Return list of (accession, type, name) tuples for a protein."""
    r = requests.get(
        f"{INTERPRO_BASE}/entry/interpro/protein/uniprot/{uniprot_acc}/",
        headers={"Accept": "application/json"}, timeout=60
    )
    r.raise_for_status()
    return [
        (e["metadata"]["accession"], e["metadata"]["type"], e["metadata"]["name"])
        for e in r.json().get("results", [])
    ]

domains = list_protein_domains("P00533")   # EGFR
print(f"InterPro entries in EGFR (P00533): {len(domains)}")
for acc, etype, name in domains:
    print(f"  {acc}  {etype:<25}  {name}")
# InterPro entries in EGFR (P00533): 10
#   IPR009030  homologous_superfamily   Growth factor receptor, cysteine-rich
#   IPR000719  domain                   Protein kinase domain
配方:查找家族中所有蛋白质及其来源数据库覆盖情况

适用场景:了解每个成员数据库(Pfam、PANTHER、SMART 等)覆盖了某个结构域家族中的多少蛋白质。

import requests, time
import pandas as pd

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

interpro_acc = "IPR000719"   # Protein kinase domain
r = requests.get(
    f"{INTERPRO_BASE}/entry/interpro/{interpro_acc}/",
    headers={"Accept": "application/json"}, timeout=30
)
r.raise_for_status()
member_dbs = r.json()["metadata"].get("member_databases", {})
print(f"Member databases for {interpro_acc}:")
for db, details in member_dbs.items():
    print(f"  {db}: {details}")

# Visualize member database source breakdown
labels = list(member_dbs.keys())
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(7, 4))
ax.bar(labels, [1] * len(labels), color="#4472C4")   # presence/absence per DB
ax.set_ylabel("Integrated (1=yes)")
ax.set_title(f"Member databases in {interpro_acc}")
plt.tight_layout()
plt.savefig(f"{interpro_acc}_member_dbs.png", dpi=150, bbox_inches="tight")
配方:获取 InterPro 条目的 GO 术语

适用场景:从结构域关联到 GO 功能注释。

import requests

INTERPRO_BASE = "https://www.ebi.ac.uk/interpro/api"

def get_go_terms_for_entry(interpro_acc: str) -> list:
    """Return GO terms associated with an InterPro entry."""
    r = requests.get(
        f"{INTERPRO_BASE}/entry/interpro/{interpro_acc}/",
        headers={"Accept": "application/json"}, timeout=30
    )
    r.raise_for_status()
    go_terms = r.json()["metadata"].get("go_terms", [])
    return [
        {"id": g["identifier"], "name": g["name"],
         "category": g.get("category", {}).get("name", "")}
        for g in go_terms
    ]

go_terms = get_go_terms_for_entry("IPR000719")
print(f"GO terms for IPR000719 (protein kinase domain): {len(go_terms)}")
for g in go_terms:
    print(f"  {g['id']}  [{g['category'][:2].upper()}]  {g['name']}")
# GO terms for IPR000719 (protein kinase domain): 3
#   GO:0004672  [MO]  protein kinase activity
#   GO:0005524  [MO]  ATP binding
#   GO:0006468  [BI]  protein phosphorylation

故障排除

问题原因解决方案
蛋白质查询返回 HTTP 404InterPro 中找不到该登录号确认该 UniProt 登录号存在;同工型登录号(P12345-2)可能不会单独编入索引
蛋白质的条目列表为空该蛋白质没有 InterPro 匹配项(例如,内在无序蛋白)直接检查 UniProt;并非所有蛋白质都有分类结构域
protein/uniprot/{acc}/ 仅返回 metadata(没有条目)该端点仅返回 蛋白质 信息;条目匹配项位于其他位置使用 entry/interpro/protein/uniprot/{acc}/ 并读取 results[] 键
entry/interpro/{IPR}/protein/{db}/ 返回 408 / 挂起以 entry/... 开头的路径会先执行较慢的联接操作调换路径顺序:protein/{db}/entry/interpro/{IPR}/
structure/pdb/?entry_interpro={IPR} 超时(408)同样是联接顺序问题使用 structure/pdb/entry/interpro/{IPR}/
大型家族的 entry/interpro/{IPR}/taxonomy/uniprot/ 返回 408同上使用 taxonomy/uniprot/entry/interpro/{IPR}/;对于非常大的条目(例如 IPR000719 激酶),调换顺序后仍可能返回 408——请改用更具体的子家族条目
条目搜索返回 HTTP 400查询参数无效或不支持该 type 值使用以下值之一:family、domain、homologous_superfamily、repeat、site
分页提前停止在达到预期数量之前,next 已为 null这是正常情况;所有结果均已返回
大型家族响应非常慢蛋白质集合包含数千个成员将 page_size 增至 200;每获取一页后就保存结果
出现 ConnectionError 或 Timeout网络或服务暂时出现问题使用指数退避策略重试;EBI 服务偶尔会短暂不可用
缺少成员数据库登录号条目较新,成员数据库集成尚未完成查询时使用 InterPro 登录号;成员数据库级别的详细信息会随每次发布更新

相关技能

  • uniprot-protein-database — 用于获取蛋白质序列、Swiss-Prot 功能注释(活性位点、PTM、疾病关联)以及进行 ID 映射的 UniProt REST API
  • esm-protein-language-model — 为序列生成蛋白质语言模型嵌入;确定蛋白质所属的 InterPro 家族后,此工具很有用
  • pdb-database — 按 PDB ID 获取并下载实验测定的 3D 结构;可与通过 InterPro 结构查询发现的结构 ID 交叉参照

参考资料

评论

支持 Markdown