matelab-python-sdk 0.2.0a3__tar.gz → 0.2.0a5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/.github/workflows/release.yml +1 -1
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/AGENTS.md +10 -10
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/CONTEXT.md +6 -1
- matelab_python_sdk-0.2.0a5/PKG-INFO +69 -0
- matelab_python_sdk-0.2.0a5/README.md +41 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/contracts/matelab-integration-v1.openapi.yaml +95 -39
- matelab_python_sdk-0.2.0a5/docs/agent-workflows.md +100 -0
- matelab_python_sdk-0.2.0a3/README.md → matelab_python_sdk-0.2.0a5/docs/api.md +34 -153
- matelab_python_sdk-0.2.0a5/docs/development.md +68 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/docs/operation-coverage.yaml +3 -3
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/pyproject.toml +14 -13
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/scripts/check_release.py +0 -1
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/__init__.py +2 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/_generated/models.py +16 -1
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/records.py +51 -10
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_records.py +105 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_release.py +2 -2
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/typing/consumer.py +8 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/uv.lock +12 -12
- matelab_python_sdk-0.2.0a3/CHANGELOG.md +0 -470
- matelab_python_sdk-0.2.0a3/PKG-INFO +0 -26
- matelab_python_sdk-0.2.0a3/docs/agent-workflows.md +0 -129
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/.env.example +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/.gitignore +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/LICENSE +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/NOTICE +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/docs/agent-architecture.md +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/scripts/generate_models.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/literature.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_async_attachment_upload.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_generation.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_record_mutations.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_transport.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_uploads_and_literature.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/tests/typing/pyproject.toml +0 -0
|
@@ -84,7 +84,7 @@ jobs:
|
|
|
84
84
|
uv pip install \
|
|
85
85
|
--python "${RUNNER_TEMP}/matelab-consumer/bin/python" \
|
|
86
86
|
dist/release/*.whl \
|
|
87
|
-
"basedpyright
|
|
87
|
+
"basedpyright>=1.40.1" \
|
|
88
88
|
"nodejs-wheel-binaries==22.20.0"
|
|
89
89
|
"${RUNNER_TEMP}/matelab-consumer/bin/python" scripts/check_installed_package.py
|
|
90
90
|
"${RUNNER_TEMP}/matelab-consumer/bin/basedpyright" \
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
## 维护顺序
|
|
6
6
|
|
|
7
|
-
1. **定界**:先读 `git status`
|
|
7
|
+
1. **定界**:先读 `git status` 和适用权威,确定任务范围、用户现有改动和所需权限。
|
|
8
8
|
2. **查证**:涉及 SDK 行为或 Contract 时,沿 public intent → wire operation → Provider evidence 核对受影响
|
|
9
9
|
operation 的 request、response、security、examples、成功码及 PVD/PCG,明确报告 Contract 缺口。文档、排版和
|
|
10
10
|
工具配置修改只核对相关权威。
|
|
11
11
|
3. **收敛**:只修改任务必需的层,检查 public、adapter、generated、tests、coverage 和 docs 中受影响的内容。
|
|
12
|
-
4.
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
4. **验证**:按变更类型执行 [delivery gate](docs/agent-workflows.md#delivery-gate),复用仍覆盖当前变更的有效结果。
|
|
13
|
+
5. **交付**:复核最终 diff 和状态,报告结果、验证证据、限制及未执行项。
|
|
14
|
+
|
|
15
|
+
本地仅为打包配置、构建元数据、发布脚本变化或制品故障按需构建。正式可复现构建、制品审计和安装后消费由
|
|
16
|
+
发布 CI 执行,本地无需重复构建或保留历史 `dist/` 产物。
|
|
15
17
|
|
|
16
18
|
## 分支指针
|
|
17
19
|
|
|
@@ -23,8 +25,6 @@
|
|
|
23
25
|
[`docs/agent-workflows.md#contract-adoption`](docs/agent-workflows.md#contract-adoption)。
|
|
24
26
|
- **Configuration and dependencies**:修改 `pyproject.toml`、依赖范围、lock 或对应 CI 配置时读
|
|
25
27
|
[`docs/agent-workflows.md#configuration-and-dependencies`](docs/agent-workflows.md#configuration-and-dependencies)。
|
|
26
|
-
- **Delivery gate**:交付前按变更类型执行
|
|
27
|
-
[`docs/agent-workflows.md#delivery-gate`](docs/agent-workflows.md#delivery-gate)。
|
|
28
28
|
- **Provider validation**:任何实时 Provider smoke、读取或 mutation 前执行
|
|
29
29
|
[`docs/agent-workflows.md#provider-validation`](docs/agent-workflows.md#provider-validation)。
|
|
30
30
|
- **Release**:准备版本或发布制品时执行;普通 commit/push 只应用其中的授权与 diff 审查要求
|
|
@@ -34,16 +34,16 @@
|
|
|
34
34
|
|
|
35
35
|
| 权威 | 负责内容 |
|
|
36
36
|
| --- | --- |
|
|
37
|
-
| `README.md` |
|
|
37
|
+
| `README.md` | 项目介绍、安装及快速入门 |
|
|
38
|
+
| `docs/api.md` | 当前 public interface、集成语义、完整示例和 Provider 限制 |
|
|
39
|
+
| `docs/development.md` | 开发、验证、版本与构建流程 |
|
|
38
40
|
| `CONTEXT.md` | public 类型和命名采用的领域词汇 |
|
|
39
|
-
| `CHANGELOG.md` | SDK 版本变化与迁移影响;不定义当前接口 |
|
|
40
41
|
| `docs/operation-coverage.yaml` | operation 状态、公开入口、稳定性和已知问题 |
|
|
41
42
|
| `pyproject.toml` | SDK 版本、依赖范围、构建与工具配置;`uv.lock` 只锁定本仓库环境 |
|
|
42
43
|
| Contract lock 与 snapshot | Contract pin 与 wire schema |
|
|
43
44
|
| `src/matelab/__init__.py::__all__` | 公开导入边界 |
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
接口、coverage 或 Contract 权威。
|
|
46
|
+
机器权威变化时,同一变更同步受影响的当前态文档。测试提供行为证据,不替代接口、coverage 或 Contract 权威。
|
|
47
47
|
|
|
48
48
|
## 范围与授权
|
|
49
49
|
|
|
@@ -63,9 +63,14 @@ _Avoid_: Record locator, public record ref, deleted record ref
|
|
|
63
63
|
|
|
64
64
|
**Record locator**:
|
|
65
65
|
A record ref paired with the owned or shared notebook in which it was observed. It is the complete source identity
|
|
66
|
-
used by record reads and record-scoped operations.
|
|
66
|
+
used by owned/shared record reads and record-scoped operations.
|
|
67
67
|
_Avoid_: Record ref, notebook ID
|
|
68
68
|
|
|
69
|
+
**Public record ref**:
|
|
70
|
+
A public association's row ID, paired source notebook and record IDs, and nullable association UID metadata.
|
|
71
|
+
The source ID pair locates its current body; it does not grant notebook-wide access.
|
|
72
|
+
_Avoid_: Record locator, public notebook ID, association ID as record ID
|
|
73
|
+
|
|
69
74
|
**Record version ref**:
|
|
70
75
|
A historical version ID bound to its record locator. It identifies observed historical content, not a separate active
|
|
71
76
|
record.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: matelab-python-sdk
|
|
3
|
+
Version: 0.2.0a5
|
|
4
|
+
Summary: Reusable async Python client for the Matelab Integration Contract
|
|
5
|
+
Author: CMPDC, Institute of Physics, Chinese Academy of Sciences
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
License-File: NOTICE
|
|
9
|
+
Keywords: asyncio,electronic-lab-notebook,eln,matelab,sdk
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: httpx2>=2.13.1
|
|
24
|
+
Requires-Dist: jsonschema>=4.26.0
|
|
25
|
+
Requires-Dist: pydantic>=2.13.5
|
|
26
|
+
Requires-Dist: typing-extensions>=4.16.0
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# matelab-python-sdk
|
|
30
|
+
|
|
31
|
+
Async Python client for the Matelab Integration Contract, with typed interfaces for authentication,
|
|
32
|
+
notebooks, records, attachments, cloud files, templates, and literature. Requires Python 3.11 or newer.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv add matelab-python-sdk
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or use `python -m pip install matelab-python-sdk`.
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
Replace the example credentials with your own:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import asyncio
|
|
48
|
+
|
|
49
|
+
from matelab import AsyncMatelab
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
async def main() -> None:
|
|
53
|
+
async with AsyncMatelab() as client:
|
|
54
|
+
await client.authenticate("user@example.org", "password")
|
|
55
|
+
notebooks = await client.notebooks.list()
|
|
56
|
+
for notebook in notebooks.owned:
|
|
57
|
+
print(notebook.ref)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
asyncio.run(main())
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`AsyncMatelab()` uses `https://matelab.iphy.ac.cn/api` by default. Pass another API root as its first argument.
|
|
64
|
+
|
|
65
|
+
## Documentation
|
|
66
|
+
|
|
67
|
+
- [API reference](https://github.com/tiannianzhu/matelab-python-sdk/blob/main/docs/api.md): Session persistence, errors, examples, and Provider limits.
|
|
68
|
+
- [Operation coverage](https://github.com/tiannianzhu/matelab-python-sdk/blob/main/docs/operation-coverage.yaml): supported operations.
|
|
69
|
+
- [Development and releases](https://github.com/tiannianzhu/matelab-python-sdk/blob/main/docs/development.md): checks, Provider smoke, versioning, and builds.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# matelab-python-sdk
|
|
2
|
+
|
|
3
|
+
Async Python client for the Matelab Integration Contract, with typed interfaces for authentication,
|
|
4
|
+
notebooks, records, attachments, cloud files, templates, and literature. Requires Python 3.11 or newer.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv add matelab-python-sdk
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or use `python -m pip install matelab-python-sdk`.
|
|
13
|
+
|
|
14
|
+
## Quick start
|
|
15
|
+
|
|
16
|
+
Replace the example credentials with your own:
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import asyncio
|
|
20
|
+
|
|
21
|
+
from matelab import AsyncMatelab
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def main() -> None:
|
|
25
|
+
async with AsyncMatelab() as client:
|
|
26
|
+
await client.authenticate("user@example.org", "password")
|
|
27
|
+
notebooks = await client.notebooks.list()
|
|
28
|
+
for notebook in notebooks.owned:
|
|
29
|
+
print(notebook.ref)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
asyncio.run(main())
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`AsyncMatelab()` uses `https://matelab.iphy.ac.cn/api` by default. Pass another API root as its first argument.
|
|
36
|
+
|
|
37
|
+
## Documentation
|
|
38
|
+
|
|
39
|
+
- [API reference](https://github.com/tiannianzhu/matelab-python-sdk/blob/main/docs/api.md): Session persistence, errors, examples, and Provider limits.
|
|
40
|
+
- [Operation coverage](https://github.com/tiannianzhu/matelab-python-sdk/blob/main/docs/operation-coverage.yaml): supported operations.
|
|
41
|
+
- [Development and releases](https://github.com/tiannianzhu/matelab-python-sdk/blob/main/docs/development.md): checks, Provider smoke, versioning, and builds.
|
{matelab_python_sdk-0.2.0a3 → matelab_python_sdk-0.2.0a5}/contracts/matelab-integration-v1.lock.json
RENAMED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"contract_line": "integration-v1",
|
|
4
4
|
"release": {
|
|
5
|
-
"tag": "v2026.10.
|
|
6
|
-
"commit": "
|
|
5
|
+
"tag": "v2026.10.2",
|
|
6
|
+
"commit": "1183d6833d88a6904598357321ef2d30cf944339"
|
|
7
7
|
},
|
|
8
8
|
"openapi": {
|
|
9
9
|
"source_path": "openapi/matelab-integration-v1.openapi.yaml",
|
|
10
10
|
"snapshot": "matelab-integration-v1.openapi.yaml",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "4806fc2e4b4cb4cf94464be6f1b5f574f5a44745bf7cbc03d8644a13e57f8ec9"
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: Matelab Integration Contract
|
|
4
|
-
version: "2026.10.
|
|
4
|
+
version: "2026.10.2"
|
|
5
5
|
description: |
|
|
6
6
|
Current PHP wire contract for generating SDKs against the selected
|
|
7
7
|
`matelab-server` Provider version.
|
|
@@ -26,6 +26,7 @@ info:
|
|
|
26
26
|
- controller/Eln.php
|
|
27
27
|
- controller/Eln_api.php
|
|
28
28
|
- controller/Eln_items.php
|
|
29
|
+
- controller/Eln_public.php
|
|
29
30
|
- controller/Eln_template.php
|
|
30
31
|
- controller/Eln_url.php
|
|
31
32
|
- controller/Files.php
|
|
@@ -36,6 +37,7 @@ info:
|
|
|
36
37
|
- model/FileQuoteModel.php
|
|
37
38
|
- model/FilesModel.php
|
|
38
39
|
- traits/ElnTrait.php
|
|
40
|
+
- traits/ElnPublicTrait.php
|
|
39
41
|
- traits/RecommendTrait.php
|
|
40
42
|
- service/ElnApiImport.php
|
|
41
43
|
- service/ElnApiUpdate.php
|
|
@@ -53,7 +55,7 @@ info:
|
|
|
53
55
|
- sql/recommend.sql
|
|
54
56
|
x-provider-audit:
|
|
55
57
|
currentCommit: 3f39d47b7ad43bed618b029a7d9cc51fab852eb6
|
|
56
|
-
previousReleaseEvidenceCommit:
|
|
58
|
+
previousReleaseEvidenceCommit: 3f39d47b7ad43bed618b029a7d9cc51fab852eb6
|
|
57
59
|
lastProviderVerifiedCommit: 3f39d47b7ad43bed618b029a7d9cc51fab852eb6
|
|
58
60
|
contractStatus: current-provider-aligned
|
|
59
61
|
# Summary of changes adopted by current Supported Routes since the last
|
|
@@ -62,36 +64,8 @@ info:
|
|
|
62
64
|
# updates against that fixed release baseline; use [] if no relevant changes.
|
|
63
65
|
# Entries are not per-change verification results or a cumulative history.
|
|
64
66
|
incorporatedChanges:
|
|
65
|
-
- {operationId:
|
|
66
|
-
- {operationId:
|
|
67
|
-
- {operationId: readRecord, change: encrypted-modules-and-unresolved-user-fields-modeled}
|
|
68
|
-
- {operationId: listRecordComments, change: unresolved-author-descriptors-modeled}
|
|
69
|
-
- {operationId: listRecordRelations, change: unresolved-comment-author-descriptors-modeled}
|
|
70
|
-
- {operationId: updateRecordData, change: staged-files-folder-append-wired-into-request-and-base64-excluded}
|
|
71
|
-
- {operationId: importRecordDataset, change: unreachable-base64-file-input-excluded}
|
|
72
|
-
- {operationId: searchRecordData, change: fixed-result-field-aliases-reserved-and-extraction-path-constrained}
|
|
73
|
-
- {operationId: saveNotebookMetadata, change: decoded-list-display-requests-reject-null-uid-and-invalid-path}
|
|
74
|
-
- {operationId: updateRecordData, change: quote-extraction-path-constrained-and-collaboration-code-0-documented}
|
|
75
|
-
- {operationId: listNotebooks, change: stored-types-return-non-null-decoded-json}
|
|
76
|
-
- {operationId: extractLiteratureMetadata, change: nested-errors-and-opaque-array-results-modeled}
|
|
77
|
-
- {operationId: listCloudDriveFiles, change: unreachable-null-timestamp-success-removed}
|
|
78
|
-
- {operationId: downloadRecordAttachment, change: zero-start-open-range-4097-byte-cap-documented}
|
|
79
|
-
- {operationId: downloadRecordCommentAttachment, change: zero-start-open-range-4097-byte-cap-documented}
|
|
80
|
-
- {operationId: downloadLiteraturePdf, change: zero-start-open-range-4097-byte-cap-documented}
|
|
81
|
-
- {operationId: downloadCloudDriveFile, change: zero-start-open-range-4097-byte-cap-documented}
|
|
82
|
-
- {operationId: listCurrentUserElnGroups, change: dangling-group-id-null-and-first-group-error-modeled}
|
|
83
|
-
- {operationId: downloadRecordCommentAttachment, change: zero-byte-attachment-download-supported}
|
|
84
|
-
- {operationId: listNotebookRecords, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
85
|
-
- {operationId: exportRecords, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
86
|
-
- {operationId: searchRecordData, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
87
|
-
- {operationId: listDeletedRecordPage, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
88
|
-
- {operationId: copyRecord, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
89
|
-
- {operationId: addRecordRelation, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
90
|
-
- {operationId: deleteRecordRelation, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
91
|
-
- {operationId: saveRecordComment, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
92
|
-
- {operationId: deleteRecordComment, change: local-data-server-success-code-zero-internal-forwarding-code-excluded}
|
|
93
|
-
- {operationId: downloadRecordAttachment, change: remote-data-server-download-excluded-pending-proxy-verification}
|
|
94
|
-
- {operationId: downloadRecordCommentAttachment, change: remote-data-server-download-excluded-pending-proxy-verification}
|
|
67
|
+
- {operationId: readRecord, change: public-only-body-access-and-source-record-identity-documented}
|
|
68
|
+
- {operationId: listPublicNotebookRecords, change: source-record-identifiers-distinguished-from-public-association-id}
|
|
95
69
|
x-consumer-evidence:
|
|
96
70
|
- repository: /home/tnzhu/projects/matelab-mcp
|
|
97
71
|
commit: 94a129b2df0ef0fbcf179c10550fb7c9a5dd2e6f
|
|
@@ -2054,6 +2028,17 @@ paths:
|
|
|
2054
2028
|
operationId: listPublicNotebookRecords
|
|
2055
2029
|
tags: [Records]
|
|
2056
2030
|
summary: List records in a visible public notebook
|
|
2031
|
+
description: |
|
|
2032
|
+
Authentication is required even for a globally visible public directory.
|
|
2033
|
+
`eln` is the public directory's name. Visibility comes from a global
|
|
2034
|
+
directory (`eln_public.userid=0`) or the caller's directory membership;
|
|
2035
|
+
owning or sharing the source notebook is not required.
|
|
2036
|
+
To read an item's current body, call `readRecord` with query
|
|
2037
|
+
`eln=items[n].eln_id&id=items[n].item_id&version=0`. The directory's own
|
|
2038
|
+
id and each returned association `id` are different identities and must
|
|
2039
|
+
not be substituted. `uid` is nullable association metadata, not a body
|
|
2040
|
+
selector. An association can survive a missing source notebook or record;
|
|
2041
|
+
listing it does not guarantee that its body can still be read.
|
|
2057
2042
|
security: [{bearerAuth: []}]
|
|
2058
2043
|
requestBody:
|
|
2059
2044
|
required: true
|
|
@@ -2092,6 +2077,8 @@ paths:
|
|
|
2092
2077
|
- {id: 52, item_id: 9002, eln_id: 12, uid: null, title: null, comm: null, locked: false, eln_name: null, userid: null, username: null, email: null, owner: false}
|
|
2093
2078
|
error:
|
|
2094
2079
|
value: {code: 2, msg: Public notebook not found, errcode: 2, errmsg: Public notebook not found}
|
|
2080
|
+
authenticationError:
|
|
2081
|
+
value: {code: 1, msg: Authentication required, errcode: 1, errmsg: Authentication required}
|
|
2095
2082
|
/eln_items/items:
|
|
2096
2083
|
get:
|
|
2097
2084
|
operationId: listNotebookRecordPage
|
|
@@ -2676,19 +2663,37 @@ paths:
|
|
|
2676
2663
|
operation uses query parameters. Reading records writes an audit-log entry;
|
|
2677
2664
|
that incidental access logging does not turn the resource read into a
|
|
2678
2665
|
mutation operation.
|
|
2666
|
+
Public-record bodies use this same operation and `ItemViewResponse`.
|
|
2667
|
+
After `listPublicNotebookRecords`, pass that item's `eln_id` as `eln` and
|
|
2668
|
+
`item_id` as `id`; keep them paired and use `version=0` for current content.
|
|
2669
|
+
Do not substitute the public directory id, the public association's `id`,
|
|
2670
|
+
or its nullable `uid`.
|
|
2671
|
+
Authentication is still required. For a caller with no source-notebook
|
|
2672
|
+
owner/share grant, an exact `(eln_id, item_id)` association in a global
|
|
2673
|
+
public directory or one they belong to grants record-level read access.
|
|
2674
|
+
This does not grant ownership or access to other records in that notebook.
|
|
2675
|
+
Global public access is read-only; a member directory can separately
|
|
2676
|
+
grant editing through the association's `editable` setting.
|
|
2677
|
+
`modules` contains the canonical body or the existing encrypted descriptor;
|
|
2678
|
+
this endpoint does not decrypt it. The required `uid` field can be null
|
|
2679
|
+
for historical content and is not needed to construct the body request.
|
|
2680
|
+
Missing/invalid authentication returns business code 1; denied access or
|
|
2681
|
+
an invalid current-record identity returns code 2, both over HTTP 200.
|
|
2682
|
+
Historical reads must use a version from this record's own `modify_log`;
|
|
2683
|
+
the Provider does not enforce historical-version ownership (PVD-005).
|
|
2679
2684
|
security:
|
|
2680
2685
|
- bearerAuth: []
|
|
2681
2686
|
parameters:
|
|
2682
2687
|
- name: eln
|
|
2683
2688
|
in: query
|
|
2684
2689
|
required: true
|
|
2685
|
-
description:
|
|
2690
|
+
description: Source notebook database identifier; use PublicRecordItem.eln_id for a public record, not the public directory id.
|
|
2686
2691
|
schema: {type: integer, minimum: 1}
|
|
2687
2692
|
example: 12
|
|
2688
2693
|
- name: id
|
|
2689
2694
|
in: query
|
|
2690
2695
|
required: true
|
|
2691
|
-
description:
|
|
2696
|
+
description: Source record database identifier; use PublicRecordItem.item_id for a public record, not its association id or UID.
|
|
2692
2697
|
schema: {type: integer, minimum: 1}
|
|
2693
2698
|
example: 9001
|
|
2694
2699
|
- name: version
|
|
@@ -2766,6 +2771,38 @@ paths:
|
|
|
2766
2771
|
template_show: ""
|
|
2767
2772
|
template_text: Calibration Template
|
|
2768
2773
|
template_intro: ""
|
|
2774
|
+
public:
|
|
2775
|
+
summary: Current body for a public-only reader without source-notebook sharing
|
|
2776
|
+
value:
|
|
2777
|
+
code: 0
|
|
2778
|
+
msg: ""
|
|
2779
|
+
errcode: 0
|
|
2780
|
+
errmsg: ""
|
|
2781
|
+
title: Calibration Run
|
|
2782
|
+
keywords: [calibration]
|
|
2783
|
+
modules:
|
|
2784
|
+
- {type: richtext, name: Notes, uid: module-example, data: Sanitized content}
|
|
2785
|
+
template_id: 8
|
|
2786
|
+
datetime_modify: 1767946200000
|
|
2787
|
+
username: Example User
|
|
2788
|
+
modify_log: []
|
|
2789
|
+
uid: REC-EXAMPLE-001
|
|
2790
|
+
current_version: 0
|
|
2791
|
+
item_id: 9001
|
|
2792
|
+
datetime_locked: 0
|
|
2793
|
+
locked: false
|
|
2794
|
+
signs: []
|
|
2795
|
+
signed: false
|
|
2796
|
+
owner: false
|
|
2797
|
+
eln_text: Example Notebook
|
|
2798
|
+
eln_server: localhost
|
|
2799
|
+
eln_id: 12
|
|
2800
|
+
editable: false
|
|
2801
|
+
keyword_eln: [calibration]
|
|
2802
|
+
pdf_enable: true
|
|
2803
|
+
template_show: ""
|
|
2804
|
+
template_text: Calibration Template
|
|
2805
|
+
template_intro: ""
|
|
2769
2806
|
nullable:
|
|
2770
2807
|
summary: Historical record with nullable UID, user, template, and keywords
|
|
2771
2808
|
value:
|
|
@@ -2902,6 +2939,11 @@ paths:
|
|
|
2902
2939
|
msg: No operation permission
|
|
2903
2940
|
errcode: 2
|
|
2904
2941
|
errmsg: No operation permission
|
|
2942
|
+
authenticationError:
|
|
2943
|
+
value: {code: 1, msg: Authentication required, errcode: 1, errmsg: Authentication required}
|
|
2944
|
+
identityError:
|
|
2945
|
+
summary: Source notebook and record identifiers do not identify the same current record
|
|
2946
|
+
value: {code: 2, msg: Illegal operation, errcode: 2, errmsg: Illegal operation}
|
|
2905
2947
|
/eln_url/eln:
|
|
2906
2948
|
get:
|
|
2907
2949
|
operationId: downloadRecordAttachment
|
|
@@ -5677,7 +5719,10 @@ components:
|
|
|
5677
5719
|
type: object
|
|
5678
5720
|
required: [eln]
|
|
5679
5721
|
properties:
|
|
5680
|
-
eln:
|
|
5722
|
+
eln:
|
|
5723
|
+
type: string
|
|
5724
|
+
minLength: 1
|
|
5725
|
+
description: Public directory name, not the source notebook name or numeric id.
|
|
5681
5726
|
additionalProperties: false
|
|
5682
5727
|
CreateRecordRequest:
|
|
5683
5728
|
type: object
|
|
@@ -6214,10 +6259,21 @@ components:
|
|
|
6214
6259
|
type: object
|
|
6215
6260
|
required: [id, item_id, eln_id, uid, title, comm, locked, eln_name, userid, username, email, owner]
|
|
6216
6261
|
properties:
|
|
6217
|
-
id:
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6262
|
+
id:
|
|
6263
|
+
type: integer
|
|
6264
|
+
minimum: 1
|
|
6265
|
+
description: Public association row identifier; not the record id accepted by readRecord.
|
|
6266
|
+
item_id:
|
|
6267
|
+
type: integer
|
|
6268
|
+
minimum: 1
|
|
6269
|
+
description: Source record identifier; pass as readRecord query id together with this row's eln_id.
|
|
6270
|
+
eln_id:
|
|
6271
|
+
type: integer
|
|
6272
|
+
minimum: 1
|
|
6273
|
+
description: Source notebook identifier; pass as readRecord query eln, not the public directory id.
|
|
6274
|
+
uid:
|
|
6275
|
+
type: [string, "null"]
|
|
6276
|
+
description: Nullable UID copied into the association; not required for the numeric readRecord selector.
|
|
6221
6277
|
title: {type: [string, "null"]}
|
|
6222
6278
|
comm: {type: [string, "null"]}
|
|
6223
6279
|
locked: {type: boolean}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Agent Maintenance Workflows
|
|
2
|
+
|
|
3
|
+
本文件只在对应分支触发时加载。机器值始终从仓库读取;这里记录顺序、授权边界和完成标准。
|
|
4
|
+
|
|
5
|
+
## Contract adoption
|
|
6
|
+
|
|
7
|
+
1. 读取 Contract lock 和远端 release refs。只选择新的 annotated tag;移动分支和改写后的旧
|
|
8
|
+
snapshot 不能成为 SDK pin。记录 tag object、peeled commit、OpenAPI path 与 SHA-256。完成标准:四者固定且
|
|
9
|
+
互相一致。
|
|
10
|
+
2. 比较当前 snapshot 与 release commit。逐项核对 operation request、response、security、examples、成功码、
|
|
11
|
+
Provider evidence 及 PVD/PCG。完成标准:每个 schema/operation 差异都分类为 generated-only、adapter、public
|
|
12
|
+
interface、test、coverage 或 docs 影响。
|
|
13
|
+
3. request/response 均由生成 wire model 校验,adapter 只映射 public Python 名称与 wire 字段。required nullable
|
|
14
|
+
使用无默认值的 `T | None`;request 拒绝未知字段,response 接受新增字段。若专用 schema、顶层 request 或
|
|
15
|
+
Provider evidence 相互矛盾,保留当前安全边界并报告缺口。
|
|
16
|
+
4. 从 release commit 复制 OpenAPI snapshot;同一变更更新 lock 的 tag、commit、snapshot path 和 SHA-256,运行
|
|
17
|
+
生成脚本并审查完整 generated diff。`_generated` 只由生成脚本修改;projection 只补偿生成器表达能力并保留
|
|
18
|
+
inherited required、`if/then`、`oneOf`、`anyOf` 和 `not`。完成标准:snapshot hash 与 lock 相等,生成差异
|
|
19
|
+
全部可由 OpenAPI 差异解释,`--check` 确定、非写入且能发现 stale output。
|
|
20
|
+
5. 同步 runtime、测试、operation coverage、README、`docs/api.md`、`docs/development.md`、`pyproject.toml` 与 `uv.lock`
|
|
21
|
+
中受影响的当前态。
|
|
22
|
+
完成标准:每个 Contract 差异都有实现或明确 containment,当前文档与采用后的 Contract 一致。
|
|
23
|
+
6. 执行 [delivery gate](#delivery-gate)。
|
|
24
|
+
|
|
25
|
+
## Configuration and dependencies
|
|
26
|
+
|
|
27
|
+
配置值以 `pyproject.toml` 为准,`uv.lock` 固定本仓库的解析环境,不反向定义发布依赖范围。
|
|
28
|
+
|
|
29
|
+
- `[project]` 字段依次为 `name`、`version`、`description`、`requires-python`、`keywords`、`authors`、
|
|
30
|
+
`dependencies`,其他字段放在其后。
|
|
31
|
+
- `[tool.basedpyright]` 字段依次为 `pythonVersion`、`typeCheckingMode`、`include`、`exclude`、
|
|
32
|
+
`reportUnannotatedClassAttribute`、`reportIncompatibleUnannotatedOverride`,其他设置放在其后。沿用 SDK 的目标
|
|
33
|
+
Python 版本与检查路径,不照搬其他项目的值。
|
|
34
|
+
- runtime、build 和 dev 依赖仅声明已验证的 `>=` 下限;`nodejs-wheel-binaries` 保留系统所需的精确版本。
|
|
35
|
+
更新声明时同步 lock 和安装后消费检查使用的 CI requirement。
|
|
36
|
+
- 构建后端依赖和 wheel package 显式配置;metadata 与制品检查从这些声明推导预期值。
|
|
37
|
+
|
|
38
|
+
完成标准:配置可解析、声明与 lock 一致、受影响 CI 使用同一约束;字段重排不改变配置含义。
|
|
39
|
+
|
|
40
|
+
## Delivery gate
|
|
41
|
+
|
|
42
|
+
按本次变更选择验证范围:
|
|
43
|
+
|
|
44
|
+
- 纯文档修改检查相关事实、本地路径和 Markdown 引用;示例或接口说明变化要对照当前 public interface。
|
|
45
|
+
- 字段重排或显式写出既有默认值,检查语法与有效配置一致性。工具配置的有效设置变化运行对应工具。
|
|
46
|
+
- SDK 代码、测试行为、Contract、依赖范围或影响制品的构建元数据变化,先跑聚焦测试,再完成下列完整门槛。
|
|
47
|
+
|
|
48
|
+
### SDK test scope
|
|
49
|
+
|
|
50
|
+
SDK 测试覆盖 public interface 到 wire adapter 的映射、认证与 Session、错误与重试、stream/上传生命周期及
|
|
51
|
+
分发制品;Provider 的逐路由原始 HTTP conformance 由 `matelab-spec` 负责。
|
|
52
|
+
|
|
53
|
+
新增或修改 operation 覆盖 method/path/encoding、认证、成功映射及适用的空结果、
|
|
54
|
+
required nullable 和 additive response fields;operation coverage 与 pinned OpenAPI exact match,implemented
|
|
55
|
+
operation 同时具备 public interface、wire adapter 和测试。删除或收紧 public interface 时同步移除过时测试,
|
|
56
|
+
不保留无承诺的墓碑 alias。生成测试覆盖 metadata/checksum、schema、required/nullable、extra policy、确定性和
|
|
57
|
+
stale detection。
|
|
58
|
+
|
|
59
|
+
优先使用 pinned sanitized examples 或小型受控 fixture 验证稳定行为。operation 数量从 pinned Contract 推导,
|
|
60
|
+
不固定当前数量;当前服务地址和依赖版本值不作为回归断言,除非它们本身就是明确的稳定契约。
|
|
61
|
+
配置值变化只验证语法、约束及相关行为,不另加冻结新值或重复实现逻辑的测试。
|
|
62
|
+
|
|
63
|
+
Ruff/Basedpyright 诊断通过修复代码或精确 ignore 解决,不缩小检查范围;Basedpyright 目标为 0 errors / 0 warnings。
|
|
64
|
+
|
|
65
|
+
### Full gate
|
|
66
|
+
|
|
67
|
+
完整命令见 [开发文档](development.md#development)。离线验证不配置 Provider 连接变量;实时 smoke 按
|
|
68
|
+
[Provider validation](#provider-validation) 执行。
|
|
69
|
+
|
|
70
|
+
检查因权限失败或无进展时,先查看输出和自己启动的进程,区分普通失败与文件、socket、网络或子进程限制。
|
|
71
|
+
有沙箱阻塞证据后停止自己启动的停滞测试,通过工具审批机制申请最小范围重试;保留配置,不改权限、凭证或测试
|
|
72
|
+
行为来绕过限制。超时本身不是沙箱拒绝的证据;无法升级或被拒绝时报告阻塞。
|
|
73
|
+
|
|
74
|
+
完成标准:必需检查退出为零,`git diff --check` 无错误;skip 报告测试名称和原因,deselected 说明筛选范围。
|
|
75
|
+
|
|
76
|
+
## Provider validation
|
|
77
|
+
|
|
78
|
+
1. 实时验证仅在任务需要且会话授权覆盖目标及副作用时执行;连接设置和 smoke 命令见
|
|
79
|
+
[开发文档](development.md#opt-in-provider-consumer-smoke)。
|
|
80
|
+
2. 执行前确认目标是隔离服务、`.env.test` 处于 Git ignore、命令显式加载该文件,并列出 authentication、refresh、
|
|
81
|
+
mutation 或带写痕迹读取的副作用。
|
|
82
|
+
3. mutation 场景在写前记录 fixture,在写后回读,并尽力清理。完成标准:目标、Provider commit、命令、通过数、
|
|
83
|
+
skip/failure 和清理结果均可追溯;凭证及敏感 payload 未进入输出或提交。
|
|
84
|
+
|
|
85
|
+
## Release
|
|
86
|
+
|
|
87
|
+
普通 commit/push 只处理已授权的 diff,不自动改版本、建 tag 或发布。发布准备完成但缺少外部操作授权时,
|
|
88
|
+
先交付可审查结果,再请求执行授权。以下步骤适用于实际发布:
|
|
89
|
+
|
|
90
|
+
1. 按 [版本规则](development.md#versioning) 选择 SDK 版本,读取 `[project].version`,确认待发布版本未发布
|
|
91
|
+
且 Contract pin 完整。公开接口删除、重命名、类型收紧或不兼容行为变化按 breaking change 处理。
|
|
92
|
+
完成标准:版本、当前文档和 tag 名 `v{version}` 一致。
|
|
93
|
+
2. 提交前同步受影响的当前文档,完成 [delivery gate](#delivery-gate)。构建元数据或发布流程变化时,核对
|
|
94
|
+
metadata 版本与固定的 PyPI 发布 Action 是否兼容;需要本地制品证据时使用
|
|
95
|
+
[手工构建命令](development.md#reproducible-release-build)。创建已审查、已授权的 release commit。
|
|
96
|
+
3. 创建指向 release commit 的 annotated `v{version}` tag。先推送 `origin` 的 main/tag,再推送 GitHub mirror 的
|
|
97
|
+
main/tag;只有与项目版本完全匹配的 tag 触发 Trusted Publishing workflow,第三方 Action 固定 immutable
|
|
98
|
+
commit SHA。
|
|
99
|
+
4. 跟踪 [发布 CI](../.github/workflows/release.yml) 的测试、可复现构建、制品审计、安装后消费和 PyPI publish。
|
|
100
|
+
完成标准:两个远端 main/tag 对应 release commit,CI 全部通过,PyPI 对应版本可读取。
|