uniprot-protein-database について
このスキルは、バイオインフォマティクス研究者向けに、UniProt REST APIを使ったタンパク質データへのプログラムアクセスを解説します。検索、配列や注釈の取得、IDマッピング、バッチ取得やストリーミングを扱います。
主な機能
- 01構造化クエリによるタンパク質検索
- 02配列とタンパク質レコードの取得
- 03データベース間のIDマッピング
- 04注釈の取得とフィールド選択
- 05バッチ取得とストリーミング
- 06大規模検索結果のページ分割
活用シーン
- 01遺伝子名や生物種でタンパク質を検索
- 02解析用FASTA配列のダウンロード
- 03UniProt IDをPDB IDに変換
- 04遺伝子セットのGO注釈を収集
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill uniprot-protein-databaseインストール後、Claude Code で/uniprot-protein-databaseを入力して読み込まれたか確認します。
詳細
UniProt — タンパク質データベース
概要
UniProt は、2億5,000万件を超えるエントリーを含む、最も包括的なタンパク質配列および機能アノテーションのデータベースです。このスキルでは、タンパク質の検索、配列の取得、ID マッピング、アノテーションの照会に UniProt REST API をプログラムから利用する方法を説明します。Swiss-Prot のエントリーは手作業でキュレーションされ、TrEMBL のエントリーは計算によって予測されます。
使用する場面
- 遺伝子名、アクセッション番号、生物種、または機能キーワードでタンパク質を検索する場合
- 下流解析用にタンパク質配列を FASTA 形式で取得する場合
- データベース間で識別子をマッピングする場合(UniProt ↔ Ensembl、PDB、RefSeq、KEGG)
- タンパク質アノテーションにアクセスする場合:GO 用語、ドメイン、翻訳後修飾
- 比較解析のために複数のタンパク質エントリーを一括取得する場合
- 特定の生物種のレビュー済み(Swiss-Prot)タンパク質データセットをダウンロードする場合
- 40 以上のデータベースへの統合アクセスには、代わりに bioservices を使用してください
- タンパク質の 3D 構造には、alphafold-database-access または pdb-database を使用してください
前提条件
pip install requests pandas
API のレート制限:UniProt REST API には厳密なレート制限はありませんが、一括リクエストの間に time.sleep(0.5) を追加することが推奨されています。大規模なクエリ(10,000 件超)には、ページネーション付き検索ではなくストリーミングエンドポイントを使用してください。ID マッピングジョブあたりの ID 数は最大 100,000 件です。
クイックスタート
import requests
# Search for human insulin proteins (reviewed/Swiss-Prot only)
url = "https://rest.uniprot.org/uniprotkb/search"
params = {"query": "insulin AND organism_id:9606 AND reviewed:true", "format": "tsv",
"fields": "accession,gene_names,protein_name,length"}
response = requests.get(url, params=params)
print(response.text[:500])
# accession gene_names protein_name length
# P01308 INS Insulin 110
コア API
1. タンパク質検索
ブール演算子とフィールド固有のフィルターを組み合わせた構造化クエリで UniProt を検索します。
import requests
import time
BASE = "https://rest.uniprot.org/uniprotkb/search"
def search_uniprot(query, fields=None, format="json", size=25):
"""Search UniProt with query syntax."""
params = {"query": query, "format": format, "size": size}
if fields:
params["fields"] = ",".join(fields)
resp = requests.get(BASE, params=params)
resp.raise_for_status()
return resp.json() if format == "json" else resp.text
# Search by gene name
results = search_uniprot("gene:BRCA1 AND reviewed:true",
fields=["accession", "gene_names", "organism_name", "length"])
for entry in results["results"][:3]:
print(f"{entry['primaryAccession']} | {entry.get('genes', [{}])[0].get('geneName', {}).get('value', 'N/A')} | {entry.get('organism', {}).get('scientificName', 'N/A')}")
クエリ構文のリファレンス:
# Boolean operators
kinase AND organism_id:9606 # Human kinases
(diabetes OR insulin) AND reviewed:true
cancer NOT lung
# Field-specific
gene:BRCA1
accession:P12345
taxonomy_name:"Homo sapiens"
go:0005515 # GO term: protein binding
# Range queries
length:[100 TO 500]
mass:[50000 TO 100000]
# Wildcards
gene:BRCA*
2. タンパク質エントリーの取得
アクセッション番号で個々のタンパク質エントリーを取得します。
import requests
def get_protein(accession, format="json"):
"""Retrieve a single protein entry."""
url = f"https://rest.uniprot.org/uniprotkb/{accession}"
resp = requests.get(url, headers={"Accept": f"application/{format}"})
resp.raise_for_status()
return resp.json() if format == "json" else resp.text
# Get human insulin
entry = get_protein("P01308")
print(f"Protein: {entry['proteinDescription']['recommendedName']['fullName']['value']}")
print(f"Gene: {entry['genes'][0]['geneName']['value']}")
print(f"Length: {entry['sequence']['length']} aa")
print(f"Sequence: {entry['sequence']['value'][:50]}...")
# Get FASTA directly
fasta = requests.get("https://rest.uniprot.org/uniprotkb/P01308.fasta").text
print(fasta[:200])
3. ID マッピング
UniProt と他のデータベース間で識別子をマッピングします。
import requests
import time
def map_ids(ids, from_db, to_db):
"""Map identifiers between databases (async job)."""
# Submit job
resp = requests.post("https://rest.uniprot.org/idmapping/run",
data={"from": from_db, "to": to_db, "ids": ",".join(ids)})
resp.raise_for_status()
job_id = resp.json()["jobId"]
# Poll for completion
while True:
status = requests.get(f"https://rest.uniprot.org/idmapping/status/{job_id}").json()
if "results" in status or "failedIds" in status:
break
time.sleep(1)
# Get results
results = requests.get(f"https://rest.uniprot.org/idmapping/results/{job_id}").json()
return results
# UniProt → PDB mapping
results = map_ids(["P01308", "P12345"], from_db="UniProtKB_AC-ID", to_db="PDB")
for r in results.get("results", []):
print(f"{r['from']} → PDB: {r['to']}")
# UniProt → Ensembl mapping
results = map_ids(["P01308"], from_db="UniProtKB_AC-ID", to_db="Ensembl")
for r in results.get("results", []):
print(f"{r['from']} → Ensembl: {r['to']}")
一般的なデータベースコード:UniProtKB_AC-ID、Ensembl、RefSeq_Protein、PDB、Gene_Name、GeneID、KEGG
4. 一括取得とストリーミング
大規模なデータセットを効率的に取得します。
import requests
import time
def batch_retrieve(accessions, fields=None, format="tsv"):
"""Retrieve multiple proteins by accession."""
query = " OR ".join(f"accession:{acc}" for acc in accessions)
params = {"query": query, "format": format}
if fields:
params["fields"] = ",".join(fields)
resp = requests.get("https://rest.uniprot.org/uniprotkb/search", params=params)
resp.raise_for_status()
return resp.text
# Batch retrieve
accessions = ["P01308", "P12345", "Q9Y6K9"]
tsv = batch_retrieve(accessions, fields=["accession", "gene_names", "protein_name", "length"])
print(tsv)
# Streaming for large queries (no pagination needed)
def stream_query(query, format="fasta"):
"""Stream large result sets."""
url = f"https://rest.uniprot.org/uniprotkb/stream?query={query}&format={format}"
resp = requests.get(url, stream=True)
resp.raise_for_status()
for chunk in resp.iter_content(chunk_size=8192, decode_unicode=True):
yield chunk
# Stream all human kinases as FASTA
# for chunk in stream_query("kinase AND organism_id:9606 AND reviewed:true"):
# print(chunk[:200])
5. ページネーションとカーソルベースの反復処理
Link ヘッダーのカーソルを使ったページネーションで、大規模な結果セットを処理します。
import requests
def paginate_search(query, fields=None, page_size=500):
"""Iterate all pages of a UniProt search using cursor pagination."""
params = {"query": query, "format": "tsv", "size": page_size}
if fields:
params["fields"] = ",".join(fields)
url = "https://rest.uniprot.org/uniprotkb/search"
rows = []
header = None
while url:
resp = requests.get(url, params=params)
resp.raise_for_status()
params = {} # cursor is embedded in the next URL
lines = resp.text.strip().split("\n")
if header is None:
header = lines[0]
rows.extend(lines[1:])
# Follow Link header for next page
link = resp.headers.get("Link", "")
url = link.split("<")[1].split(">")[0] if "<" in link else None
return header, rows
header, rows = paginate_search(
"kinase AND organism_id:9606 AND reviewed:true",
fields=["accession", "gene_names", "length"]
)
print(f"Retrieved {len(rows)} proteins")
print(header)
print("\n".join(rows[:3]))
6. フィールド選択とアノテーション
取得するデータフィールドをカスタマイズします。
import requests
import pandas as pd
from io import StringIO
# Retrieve specific annotation fields
params = {
"query": "gene:TP53 AND organism_id:9606 AND reviewed:true",
"format": "tsv",
"fields": "accession,gene_names,protein_name,go_p,go_f,go_c,cc_function,ft_domain",
}
resp = requests.get("https://rest.uniprot.org/uniprotkb/search", params=params)
df = pd.read_csv(StringIO(resp.text), sep="\t")
print(df.columns.tolist())
print(df.iloc[0])
一般的なフィールドグループ:
- 配列:
accession、sequence、length、mass - 名称:
gene_names、protein_name、organism_name - GO:
go_p(プロセス)、go_f(機能)、go_c(コンポーネント) - 特徴:
ft_domain、ft_binding、ft_act_site、ft_mod_res - コメント:
cc_function、cc_interaction、cc_subcellular_location
主なパラメーター
| パラメーター | 機能/エンドポイント | デフォルト | 範囲/オプション | 効果 |
|---|---|---|---|---|
query | /search、/stream | — | UniProt クエリ構文 | 条件に基づいてタンパク質を絞り込みます |
format | すべてのエンドポイント | json | json、tsv、fasta、xml、gff | 出力形式 |
fields | /search | すべて | カンマ区切りのフィールド名 | レスポンスサイズを削減します |
size | /search | 25 | 1–500 | 1 ページあたりの結果数 |
from / to | /idmapping/run | — | データベースコード | ID マッピングの方向 |
reviewed:true | クエリフィルター | — | true/false | Swiss-Prot(キュレーション済み)のみ |
organism_id | クエリフィルター | — | NCBI 分類 ID | 生物種で絞り込みます |
ベストプラクティス
-
厳選データには
reviewed:trueでフィルタリングする:Swiss-Prot のエントリは手動でレビューされていますが、TrEMBL のエントリは計算による予測です。信頼性の高いアノテーションには Swiss-Prot を使用してください。 -
表形式の分析には
fieldsを指定して TSV 形式を使用する:必要なフィールドのみを TSV 形式でリクエストすると、エントリ全体を JSON 形式で取得するより高速で、解析も容易です。 -
大規模なダウンロードにはストリーミングを使用する:
/streamエンドポイントはページネーションなしですべての結果を返すため、複数ページを反復処理する必要がありません。 -
バッチリクエストの間に
time.sleep(0.5)を追加する:特に連続して多くのリクエストを行う場合は、API のリソースに配慮してください。 -
頻繁にアクセスするエントリはローカルにキャッシュする:UniProt は毎月更新されるため、結果をキャッシュし、必要な場合にのみ再取得してください。
-
アンチパターン —
organism_idを指定せずにクエリする:gene:INSのような広範なクエリでは、全種にわたって数千件のエントリが返されます。対象を絞った結果を得るには、必ず生物種でフィルタリングしてください。
よく使うレシピ
レシピ:ヒトの全キナーゼを DataFrame としてダウンロードする
import requests
import pandas as pd
from io import StringIO
url = "https://rest.uniprot.org/uniprotkb/stream"
params = {
"query": "ec:2.7.* AND organism_id:9606 AND reviewed:true",
"format": "tsv",
"fields": "accession,gene_names,protein_name,length,go_f",
}
resp = requests.get(url, params=params)
df = pd.read_csv(StringIO(resp.text), sep="\t")
print(f"Human kinases (Swiss-Prot): {len(df)}")
print(df.head())
レシピ:遺伝子セットの GO アノテーションを抽出する
import requests
import pandas as pd
from io import StringIO
gene_list = ["BRCA1", "BRCA2", "TP53", "ATM", "CHEK2"]
query = " OR ".join(f"gene:{g}" for g in gene_list)
query += " AND organism_id:9606 AND reviewed:true"
params = {
"query": query,
"format": "tsv",
"fields": "accession,gene_names,go_p,go_f,go_c",
}
resp = requests.get("https://rest.uniprot.org/uniprotkb/search", params=params)
df = pd.read_csv(StringIO(resp.text), sep="\t")
print(df[["Accession", "Gene Names", "Gene Ontology (biological process)"]].head())
レシピ:UniProt を PDB 構造に相互参照する
import requests
import time
accessions = ["P53_HUMAN", "P01308", "P00533"] # TP53, Insulin, EGFR
resp = requests.post("https://rest.uniprot.org/idmapping/run",
data={"from": "UniProtKB_AC-ID", "to": "PDB", "ids": ",".join(accessions)})
job_id = resp.json()["jobId"]
time.sleep(2)
results = requests.get(f"https://rest.uniprot.org/idmapping/results/{job_id}").json()
for r in results.get("results", []):
print(f"{r['from']} → PDB: {r['to']}")
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
400 Bad Request | クエリ構文が無効 | ブール演算子、フィールド名、括弧の対応を確認してください。UniProt のクエリ構文ドキュメントを参照してください |
| 結果が多すぎる(遅い) | 生物種またはレビューのフィルターがない | AND organism_id:9606 AND reviewed:true を追加して結果を絞り込んでください |
| ID マッピングの結果が空 | データベースコードが誤っている | from/to のコードを確認してください。UniProtKB のみではなく、UniProtKB_AC-ID を使用してください |
| ページネーションでエントリが欠落する | 結果セットが大きい | ページネーションありの /search ではなく、/stream エンドポイントを使用してください |
429 Too Many Requests | API 呼び出しが過剰 | リクエストの間に time.sleep(0.5) を追加してください。アクセッションを単一のクエリにまとめてください |
| FASTA に遺伝子名がない | アノテーションが最小限の TrEMBL エントリ | 完全なアノテーションを持つ Swiss-Prot エントリには reviewed:true でフィルタリングしてください |
関連スキル
- biopython-molecular-biology — UniProt から返された FASTA 配列を解析します。取得した配列で BLAST を実行します
- alphafold-database-access — UniProt アクセッションを使用して予測された 3D 構造を取得します
- esm-protein-language-model — UniProt のタンパク質配列から埋め込みを生成します
- gget-genomic-databases — データベース間で遺伝子/タンパク質をすばやく検索するための代替インターフェースです
参考資料
- UniProt REST API ドキュメント — 公式 API リファレンス
- UniProt クエリ構文 — フィールド固有の検索演算子
- UniProt Consortium (2023) — 「UniProt: the Universal Protein Knowledgebase in 2023」— Nucleic Acids Research