内容
# psimodpy
[](https://github.com/tacular-omics/psimodpy/actions/workflows/ci.yml)
[](https://pypi.org/project/psimodpy/)
[](https://pypi.org/project/psimodpy/)
[](LICENSE)
用于解析和查询[PSI-MOD](https://github.com/HUPO-PSI/psi-mod-CV)蛋白质修饰本体论的Python库。
- 零核心依赖
- 捆绑PSI-MOD数据(2,116条记录)- 开箱即用,无需联网
- 类型化、不可变的数据模型(`py.typed` / PEP 561)
- TSV/CSV导出和循环写入OBO
- 可选FastAPI / [模型上下文协议](https://modelcontextprotocol.io)服务器(`pip install psimodpy[server]`)
## 在线查看器
#### [点击我!](https://tacular-omics.github.io/psimodpy/)
相同的数据库也可以作为托管的REST + MCP服务访问 - 请参见下面的[HTTP API和MCP服务器](#http-api-and-mcp-server)。
## 安装
```bash
pip install psimodpy
```
或使用[uv](https://docs.astral.sh/uv/):
```bash
uv add psimodpy
```
需要Python 3.12+。无第三方依赖。
## 快速入门
```python
import psimodpy
# 加载捆绑的PSI-MOD数据库
db = psimodpy.load()
# 按ID查找
entry = db[46] # O-phospho-L-serine
print(entry.name) # "O-phospho-L-serine"
print(entry.diff_mono) # 79.966331
print(entry.origin) # AminoAcid.SER
# 按名称查找(不区分大小写)
entry = db.get_by_name("O-phospho-L-serine")
# 也接受MOD:NNNNN格式
entry = db.get_by_id("MOD:00046")
# 在名称、定义和同义词中搜索
results = db.search("phospho")
# 查找氨基酸的所有修饰
ser_mods = db.get_by_origin("S")
# 过滤条目
slim = db.filter(slim_only=True, include_obsolete=False)
# 公式解析
print(entry.dict_diff_formula) # {'C': 0, 'H': 0, 'N': 0, 'O': 3, 'P': 1}
print(entry.proforma_diff_formula) # 'O3P'
```
## 导出到TSV/CSV
```python
# 将所有条目写入制表符分隔的文件
db.write_tsv("psimod.tsv")
# 或CSV
db.write_tsv("psimod.csv", delimiter=",")
# 独立函数
from psimodpy import write_tsv
write_tsv(db, "psimod.tsv")
```
TSV包括每个条目的一行。动态同义词列(例如`synonym_psi_mod_label`,`synonym_omssa_label`)为找到的每个`SynonymType`添加。
## 写回OBO格式
```python
# 循环写入:以PSI-MOD OBO格式写回条目
db.write_obo("out/psi-mod.obo")
# 解析 - 相同的条目数量和字段值
db2 = psimodpy.parse_obo("out/psi-mod.obo")
# 独立函数;传递原始标题行以实现忠实循环
from psimodpy import write_obo
write_obo(db, "out/psi-mod.obo", header_lines=db.header_lines)
```
## HTTP API 和 MCP 服务器
可选的`[server]`额外功能提供了一个FastAPI应用程序,通过JSON REST API和[模型上下文协议](https://modelcontextprotocol.io)公开同一个数据库,以便语言模型工具可以直接查询PSI-MOD。
```bash
pip install psimodpy[server]
uvicorn psimodpy.server.app:app --reload
```
### REST 端点
| 方法 & 路径 | 返回值 |
|---------------|---------|
| `GET /api/health` | 服务元数据和条目计数。 |
| `GET /api/entries?limit=&offset=&include_obsolete=` | 分页完整条目。 |
| `GET /api/entries/{id}` | 按ID(`46`或`MOD:00046`)查找一个完整条目。 |
| `GET /api/entries/by-name/{name}` | 按确切名称查找一个完整条目。 |
| `GET /api/entries/{id}/parents` | 直接`is_a`父级。 |
| `GET /api/entries/{id}/children` | 直接`is_a`子级。 |
| `GET /api/by-origin/{aa}` | 具有给定氨基酸来源的条目。 |
| `GET /api/search?q=&limit=` | 搜索结果为轻量级摘要。 |
完整条目有效载荷包括从`definition_ref`解析的`references`,以及类型化的`origin`对象(`{type: "amino_acid", code}`或`{type: "crosslink", sites}`)。搜索响应仅包含`{id, accession, name, mass_mono, is_obsolete}`以降低令牌成本;对任何命中调用`/api/entries/{id}`以获取完整记录。
### MCP 服务器
同一个FastAPI应用程序在`POST /mcp`上安装了一个MCP端点,包含以下工具:
| 工具 | 用途 |
|------|---------|
| `get_by_id(id)` | 查找单个条目。 |
| `get_by_name(name)` | 精确名称查找。 |
| `search(query, limit=25)` | 返回摘要的全文本搜索。 |
| `get_parents(id)` | 条目的直接`is_a`父级。 |
| `get_children(id)` | 条目的直接`is_a`子级。 |
| `get_by_origin(aa)` | 具有给定氨基酸来源的条目。 |
工具响应使用MCP的结构化输出机制:服务器在`tools/list`中发出每个工具的`outputSchema`,并在`tools/call`上返回`structuredContent`(类型化的Pydantic实例)和`content`(文本备用),以便LLM客户端可以解析响应而无需重新读取JSON字符串。
配置您的MCP感知客户端以指向`http://localhost:8000/mcp`(或您部署应用程序的任何位置)。使用Anthropic CLI的示例:
```bash
claude mcp add psi-mod http://localhost:8000/mcp --transport http
```
## API 概述
### 加载
| 函数 | 描述 |
|----------|-------------|
| `psimodpy.load()` | 加载捆绑的PSI-MOD数据库。 |
| `psimodpy.load_from(path)` | 从自定义OBO文件加载。 |
| `psimodpy.parse_obo(path)` | 将OBO文件解析为数据库。 |
| `psimodpy.download_obo()` | 从GitHub下载最新的OBO文件。 |
| `psimodpy.write_tsv(entries, path, *, delimiter)` | 将条目写入TSV(或CSV)文件。 |
| `psimodpy.write_obo(entries, path, *, header_lines)` | 将条目写回PSI-MOD OBO格式。 |
### PsiModDatabase
| 方法 | 描述 |
|--------|-------------|
| `db[id]` | 按ID(int或`"MOD:00046"`)查找,引发`KeyError`。 |
| `db.get_by_id(id)` | 按ID查找,找不到时返回`None`。 |
| `db.get_by_name(name)` | 不区分大小写的名称查找。 |
| `db.search(query)` | 在名称、定义和同义词中进行全文搜索。 |
| `db.get_by_origin(aa)` | 按氨基酸来源查找条目。 |
| `db.get_parents(entry)` | 直接父级条目(is_a层次结构)。 |
| `db.get_children(entry)` | 直接子级条目。 |
| `db.get_related(entry, type)` | 跟随关系边(derives_from、contains等)。 |
| `db.filter(...)` | 按过时/精简状态过滤。 |
| `db.write_tsv(path, *, delimiter)` | 将所有条目写入TSV(或CSV)文件。 |
| `db.write_obo(path)` | 将所有条目写回OBO格式。 |
| `db.header_lines` | 解析的OBO文件的原始标题行。 |
### PsiModEntry
每个条目提供:`id`、`name`、`definition`、`definition_ref`、`synonyms`、`is_a`、`relationships`、`origin`、`diff_mono`、`diff_avg`、`diff_formula`、`mass_mono`、`mass_avg`、`formula`、`term_spec`、`source`、`formal_charge`、`xref_unimod`、`xref_uniprot_ptm`、`xref_gnome`、`xref_remap`、`in_slim_subset`、`is_obsolete`。
计算属性:`dict_diff_formula`、`dict_formula`、`proforma_diff_formula`。
每个`Synonym`具有:`value`、`type`(`SynonymType`)、`scope`(例如`"EXACT"`、`"RELATED"`)。
### 数据类型
- `AminoAcid` — 单字母氨基酸代码
- `Crosslink` — 多残基或MOD引用的来源
- `Synonym` / `SynonymType` — 类型化的同义词
- `Relationship` / `RelationshipType` — 有向关系
- `TermSpec` — 位置特定度
- `Source` — 修饰来源
## 开发
```bash
just install # 使用uv安装依赖项
just lint # ruff check
just format # ruff format
just ty # ty类型检查
just test # pytest
just check # lint + 类型检查 + 测试
```
## 相关项目
| 软件包 | 描述 |
|---------|-------------|
| [unimodpy](https://github.com/tacular-omics/unimodpy) | 解析和查询UNIMOD质谱修饰数据库 |
| [uniprotptmpy](https://github.com/tacular-omics/uniprotptmpy) | 解析和查询UniProt PTM受控词汇表 |
## 许可证
[MIT](LICENSE)