interpro-database について
interpro-database は、EBI InterPro REST API を利用するスキルです。タンパク質ファミリー、ドメイン、保存部位を調べる研究者向けに、統合エントリー検索やタンパク質照合などを扱います。
主な機能
- 01キーワードまたはアクセッションで検索
- 02タンパク質のドメイン構成を取得
- 03エントリーに一致するタンパク質を一覧
- 04分類群の分布を確認
- 05関連する PDB 構造を取得
- 06ファミリー配列を FASTA で取得
活用シーン
- 01UniProt タンパク質のドメインを特定
- 02ファミリーに属するタンパク質を検索
- 03分類群間のドメイン分布を比較
- 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 | アクセッションの接頭辞 | モデリング手法 |
|---|---|---|
| Pfam | PF | 隠れマルコフモデル(プロファイル HMM) |
| PANTHER | PTHR | 系統樹 + HMM |
| PIRSF | PIRSF | 全長 HMM |
| PRINTS | PR | フィンガープリントモチーフ群 |
| PROSITE | PS | パターンとプロファイル |
| SMART | SM | データベース統合を伴う HMM |
| CDD | cd | 位置特異的スコア行列(PSSM) |
| NCBIfam | NF | 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")
主なパラメーター
| パラメーター | エンドポイント | デフォルト | 範囲 / 選択肢 | 効果 |
|---|---|---|---|---|
search | entry/interpro/ | — | 自由記述の文字列 | エントリ名と短縮名でキーワード検索します |
type | entry/interpro/ | すべてのタイプ | family、domain、homologous_superfamily、repeat、site | InterPro のタイプでエントリを絞り込みます |
page_size | すべてのリストエンドポイント | 20 | 1–200 | 1 ページあたりに返される結果数 |
entry_interpro | structure/pdb/ | — | IPR###### | 関連する InterPro エントリで構造を絞り込みます |
source_database | protein/ | — | reviewed、uniprot、trembl | UniProt のキュレーションレベルでタンパク質を絞り込みます |
reviewed(URL パス) | entry/{ipr}/{acc}/protein/ | uniprot | reviewed、uniprot | Swiss-Prot のレビュー済みエントリのみを対象にするか、すべての UniProtKB を対象にするかを指定します |
relations | entry/interpro/{acc}/ | — | contains、contained_by、child_of、parent_of | InterPro の階層をたどります |
next | すべてのリストエンドポイント | — | レスポンスに含まれる URL | カーソルベースのページネーションです。next フィールドの URL 全体を使用します |
ベストプラクティス
-
キュレーション済みのドメインリストには
reviewedタンパク質を使用する:未レビューの TrEMBL セットは 5~10 倍大きく、自動予測が含まれます。ベンチマーク、ファミリー解析、トレーニングセットでは、未レビューの予測によるノイズを避けるため、対象をreviewed(Swiss-Prot)エントリに限定してください。 -
大規模な分類群リストやタンパク質リストは分割する:プロテインキナーゼスーパーファミリーのような幅広いファミリーから 10,000 件を超えるタンパク質をすべて取得すると、数分かかり、ペイロードも大きくなることがあります。
page_size=200とnextカーソルを使ってクエリを制限し、中間結果をディスクに保存してください。 -
ページネーションの呼び出し間に
time.sleep(1.0)を追加する:InterPro API は共有 EBI インフラストラクチャ上で動作しており、公開されたレート制限はありません。バッチスクリプトでは、ページごとに 1 秒間待機するのが安全な最小値です。 -
データベースをまたぐクエリでは、メンバー DB のアクセッションより InterPro アクセッションを優先する:Pfam PF00069 と PANTHER PTHR24340 はどちらもキナーゼドメインをモデル化していますが、対象となるタンパク質の範囲は異なります。親 InterPro の
IPR000719を使うと、すべてのメンバー DB のマッチを 1 回のクエリでまとめて取得できます。 -
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 APIesm-protein-language-model— 配列からタンパク質言語モデルの埋め込みを生成します。InterPro でタンパク質ファミリーを特定した後に役立ちますpdb-database— PDB ID による実験的な 3D 構造の取得とダウンロードに使用します。InterPro の構造クエリで見つかった構造 ID との相互参照にも使えます
参考資料
- InterPro REST API ドキュメント — エンドポイント、フィルター、クエリ例のリファレンス
- Blum et al., Nucleic Acids Research 2021 — メンバーデータベースとの統合について説明した InterPro の主要論文
- InterPro ウェブポータル — タンパク質ドメインを対話的に閲覧できます
- Paysan-Lafosse et al., Nucleic Acids Research 2023 — 新しいエントリータイプとメンバーデータベースについて説明した InterPro の 2023 年更新論文