mcpField
I
interpro-database

interpro-database

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

interpro-database について

interpro-database は、EBI InterPro REST API を利用するスキルです。タンパク質ファミリー、ドメイン、保存部位を調べる研究者向けに、統合エントリー検索やタンパク質照合などを扱います。

主な機能

  1. 01キーワードまたはアクセッションで検索
  2. 02タンパク質のドメイン構成を取得
  3. 03エントリーに一致するタンパク質を一覧
  4. 04分類群の分布を確認
  5. 05関連する PDB 構造を取得
  6. 06ファミリー配列を FASTA で取得

活用シーン

  1. 01UniProt タンパク質のドメインを特定
  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 Database

概要

InterPro は、EBI が提供する、タンパク質ファミリー、ドメイン、機能部位を統合したデータベースです。13 のメンバーデータベース(Pfam、PANTHER、PIRSF、PRINTS、PROSITE、SMART、CDD、NCBIfam など)のシグネチャーを統合し、相同スーパーファミリー、ドメイン、ファミリー、リピート、保存部位をそれぞれ記述する InterPro エントリーを提供します。https://www.ebi.ac.uk/interpro/api/ の REST API は無料で、認証は不要です。

使用する場面

  • UniProt アクセッションから、タンパク質に含まれるすべてのドメインとファミリー(ドメイン構成)を特定する
  • 特定のドメインを含む、または特定のファミリーに属するタンパク質を検索する
  • 特定のドメインやファミリーをコードする生物の分類学的分布を調べる
  • ドメインを PDB の実験的な 3D 構造と相互参照する
  • InterPro エントリーをカバーするソースデータベース(Pfam、PANTHER、SMART など)を確認する
  • アクセッションがまだわからない場合に、キーワード(例:「kinase domain」)で InterPro エントリーを探す
  • タンパク質配列の取得、機能アノテーション(GO、パスウェイ、活性部位)、ID マッピングには uniprot-protein-database を使用する
  • ドメインにアラインメントされた配列のダウンロードや HMM プロファイルの作成には、InterPro ではなく 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 はエントリーを 5 種類に分類します。種類によって、マッチが示す生物学的な関係が決まります。

種類説明例
family共通の祖先と機能を持つ相同タンパク質のグループIPR000719(Protein kinase)
domain複数のタンパク質の文脈に現れる、独立した構造的・機能的単位IPR011009(Protein kinase-like SF)
homologous_superfamily配列が分岐している可能性のある、構造的に類似したドメインIPR011993(Pleckstrin-like)
repeatタンパク質内に複数回出現する、短い反復配列単位IPR001440(TPR repeat)
site活性部位、結合部位、翻訳後修飾部位などの短い保存モチーフIPR008271(Ser/Thr kinase active site)
メンバーデータベースの階層

各 InterPro エントリには、1 つ以上のメンバーデータベースのシグネチャが統合されています。InterPro アクセッション(IPR...)は統合されたメタエントリであり、メンバーデータベースのアクセッションは基盤となるモデルを示します。

メンバー DBアクセッションの接頭辞モデリング手法
PfamPF隠れマルコフモデル(プロファイル HMM)
PANTHERPTHR系統樹 + HMM
PIRSFPIRSF全長 HMM
PRINTSPRフィンガープリントモチーフ群
PROSITEPSパターンとプロファイル
SMARTSMデータベース統合を伴う HMM
CDDcd位置特異的スコア行列(PSSM)
NCBIfamNFNCBI がキュレーションした 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、siteInterPro のタイプでエントリを絞り込みます
page_sizeすべてのリストエンドポイント201–2001 ページあたりに返される結果数
entry_interprostructure/pdb/—IPR######関連する InterPro エントリで構造を絞り込みます
source_databaseprotein/—reviewed、uniprot、tremblUniProt のキュレーションレベルでタンパク質を絞り込みます
reviewed(URL パス)entry/{ipr}/{acc}/protein/uniprotreviewed、uniprotSwiss-Prot のレビュー済みエントリのみを対象にするか、すべての UniProtKB を対象にするかを指定します
relationsentry/interpro/{acc}/—contains、contained_by、child_of、parent_ofInterPro の階層をたどります
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. データベースをまたぐクエリでは、メンバー DB のアクセッションより InterPro アクセッションを優先する:Pfam PF00069 と PANTHER PTHR24340 はどちらもキナーゼドメインをモデル化していますが、対象となるタンパク質の範囲は異なります。親 InterPro の IPR000719 を使うと、すべてのメンバー DB のマッチを 1 回のクエリでまとめて取得できます。

  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
レシピ:ファミリー内の全タンパク質をソース DB のカバレッジとともに取得する

使用する場面:ドメインファミリー内のタンパク質が、各メンバーデータベース(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 404 が返されるInterPro でアクセッションが見つからない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 kinase)では、順序を逆にしても 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 との相互参照にも使えます

参考資料

コメント