关于 pride-database
PRIDE Database 技能通过 PRIDE Archive 的 REST API 查询质谱蛋白质组学项目,适合寻找数据集并获取项目文件和元数据。它还支持筛选值发现、相似项目检索及项目级蛋白质映射;肽段和 PSM 结果需从文件下载后解析。
主要功能
- 01按关键词与筛选条件搜索项目
- 02查询项目元数据与文件
- 03获取 SDRF 样本运行映射
- 04检索相似项目与自动补全
- 05查询蛋白质对应项目
适用场景
- 01发现特定疾病或仪器相关数据集
- 02下载质谱原始数据或鉴定结果
- 03整理样本与质谱运行的对应关系
- 04查找提及特定 UniProt 蛋白的项目
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill pride-database安装后在 Claude Code 中输入/pride-database确认已加载。
详细介绍
PRIDE 数据库
概述
EMBL-EBI 的 PRIDE Archive(ProteomicsIDEntifications database)是全球最大的公共质谱蛋白质组学数据库;截至 2026 年,收录了 39,000 多个项目和 340 多万个已提交文件。可通过 https://www.ebi.ac.uk/pride/ws/archive/v3/ 上的 JSON REST API 以编程方式访问。无需身份验证。OpenAPI/Swagger 规范位于 https://www.ebi.ac.uk/pride/ws/archive/v3/v3/api-docs。PRIDE v3 的列表端点返回纯 JSON 数组(不包含 HAL+JSON _embedded 封装),并且有意不提供单肽段或单 PSM 的鉴定端点;如需谱图级鉴定信息,请下载项目的 RESULT 文件(mzIdentML、MaxQuant txt 等),并在本地解析。
使用场景
- 通过自由文本关键词和分面筛选条件(生物体、组织、疾病、仪器、软件、PTM)查找已发表的蛋白质组学数据集,用于元分析或基准测试
- 从特定 PRIDE 项目登录号下载原始质谱数据(RAW、mzML、MGF)或预处理后的鉴定结果(RESULT 文件)
- 查询哪些 PRIDE 项目提及特定 UniProt 蛋白质登录号(仅提供项目级出现情况映射;API 不提供 PSM/覆盖率计数)
- 查找与目标项目相似的项目,以便重新分析或进行跨研究比较
- 获取项目的 SDRF(Sample-Data Relationship Format)文件,以便以编程方式建模样本与 MS 运行之间的映射关系
- 在构建结构化查询之前,通过分面搜索发现有效的筛选值
- 蛋白质序列、Swiss-Prot 注释和 ID 映射请使用
uniprot-protein-database - 蛋白质结构域和家族分类请使用
interpro-database——PRIDE 只报告项目级出现情况,不提供结构域级特征 - PRIDE v3 没有
/peptides、/psms或/proteins?proteinAccession=端点——如需肽段级或 PSM 级数据,请从/projects/{accession}/files下载 RESULT 文件,并使用pyteomics或特定搜索引擎的读取器进行解析
先决条件
- Python 包:
requests、pandas、matplotlib - 数据要求:PRIDE 项目登录号(格式为
PXD######)或搜索关键词;如需查询蛋白质出现情况,可选提供 UniProt 登录号 - 环境:需要联网;无需 API 密钥
- 速率限制:未正式公布;请求突发频率请控制在每秒约 5 次以下,并在循环中加入
time.sleep(0.3)
pip install requests pandas matplotlib
快速开始
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
# 1) Free-text search for cancer proteomics projects
projects = requests.get(f"{PRIDE}/search/projects",
params={"keyword": "prostate cancer", "pageSize": 5},
timeout=30).json()
print(f"Top {len(projects)} projects:")
for p in projects[:3]:
instr = ", ".join(p.get("instruments", []))[:50]
print(f" {p['accession']} {(p['title'] or '')[:70]} [{instr}]")
# 2) Drill into one project
acc = projects[0]["accession"]
proj = requests.get(f"{PRIDE}/projects/{acc}", timeout=30).json()
print(f"\n{proj['accession']}: {proj['title'][:70]}")
print(f" Submitted: {proj.get('submissionDate')} DOI: {proj.get('doi')}")
print(f" Organisms: {[o['name'] for o in proj.get('organisms', [])]}")
print(f" Instruments: {[i['name'] for i in proj.get('instruments', [])]}")
# 3) List files and total size
files = requests.get(f"{PRIDE}/projects/{acc}/files/all", timeout=60).json()
total_mb = sum(f.get("fileSizeBytes", 0) for f in files) / 1e6
print(f"\n {len(files)} files, {total_mb:.0f} MB total")
核心 API
模块 1:项目搜索 — /search/projects
支持自由文本搜索,以及可选的基于分面的筛选、分页和排序。返回纯 JSON 项目记录数组;不包含 HAL+JSON _embedded/page 封装。
import requests, pandas as pd
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def search_projects(keyword=None, organism=None, instrument=None,
disease=None, software=None,
page_size=25, page=0, sort_field="submission_date",
sort_direction="DESC"):
"""Search PRIDE v3 for projects.
Filter syntax (for the `filter` arg) is `field==value, field==value` using `_facet` field names
that are discoverable via /facet/projects."""
filters = []
if organism: filters.append(f"organisms_facet=={organism}")
if instrument: filters.append(f"instruments_facet=={instrument}")
if disease: filters.append(f"diseases_facet=={disease}")
if software: filters.append(f"softwares_facet=={software}")
params = {"pageSize": page_size, "page": page,
"sortFields": sort_field, "sortDirection": sort_direction}
if keyword: params["keyword"] = keyword
if filters: params["filter"] = ",".join(filters)
r = requests.get(f"{PRIDE}/search/projects", params=params, timeout=30)
r.raise_for_status()
return r.json() # plain list[dict]
projects = search_projects(keyword="cancer", organism="Homo sapiens (human)",
instrument="Q Exactive", page_size=5)
df = pd.DataFrame([{
"accession": p["accession"],
"title": (p.get("title") or "")[:70],
"submission_date": p.get("submissionDate"),
"diseases": ", ".join(p.get("diseases", []))[:60],
"instruments": ", ".join(p.get("instruments", []))[:50],
} for p in projects])
print(df.to_string(index=False))
# Paginate through all matches for a keyword. The API doesn't return total counts inline;
# walk pages until the next one is empty.
def search_all_projects(keyword, page_size=100, max_pages=20):
all_records, page = [], 0
while page < max_pages:
batch = search_projects(keyword=keyword, page_size=page_size, page=page)
if not batch:
break
all_records.extend(batch)
if len(batch) < page_size:
break # last page
page += 1
return all_records
results = search_all_projects("phosphoproteomics", page_size=100, max_pages=3)
print(f"Phosphoproteomics projects collected (max 300): {len(results)}")
模块 2:分面筛选项发现 — /facet/projects
构建筛选搜索之前,先查询分面端点,查看给定关键词下实际存在的仪器、生物体、疾病和软件值及其计数。响应是一个由分面组构成的字典,每组均映射 {value: count}。
import requests, pandas as pd
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def get_facets(keyword=None, facet_page_size=20):
"""Return facet counts for projects matching `keyword`. Keys are facet groups
(instruments, organisms, diseases, softwares, experimentTypes, ...); values are
dicts of {value: count}."""
params = {"facetPageSize": facet_page_size}
if keyword: params["keyword"] = keyword
r = requests.get(f"{PRIDE}/facet/projects", params=params, timeout=30)
r.raise_for_status()
return r.json()
facets = get_facets(keyword="cancer", facet_page_size=10)
print(f"Facet groups: {list(facets.keys())}")
print(f"\nTop instruments for 'cancer':")
for instr, n in sorted(facets.get("instruments", {}).items(), key=lambda kv: -kv[1])[:8]:
print(f" {instr:<35} {n}")
print(f"\nTop diseases:")
for d, n in sorted(facets.get("diseases", {}).items(), key=lambda kv: -kv[1])[:6]:
print(f" {d:<55} {n}")
模块 3:项目详情 — /projects/{accession}
单个项目的完整元数据:提交者、实验室 PI、仪器、生物体(采用 CV 编码)、疾病、实验类型、参考文献、DOI、提交/发表日期。列表中的元素是 CvParam 风格的对象,包含 accession、cvLabel、name,并可选包含 value。
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def get_project(accession):
r = requests.get(f"{PRIDE}/projects/{accession}", timeout=30)
r.raise_for_status()
return r.json()
p = get_project("PXD004131")
print(f"Accession : {p['accession']}")
print(f"Title : {p['title'][:80]}")
print(f"Submission : {p.get('submissionDate')}")
print(f"Publication : {p.get('publicationDate')}")
print(f"DOI : {p.get('doi')}")
print(f"License : {p.get('license')}")
print(f"Type : {p.get('submissionType')}")
print(f"Organisms : {[o['name'] for o in p.get('organisms', [])]}")
print(f"Instruments : {[i['name'] for i in p.get('instruments', [])]}")
print(f"Experiment : {[e['name'] for e in p.get('experimentTypes', [])]}")
print(f"PIs : {[pi.get('name') for pi in p.get('labPIs', [])]}")
print(f"References : {[r.get('doi') for r in p.get('references', [])[:3]]}")
模块 4:项目文件 — /projects/{accession}/files + /files/all
列出与项目相关的文件。大型项目请使用分页端点;/files/all 会一次性返回所有文件。每条文件记录都包含 fileCategory.value(取值为 RAW、PEAK、RESULT、FASTA、OTHER 之一)、fileSizeBytes(注意后缀是 Bytes,而不是 fileSize),以及一个 publicFileLocations 列表,其中每个位置都标记为 FTP Protocol 或 Aspera Protocol。
import requests, pandas as pd
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def get_project_files(accession, file_type=None, page_size=100):
"""Walk paginated /files for a project. Optionally filter by category code
(RAW, PEAK, RESULT, FASTA, OTHER). Returns a DataFrame."""
rows, page = [], 0
while True:
r = requests.get(f"{PRIDE}/projects/{accession}/files",
params={"pageSize": page_size, "page": page},
timeout=30)
r.raise_for_status()
batch = r.json()
if not batch:
break
for f in batch:
cat = f.get("fileCategory") or {}
ftp = next((loc["value"] for loc in f.get("publicFileLocations", [])
if loc.get("name") == "FTP Protocol"), "")
asp = next((loc["value"] for loc in f.get("publicFileLocations", [])
if loc.get("name") == "Aspera Protocol"), "")
rows.append({
"file_name": f.get("fileName"),
"category": cat.get("value"), # RAW/PEAK/RESULT/FASTA/OTHER
"size_mb": round((f.get("fileSizeBytes") or 0) / 1e6, 2),
"ftp_url": ftp,
"aspera_url": asp,
"downloads": f.get("totalDownloads"),
})
if len(batch) < page_size:
break
page += 1
df = pd.DataFrame(rows)
if file_type:
df = df[df["category"] == file_type]
return df
files_df = get_project_files("PXD004131")
print(f"Total files: {len(files_df)}")
print(files_df.groupby("category")["size_mb"].agg(["count", "sum"]).round(1).to_string())
raw_only = files_df[files_df["category"] == "RAW"]
print(f"\nRAW files: {len(raw_only)}; combined {raw_only['size_mb'].sum():.0f} MB")
print(raw_only[["file_name", "size_mb", "downloads"]].head(5).to_string(index=False))
# /files/all returns every file in one response — convenient for small projects
files = requests.get(f"{PRIDE}/projects/PXD000001/files/all", timeout=60).json()
print(f"PXD000001 files (all): {len(files)}")
for f in files[:4]:
print(f" [{f.get('fileCategory',{}).get('value','?'):<6}] {f['fileName']} "
f"{f.get('fileSizeBytes',0)/1e6:.2f} MB")
Module 5:SDRF 文件 — /files/sdrf/{projectAccession}
遵循现代提交标准的 PRIDE 项目包含一个 SDRF(Sample-Data Relationship Format,样本-数据关系格式)TSV 文件,用于将每次 MS 运行与其生物样本、处理方式、标记、分级等信息对应起来。获取一次后,将其解析为 TSV。
import requests, pandas as pd, io
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def get_sdrf(accession):
"""Fetch the SDRF sample-to-run mapping for a project (404 if not provided)."""
r = requests.get(f"{PRIDE}/files/sdrf/{accession}", timeout=30)
if r.status_code == 404:
return None
r.raise_for_status()
return pd.read_csv(io.StringIO(r.text), sep="\t")
# Many older projects have no SDRF — newer ones typically do
sdrf = get_sdrf("PXD000001")
if sdrf is None or sdrf.empty:
print("No SDRF available for this project")
else:
print(f"SDRF rows: {len(sdrf)} cols: {len(sdrf.columns)}")
print(f"First columns: {list(sdrf.columns)[:8]}")
Module 6:蛋白质 → 项目映射 — /proteins/{accession}
PRIDE v3 的蛋白质端点只返回包含给定 UniProt 登录号对应鉴定结果的项目登录号列表。它不会返回 PSM 数量、肽段数量或序列覆盖率——这些信息未在 v3 的 API 层公开。要获取深度指标,必须下载项目的 RESULT 文件并在本地解析。
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def get_protein_projects(uniprot_acc):
"""Return the list of PRIDE project accessions that mention this UniProt accession.
No PSM/peptide/coverage counts are available at this endpoint."""
r = requests.get(f"{PRIDE}/proteins/{uniprot_acc}", timeout=30)
if r.status_code == 404:
return None
r.raise_for_status()
data = r.json()
return data.get("projects", [])
tp53 = get_protein_projects("P04637")
print(f"TP53 (P04637) is reported in {len(tp53)} PRIDE projects")
print(f"First 8: {tp53[:8]}")
unknown = get_protein_projects("Q99999")
print(f"\nQ99999 (no real protein): "
f"{'no PRIDE evidence' if not unknown else f'{len(unknown)} projects'}")
Module 7:发现辅助功能 — 相似项目、自动补全
/projects/{accession}/similarProjects 会返回元数据特征(生物体、仪器、实验类型、标签)相关的项目。/search/autocomplete?keyword=... 会返回标题以此前缀开头的项目——可用于提供搜索建议。
import requests, pandas as pd
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
# Find similar projects to one of interest
similar = requests.get(f"{PRIDE}/projects/PXD004131/similarProjects",
params={"pageSize": 5}, timeout=30).json()
print(f"Similar to PXD004131: {len(similar)} projects")
for p in similar[:5]:
print(f" {p['accession']} {(p.get('title') or '')[:70]}")
# Autocomplete suggestions for a project-title prefix
suggestions = requests.get(f"{PRIDE}/search/autocomplete",
params={"keyword": "tp53"}, timeout=30).json()
print(f"\nAutocomplete for 'tp53': {len(suggestions)} suggestions")
for s in suggestions[:5]:
print(f" {s}")
Module 8:整个存储库的计数 — /projects/count、/files/count
获取整个存储库中的总数量——可用于状态显示和合理性检查。两个端点都返回纯整数正文(没有 JSON 对象包装)。
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
n_projects = int(requests.get(f"{PRIDE}/projects/count", timeout=30).text)
n_files = int(requests.get(f"{PRIDE}/files/count", timeout=30).text)
print(f"PRIDE Archive current scale:")
print(f" Projects: {n_projects:,}")
print(f" Files: {n_files:,}")
关键概念
纯 JSON 数组,无 HAL 封装
PRIDE v3 列表端点返回纯 JSON 数组——例如,/search/projects 会直接返回 [{...}, {...}, ...]。其中没有 _embedded.compactprojects、page.totalElements/totalPages 或 _links.next.href。使用 data["_embedded"]["compactprojects"] 解析响应的旧版 PRIDE v2 客户端,在当前 API 中会悄然返回空结果。要进行分页,请遍历 page=0, 1, 2, ...,直到获得空数组(或长度小于 pageSize 的部分页面)。
v3 移除的内容
以下端点系列在 v3 中已不复存在(v2 现在在内部是 v3 的别名——来自 /v2/peptides 的错误消息会直接报告 path: "/pride/ws/archive/v3/peptides"):
| 已移除的端点 | v3 中的状态 | 替代方案 |
|---|---|---|
GET /peptides?projectAccessions=X | 404 | 无——下载项目的 RESULT 文件并解析 |
GET /psms?projectAccessions=X | 404 | 无——下载 RESULT 文件 |
GET /proteins?proteinAccession=X(查询参数形式) | 404 | GET /proteins/{accession}(路径参数形式) |
HAL+JSON _embedded/page 封装 | 已移除 | 纯 JSON 数组 |
/projects?keyword=...&organisms=...&tissues=... 筛选器 | 被静默忽略 | /search/projects?keyword=...&filter=field==value |
/search/projects 上的筛选语法
filter 查询参数接受以逗号分隔的 field==value 条件列表。字段名使用 _facet 后缀(底层采用 Solr 风格的字段)。构造筛选条件前,请通过 /facet/projects 查找有效的字段名和值:
# Valid filter forms
"organisms_facet==Homo sapiens (human)"
"instruments_facet==Q Exactive"
"diseases_facet==Prostate adenocarcinoma"
"softwares_facet==MaxQuant"
# Combine with commas
filter="organisms_facet==Homo sapiens (human),instruments_facet==Orbitrap Fusion Lumos"
文件类别
项目中的每个文件都带有一个 fileCategory CV 参数。.value 是类别代码;.name 是人类可读的标签:
value 代码 | 描述 | 常见格式 |
|---|---|---|
RAW | 未处理的仪器输出 | .raw(Thermo)、.d(Bruker/Agilent)、.wiff(Sciex) |
PEAK | 质心化/反卷积后的谱图 | .mzML、.mzXML、.mgf |
RESULT | 鉴定结果 | .mzid、.mzTab、MaxQuant txt、PRIDE XML |
FASTA | 搜索中使用的蛋白质序列数据库 | .fasta |
OTHER | 补充材料/脚本/表格 | .txt、.xlsx、.csv |
对于重新分析工作流,RESULT 是成本最低的切入点——无需重新搜索谱图即可获取已鉴定的肽段。PEAK 可用于使用其他引擎重新搜索。只有在完整重新处理供应商格式数据时才需要 RAW。
登录号格式
PRIDE 项目登录号遵循 ProteomeXchange 格式 PXD######。这些登录号在 PRIDE、MassIVE、jPOST 和 iProX 中保持一致。PRIDE 中的文件登录号是类似 SHA-256 的哈希值(例如,5bda360133398f66021c8889e01dce921cb51300c7269e1f2b0f20368ab20af6),属于不透明标识符;如需获取便于人类识读的文件名,请使用 fileName。
常见工作流
工作流 1:分面发现——从疾病关键词到筛选后的项目列表
目标:从疾病关键词开始,通过分面计数查看匹配数据集中常见的仪器和软件,然后使用其中一个热门值获取筛选后的项目列表。
import requests, pandas as pd
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
disease_kw = "colorectal cancer"
# 1) Inspect facet counts to learn which filter values dominate
facets = requests.get(f"{PRIDE}/facet/projects",
params={"keyword": disease_kw, "facetPageSize": 10},
timeout=30).json()
top_instr = sorted(facets.get("instruments", {}).items(), key=lambda kv: -kv[1])[:5]
top_org = sorted(facets.get("organisms", {}).items(), key=lambda kv: -kv[1])[:3]
print(f"Top instruments for '{disease_kw}':")
for k, v in top_instr: print(f" {k:<35} {v}")
print(f"Top organisms:")
for k, v in top_org: print(f" {k:<35} {v}")
# 2) Build a filtered search using one top instrument
target_instr = top_instr[0][0]
projects = requests.get(f"{PRIDE}/search/projects",
params={"keyword": disease_kw,
"filter": f"organisms_facet==Homo sapiens (human),instruments_facet=={target_instr}",
"pageSize": 50,
"sortFields": "submission_date",
"sortDirection": "DESC"},
timeout=30).json()
df = pd.DataFrame([{
"accession": p["accession"],
"title": (p.get("title") or "")[:70],
"submission_date": p.get("submissionDate"),
"tissues": ", ".join(p.get("organismsPart", []))[:40],
"submitter": (p.get("submitters") or [""])[0] if p.get("submitters") else "",
} for p in projects])
print(f"\nFiltered projects: {len(df)} (target instrument: {target_instr})")
print(df.head(10).to_string(index=False))
df.to_csv(f"{disease_kw.replace(' ', '_')}_{target_instr.replace(' ', '_')}_projects.csv",
index=False)
工作流 2:单个项目的文件下载清单
目标:获取某个项目的文件列表,筛选出所需类别(RAW + RESULT),并生成可供 aria2c 使用的 URL 列表,以便通过 FTP 并行下载。
import requests, pandas as pd
from pathlib import Path
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
accession = "PXD004131"
keep_categories = {"RAW", "RESULT"}
output_dir = Path(f"/data/pride/{accession}")
files = requests.get(f"{PRIDE}/projects/{accession}/files/all", timeout=120).json()
manifest = []
for f in files:
cat = (f.get("fileCategory") or {}).get("value")
if cat not in keep_categories:
continue
ftp = next((loc["value"] for loc in f.get("publicFileLocations", [])
if loc.get("name") == "FTP Protocol"), None)
if not ftp:
continue
manifest.append({
"file_name": f["fileName"],
"category": cat,
"size_mb": round((f.get("fileSizeBytes") or 0) / 1e6, 2),
"ftp": ftp,
})
mdf = pd.DataFrame(manifest).sort_values(["category", "file_name"])
print(f"{accession}: keeping {len(mdf)}/{len(files)} files "
f"({mdf['size_mb'].sum():.0f} MB total)")
print(mdf.groupby("category")[["size_mb"]].sum().round(0))
# aria2c -i pride_dl.list -d /data/pride/PXD004131 -x 8 -j 4
with open("pride_dl.list", "w") as fh:
fh.write("\n".join(mdf["ftp"]))
print(f"\nWrote pride_dl.list with {len(mdf)} URLs (use aria2c -i)")
工作流 3:蛋白质在多个项目中的出现情况
目标:针对一组候选蛋白质(例如,来自差异表达分析),查询 PRIDE 中提及每种蛋白质的项目数量,并优先选出证据最充分的蛋白质。注意:这项指标仅表示项目数量——v3 的 API 接口不提供 PSM/肽段计数,因此较高的项目数量代表覆盖面广,而非证据深度大。
import requests, time, pandas as pd, matplotlib.pyplot as plt
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
candidates = {
"P04637": "TP53", "P38398": "BRCA1", "P31749": "AKT1",
"P40763": "STAT3", "O15530": "PDPK1", "P10275": "AR",
}
rows = []
for acc, sym in candidates.items():
r = requests.get(f"{PRIDE}/proteins/{acc}", timeout=30)
projs = r.json().get("projects", []) if r.status_code == 200 else []
rows.append({"uniprot": acc, "symbol": sym, "n_projects": len(projs)})
time.sleep(0.3)
df = pd.DataFrame(rows).sort_values("n_projects", ascending=False)
print(df.to_string(index=False))
fig, ax = plt.subplots(figsize=(8, 3.5))
bars = ax.bar(df["symbol"], df["n_projects"], color="#3182BD")
ax.bar_label(bars, fmt="%d", fontsize=9, padding=2)
ax.set_ylabel("# PRIDE projects mentioning the protein")
ax.set_title("PRIDE project-level occurrence — candidate panel")
plt.tight_layout()
plt.savefig("pride_protein_occurrence.png", dpi=150, bbox_inches="tight")
print("Saved pride_protein_occurrence.png")
关键参数
| 参数 | 端点 | 默认值 | 范围 / 选项 | 作用 |
|---|---|---|---|---|
keyword | /search/projects、/facet/projects、/search/autocomplete | — | 自由文本字符串 | 对标题、描述和标签进行全文搜索 |
filter | /search/projects | — | field_facet==value, field_facet==value | 使用分面字段名称进行服务端筛选 |
pageSize | /search/projects、/projects、/projects/{acc}/files、/projects/{acc}/similarProjects | 100 | 正整数 | 每页结果数 |
page | 同上 | 0 | 从 0 开始的整数 | 页码(不返回元数据——持续遍历各页,直到页面为空) |
sortFields | /search/projects | submission_date | 以逗号分隔的字段名称 | 排序键 |
sortDirection | /search/projects | DESC | ASC 或 DESC | 排序顺序 |
facetPageSize | /facet/projects | 20 | 正整数 | 每个分面组返回的值数量 |
dateGap | /search/projects、/facet/projects | — | 例如,+1MONTH、+1YEAR | 日期范围聚合粒度 |
(路径) accession | /projects/{acc}、/projects/{acc}/files、/projects/{acc}/similarProjects、/proteins/{acc} | 必填 | PXD###### 或 UniProt 登录号 | 标识资源 |
最佳实践
-
使用
/search/projects进行搜索,而不是/projects。 普通的/projects是分页列表端点,会静默忽略关键词/生物/疾病筛选条件。只有通过/search/projects并使用filter=field_facet==value语法,筛选才会生效。 -
筛选前先通过
/facet/projects查询筛选值。 Facet 字段值必须完全匹配(例如,organisms_facet==Homo sapiens (human),包括括号)。Facet 端点会告诉你有哪些值,以及每个值对应多少个项目,可省去大量反复尝试。 -
不要尝试通过 API 查询肽段级或 PSM 级数据。 这些端点已在 v3 中移除。请下载项目的 RESULT 文件,并使用
pyteomics、pyOpenMS或搜索引擎读取器(MaxQuant、ProteomeDiscoverer 等)在本地解析。 -
批量下载文件时优先使用 FTP URL。 每条文件记录都包含
FTP Protocol和Aspera ProtocolURL。FTP 的支持范围更广;可搭配aria2c -x 8 -j 4并行下载分块。仅当你有 Aspera 客户端且需要超过 100 Mbit 的传输速度时,才使用 Aspera。 -
注意字段名
fileSizeBytes。 当前 v3 字段名是fileSizeBytes,而不是fileSize(旧版 v2 文档中可能写作fileSize)。大小单位为字节;除以1e6可换算为 MB,除以1e9可换算为 GB。 -
根据
fileCategory.value筛选下载文件。 一个项目可能包含数百个文件,涵盖 RAW(GB 级)和 OTHER(KB 级)。将下载任务加入队列前,务必筛选出实际需要的类别,否则你可能会轻易下载数十 GB 的供应商 RAW 文件,而你需要的却只有鉴定表。 -
分页没有元数据——持续请求直到结果为空。 与旧版 PRIDE v2 不同,v3 API 不会返回
totalElements/totalPages。依次遍历page=0, 1, 2, ...,当某页返回空数组或其长度小于pageSize时停止。
常见用法
配方:快速汇总项目文件
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def project_file_summary(accession):
files = requests.get(f"{PRIDE}/projects/{accession}/files/all", timeout=60).json()
by_cat = {}
for f in files:
cat = (f.get("fileCategory") or {}).get("value", "OTHER")
by_cat.setdefault(cat, [0, 0])
by_cat[cat][0] += 1
by_cat[cat][1] += (f.get("fileSizeBytes") or 0) / 1e6
print(f"\n{accession} file summary:")
for cat, (n, mb) in sorted(by_cat.items()):
print(f" {cat:<8} {n:>4} file(s) {mb:>10.1f} MB")
total_mb = sum(mb for _, mb in by_cat.values())
total_n = sum(n for n, _ in by_cat.values())
print(f" {'TOTAL':<8} {total_n:>4} file(s) {total_mb:>10.1f} MB")
project_file_summary("PXD000001")
配方:检查某个蛋白质是否有任何 PRIDE 证据
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
def pride_evidence(uniprot_acc):
"""Return (has_evidence, n_projects). PRIDE v3 only exposes project list, no PSM counts."""
r = requests.get(f"{PRIDE}/proteins/{uniprot_acc}", timeout=30)
if r.status_code != 200:
return False, 0
projs = r.json().get("projects", [])
return bool(projs), len(projs)
for acc in ["P04637", "Q99999"]:
has, n = pride_evidence(acc)
print(f"{acc}: evidence={has} projects={n}")
配方:按日期排序的关键词近期提交
import requests, pandas as pd
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
r = requests.get(f"{PRIDE}/search/projects",
params={"keyword": "single-cell proteomics",
"sortFields": "submission_date",
"sortDirection": "DESC",
"pageSize": 15},
timeout=30)
recent = r.json()
df = pd.DataFrame([{
"submission_date": p.get("submissionDate"),
"accession": p["accession"],
"title": (p.get("title") or "")[:80],
} for p in recent]).sort_values("submission_date", ascending=False)
print(df.to_string(index=False))
配方:通过自动补全实现输入时建议
import requests
PRIDE = "https://www.ebi.ac.uk/pride/ws/archive/v3"
for prefix in ["alzheimer", "single cell", "brca"]:
s = requests.get(f"{PRIDE}/search/autocomplete",
params={"keyword": prefix}, timeout=30).json()
print(f"\n'{prefix}' → {len(s)} suggestions:")
for sug in s[:3]:
print(f" · {sug[:80]}")
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
即使 r.json() 中有数据,解析仍返回空列表 | 代码使用了 data["_embedded"]["compactprojects"]——这是 v3 不再返回的旧 HAL+JSON 包装结构 | 将响应直接解析为列表:projects = r.json() |
对 /peptides、/psms 或 /proteins?proteinAccession=X 请求时出现 HTTP 404 | 这些端点已在 v3 中移除 | 对于肽段/PSM 数据,请下载项目的 RESULT 文件并在本地解析。对于蛋白质查询,请使用 /proteins/{accession}(路径参数) |
/projects?keyword=cancer 返回的 100 条结果与不带关键词的 /projects 相同 | /projects 端点只接受 pageSize/page——关键词和其他筛选条件会被静默忽略 | 改用 /search/projects?keyword=...&filter=... |
/projects/{acc}/files 显示文件大小为 0 | 读取了 fileSize,而不是 fileSizeBytes | v3 字段是 fileSizeBytes(单位为字节);用 fileSizeBytes / 1e6 计算 MB |
| 筛选没有效果 | Facet 值与实际值不完全匹配 | 先调用 /facet/projects?keyword=... 列出有效值(Homo sapiens (human),而不是 Homo sapiens) |
pageSize 超过实际结果集大小时返回空数组 | 正常的分页行为 | 当返回数组长度小于 pageSize 或数组为空时,停止遍历 |
findAllOrganismsCount 返回 HTTP 406 Not Acceptable | 该端点要求非 JSON 的 Accept 标头 | 跳过此端点——通过 /facet/projects 获取 Facet 计数即可满足相同需求 |
突发请求时出现 HTTP 429 或 ConnectionError | EBI 基础设施由多个服务共享 | 在循环中添加 time.sleep(0.3);遇到 5xx 错误时使用指数退避重试 |
相关技能
uniprot-protein-database— UniProt 序列、Swiss-Prot 注释、ID 映射;可与 PRIDE 蛋白质查询搭配使用,为每个 UniProt 登录号补充序列和功能信息interpro-database— PRIDE 中报告的蛋白质的结构域架构(Pfam、SMART、PANTHER)pdb-database— 有 PRIDE 证据支持的蛋白质的已解析 3D 结构pyteomics(技能外的 Python 库)— 解析从/projects/{accession}/files下载的 mzIdentML / mzML / mzTab 文件;REST API 不再提供这些数据后,这是进行谱图级和 PSM 级分析的途径
参考资料
- PRIDE Archive v3 REST API 根目录 — 基础 URL
- PRIDE v3 OpenAPI/Swagger 规范 — 权威的端点清单
- PRIDE Archive Web 门户 — 交互式数据集浏览器
- Perez-Riverol 等人,《Nucleic Acids Research》,2022 — 介绍仓库及其架构的 PRIDE 2022 更新
- ProteomeXchange Consortium — PRIDE、MassIVE、jPOST、iProX 共用的标准登录号系统
- SDRF-Proteomics 规范 —
/files/sdrf/{projectAccession}使用的格式