mcpField
U
uniprot-protein-database

uniprot-protein-database

github.com/jaechang-hits数据与数据库38472 次安装6 天前更新
代码仓库

关于 uniprot-protein-database

这项技能介绍生物信息学研究者如何通过 UniProt REST API 访问蛋白质记录。内容涵盖蛋白质搜索、序列与注释获取、标识符映射,以及批量或流式获取结果。

主要功能

  1. 01使用结构化查询搜索蛋白质
  2. 02获取序列和蛋白质记录
  3. 03跨数据库映射 ID
  4. 04获取注释并选择字段
  5. 05批量获取与流式下载
  6. 06分页遍历大型搜索结果

适用场景

  1. 01按基因或物种查找蛋白质
  2. 02下载 FASTA 序列用于分析
  3. 03将 UniProt ID 映射为 PDB ID
  4. 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 亿条记录。本技能介绍如何通过 UniProt REST API 以编程方式搜索蛋白质、获取序列、映射 ID,以及查询注释。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)。对于大型查询(结果超过 10k),请使用流式端点,而不是分页搜索。每个 ID 映射任务最多支持 100,000 个 ID。

快速入门

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所有端点jsonjson、tsv、fasta、xml、gff输出格式
fields/search全部以逗号分隔的字段名称缩小响应大小
size/search251–500每页结果数
from / to/idmapping/run—数据库代码ID 映射方向
reviewed:true查询筛选条件—true/false仅限 Swiss-Prot(已整理)条目
organism_id查询筛选条件—NCBI 分类学 ID按物种筛选

最佳实践

  1. 使用 reviewed:true 筛选经过人工审核的数据:Swiss-Prot 条目经过人工审核;TrEMBL 条目则由计算预测生成。使用 Swiss-Prot 可获得高置信度注释。

  2. 进行表格分析时,使用 TSV 格式并指定 fields:仅请求所需字段并使用 TSV 格式,比获取完整 JSON 条目更快,也更易解析。

  3. 下载大量数据时使用流式传输:/stream 端点会返回所有结果,无需分页,避免逐页获取。

  4. 批量请求之间添加 time.sleep(0.5):尊重 API 资源限制,尤其是在连续发送多个请求时。

  5. 在本地缓存经常访问的条目:UniProt 每月更新;缓存结果,仅在需要时重新获取。

  6. 反模式——查询时不指定 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_AC-ID(不要只用 UniProtKB)
分页缺少条目结果集过大使用 /stream 端点,而不是分页的 /search
429 Too Many RequestsAPI 调用过于频繁在请求之间添加 time.sleep(0.5);在单个查询中批量处理 accession
FASTA 中没有基因名称TrEMBL 条目的注释不完整使用 reviewed:true 筛选注释完整的 Swiss-Prot 条目

相关技能

  • biopython-molecular-biology — 解析 UniProt 返回的 FASTA 序列;使用获取的序列运行 BLAST
  • alphafold-database-access — 使用 UniProt 登录号获取预测的 3D 结构
  • esm-protein-language-model — 根据 UniProt 蛋白质序列生成嵌入
  • gget-genomic-databases — 用于跨数据库快速查询基因/蛋白质的替代接口

参考资料

评论

支持 Markdown