matelab-python-sdk 0.1.0a23__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.0a23 → matelab_python_sdk-0.2.0a1}/CHANGELOG.md +51 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/CONTEXT.md +5 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/PKG-INFO +126 -64
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/README.md +125 -63
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/contracts/matelab-integration-v1.openapi.yaml +647 -215
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/docs/agent-workflows.md +5 -2
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/docs/operation-coverage.yaml +58 -58
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/scripts/generate_models.py +11 -3
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/__init__.py +2 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/_generated/models.py +785 -210
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/_wire_validation.py +30 -2
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/cloud_drive.py +1 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/groups.py +6 -2
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/literature.py +12 -2
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/notebooks.py +4 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/records.py +64 -26
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/templates.py +1 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/streaming.py +1 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_client.py +25 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_cloud_drive.py +10 -5
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_comments_and_downloads.py +62 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_extended_records.py +32 -4
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_generation.py +122 -12
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_groups.py +4 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_notebook_lifecycle.py +33 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_record_lifecycle.py +1 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_record_mutations.py +119 -2
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_records.py +75 -4
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_template_lifecycle.py +31 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_transport.py +12 -15
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_uploads_and_literature.py +42 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/docs/agent-architecture.md +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_async_attachment_upload.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a23 → matelab_python_sdk-0.2.0a1}/tests/typing/pyproject.toml +0 -0
|
@@ -3,6 +3,57 @@
|
|
|
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
|
+
|
|
38
|
+
## 0.1.0a24 - 2026-09-26
|
|
39
|
+
|
|
40
|
+
- Adopts immutable `matelab-spec v0.5.0` at commit `4f2959472933da47d1ea3e275552884d51d4fdd9`
|
|
41
|
+
(annotated tag object `cc362a9a36601f5d07d6e90c2c6994e33c202d88`) and OpenAPI SHA-256
|
|
42
|
+
`dee14f76e24b2d7c3d97a6f30a9369ac093d615d132db85836ab86671eadcf18`, aligned with Provider source evidence
|
|
43
|
+
`acb0e12f2d62a8959ab9e9bddf38e34a67c19b48`. The release evidence covers an isolated Provider, not production.
|
|
44
|
+
- Breaking: `templates.save_content()` rejects invalid JSON in JSON code modules with non-null `style` before HTTP.
|
|
45
|
+
Generated write models and whole-request validation now enforce nested JSON content schemas. Readback continues to
|
|
46
|
+
preserve raw code strings (including empty or non-JSON text) and null; reading a module does not guarantee it can
|
|
47
|
+
be saved unchanged. JSON code without a style, or with null style, retains its existing write boundary.
|
|
48
|
+
- Regenerates the private application bootstrap fields and credential-login restriction to an omitted or empty
|
|
49
|
+
WeChat code. Public credential login already omits that input. Record module creation preserves explicit code
|
|
50
|
+
strings and leaves omitted/null initialization to the Provider, which now uses an empty string without synthesizing
|
|
51
|
+
an ECharts series object.
|
|
52
|
+
- Documents Chat SSO expiry against the user's mutable activity timestamp, single-attempt exchange, and lack of
|
|
53
|
+
concurrent one-time guarantees. Synchronizes the release's PVD/PCG renumbering and retired comment-upload issue.
|
|
54
|
+
- Keeps staged files-module append root-only because its dedicated schema and `UpdateRecordRequest.add[]` still
|
|
55
|
+
disagree about folder paths (now PVD-030). Retains the read-only missing table-attachment timestamp compatibility.
|
|
56
|
+
|
|
6
57
|
## 0.1.0a23 - 2026-09-04
|
|
7
58
|
|
|
8
59
|
- Temporarily accepts `readRecord` table file attachments that contain valid `filename`, `hash`, and `size` fields but
|
|
@@ -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,12 +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`,
|
|
43
|
-
|
|
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
|
+
source `openapi/matelab-integration-v1.openapi.yaml`, the local snapshot path, and SHA-256
|
|
44
|
+
`a07997128c1df17a03724c5af8e11b45a34166f9d6e15558e66e0a301f2e0813`. The annotated tag object is
|
|
45
|
+
`ae8098e1b5178b69706bddd8b70c1b4cfe3e09ba`.
|
|
44
46
|
|
|
45
47
|
## Installation
|
|
46
48
|
|
|
@@ -64,15 +66,32 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
64
66
|
|
|
65
67
|
```bash
|
|
66
68
|
uv build --no-build-isolation --out-dir dist/release
|
|
67
|
-
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
|
|
68
70
|
```
|
|
69
71
|
|
|
70
72
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
71
73
|
tag, commit, and checksum recorded below.
|
|
72
74
|
|
|
73
|
-
The Contract
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
The Contract uses Provider source evidence from `3f39d47b7ad43bed618b029a7d9cc51fab852eb6`; v2026.10.1 validation ran
|
|
76
|
+
against an isolated test instance and does not establish production behavior. The corresponding Front Consumer evidence
|
|
77
|
+
is `0c985f5b6da8e8ef4627ca7065cea85e408ae981`; it informs cross-Consumer capability review but does not define the SDK
|
|
78
|
+
interface. Provider limitations that remain relevant to integrations are documented alongside the affected interfaces
|
|
79
|
+
below.
|
|
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.
|
|
76
95
|
|
|
77
96
|
## Design
|
|
78
97
|
|
|
@@ -107,7 +126,7 @@ category:
|
|
|
107
126
|
| `MatelabUsageError` | `VALIDATION` | No | The call cannot be represented safely; correct its arguments. |
|
|
108
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. |
|
|
109
128
|
| `MatelabTransportError` | `UPSTREAM` | No | The HTTP exchange failed; `status_code` is present for HTTP failures, and a mutation outcome may be unknown. |
|
|
110
|
-
| `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. |
|
|
111
130
|
|
|
112
131
|
For `MatelabProviderError`, the SDK maps Provider wire code `2` to `BUSINESS`, `4` to `VALIDATION`, and `3` or an
|
|
113
132
|
unknown code to `UPSTREAM`. `provider_code` is diagnostic metadata, not a stable routing identifier, and integrations
|
|
@@ -116,12 +135,12 @@ selected from the code mapping; they do not reproduce Provider-authored text. Au
|
|
|
116
135
|
`MatelabAuthenticationError`; code `5`
|
|
117
136
|
triggers at most one refresh and replay only for authenticated operations that explicitly enable
|
|
118
137
|
`retry_on_access_expired`, otherwise codes `1` and `5` raise `MatelabAuthenticationError` directly.
|
|
119
|
-
|
|
120
|
-
|
|
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.
|
|
121
140
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
122
141
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
123
142
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
124
|
-
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
|
|
125
144
|
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
126
145
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
127
146
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
@@ -315,11 +334,10 @@ These three operations use the Provider's staged-name finalizer and must be the
|
|
|
315
334
|
supports one file column. A locally rejected target does not spend the handle; once transport starts, an ambiguous
|
|
316
335
|
result cannot be retried through the same client.
|
|
317
336
|
|
|
318
|
-
Files-module append and table/files replacement
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
until that wire-schema conflict is resolved (PVD-044):
|
|
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):
|
|
323
341
|
|
|
324
342
|
```python
|
|
325
343
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -333,6 +351,20 @@ await client.records.update(
|
|
|
333
351
|
)
|
|
334
352
|
```
|
|
335
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
|
+
|
|
363
|
+
For `RecordModuleCreation(module_type="code", language="json", style="echarts")`, omitted, null, and empty `data` all
|
|
364
|
+
produce an empty string; explicit `"0"` stays `"0"`. Send the desired initial chart configuration as a JSON code string.
|
|
365
|
+
Richtext/code module creation defaults missing `data` to `""`; form/table/files creation ignores it and initializes
|
|
366
|
+
content as `[]`.
|
|
367
|
+
|
|
336
368
|
A replacement starts with an occurrence returned by `records.read()`; applications must not fabricate a
|
|
337
369
|
`RecordAttachmentRef`. The same `RecordAttachmentReplacement` covers both table-file and files-module occurrences:
|
|
338
370
|
|
|
@@ -436,7 +468,8 @@ and `deletePersonalLiteratureItem`.
|
|
|
436
468
|
Every other implemented operation is explicitly `experimental`; the exact per-operation list and its
|
|
437
469
|
PVD/PCG references live in
|
|
438
470
|
`docs/operation-coverage.yaml`. `readApplicationBootstrap` is intentionally unexposed because it returns the Provider
|
|
439
|
-
application environment and menu model,
|
|
471
|
+
application environment and menu model, including required `data_express_enable` and `data_express_text` fields, while
|
|
472
|
+
SDK identity is sourced from token issuance. `readLiteratureCreateTemplate`
|
|
440
473
|
is intentionally unexposed because it returns a frontend form definition and an optional deployment flag rather than
|
|
441
474
|
a resource needed by the SDK interface. There are no `planned` operations. Experimental support means the SDK
|
|
442
475
|
validates and exposes the pinned Contract while preserving limitations such as unstable ordering/pagination,
|
|
@@ -450,6 +483,13 @@ automatically retried, and the returned token set is stored in the same in-memor
|
|
|
450
483
|
session = await client.exchange_chat_sso_code(code="chat-sanitizedcode123", key="sanitized-shared-key")
|
|
451
484
|
```
|
|
452
485
|
|
|
486
|
+
The code suffix must be non-empty and the shared key must be non-blank. The Provider rejects a code after the current
|
|
487
|
+
user's `active_datetime` plus 300 seconds; that timestamp can change through other user activity, so Consumers must not
|
|
488
|
+
derive a deadline from the code or automatically retry an uncertain exchange. A sequential replay is rejected, but the
|
|
489
|
+
Provider's read-then-clear implementation does not guarantee that concurrent exchanges have only one winner.
|
|
490
|
+
Ordinary credential login does not expose the non-empty WeChat binding code branch, which can reassign another account's
|
|
491
|
+
OpenID (PVD-032).
|
|
492
|
+
|
|
453
493
|
Group and user discovery expose sharing identities without inventing Provider pagination:
|
|
454
494
|
|
|
455
495
|
```python
|
|
@@ -460,9 +500,11 @@ targets = await client.users.search("Example Researcher", global_scope=False)
|
|
|
460
500
|
`groups.list()` returns the `GroupSummary` tuple directly. Ordering remains Provider-unspecified and is documented
|
|
461
501
|
rather than repeated as a constant result field. The Provider's members for an unstable first group remain wire-only;
|
|
462
502
|
`users.search()` is the public recipient-discovery interface. These two discovery interfaces are experimental because
|
|
463
|
-
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-
|
|
503
|
+
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-017, PVD-025).
|
|
464
504
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
465
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).
|
|
466
508
|
|
|
467
509
|
Notebook create and direct sharing use the Provider acknowledgement without an automatic follow-up read:
|
|
468
510
|
|
|
@@ -485,9 +527,12 @@ Consequently, update performs one list pre-read followed by the write. This pres
|
|
|
485
527
|
Provider offers no compare-and-swap or atomic read-modify-write operation. Call `list()` or `shares()` explicitly when
|
|
486
528
|
the application needs current state. `NotebookPermissions` normalizes the Provider's stored and effective masks and
|
|
487
529
|
is reused by record pages instead of maintaining a second nearly identical permission model. Direct shares always
|
|
488
|
-
have implicit read access even when every optional permission is false (PVD-
|
|
530
|
+
have implicit read access even when every optional permission is false (PVD-037).
|
|
489
531
|
`provider_signing_allowed` only represents Provider policy, not an SDK signing operation. Share-list order remains
|
|
490
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).
|
|
491
536
|
|
|
492
537
|
Template discovery keeps a template database identity separate from direct-share, market-acquisition, and group
|
|
493
538
|
relation identities:
|
|
@@ -510,17 +555,19 @@ await client.templates.save_content(template, modules)
|
|
|
510
555
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
511
556
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
512
557
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
513
|
-
types. A JSON-language code module
|
|
514
|
-
|
|
558
|
+
types. A JSON-language code module's `data` remains code text and may be empty, null, or invalid JSON;
|
|
559
|
+
`language=json` does not imply that Consumers can parse it. When template content contains a code module with
|
|
560
|
+
`language=json` and non-null `style`, its code text must be valid JSON to save. Number and boolean table cells preserve
|
|
561
|
+
the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
515
562
|
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
516
|
-
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-
|
|
517
|
-
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-
|
|
563
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-013).
|
|
564
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-008),
|
|
518
565
|
so a read-modify-save sequence can overwrite a concurrent change.
|
|
519
566
|
|
|
520
567
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
521
568
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
522
569
|
because Provider discovery ordering/pagination and historical `images` compatibility are not fully stable
|
|
523
|
-
(PCG-
|
|
570
|
+
(PCG-011, PCG-012, PVD-038, PVD-022).
|
|
524
571
|
|
|
525
572
|
`templates.list()` returns one tuple. `TemplateSummary.scope` is limited to `owned`, `shared`, `group`, and `public`;
|
|
526
573
|
Provider marketplace acquisitions and system defaults are both public templates. An acquired public template carries
|
|
@@ -535,7 +582,7 @@ transaction. Creation returns the new `TemplateRef`; metadata replacement and ot
|
|
|
535
582
|
the Provider supplies no new resource representation. `update()` therefore requires the complete title, summary, and
|
|
536
583
|
keyword set rather than implying a partial patch. `update_usage()` generates the Provider's required fresh hidden
|
|
537
584
|
correlation value internally. Usage attachments remain unsupported until their staging and binding lifecycle is
|
|
538
|
-
contracted safely (PVD-
|
|
585
|
+
contracted safely (PVD-003). Marketplace revision limitations remain explicit through `content_version`,
|
|
539
586
|
`published_content_version`, and `market_review_reason` (PVD-021).
|
|
540
587
|
|
|
541
588
|
Extended record reads stay behind the same `records` interface:
|
|
@@ -555,7 +602,10 @@ relations = await client.records.relations(source)
|
|
|
555
602
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
556
603
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
557
604
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
558
|
-
|
|
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.
|
|
608
|
+
The current Provider excludes encrypted records from search (PVD-041); an empty search result therefore does
|
|
559
609
|
not prove that no matching encrypted record exists.
|
|
560
610
|
|
|
561
611
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
@@ -565,7 +615,7 @@ The Provider calls its notebook directory tree `subtype`; that name remains wire
|
|
|
565
615
|
positive folder ID for one folder.
|
|
566
616
|
|
|
567
617
|
`records.page` fixes the legacy request to `page_size=0&default=1`, preventing the known owner-preference writes
|
|
568
|
-
described by PVD-
|
|
618
|
+
described by PVD-028; its total is derived internally from the Provider's complete matching ID list. The result keeps
|
|
569
619
|
semantic `NotebookPermissions` directly, without a shallow context model or duplicated notebook/owner/template
|
|
570
620
|
display metadata. Effective request pagination, the UI selection list and Provider keyword-filter echo are not exposed.
|
|
571
621
|
Its `search` argument, shared with `records.list()`, maps the Provider's wire-level `content` filter without exposing
|
|
@@ -578,8 +628,7 @@ Public summaries keep source notebook attribution but omit the Provider's unused
|
|
|
578
628
|
email; their `notebook_title` follows the same naming used by export and search results. Relation refs retain only the
|
|
579
629
|
stored relation row and declared target IDs; nullable JOIN previews and resolved target identity stay wire-only.
|
|
580
630
|
Search and relation order remain unspecified, and no continuation token is invented. Export and search return tuples
|
|
581
|
-
directly
|
|
582
|
-
shape.
|
|
631
|
+
directly. Remote data-server forwarding code `10` is rejected because only local data-server results are covered.
|
|
583
632
|
`DeletedRecordPage` does not repeat its input notebook.
|
|
584
633
|
|
|
585
634
|
Record creation keeps blank creation and structured import as separate capabilities:
|
|
@@ -603,10 +652,10 @@ imported = await client.records.import_dataset(
|
|
|
603
652
|
|
|
604
653
|
Blank-record creation returns `None` because the Provider returns no record identity, even when the caller supplies a
|
|
605
654
|
UID. Import validates the complete batch with generated wire models but cannot map returned database IDs to
|
|
606
|
-
individual inputs or promise atomicity (PCG-
|
|
655
|
+
individual inputs or promise atomicity (PCG-009); it therefore returns only the tuple of database IDs actually
|
|
607
656
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
608
657
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
609
|
-
missing folders. The current Provider rejects explicit-null table-file imports (PVD-
|
|
658
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-031). Because the SDK accepts
|
|
610
659
|
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
611
660
|
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
612
661
|
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
@@ -618,19 +667,24 @@ without a readback request. Omitting `target_notebook` copies within the source
|
|
|
618
667
|
Record patching exposes a deliberately narrower capability than the raw Provider operation. Scalar/module changes
|
|
619
668
|
cannot smuggle Provider-native attachment strings; staged attachments use separate form-removal, table-replacement,
|
|
620
669
|
files append/replace/remove, and rich-text types. Unsafe form replacement and table-file removal are absent, while a
|
|
621
|
-
files/images removal is rejected when the observed module contains the same hash more than once (PVD-
|
|
622
|
-
PVD-
|
|
670
|
+
files/images removal is rejected when the observed module contains the same hash more than once (PVD-010, PVD-018,
|
|
671
|
+
and PVD-019). The SDK reads current content only when a change needs attachment type, occurrence, row, or index state;
|
|
623
672
|
ordinary module creation and deletion rely on the Provider's own canonical update validation. `records.update()`
|
|
624
673
|
returns the acknowledgement classification
|
|
625
674
|
`"persisted"`, `"pending"`, or `"unknown"`; it does not
|
|
626
675
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
627
|
-
retries stay disabled.
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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.
|
|
686
|
+
|
|
687
|
+
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-009
|
|
634
688
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
635
689
|
caller-relative `editable` display flag: the mutation endpoint performs the source permission check. Relation
|
|
636
690
|
deletion lists current relations only to refuse an observed cross-notebook target-ID collision because the Provider
|
|
@@ -640,12 +694,12 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
640
694
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
641
695
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
642
696
|
|
|
643
|
-
Comment upload follows the current Provider's literal one-request `file` field
|
|
697
|
+
Comment upload follows the current Provider's literal one-request `file` field. Comment mutations return `None`
|
|
644
698
|
after acknowledgement. Edit first verifies that the selected
|
|
645
699
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
646
700
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
647
701
|
caller ownership. Neither operation performs a post-write read. Staged comment attachments have no Contract abort
|
|
648
|
-
operation, and binding remains affected by PVD-
|
|
702
|
+
operation, and binding remains affected by PVD-003. Comment create/update use the same `body` vocabulary as the
|
|
649
703
|
returned `RecordComment.body`; the SDK does not perform rich-text display normalization, while the Provider's
|
|
650
704
|
documented surrounding-whitespace trim still applies when saving.
|
|
651
705
|
`RecordCommentRef` carries its `RecordLocator`, so update and delete accept the ref rather than an entire comment or a
|
|
@@ -667,9 +721,12 @@ async with await client.records.download_comment_attachment(
|
|
|
667
721
|
```
|
|
668
722
|
|
|
669
723
|
`DownloadStream` exposes status, content type, length, range, and disposition metadata without buffering the
|
|
670
|
-
complete file. Streams are not automatically replayed. `ByteRange` deliberately rejects `bytes=0-0` (PVD-
|
|
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.
|
|
671
728
|
Comment attachment refs contain only file identity. Pass the parent comment ref returned by the same read when
|
|
672
|
-
downloading; current Providers do not verify that association (PVD-
|
|
729
|
+
downloading; current Providers do not verify that association (PVD-006).
|
|
673
730
|
|
|
674
731
|
Cross-domain staging keeps resumable state and completed-file identity separate:
|
|
675
732
|
|
|
@@ -691,7 +748,7 @@ Provider URL and upload-session identity needed by internal binding and cleanup
|
|
|
691
748
|
splice either into content. The result does not claim that a later literature/cloud operation checks the uploader or
|
|
692
749
|
consumes the file exactly once. `uploads.abort()` accepts either an active `StagedUploadSession` or a completed
|
|
693
750
|
`StagedFile` and exposes the Provider's legacy code-2 cancellation signal as a `None`-returning compensating cleanup
|
|
694
|
-
that is not independently verified (PVD-
|
|
751
|
+
that is not independently verified (PVD-024).
|
|
695
752
|
Staging mutations are never automatically retried.
|
|
696
753
|
|
|
697
754
|
Literature identities distinguish the personal library from shared libraries:
|
|
@@ -721,7 +778,11 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
721
778
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
722
779
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
723
780
|
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
724
|
-
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-
|
|
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).
|
|
725
786
|
Literature list
|
|
726
787
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
727
788
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
@@ -746,22 +807,22 @@ Create returns `None` and never guesses the new item from list position because
|
|
|
746
807
|
canonical update preflights the raw item response and refuses to drop top-level or nested source/hidden fields. Passing
|
|
747
808
|
`allow_source_metadata_loss=True` explicitly skips that preflight and sends the canonical replacement directly. The
|
|
748
809
|
default read/check/write protection is best effort rather than atomic because the Provider offers no revision or
|
|
749
|
-
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-
|
|
810
|
+
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-012).
|
|
750
811
|
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata.
|
|
751
812
|
Permanent personal deletion is named `permanently_delete`, returns `None`, and is non-recoverable. Sharing requires
|
|
752
813
|
list-observed item summaries, user-search summaries and a
|
|
753
|
-
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-
|
|
814
|
+
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-008, PVD-027).
|
|
754
815
|
|
|
755
816
|
Literature comments use explicit `create_comment()` and `update_comment()` intents. Creation first reads the current
|
|
756
817
|
detail and rejects when the caller already owns a comment; callers then use that comment's `LiteratureCommentRef` with
|
|
757
818
|
`update_comment()`. The ref contains only the Provider comment-row identity. Update and delete send that identity
|
|
758
819
|
directly because the Provider mutation verifies current ownership and library permission. The creation preflight
|
|
759
820
|
maintains the Integration Contract's one-caller-comment invariant for ordinary SDK use, but is not atomic because the
|
|
760
|
-
Provider has no matching uniqueness constraint (PVD-
|
|
821
|
+
Provider has no matching uniqueness constraint (PVD-026). When sharing with `copy_owner_comment=True`, multiple
|
|
761
822
|
caller-owned comments remain an explicit ambiguity because the Provider would otherwise choose one implicitly. A
|
|
762
823
|
staged attachment can replace one `matelab-staged-file` marker; raw temporary URLs are rejected. These checks prevent
|
|
763
|
-
common misuse but do not repair the Provider's cross-user UID lookup (PVD-
|
|
764
|
-
experimental because the Provider permission JOIN is not scoped to the current user (PVD-
|
|
824
|
+
common misuse but do not repair the Provider's cross-user UID lookup (PVD-003). Shared-library reads and writes remain
|
|
825
|
+
experimental because the Provider permission JOIN is not scoped to the current user (PVD-007); successful SDK calls
|
|
765
826
|
must not be treated as independent authorization proof. Literature PDF downloads reuse `DownloadStream` and the
|
|
766
827
|
stable `ByteRange` subset.
|
|
767
828
|
|
|
@@ -777,16 +838,16 @@ await client.cloud_drive.bind_staged_file(staged, target=folder)
|
|
|
777
838
|
snapshot and quota usage; pagination applies only to `files`, while request page arguments are not echoed. Personal-root
|
|
778
839
|
metadata and permissions are synthetic/fixed for this Contract line and remain wire-only. File rows omit the constant
|
|
779
840
|
caller owner fields and do not invent a folder location that the Provider fails to return for root-wide searches.
|
|
780
|
-
Listings likewise omit search/order/direction request echoes. Ordering has no stable ID tie-breaker (PCG-
|
|
781
|
-
|
|
782
|
-
time
|
|
841
|
+
Listings likewise omit search/order/direction request echoes. Ordering has no stable ID tie-breaker (PCG-011, PVD-038).
|
|
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.
|
|
783
844
|
|
|
784
845
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
785
846
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
786
|
-
the Provider binds by temporary row ID without checking its owner (PVD-
|
|
847
|
+
the Provider binds by temporary row ID without checking its owner (PVD-002), and finalize atomicity/idempotency remain
|
|
787
848
|
absent. Batch move and permanent delete do not claim Provider per-item results or atomicity. Permanent
|
|
788
849
|
deletion is named `permanently_delete_files` and is non-recoverable. Cloud downloads
|
|
789
|
-
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-
|
|
850
|
+
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-015-safe
|
|
790
851
|
range subset. Cloud mutations are not automatically retried.
|
|
791
852
|
|
|
792
853
|
Owned, shared, and public catalog notebooks use one `NotebookRef`, distinguished by its
|
|
@@ -813,8 +874,9 @@ names or groups, so those fields are `None`. Public summary and creation time re
|
|
|
813
874
|
Contract, while the unified model uses the wider owned/shared nullable types.
|
|
814
875
|
|
|
815
876
|
Provider `types`, `display`, and `requests` fields configure its notebook-list UI rather than notebook domain data.
|
|
816
|
-
`types`
|
|
817
|
-
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
|
|
818
880
|
preservation only as an internal Provider compatibility detail.
|
|
819
881
|
|
|
820
882
|
Template render metadata is also excluded from template summaries and record reads. A `Record` has one
|
|
@@ -822,7 +884,7 @@ Template render metadata is also excluded from template summaries and record rea
|
|
|
822
884
|
notebook title/keywords, Provider data-server routing, or the frontend PDF-capability flag. `Record.version` identifies
|
|
823
885
|
historical content and is `None` for the current content. `Record.versions` contains refs usable for historical reads;
|
|
824
886
|
Provider lock and signature projections remain wire-only. Relation creation still checks returned data servers
|
|
825
|
-
internally to mitigate PVD-
|
|
887
|
+
internally to mitigate PVD-009.
|
|
826
888
|
|
|
827
889
|
Provider record-finalization and additional-signature mutations are intentionally outside the pinned Contract and SDK
|
|
828
890
|
interface. They require the account password to unlock a private key, combine version creation with signing, provide no
|
|
@@ -926,6 +988,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
926
988
|
```
|
|
927
989
|
|
|
928
990
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
929
|
-
byte-identical wheel and source distribution hashes. The
|
|
930
|
-
`
|
|
931
|
-
`
|
|
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`.
|