matelab-python-sdk 0.1.0a24__tar.gz → 0.2.0a1__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.1.0a24 → matelab_python_sdk-0.2.0a1}/CHANGELOG.md +32 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/CONTEXT.md +5 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/PKG-INFO +74 -31
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/README.md +73 -30
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/contracts/matelab-integration-v1.openapi.yaml +465 -140
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/docs/agent-workflows.md +5 -2
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/docs/operation-coverage.yaml +22 -22
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/scripts/generate_models.py +11 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/__init__.py +2 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/_generated/models.py +488 -169
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/cloud_drive.py +1 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/groups.py +6 -2
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/literature.py +11 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/notebooks.py +4 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/records.py +61 -23
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/streaming.py +1 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_cloud_drive.py +10 -5
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_comments_and_downloads.py +62 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_extended_records.py +32 -4
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_generation.py +43 -8
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_groups.py +4 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_notebook_lifecycle.py +33 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_record_lifecycle.py +1 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_record_mutations.py +82 -2
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_records.py +75 -4
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_transport.py +12 -15
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_uploads_and_literature.py +42 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/docs/agent-architecture.md +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_async_attachment_upload.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a24 → matelab_python_sdk-0.2.0a1}/tests/typing/pyproject.toml +0 -0
|
@@ -3,6 +3,38 @@
|
|
|
3
3
|
This file records release-to-release changes and migration impact. It is not the authority for the current interface;
|
|
4
4
|
see [README.md](README.md) for current behavior and [AGENTS.md](AGENTS.md) for maintenance policy.
|
|
5
5
|
|
|
6
|
+
## 0.2.0a1 - 2026-10-02
|
|
7
|
+
|
|
8
|
+
- Establishes the `0.x` versioning rule: incompatible public changes advance the SDK minor version; alpha/beta/RC
|
|
9
|
+
counters identify successive candidates for the same target version. SDK and Contract versions remain independent.
|
|
10
|
+
- Adopts immutable `matelab-spec v2026.10.1` at commit `9941e2d623a1c2633adb459b823d78d4e62d3802`
|
|
11
|
+
(annotated tag object `ae8098e1b5178b69706bddd8b70c1b4cfe3e09ba`) and OpenAPI SHA-256
|
|
12
|
+
`a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813`, aligned with Provider evidence
|
|
13
|
+
`3f39d47b7ad43bed618b029a7d9cc51fab852eb6`. The Contract's calendar version identifies a Provider-specific
|
|
14
|
+
snapshot verified on an isolated Workerman instance with local data servers.
|
|
15
|
+
- Breaking: record JSON operations accept business code `0` only; Provider-internal forwarding code `10` is outside
|
|
16
|
+
the verified callable scope and raises `MatelabProtocolError` (PVD-049). Search aliases additionally reserve
|
|
17
|
+
`eln_id`, `title`, and `eln_name`; extraction paths reject numeric strings, negative indices and a numeric fourth
|
|
18
|
+
segment before HTTP. Generation retains these referenced scalar and positional JSON Schema constraints.
|
|
19
|
+
- Adds `Record.encrypted_modules` and public `EncryptedRecordModules`, preserving ciphertext and additive fields
|
|
20
|
+
without decryption. Encrypted reads have no plaintext modules or attachment refs. State-dependent updates reject
|
|
21
|
+
encrypted content locally; stateless module changes retain the Provider's pre-write password check. Unresolved
|
|
22
|
+
author descriptors map to `author_name=None` while remaining validated in the private wire layer (PVD-044).
|
|
23
|
+
- Restores `RecordFilesAttachmentAppend.folder_path` after the dedicated shape became valid within the top-level
|
|
24
|
+
update request. A non-empty path uses the staged-name finalizer, validates safe segments and requires an exclusive
|
|
25
|
+
mutation; reuse and ambiguous-finalization protections remain in effect (PVD-030). Inline base64 file input remains
|
|
26
|
+
outside the public write boundary (PVD-042).
|
|
27
|
+
- Breaking: `GroupSummary.ref` can be `None` for a dangling membership (PVD-048), and `CloudFile.modified_at` is now
|
|
28
|
+
a required string because stored null timestamps fail before a successful Provider row is returned (PVD-047).
|
|
29
|
+
Notebook reads accept non-null JSON type settings, but metadata updates reject settings or extraction requests that
|
|
30
|
+
cannot be preserved within the write Contract before mutation (PVD-046).
|
|
31
|
+
- Literature metadata extraction maps nested Provider errors to the usual safe SDK errors. Empty or opaque lists
|
|
32
|
+
raise `MatelabProtocolError` instead of being presented as publication candidates (PVD-045).
|
|
33
|
+
- Allows zero-byte comment attachment discovery/downloads and documents the 4097-byte cap on local open ranges
|
|
34
|
+
beginning at zero. Download metadata remains available for explicit continuation; no automatic replay is added.
|
|
35
|
+
- Retains the existing read-only missing table-attachment timestamp containment and the unexposed password,
|
|
36
|
+
signing, record-title-update and structured-error-detail capabilities.
|
|
37
|
+
|
|
6
38
|
## 0.1.0a24 - 2026-09-26
|
|
7
39
|
|
|
8
40
|
- Adopts immutable `matelab-spec v0.5.0` at commit `4f2959472933da47d1ea3e275552884d51d4fdd9`
|
|
@@ -85,6 +85,11 @@ A template-shaped value composed of JSON-compatible scalars and containers, with
|
|
|
85
85
|
allowed wherever the template expects a file.
|
|
86
86
|
_Avoid_: Arbitrary object, stored record module, Provider attachment reference
|
|
87
87
|
|
|
88
|
+
**Encrypted record modules**:
|
|
89
|
+
Stored ciphertext returned without decryption, separate from a record's available plaintext modules and attachments.
|
|
90
|
+
The encrypted descriptor is read evidence; it does not provide a decryption or password management interface.
|
|
91
|
+
_Avoid_: Empty record content, decrypted modules
|
|
92
|
+
|
|
88
93
|
**Staged attachment**:
|
|
89
94
|
An upload prepared in a selected notebook for one later record import or update; uploading does not choose the target
|
|
90
95
|
record.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matelab-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0a1
|
|
4
4
|
Summary: Reusable async Python client for the Matelab Integration Contract
|
|
5
5
|
Author-email: 朱天念 <zhutiannian@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -35,14 +35,14 @@ This README describes the current SDK interface, integration semantics, examples
|
|
|
35
35
|
[AGENTS.md](AGENTS.md) for durable maintenance rules, and `docs/operation-coverage.yaml` for the machine-readable
|
|
36
36
|
operation inventory.
|
|
37
37
|
|
|
38
|
-
The current alpha is `0.
|
|
38
|
+
The current alpha is `0.2.0a1`. `[project].version` in `pyproject.toml` is the sole SDK version source;
|
|
39
39
|
`uv.lock` only mirrors that source.
|
|
40
40
|
|
|
41
|
-
The SDK is pinned to the immutable `matelab-spec
|
|
42
|
-
`contracts/matelab-integration-v1.lock.json`, records peeled commit `
|
|
41
|
+
The SDK is pinned to the immutable `matelab-spec v2026.10.1` Contract Release. The sole pin,
|
|
42
|
+
`contracts/matelab-integration-v1.lock.json`, records peeled commit `9941e2d623a1c2633adb459b823d78d4e62d3802`,
|
|
43
43
|
source `openapi/matelab-integration-v1.openapi.yaml`, the local snapshot path, and SHA-256
|
|
44
|
-
`
|
|
45
|
-
`
|
|
44
|
+
`a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813`. The annotated tag object is
|
|
45
|
+
`ae8098e1b5178b69706bddd8b70c1b4cfe3e09ba`.
|
|
46
46
|
|
|
47
47
|
## Installation
|
|
48
48
|
|
|
@@ -66,18 +66,33 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
68
|
uv build --no-build-isolation --out-dir dist/release
|
|
69
|
-
python -m pip install dist/release/matelab_python_sdk-0.
|
|
69
|
+
python -m pip install dist/release/matelab_python_sdk-0.2.0a1-py3-none-any.whl
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
73
73
|
tag, commit, and checksum recorded below.
|
|
74
74
|
|
|
75
|
-
The Contract uses Provider source evidence from `
|
|
75
|
+
The Contract uses Provider source evidence from `3f39d47b7ad43bed618b029a7d9cc51fab852eb6`; v2026.10.1 validation ran
|
|
76
76
|
against an isolated test instance and does not establish production behavior. The corresponding Front Consumer evidence
|
|
77
77
|
is `0c985f5b6da8e8ef4627ca7065cea85e408ae981`; it informs cross-Consumer capability review but does not define the SDK
|
|
78
78
|
interface. Provider limitations that remain relevant to integrations are documented alongside the affected interfaces
|
|
79
79
|
below.
|
|
80
80
|
|
|
81
|
+
Contract releases now use calendar versions to identify Provider-specific snapshots. This snapshot covers the
|
|
82
|
+
Workerman runtime with the `localhost` data-server branch for ELN records and attachments; remote data-server
|
|
83
|
+
forwarding is outside its verified callable scope (PVD-049).
|
|
84
|
+
|
|
85
|
+
## Versioning
|
|
86
|
+
|
|
87
|
+
SDK versions express compatibility of the public Python interface and behavior. Python prerelease spelling follows
|
|
88
|
+
PEP 440: `0.2.0a1` is the first alpha candidate for `0.2.0`. During `0.x` development, incompatible changes advance
|
|
89
|
+
the minor version. From `1.0.0`, compatible fixes advance patch, compatible additions advance minor, and incompatible
|
|
90
|
+
changes advance major. Successive candidates for the same target version use `aN`, `bN`, or `rcN`.
|
|
91
|
+
|
|
92
|
+
Contract calendar versions identify Provider wire snapshots independently. Each SDK release records its exact
|
|
93
|
+
Contract tag, commit and checksum in the lock; multiple SDK fixes can use the same Contract release. Adopting a new
|
|
94
|
+
Contract changes the SDK version according to its public impact. See [CHANGELOG.md](CHANGELOG.md) for migration details.
|
|
95
|
+
|
|
81
96
|
## Design
|
|
82
97
|
|
|
83
98
|
The public module is intentionally small:
|
|
@@ -111,7 +126,7 @@ category:
|
|
|
111
126
|
| `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
|
|
112
127
|
| `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; record `provider_code` and route recovery by `category`; `provider_message` is an SDK-owned safe summary. |
|
|
113
128
|
| `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
|
|
114
|
-
| `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract;
|
|
129
|
+
| `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract or cannot supply the structured result required by the SDK operation; inspect the Provider result or SDK boundary. |
|
|
115
130
|
|
|
116
131
|
For `MatelabProviderError`, the SDK maps Provider wire code `2` to `BUSINESS`, `4` to `VALIDATION`, and `3` or an
|
|
117
132
|
unknown code to `UPSTREAM`. `provider_code` is diagnostic metadata, not a stable routing identifier, and integrations
|
|
@@ -120,12 +135,12 @@ selected from the code mapping; they do not reproduce Provider-authored text. Au
|
|
|
120
135
|
`MatelabAuthenticationError`; code `5`
|
|
121
136
|
triggers at most one refresh and replay only for authenticated operations that explicitly enable
|
|
122
137
|
`retry_on_access_expired`, otherwise codes `1` and `5` raise `MatelabAuthenticationError` directly.
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
Record operations accept business code `0`. Provider-internal forwarding code `10` is outside the pinned
|
|
139
|
+
callable Contract and raises `MatelabProtocolError` rather than assigning an error category.
|
|
125
140
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
126
141
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
127
142
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
128
|
-
The pinned
|
|
143
|
+
The pinned v2026.10.1 Contract also declares optional code-4 `errs`, but PVD-029 and PCG-010 record opaque array/object
|
|
129
144
|
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
130
145
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
131
146
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
@@ -319,11 +334,10 @@ These three operations use the Provider's staged-name finalizer and must be the
|
|
|
319
334
|
supports one file column. A locally rejected target does not spend the handle; once transport starts, an ambiguous
|
|
320
335
|
result cannot be retried through the same client.
|
|
321
336
|
|
|
322
|
-
Files-module append and table/files replacement
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
until that wire-schema conflict is resolved (PVD-030):
|
|
337
|
+
Files-module append at the module root and table/files replacement may be combined with other non-conflicting record
|
|
338
|
+
changes. `RecordFilesAttachmentAppend.folder_path` optionally selects folders within the files module. A non-empty
|
|
339
|
+
path uses the staged-name finalizer and must be the only mutation in its update request; the SDK validates every
|
|
340
|
+
segment before writing to avoid the Provider's malformed-path fallback to the module root (PVD-030):
|
|
327
341
|
|
|
328
342
|
```python
|
|
329
343
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -337,6 +351,15 @@ await client.records.update(
|
|
|
337
351
|
)
|
|
338
352
|
```
|
|
339
353
|
|
|
354
|
+
To append within a folder, use a fresh upload in a separate update:
|
|
355
|
+
|
|
356
|
+
```python
|
|
357
|
+
await client.records.update(
|
|
358
|
+
source,
|
|
359
|
+
(RecordFilesAttachmentAppend(module="Files", attachment=folder_uploaded, folder_path=("Evidence", "Raw Data")),),
|
|
360
|
+
)
|
|
361
|
+
```
|
|
362
|
+
|
|
340
363
|
For `RecordModuleCreation(module_type="code", language="json", style="echarts")`, omitted, null, and empty `data` all
|
|
341
364
|
produce an empty string; explicit `"0"` stays `"0"`. Send the desired initial chart configuration as a JSON code string.
|
|
342
365
|
Richtext/code module creation defaults missing `data` to `""`; form/table/files creation ignores it and initializes
|
|
@@ -480,6 +503,8 @@ rather than repeated as a constant result field. The Provider's members for an u
|
|
|
480
503
|
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-017, PVD-025).
|
|
481
504
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
482
505
|
exposing the Provider's data-server routing value.
|
|
506
|
+
An observed dangling group membership has `GroupSummary.ref=None` and no usable group identity. If such a membership
|
|
507
|
+
is selected as the Provider's first group, the whole request can fail with a Provider error (PVD-048).
|
|
483
508
|
|
|
484
509
|
Notebook create and direct sharing use the Provider acknowledgement without an automatic follow-up read:
|
|
485
510
|
|
|
@@ -505,6 +530,9 @@ is reused by record pages instead of maintaining a second nearly identical permi
|
|
|
505
530
|
have implicit read access even when every optional permission is false (PVD-037).
|
|
506
531
|
`provider_signing_allowed` only represents Provider policy, not an SDK signing operation. Share-list order remains
|
|
507
532
|
unspecified.
|
|
533
|
+
Stored notebook type configuration may decode to any non-null JSON value, but metadata writes accept arrays only.
|
|
534
|
+
If the stored configuration or display extraction requests cannot be preserved within the write Contract, update
|
|
535
|
+
raises `MatelabProtocolError` before sending a mutation instead of silently replacing them (PVD-046).
|
|
508
536
|
|
|
509
537
|
Template discovery keeps a template database identity separate from direct-share, market-acquisition, and group
|
|
510
538
|
relation identities:
|
|
@@ -574,6 +602,9 @@ relations = await client.records.relations(source)
|
|
|
574
602
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
575
603
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
576
604
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
605
|
+
Extraction aliases cannot use `id`, `uid`, `eln_id`, `title`, or `eln_name`, which would overwrite result metadata
|
|
606
|
+
(PVD-043). Paths contain one to four segments: the first three accept non-empty, non-numeric names or non-negative
|
|
607
|
+
integer indices; a fourth segment must be a non-numeric property name. Numeric strings are rejected before HTTP.
|
|
577
608
|
The current Provider excludes encrypted records from search (PVD-041); an empty search result therefore does
|
|
578
609
|
not prove that no matching encrypted record exists.
|
|
579
610
|
|
|
@@ -597,8 +628,7 @@ Public summaries keep source notebook attribution but omit the Provider's unused
|
|
|
597
628
|
email; their `notebook_title` follows the same naming used by export and search results. Relation refs retain only the
|
|
598
629
|
stored relation row and declared target IDs; nullable JOIN previews and resolved target identity stay wire-only.
|
|
599
630
|
Search and relation order remain unspecified, and no continuation token is invented. Export and search return tuples
|
|
600
|
-
directly
|
|
601
|
-
shape.
|
|
631
|
+
directly. Remote data-server forwarding code `10` is rejected because only local data-server results are covered.
|
|
602
632
|
`DeletedRecordPage` does not repeat its input notebook.
|
|
603
633
|
|
|
604
634
|
Record creation keeps blank creation and structured import as separate capabilities:
|
|
@@ -643,11 +673,16 @@ ordinary module creation and deletion rely on the Provider's own canonical updat
|
|
|
643
673
|
returns the acknowledgement classification
|
|
644
674
|
`"persisted"`, `"pending"`, or `"unknown"`; it does not
|
|
645
675
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
646
|
-
retries stay disabled.
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
676
|
+
retries stay disabled. Business code `0` alone does not distinguish persisted data from a browser collaboration
|
|
677
|
+
broadcast; the classification uses the observed Provider acknowledgement and supplies no revision or atomicity
|
|
678
|
+
guarantee. Current collaboration peers must be browsers viewing the same notebook and record.
|
|
679
|
+
Encrypted reads return `Record.encrypted_modules` as an `EncryptedRecordModules` containing the ciphertext,
|
|
680
|
+
algorithm and additive fields; `modules` and `attachments` are empty because no plaintext is available. Plaintext
|
|
681
|
+
reads have `encrypted_modules=None`. State-dependent updates reject encrypted content before mutation, while
|
|
682
|
+
ordinary module changes rely on the Provider's password validation before any write. The password and decryption
|
|
683
|
+
lifecycle remain unexposed. The list-level `RecordSummary.encrypted` flag remains available for discovery.
|
|
684
|
+
Unresolved author lookup descriptors remain wire-only and map to `author_name=None` on records and comments (PVD-044).
|
|
685
|
+
A staged attachment is indeterminate once the write has started.
|
|
651
686
|
|
|
652
687
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-009
|
|
653
688
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -687,6 +722,9 @@ async with await client.records.download_comment_attachment(
|
|
|
687
722
|
|
|
688
723
|
`DownloadStream` exposes status, content type, length, range, and disposition metadata without buffering the
|
|
689
724
|
complete file. Streams are not automatically replayed. `ByteRange` deliberately rejects `bytes=0-0` (PVD-015).
|
|
725
|
+
For local files, `ByteRange.from_start(0)` returns at most the first 4097 bytes. Inspect `content_range` and request
|
|
726
|
+
the next range starting at its end plus one, use a positive explicit end, or omit `byte_range` for the full file.
|
|
727
|
+
Zero-byte comment attachments can be discovered and downloaded without a range.
|
|
690
728
|
Comment attachment refs contain only file identity. Pass the parent comment ref returned by the same read when
|
|
691
729
|
downloading; current Providers do not verify that association (PVD-006).
|
|
692
730
|
|
|
@@ -741,6 +779,10 @@ returns a `PublicationMetadataCandidate`: unstored, rich publication evidence ra
|
|
|
741
779
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
742
780
|
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
743
781
|
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-040).
|
|
782
|
+
The Provider can wrap an error inside an outer successful extraction response. The SDK maps that nested error to
|
|
783
|
+
its usual safe Provider/authentication error. Empty or opaque backend lists raise `MatelabProtocolError` because they
|
|
784
|
+
provide no structured `PublicationMetadataCandidate`; an outer success code does not promise extracted metadata
|
|
785
|
+
(PVD-045).
|
|
744
786
|
Literature list
|
|
745
787
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
746
788
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
@@ -797,8 +839,8 @@ snapshot and quota usage; pagination applies only to `files`, while request page
|
|
|
797
839
|
metadata and permissions are synthetic/fixed for this Contract line and remain wire-only. File rows omit the constant
|
|
798
840
|
caller owner fields and do not invent a folder location that the Provider fails to return for root-wide searches.
|
|
799
841
|
Listings likewise omit search/order/direction request echoes. Ordering has no stable ID tie-breaker (PCG-011, PVD-038).
|
|
800
|
-
|
|
801
|
-
time
|
|
842
|
+
`CloudFile.modified_at` contains the stored modification timestamp as a non-null string. A stored null causes a
|
|
843
|
+
Provider error before a successful file row can be returned (PVD-047). Display-formatted date and time remain wire-only.
|
|
802
844
|
|
|
803
845
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
804
846
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
@@ -832,8 +874,9 @@ names or groups, so those fields are `None`. Public summary and creation time re
|
|
|
832
874
|
Contract, while the unified model uses the wider owned/shared nullable types.
|
|
833
875
|
|
|
834
876
|
Provider `types`, `display`, and `requests` fields configure its notebook-list UI rather than notebook domain data.
|
|
835
|
-
`types`
|
|
836
|
-
fields are
|
|
877
|
+
`types` normally holds classification tags used by the Provider frontend for client-side filtering; legacy stored JSON
|
|
878
|
+
can have another non-null shape. These fields are absent from `NotebookSummary` and from create/update inputs;
|
|
879
|
+
the SDK handles their update-time
|
|
837
880
|
preservation only as an internal Provider compatibility detail.
|
|
838
881
|
|
|
839
882
|
Template render metadata is also excluded from template summaries and record reads. A `Record` has one
|
|
@@ -945,6 +988,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
945
988
|
```
|
|
946
989
|
|
|
947
990
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
948
|
-
byte-identical wheel and source distribution hashes. The SDK Contract pin is immutable `matelab-spec
|
|
949
|
-
`
|
|
950
|
-
`
|
|
991
|
+
byte-identical wheel and source distribution hashes. The SDK Contract pin is immutable `matelab-spec v2026.10.1`, commit
|
|
992
|
+
`9941e2d623a1c2633adb459b823d78d4e62d3802`, and OpenAPI SHA-256
|
|
993
|
+
`a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813`.
|
|
@@ -7,14 +7,14 @@ This README describes the current SDK interface, integration semantics, examples
|
|
|
7
7
|
[AGENTS.md](AGENTS.md) for durable maintenance rules, and `docs/operation-coverage.yaml` for the machine-readable
|
|
8
8
|
operation inventory.
|
|
9
9
|
|
|
10
|
-
The current alpha is `0.
|
|
10
|
+
The current alpha is `0.2.0a1`. `[project].version` in `pyproject.toml` is the sole SDK version source;
|
|
11
11
|
`uv.lock` only mirrors that source.
|
|
12
12
|
|
|
13
|
-
The SDK is pinned to the immutable `matelab-spec
|
|
14
|
-
`contracts/matelab-integration-v1.lock.json`, records peeled commit `
|
|
13
|
+
The SDK is pinned to the immutable `matelab-spec v2026.10.1` Contract Release. The sole pin,
|
|
14
|
+
`contracts/matelab-integration-v1.lock.json`, records peeled commit `9941e2d623a1c2633adb459b823d78d4e62d3802`,
|
|
15
15
|
source `openapi/matelab-integration-v1.openapi.yaml`, the local snapshot path, and SHA-256
|
|
16
|
-
`
|
|
17
|
-
`
|
|
16
|
+
`a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813`. The annotated tag object is
|
|
17
|
+
`ae8098e1b5178b69706bddd8b70c1b4cfe3e09ba`.
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
@@ -38,18 +38,33 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
uv build --no-build-isolation --out-dir dist/release
|
|
41
|
-
python -m pip install dist/release/matelab_python_sdk-0.
|
|
41
|
+
python -m pip install dist/release/matelab_python_sdk-0.2.0a1-py3-none-any.whl
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
45
45
|
tag, commit, and checksum recorded below.
|
|
46
46
|
|
|
47
|
-
The Contract uses Provider source evidence from `
|
|
47
|
+
The Contract uses Provider source evidence from `3f39d47b7ad43bed618b029a7d9cc51fab852eb6`; v2026.10.1 validation ran
|
|
48
48
|
against an isolated test instance and does not establish production behavior. The corresponding Front Consumer evidence
|
|
49
49
|
is `0c985f5b6da8e8ef4627ca7065cea85e408ae981`; it informs cross-Consumer capability review but does not define the SDK
|
|
50
50
|
interface. Provider limitations that remain relevant to integrations are documented alongside the affected interfaces
|
|
51
51
|
below.
|
|
52
52
|
|
|
53
|
+
Contract releases now use calendar versions to identify Provider-specific snapshots. This snapshot covers the
|
|
54
|
+
Workerman runtime with the `localhost` data-server branch for ELN records and attachments; remote data-server
|
|
55
|
+
forwarding is outside its verified callable scope (PVD-049).
|
|
56
|
+
|
|
57
|
+
## Versioning
|
|
58
|
+
|
|
59
|
+
SDK versions express compatibility of the public Python interface and behavior. Python prerelease spelling follows
|
|
60
|
+
PEP 440: `0.2.0a1` is the first alpha candidate for `0.2.0`. During `0.x` development, incompatible changes advance
|
|
61
|
+
the minor version. From `1.0.0`, compatible fixes advance patch, compatible additions advance minor, and incompatible
|
|
62
|
+
changes advance major. Successive candidates for the same target version use `aN`, `bN`, or `rcN`.
|
|
63
|
+
|
|
64
|
+
Contract calendar versions identify Provider wire snapshots independently. Each SDK release records its exact
|
|
65
|
+
Contract tag, commit and checksum in the lock; multiple SDK fixes can use the same Contract release. Adopting a new
|
|
66
|
+
Contract changes the SDK version according to its public impact. See [CHANGELOG.md](CHANGELOG.md) for migration details.
|
|
67
|
+
|
|
53
68
|
## Design
|
|
54
69
|
|
|
55
70
|
The public module is intentionally small:
|
|
@@ -83,7 +98,7 @@ category:
|
|
|
83
98
|
| `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
|
|
84
99
|
| `MatelabProviderError` | `BUSINESS`, `VALIDATION`, or `UPSTREAM` | No | The Provider rejected the request; record `provider_code` and route recovery by `category`; `provider_message` is an SDK-owned safe summary. |
|
|
85
100
|
| `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
|
|
86
|
-
| `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract;
|
|
101
|
+
| `MatelabProtocolError` | `UPSTREAM` | No | The response violates the pinned Contract or cannot supply the structured result required by the SDK operation; inspect the Provider result or SDK boundary. |
|
|
87
102
|
|
|
88
103
|
For `MatelabProviderError`, the SDK maps Provider wire code `2` to `BUSINESS`, `4` to `VALIDATION`, and `3` or an
|
|
89
104
|
unknown code to `UPSTREAM`. `provider_code` is diagnostic metadata, not a stable routing identifier, and integrations
|
|
@@ -92,12 +107,12 @@ selected from the code mapping; they do not reproduce Provider-authored text. Au
|
|
|
92
107
|
`MatelabAuthenticationError`; code `5`
|
|
93
108
|
triggers at most one refresh and replay only for authenticated operations that explicitly enable
|
|
94
109
|
`retry_on_access_expired`, otherwise codes `1` and `5` raise `MatelabAuthenticationError` directly.
|
|
95
|
-
|
|
96
|
-
|
|
110
|
+
Record operations accept business code `0`. Provider-internal forwarding code `10` is outside the pinned
|
|
111
|
+
callable Contract and raises `MatelabProtocolError` rather than assigning an error category.
|
|
97
112
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
98
113
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
99
114
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
100
|
-
The pinned
|
|
115
|
+
The pinned v2026.10.1 Contract also declares optional code-4 `errs`, but PVD-029 and PCG-010 record opaque array/object
|
|
101
116
|
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
102
117
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
103
118
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
@@ -291,11 +306,10 @@ These three operations use the Provider's staged-name finalizer and must be the
|
|
|
291
306
|
supports one file column. A locally rejected target does not spend the handle; once transport starts, an ambiguous
|
|
292
307
|
result cannot be retried through the same client.
|
|
293
308
|
|
|
294
|
-
Files-module append and table/files replacement
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
until that wire-schema conflict is resolved (PVD-030):
|
|
309
|
+
Files-module append at the module root and table/files replacement may be combined with other non-conflicting record
|
|
310
|
+
changes. `RecordFilesAttachmentAppend.folder_path` optionally selects folders within the files module. A non-empty
|
|
311
|
+
path uses the staged-name finalizer and must be the only mutation in its update request; the SDK validates every
|
|
312
|
+
segment before writing to avoid the Provider's malformed-path fallback to the module root (PVD-030):
|
|
299
313
|
|
|
300
314
|
```python
|
|
301
315
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -309,6 +323,15 @@ await client.records.update(
|
|
|
309
323
|
)
|
|
310
324
|
```
|
|
311
325
|
|
|
326
|
+
To append within a folder, use a fresh upload in a separate update:
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
await client.records.update(
|
|
330
|
+
source,
|
|
331
|
+
(RecordFilesAttachmentAppend(module="Files", attachment=folder_uploaded, folder_path=("Evidence", "Raw Data")),),
|
|
332
|
+
)
|
|
333
|
+
```
|
|
334
|
+
|
|
312
335
|
For `RecordModuleCreation(module_type="code", language="json", style="echarts")`, omitted, null, and empty `data` all
|
|
313
336
|
produce an empty string; explicit `"0"` stays `"0"`. Send the desired initial chart configuration as a JSON code string.
|
|
314
337
|
Richtext/code module creation defaults missing `data` to `""`; form/table/files creation ignores it and initializes
|
|
@@ -452,6 +475,8 @@ rather than repeated as a constant result field. The Provider's members for an u
|
|
|
452
475
|
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-017, PVD-025).
|
|
453
476
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
454
477
|
exposing the Provider's data-server routing value.
|
|
478
|
+
An observed dangling group membership has `GroupSummary.ref=None` and no usable group identity. If such a membership
|
|
479
|
+
is selected as the Provider's first group, the whole request can fail with a Provider error (PVD-048).
|
|
455
480
|
|
|
456
481
|
Notebook create and direct sharing use the Provider acknowledgement without an automatic follow-up read:
|
|
457
482
|
|
|
@@ -477,6 +502,9 @@ is reused by record pages instead of maintaining a second nearly identical permi
|
|
|
477
502
|
have implicit read access even when every optional permission is false (PVD-037).
|
|
478
503
|
`provider_signing_allowed` only represents Provider policy, not an SDK signing operation. Share-list order remains
|
|
479
504
|
unspecified.
|
|
505
|
+
Stored notebook type configuration may decode to any non-null JSON value, but metadata writes accept arrays only.
|
|
506
|
+
If the stored configuration or display extraction requests cannot be preserved within the write Contract, update
|
|
507
|
+
raises `MatelabProtocolError` before sending a mutation instead of silently replacing them (PVD-046).
|
|
480
508
|
|
|
481
509
|
Template discovery keeps a template database identity separate from direct-share, market-acquisition, and group
|
|
482
510
|
relation identities:
|
|
@@ -546,6 +574,9 @@ relations = await client.records.relations(source)
|
|
|
546
574
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
547
575
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
548
576
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
577
|
+
Extraction aliases cannot use `id`, `uid`, `eln_id`, `title`, or `eln_name`, which would overwrite result metadata
|
|
578
|
+
(PVD-043). Paths contain one to four segments: the first three accept non-empty, non-numeric names or non-negative
|
|
579
|
+
integer indices; a fourth segment must be a non-numeric property name. Numeric strings are rejected before HTTP.
|
|
549
580
|
The current Provider excludes encrypted records from search (PVD-041); an empty search result therefore does
|
|
550
581
|
not prove that no matching encrypted record exists.
|
|
551
582
|
|
|
@@ -569,8 +600,7 @@ Public summaries keep source notebook attribution but omit the Provider's unused
|
|
|
569
600
|
email; their `notebook_title` follows the same naming used by export and search results. Relation refs retain only the
|
|
570
601
|
stored relation row and declared target IDs; nullable JOIN previews and resolved target identity stay wire-only.
|
|
571
602
|
Search and relation order remain unspecified, and no continuation token is invented. Export and search return tuples
|
|
572
|
-
directly
|
|
573
|
-
shape.
|
|
603
|
+
directly. Remote data-server forwarding code `10` is rejected because only local data-server results are covered.
|
|
574
604
|
`DeletedRecordPage` does not repeat its input notebook.
|
|
575
605
|
|
|
576
606
|
Record creation keeps blank creation and structured import as separate capabilities:
|
|
@@ -615,11 +645,16 @@ ordinary module creation and deletion rely on the Provider's own canonical updat
|
|
|
615
645
|
returns the acknowledgement classification
|
|
616
646
|
`"persisted"`, `"pending"`, or `"unknown"`; it does not
|
|
617
647
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
618
|
-
retries stay disabled.
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
648
|
+
retries stay disabled. Business code `0` alone does not distinguish persisted data from a browser collaboration
|
|
649
|
+
broadcast; the classification uses the observed Provider acknowledgement and supplies no revision or atomicity
|
|
650
|
+
guarantee. Current collaboration peers must be browsers viewing the same notebook and record.
|
|
651
|
+
Encrypted reads return `Record.encrypted_modules` as an `EncryptedRecordModules` containing the ciphertext,
|
|
652
|
+
algorithm and additive fields; `modules` and `attachments` are empty because no plaintext is available. Plaintext
|
|
653
|
+
reads have `encrypted_modules=None`. State-dependent updates reject encrypted content before mutation, while
|
|
654
|
+
ordinary module changes rely on the Provider's password validation before any write. The password and decryption
|
|
655
|
+
lifecycle remain unexposed. The list-level `RecordSummary.encrypted` flag remains available for discovery.
|
|
656
|
+
Unresolved author lookup descriptors remain wire-only and map to `author_name=None` on records and comments (PVD-044).
|
|
657
|
+
A staged attachment is indeterminate once the write has started.
|
|
623
658
|
|
|
624
659
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-009
|
|
625
660
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -659,6 +694,9 @@ async with await client.records.download_comment_attachment(
|
|
|
659
694
|
|
|
660
695
|
`DownloadStream` exposes status, content type, length, range, and disposition metadata without buffering the
|
|
661
696
|
complete file. Streams are not automatically replayed. `ByteRange` deliberately rejects `bytes=0-0` (PVD-015).
|
|
697
|
+
For local files, `ByteRange.from_start(0)` returns at most the first 4097 bytes. Inspect `content_range` and request
|
|
698
|
+
the next range starting at its end plus one, use a positive explicit end, or omit `byte_range` for the full file.
|
|
699
|
+
Zero-byte comment attachments can be discovered and downloaded without a range.
|
|
662
700
|
Comment attachment refs contain only file identity. Pass the parent comment ref returned by the same read when
|
|
663
701
|
downloading; current Providers do not verify that association (PVD-006).
|
|
664
702
|
|
|
@@ -713,6 +751,10 @@ returns a `PublicationMetadataCandidate`: unstored, rich publication evidence ra
|
|
|
713
751
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
714
752
|
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
715
753
|
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-040).
|
|
754
|
+
The Provider can wrap an error inside an outer successful extraction response. The SDK maps that nested error to
|
|
755
|
+
its usual safe Provider/authentication error. Empty or opaque backend lists raise `MatelabProtocolError` because they
|
|
756
|
+
provide no structured `PublicationMetadataCandidate`; an outer success code does not promise extracted metadata
|
|
757
|
+
(PVD-045).
|
|
716
758
|
Literature list
|
|
717
759
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
718
760
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
@@ -769,8 +811,8 @@ snapshot and quota usage; pagination applies only to `files`, while request page
|
|
|
769
811
|
metadata and permissions are synthetic/fixed for this Contract line and remain wire-only. File rows omit the constant
|
|
770
812
|
caller owner fields and do not invent a folder location that the Provider fails to return for root-wide searches.
|
|
771
813
|
Listings likewise omit search/order/direction request echoes. Ordering has no stable ID tie-breaker (PCG-011, PVD-038).
|
|
772
|
-
|
|
773
|
-
time
|
|
814
|
+
`CloudFile.modified_at` contains the stored modification timestamp as a non-null string. A stored null causes a
|
|
815
|
+
Provider error before a successful file row can be returned (PVD-047). Display-formatted date and time remain wire-only.
|
|
774
816
|
|
|
775
817
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
776
818
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
@@ -804,8 +846,9 @@ names or groups, so those fields are `None`. Public summary and creation time re
|
|
|
804
846
|
Contract, while the unified model uses the wider owned/shared nullable types.
|
|
805
847
|
|
|
806
848
|
Provider `types`, `display`, and `requests` fields configure its notebook-list UI rather than notebook domain data.
|
|
807
|
-
`types`
|
|
808
|
-
fields are
|
|
849
|
+
`types` normally holds classification tags used by the Provider frontend for client-side filtering; legacy stored JSON
|
|
850
|
+
can have another non-null shape. These fields are absent from `NotebookSummary` and from create/update inputs;
|
|
851
|
+
the SDK handles their update-time
|
|
809
852
|
preservation only as an internal Provider compatibility detail.
|
|
810
853
|
|
|
811
854
|
Template render metadata is also excluded from template summaries and record reads. A `Record` has one
|
|
@@ -917,6 +960,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
917
960
|
```
|
|
918
961
|
|
|
919
962
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
920
|
-
byte-identical wheel and source distribution hashes. The SDK Contract pin is immutable `matelab-spec
|
|
921
|
-
`
|
|
922
|
-
`
|
|
963
|
+
byte-identical wheel and source distribution hashes. The SDK Contract pin is immutable `matelab-spec v2026.10.1`, commit
|
|
964
|
+
`9941e2d623a1c2633adb459b823d78d4e62d3802`, and OpenAPI SHA-256
|
|
965
|
+
`a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813`.
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"contract_line": "integration-v1",
|
|
4
4
|
"release": {
|
|
5
|
-
"tag": "
|
|
6
|
-
"commit": "
|
|
5
|
+
"tag": "v2026.10.1",
|
|
6
|
+
"commit": "9941e2d623a1c2633adb459b823d78d4e62d3802"
|
|
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": "a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813"
|
|
12
12
|
}
|
|
13
13
|
}
|