APIで生物学データベースを照会する
このトピックを終えたら
Python requestsライブラリでNCBIとUniProt APIを呼び出し、JSON応答から必要なデータを抽出し、複数の遺伝子をループで照会できるようになります。
APIとは
NCBIのウェブサイトで遺伝子を検索したことがあるでしょう。検索窓に「EGFR」と入力すると遺伝子情報ページが表示されます。この時ブラウザはNCBIサーバーに**リクエスト(request)を送り、サーバーがレスポンス(response)**を返しています。
API(Application Programming Interface)はこのプロセスをコードで行うことです。ブラウザの代わりにPythonがリクエストを送り、HTMLの代わりに構造化されたデータ(JSON)でレスポンスを受け取ります。
実験機器で例えると — 試料を入れてボタンを押すと結果が出るように、APIに遺伝子名を入れると情報が出てきます。ただし人がボタンを押す代わりにコードが自動で押します。
requestsライブラリ
pip install requestsimport requests
response = requests.get("https://api.github.com")print(f"ステータスコード: {response.status_code}")print(f"レスポンスデータ: {response.json()}")requests.get(URL) — そのURLにGETリクエストを送ります。ウェブブラウザでURLを入力するのと同じです。
ステータスコード:
- 200 — 成功
- 404 — 存在しないURL
- 429 — リクエストが多すぎる(rate limit)
- 500 — サーバー内部エラー
JSON:API応答形式
APIはほとんどJSON形式でレスポンスします。Pythonのディクショナリとほぼ同じ構造です:
{
"gene": "EGFR",
"organism": "Homo sapiens",
"chromosome": "7",
"aliases": ["ERBB1", "HER1"]
}PythonでJSON応答を扱う方法:
import requests
response = requests.get("https://rest.uniprot.org/uniprotkb/P04637.json")data = response.json()
print(f"Protein: {data['proteinDescription']['recommendedName']['fullName']['value']}")print(f"Organism: {data['organism']['scientificName']}")print(f"Sequence length: {data['sequence']['length']}")response.json() — JSON応答をPythonディクショナリに変換します。その後data["key"]で欲しい値を取り出します。
実践:UniProt APIでタンパク質情報を取得
import requests
def get_protein_info(uniprot_id: str) -> dict: url = f"https://rest.uniprot.org/uniprotkb/{uniprot_id}.json" response = requests.get(url)
if response.status_code != 200: print(f"エラー: {uniprot_id} — ステータスコード {response.status_code}") return {}
data = response.json() return { "id": uniprot_id, "name": data["proteinDescription"]["recommendedName"]["fullName"]["value"], "organism": data["organism"]["scientificName"], "length": data["sequence"]["length"], }
info = get_protein_info("P04637")print(info)関数にすれば複数のタンパク質をループで照会できます:
ids = ["P04637", "P00533", "P38398"]results = []
for uid in ids: info = get_protein_info(uid) if info: results.append(info) print(f" ✓ {info['name']} ({info['length']} aa)")
print(f"\n合計 {len(results)}件照会完了")実践:NCBI E-utilities
NCBIはE-utilitiesというAPIを提供しています。遺伝子検索、配列ダウンロード、論文検索などをコードで行えます。
import requests
gene_name = "BRCA1"url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"params = { "db": "gene", "term": f"{gene_name}[Gene Name] AND Homo sapiens[Organism]", "retmode": "json",}
response = requests.get(url, params=params)data = response.json()
gene_ids = data["esearchresult"]["idlist"]print(f"{gene_name} 検索結果: {gene_ids}")params — URLパラメータをディクショナリで渡します。requestsが自動で?db=gene&term=...をURLに付けてくれます。
API呼び出しのマナー:Rate Limiting
APIは無限に呼び出すことはできません。サーバーに負荷をかけないようリクエスト間隔を空ける必要があります:
import timeimport requests
ids = ["P04637", "P00533", "P38398", "Q13315", "P42336"]
for uid in ids: info = get_protein_info(uid) if info: print(f" {info['name']}") time.sleep(0.5)time.sleep(0.5) — 0.5秒待機。NCBIは秒間3回、UniProtは秒間10回程度を推奨しています。これは研究室で共用機器を使うマナーと同じです — 一人で独占すると他の人が使えません。
APIキー
一部のAPIはAPIキーを要求します。NCBI E-utilitiesはAPIキーなしでも使えますが、キーを登録するとレート制限が秒間3回から10回に増えます。
params = { "db": "gene", "term": "TP53[Gene Name]", "retmode": "json", "api_key": "YOUR_API_KEY_HERE",}APIキーは絶対にコードに直接書かないでください。 環境変数や別の設定ファイルに保存し、Gitにアップロードしないでください。
エラー処理
ネットワークの問題や不正なIDでAPI呼び出しが失敗することがあります:
import requests
def safe_api_call(url: str, params: dict = None) -> dict: try: response = requests.get(url, params=params, timeout=10) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print("リクエストがタイムアウトしました — 後でもう一度お試しください") return {} except requests.exceptions.HTTPError as e: print(f"HTTPエラー: {e}") return {}timeout=10 — 10秒以内に応答がなければ諦めます。サーバーが遅い時にプログラムが永遠に止まるのを防ぎます。
やってみよう(Faded Example)
空欄を埋めて、UniProt APIからタンパク質配列の長さを取得するコードを完成させてください。
importurl = "https://rest.uniprot.org/uniprotkb/P04637.json"response = requests.(url)if response.status_code == :data = response.()length = data["sequence"]["length"]print(f"配列の長さ: {length} aa")
よくあるエラーと解決法
Q: ConnectionErrorまたはTimeoutエラーが出ます
インターネット接続を確認してください。サーバーが一時的にダウンしている可能性もあります。time.sleep(5)後にリトライするか、後で再実行してください。
Q: KeyError — JSONから値を取得できません
API応答の構造が予想と異なる可能性があります。print(json.dumps(data, indent=2))で全体の応答を出力して実際のキー構造を確認してください。またはdata.get("key", "なし")でキーがない時にデフォルト値を返すようにしてください。
Q: API応答がHTMLで返ってきます
URLがウェブページアドレス(ブラウザ用)でAPIアドレスではない可能性があります。APIドキュメントで正確なエンドポイントを確認してください。通常/api/や.jsonが含まれたURLがAPI用です。
Q: 429 Too Many Requestsエラーが出ます
リクエストを速すぎる頻度で送っています。time.sleep(1)などでリクエスト間隔を広げてください。NCBIはAPIキーの登録を推奨しています。