matelab-python-sdk 0.1.0a22__tar.gz → 0.1.0a24__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.0a22 → matelab_python_sdk-0.1.0a24}/CHANGELOG.md +25 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/PKG-INFO +72 -47
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/README.md +71 -46
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/contracts/matelab-integration-v1.openapi.yaml +204 -97
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/docs/operation-coverage.yaml +53 -53
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/scripts/generate_models.py +0 -2
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/_generated/models.py +274 -18
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/_wire_validation.py +30 -2
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/literature.py +1 -1
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/records.py +57 -6
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/templates.py +1 -1
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_client.py +25 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_generation.py +79 -4
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_record_mutations.py +37 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_records.py +71 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_template_lifecycle.py +31 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/CONTEXT.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/docs/agent-architecture.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/docs/agent-workflows.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_async_attachment_upload.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_transport.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_uploads_and_literature.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a24}/tests/typing/pyproject.toml +0 -0
|
@@ -3,6 +3,31 @@
|
|
|
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.1.0a24 - 2026-09-26
|
|
7
|
+
|
|
8
|
+
- Adopts immutable `matelab-spec v0.5.0` at commit `4f2959472933da47d1ea3e275552884d51d4fdd9`
|
|
9
|
+
(annotated tag object `cc362a9a36601f5d07d6e90c2c6994e33c202d88`) and OpenAPI SHA-256
|
|
10
|
+
`dee14f76e24b2d7c3d97a6f30a9369ac093d615d132db85836ab86671eadcf18`, aligned with Provider source evidence
|
|
11
|
+
`acb0e12f2d62a8959ab9e9bddf38e34a67c19b48`. The release evidence covers an isolated Provider, not production.
|
|
12
|
+
- Breaking: `templates.save_content()` rejects invalid JSON in JSON code modules with non-null `style` before HTTP.
|
|
13
|
+
Generated write models and whole-request validation now enforce nested JSON content schemas. Readback continues to
|
|
14
|
+
preserve raw code strings (including empty or non-JSON text) and null; reading a module does not guarantee it can
|
|
15
|
+
be saved unchanged. JSON code without a style, or with null style, retains its existing write boundary.
|
|
16
|
+
- Regenerates the private application bootstrap fields and credential-login restriction to an omitted or empty
|
|
17
|
+
WeChat code. Public credential login already omits that input. Record module creation preserves explicit code
|
|
18
|
+
strings and leaves omitted/null initialization to the Provider, which now uses an empty string without synthesizing
|
|
19
|
+
an ECharts series object.
|
|
20
|
+
- Documents Chat SSO expiry against the user's mutable activity timestamp, single-attempt exchange, and lack of
|
|
21
|
+
concurrent one-time guarantees. Synchronizes the release's PVD/PCG renumbering and retired comment-upload issue.
|
|
22
|
+
- Keeps staged files-module append root-only because its dedicated schema and `UpdateRecordRequest.add[]` still
|
|
23
|
+
disagree about folder paths (now PVD-030). Retains the read-only missing table-attachment timestamp compatibility.
|
|
24
|
+
|
|
25
|
+
## 0.1.0a23 - 2026-09-04
|
|
26
|
+
|
|
27
|
+
- Temporarily accepts `readRecord` table file attachments that contain valid `filename`, `hash`, and `size` fields but
|
|
28
|
+
omit the Contract-required `timestamp`. The SDK preserves the omission instead of synthesizing a timestamp; explicit
|
|
29
|
+
null timestamps and other malformed attachment values remain rejected.
|
|
30
|
+
|
|
6
31
|
## 0.1.0a22 - 2026-09-03
|
|
7
32
|
|
|
8
33
|
- Adopts immutable `matelab-spec v0.4.5` at commit `6afac7ff151680130e6e4bc6d95782589b97f4e7` and OpenAPI
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: matelab-python-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a24
|
|
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.1.
|
|
38
|
+
The current alpha is `0.1.0a24`. `[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 v0.
|
|
42
|
-
`contracts/matelab-integration-v1.lock.json`,
|
|
43
|
-
|
|
41
|
+
The SDK is pinned to the immutable `matelab-spec v0.5.0` Contract Release. The sole pin,
|
|
42
|
+
`contracts/matelab-integration-v1.lock.json`, records peeled commit `4f2959472933da47d1ea3e275552884d51d4fdd9`,
|
|
43
|
+
source `openapi/matelab-integration-v1.openapi.yaml`, the local snapshot path, and SHA-256
|
|
44
|
+
`dee14f76e24b2d7c3d97a6f30a9369ac093d615d132db85836ab86671eadcf18`. The annotated tag object is
|
|
45
|
+
`cc362a9a36601f5d07d6e90c2c6994e33c202d88`.
|
|
44
46
|
|
|
45
47
|
## Installation
|
|
46
48
|
|
|
@@ -64,15 +66,17 @@ 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.1.
|
|
69
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a24-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 `acb0e12f2d62a8959ab9e9bddf38e34a67c19b48`; v0.5.0 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.
|
|
76
80
|
|
|
77
81
|
## Design
|
|
78
82
|
|
|
@@ -121,7 +125,7 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
121
125
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
122
126
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
123
127
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
124
|
-
The pinned v0.
|
|
128
|
+
The pinned v0.5.0 Contract also declares optional code-4 `errs`, but PVD-029 and PCG-010 record opaque array/object
|
|
125
129
|
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
126
130
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
127
131
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
@@ -317,9 +321,9 @@ result cannot be retried through the same client.
|
|
|
317
321
|
|
|
318
322
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
319
323
|
other non-conflicting record changes. `RecordFilesAttachmentAppend` currently targets the module root. Although
|
|
320
|
-
v0.
|
|
324
|
+
v0.5.0 records Provider evidence for safe folder paths, its top-level `UpdateRecordRequest.add[]` schema still excludes
|
|
321
325
|
the `path` property declared by the dedicated staged-name append shape; the SDK therefore does not expose folder paths
|
|
322
|
-
until that wire-schema conflict is resolved (PVD-
|
|
326
|
+
until that wire-schema conflict is resolved (PVD-030):
|
|
323
327
|
|
|
324
328
|
```python
|
|
325
329
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -333,6 +337,11 @@ await client.records.update(
|
|
|
333
337
|
)
|
|
334
338
|
```
|
|
335
339
|
|
|
340
|
+
For `RecordModuleCreation(module_type="code", language="json", style="echarts")`, omitted, null, and empty `data` all
|
|
341
|
+
produce an empty string; explicit `"0"` stays `"0"`. Send the desired initial chart configuration as a JSON code string.
|
|
342
|
+
Richtext/code module creation defaults missing `data` to `""`; form/table/files creation ignores it and initializes
|
|
343
|
+
content as `[]`.
|
|
344
|
+
|
|
336
345
|
A replacement starts with an occurrence returned by `records.read()`; applications must not fabricate a
|
|
337
346
|
`RecordAttachmentRef`. The same `RecordAttachmentReplacement` covers both table-file and files-module occurrences:
|
|
338
347
|
|
|
@@ -354,6 +363,12 @@ not accept a caption. Record reads likewise accept only one canonical attachment
|
|
|
354
363
|
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
355
364
|
differ from the current occurrence.
|
|
356
365
|
|
|
366
|
+
As a temporary Provider-compatibility exception, `records.read()` also accepts a table file attachment object whose
|
|
367
|
+
otherwise valid `filename`, `hash`, and `size` are present but whose Contract-required `timestamp` is omitted. The SDK
|
|
368
|
+
preserves that omission in `Record.modules` and does not invent a timestamp; null timestamps and all other malformed
|
|
369
|
+
attachment shapes remain response errors. This exception can be removed after the Provider canonicalizes current and
|
|
370
|
+
historical record content.
|
|
371
|
+
|
|
357
372
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
358
373
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
359
374
|
must not be called while a concurrent editor is known to be active. The Provider offers no expected hash or revision,
|
|
@@ -430,7 +445,8 @@ and `deletePersonalLiteratureItem`.
|
|
|
430
445
|
Every other implemented operation is explicitly `experimental`; the exact per-operation list and its
|
|
431
446
|
PVD/PCG references live in
|
|
432
447
|
`docs/operation-coverage.yaml`. `readApplicationBootstrap` is intentionally unexposed because it returns the Provider
|
|
433
|
-
application environment and menu model,
|
|
448
|
+
application environment and menu model, including required `data_express_enable` and `data_express_text` fields, while
|
|
449
|
+
SDK identity is sourced from token issuance. `readLiteratureCreateTemplate`
|
|
434
450
|
is intentionally unexposed because it returns a frontend form definition and an optional deployment flag rather than
|
|
435
451
|
a resource needed by the SDK interface. There are no `planned` operations. Experimental support means the SDK
|
|
436
452
|
validates and exposes the pinned Contract while preserving limitations such as unstable ordering/pagination,
|
|
@@ -444,6 +460,13 @@ automatically retried, and the returned token set is stored in the same in-memor
|
|
|
444
460
|
session = await client.exchange_chat_sso_code(code="chat-sanitizedcode123", key="sanitized-shared-key")
|
|
445
461
|
```
|
|
446
462
|
|
|
463
|
+
The code suffix must be non-empty and the shared key must be non-blank. The Provider rejects a code after the current
|
|
464
|
+
user's `active_datetime` plus 300 seconds; that timestamp can change through other user activity, so Consumers must not
|
|
465
|
+
derive a deadline from the code or automatically retry an uncertain exchange. A sequential replay is rejected, but the
|
|
466
|
+
Provider's read-then-clear implementation does not guarantee that concurrent exchanges have only one winner.
|
|
467
|
+
Ordinary credential login does not expose the non-empty WeChat binding code branch, which can reassign another account's
|
|
468
|
+
OpenID (PVD-032).
|
|
469
|
+
|
|
447
470
|
Group and user discovery expose sharing identities without inventing Provider pagination:
|
|
448
471
|
|
|
449
472
|
```python
|
|
@@ -454,7 +477,7 @@ targets = await client.users.search("Example Researcher", global_scope=False)
|
|
|
454
477
|
`groups.list()` returns the `GroupSummary` tuple directly. Ordering remains Provider-unspecified and is documented
|
|
455
478
|
rather than repeated as a constant result field. The Provider's members for an unstable first group remain wire-only;
|
|
456
479
|
`users.search()` is the public recipient-discovery interface. These two discovery interfaces are experimental because
|
|
457
|
-
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-
|
|
480
|
+
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-017, PVD-025).
|
|
458
481
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
459
482
|
exposing the Provider's data-server routing value.
|
|
460
483
|
|
|
@@ -479,7 +502,7 @@ Consequently, update performs one list pre-read followed by the write. This pres
|
|
|
479
502
|
Provider offers no compare-and-swap or atomic read-modify-write operation. Call `list()` or `shares()` explicitly when
|
|
480
503
|
the application needs current state. `NotebookPermissions` normalizes the Provider's stored and effective masks and
|
|
481
504
|
is reused by record pages instead of maintaining a second nearly identical permission model. Direct shares always
|
|
482
|
-
have implicit read access even when every optional permission is false (PVD-
|
|
505
|
+
have implicit read access even when every optional permission is false (PVD-037).
|
|
483
506
|
`provider_signing_allowed` only represents Provider policy, not an SDK signing operation. Share-list order remains
|
|
484
507
|
unspecified.
|
|
485
508
|
|
|
@@ -504,17 +527,19 @@ await client.templates.save_content(template, modules)
|
|
|
504
527
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
505
528
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
506
529
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
507
|
-
types. A JSON-language code module
|
|
508
|
-
|
|
530
|
+
types. A JSON-language code module's `data` remains code text and may be empty, null, or invalid JSON;
|
|
531
|
+
`language=json` does not imply that Consumers can parse it. When template content contains a code module with
|
|
532
|
+
`language=json` and non-null `style`, its code text must be valid JSON to save. Number and boolean table cells preserve
|
|
533
|
+
the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
509
534
|
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
510
|
-
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-
|
|
511
|
-
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-
|
|
535
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-013).
|
|
536
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-008),
|
|
512
537
|
so a read-modify-save sequence can overwrite a concurrent change.
|
|
513
538
|
|
|
514
539
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
515
540
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
516
541
|
because Provider discovery ordering/pagination and historical `images` compatibility are not fully stable
|
|
517
|
-
(PCG-
|
|
542
|
+
(PCG-011, PCG-012, PVD-038, PVD-022).
|
|
518
543
|
|
|
519
544
|
`templates.list()` returns one tuple. `TemplateSummary.scope` is limited to `owned`, `shared`, `group`, and `public`;
|
|
520
545
|
Provider marketplace acquisitions and system defaults are both public templates. An acquired public template carries
|
|
@@ -529,7 +554,7 @@ transaction. Creation returns the new `TemplateRef`; metadata replacement and ot
|
|
|
529
554
|
the Provider supplies no new resource representation. `update()` therefore requires the complete title, summary, and
|
|
530
555
|
keyword set rather than implying a partial patch. `update_usage()` generates the Provider's required fresh hidden
|
|
531
556
|
correlation value internally. Usage attachments remain unsupported until their staging and binding lifecycle is
|
|
532
|
-
contracted safely (PVD-
|
|
557
|
+
contracted safely (PVD-003). Marketplace revision limitations remain explicit through `content_version`,
|
|
533
558
|
`published_content_version`, and `market_review_reason` (PVD-021).
|
|
534
559
|
|
|
535
560
|
Extended record reads stay behind the same `records` interface:
|
|
@@ -549,7 +574,7 @@ relations = await client.records.relations(source)
|
|
|
549
574
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
550
575
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
551
576
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
552
|
-
The current Provider excludes encrypted records from search (PVD-
|
|
577
|
+
The current Provider excludes encrypted records from search (PVD-041); an empty search result therefore does
|
|
553
578
|
not prove that no matching encrypted record exists.
|
|
554
579
|
|
|
555
580
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
@@ -559,7 +584,7 @@ The Provider calls its notebook directory tree `subtype`; that name remains wire
|
|
|
559
584
|
positive folder ID for one folder.
|
|
560
585
|
|
|
561
586
|
`records.page` fixes the legacy request to `page_size=0&default=1`, preventing the known owner-preference writes
|
|
562
|
-
described by PVD-
|
|
587
|
+
described by PVD-028; its total is derived internally from the Provider's complete matching ID list. The result keeps
|
|
563
588
|
semantic `NotebookPermissions` directly, without a shallow context model or duplicated notebook/owner/template
|
|
564
589
|
display metadata. Effective request pagination, the UI selection list and Provider keyword-filter echo are not exposed.
|
|
565
590
|
Its `search` argument, shared with `records.list()`, maps the Provider's wire-level `content` filter without exposing
|
|
@@ -597,10 +622,10 @@ imported = await client.records.import_dataset(
|
|
|
597
622
|
|
|
598
623
|
Blank-record creation returns `None` because the Provider returns no record identity, even when the caller supplies a
|
|
599
624
|
UID. Import validates the complete batch with generated wire models but cannot map returned database IDs to
|
|
600
|
-
individual inputs or promise atomicity (PCG-
|
|
625
|
+
individual inputs or promise atomicity (PCG-009); it therefore returns only the tuple of database IDs actually
|
|
601
626
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
602
627
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
603
|
-
missing folders. The current Provider rejects explicit-null table-file imports (PVD-
|
|
628
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-031). Because the SDK accepts
|
|
604
629
|
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
605
630
|
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
606
631
|
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
@@ -612,8 +637,8 @@ without a readback request. Omitting `target_notebook` copies within the source
|
|
|
612
637
|
Record patching exposes a deliberately narrower capability than the raw Provider operation. Scalar/module changes
|
|
613
638
|
cannot smuggle Provider-native attachment strings; staged attachments use separate form-removal, table-replacement,
|
|
614
639
|
files append/replace/remove, and rich-text types. Unsafe form replacement and table-file removal are absent, while a
|
|
615
|
-
files/images removal is rejected when the observed module contains the same hash more than once (PVD-
|
|
616
|
-
PVD-
|
|
640
|
+
files/images removal is rejected when the observed module contains the same hash more than once (PVD-010, PVD-018,
|
|
641
|
+
and PVD-019). The SDK reads current content only when a change needs attachment type, occurrence, row, or index state;
|
|
617
642
|
ordinary module creation and deletion rely on the Provider's own canonical update validation. `records.update()`
|
|
618
643
|
returns the acknowledgement classification
|
|
619
644
|
`"persisted"`, `"pending"`, or `"unknown"`; it does not
|
|
@@ -622,9 +647,9 @@ retries stay disabled. Encrypted record content is outside the SDK's public read
|
|
|
622
647
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
623
648
|
password lifecycle remain unexposed. Files-module attachment append remains root-only because the pinned top-level
|
|
624
649
|
update request schema does not admit the dedicated staged-name append shape's folder `path`; malformed path containers
|
|
625
|
-
may also silently append at root according to PVD-
|
|
650
|
+
may also silently append at root according to PVD-030. A staged attachment is indeterminate once the write has started.
|
|
626
651
|
|
|
627
|
-
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-
|
|
652
|
+
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-009
|
|
628
653
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
629
654
|
caller-relative `editable` display flag: the mutation endpoint performs the source permission check. Relation
|
|
630
655
|
deletion lists current relations only to refuse an observed cross-notebook target-ID collision because the Provider
|
|
@@ -634,12 +659,12 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
634
659
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
635
660
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
636
661
|
|
|
637
|
-
Comment upload follows the current Provider's literal one-request `file` field
|
|
662
|
+
Comment upload follows the current Provider's literal one-request `file` field. Comment mutations return `None`
|
|
638
663
|
after acknowledgement. Edit first verifies that the selected
|
|
639
664
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
640
665
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
641
666
|
caller ownership. Neither operation performs a post-write read. Staged comment attachments have no Contract abort
|
|
642
|
-
operation, and binding remains affected by PVD-
|
|
667
|
+
operation, and binding remains affected by PVD-003. Comment create/update use the same `body` vocabulary as the
|
|
643
668
|
returned `RecordComment.body`; the SDK does not perform rich-text display normalization, while the Provider's
|
|
644
669
|
documented surrounding-whitespace trim still applies when saving.
|
|
645
670
|
`RecordCommentRef` carries its `RecordLocator`, so update and delete accept the ref rather than an entire comment or a
|
|
@@ -661,9 +686,9 @@ async with await client.records.download_comment_attachment(
|
|
|
661
686
|
```
|
|
662
687
|
|
|
663
688
|
`DownloadStream` exposes status, content type, length, range, and disposition metadata without buffering the
|
|
664
|
-
complete file. Streams are not automatically replayed. `ByteRange` deliberately rejects `bytes=0-0` (PVD-
|
|
689
|
+
complete file. Streams are not automatically replayed. `ByteRange` deliberately rejects `bytes=0-0` (PVD-015).
|
|
665
690
|
Comment attachment refs contain only file identity. Pass the parent comment ref returned by the same read when
|
|
666
|
-
downloading; current Providers do not verify that association (PVD-
|
|
691
|
+
downloading; current Providers do not verify that association (PVD-006).
|
|
667
692
|
|
|
668
693
|
Cross-domain staging keeps resumable state and completed-file identity separate:
|
|
669
694
|
|
|
@@ -685,7 +710,7 @@ Provider URL and upload-session identity needed by internal binding and cleanup
|
|
|
685
710
|
splice either into content. The result does not claim that a later literature/cloud operation checks the uploader or
|
|
686
711
|
consumes the file exactly once. `uploads.abort()` accepts either an active `StagedUploadSession` or a completed
|
|
687
712
|
`StagedFile` and exposes the Provider's legacy code-2 cancellation signal as a `None`-returning compensating cleanup
|
|
688
|
-
that is not independently verified (PVD-
|
|
713
|
+
that is not independently verified (PVD-024).
|
|
689
714
|
Staging mutations are never automatically retried.
|
|
690
715
|
|
|
691
716
|
Literature identities distinguish the personal library from shared libraries:
|
|
@@ -715,7 +740,7 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
715
740
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
716
741
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
717
742
|
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
718
|
-
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-
|
|
743
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-040).
|
|
719
744
|
Literature list
|
|
720
745
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
721
746
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
@@ -740,22 +765,22 @@ Create returns `None` and never guesses the new item from list position because
|
|
|
740
765
|
canonical update preflights the raw item response and refuses to drop top-level or nested source/hidden fields. Passing
|
|
741
766
|
`allow_source_metadata_loss=True` explicitly skips that preflight and sends the canonical replacement directly. The
|
|
742
767
|
default read/check/write protection is best effort rather than atomic because the Provider offers no revision or
|
|
743
|
-
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-
|
|
768
|
+
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-012).
|
|
744
769
|
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata.
|
|
745
770
|
Permanent personal deletion is named `permanently_delete`, returns `None`, and is non-recoverable. Sharing requires
|
|
746
771
|
list-observed item summaries, user-search summaries and a
|
|
747
|
-
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-
|
|
772
|
+
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-008, PVD-027).
|
|
748
773
|
|
|
749
774
|
Literature comments use explicit `create_comment()` and `update_comment()` intents. Creation first reads the current
|
|
750
775
|
detail and rejects when the caller already owns a comment; callers then use that comment's `LiteratureCommentRef` with
|
|
751
776
|
`update_comment()`. The ref contains only the Provider comment-row identity. Update and delete send that identity
|
|
752
777
|
directly because the Provider mutation verifies current ownership and library permission. The creation preflight
|
|
753
778
|
maintains the Integration Contract's one-caller-comment invariant for ordinary SDK use, but is not atomic because the
|
|
754
|
-
Provider has no matching uniqueness constraint (PVD-
|
|
779
|
+
Provider has no matching uniqueness constraint (PVD-026). When sharing with `copy_owner_comment=True`, multiple
|
|
755
780
|
caller-owned comments remain an explicit ambiguity because the Provider would otherwise choose one implicitly. A
|
|
756
781
|
staged attachment can replace one `matelab-staged-file` marker; raw temporary URLs are rejected. These checks prevent
|
|
757
|
-
common misuse but do not repair the Provider's cross-user UID lookup (PVD-
|
|
758
|
-
experimental because the Provider permission JOIN is not scoped to the current user (PVD-
|
|
782
|
+
common misuse but do not repair the Provider's cross-user UID lookup (PVD-003). Shared-library reads and writes remain
|
|
783
|
+
experimental because the Provider permission JOIN is not scoped to the current user (PVD-007); successful SDK calls
|
|
759
784
|
must not be treated as independent authorization proof. Literature PDF downloads reuse `DownloadStream` and the
|
|
760
785
|
stable `ByteRange` subset.
|
|
761
786
|
|
|
@@ -771,16 +796,16 @@ await client.cloud_drive.bind_staged_file(staged, target=folder)
|
|
|
771
796
|
snapshot and quota usage; pagination applies only to `files`, while request page arguments are not echoed. Personal-root
|
|
772
797
|
metadata and permissions are synthetic/fixed for this Contract line and remain wire-only. File rows omit the constant
|
|
773
798
|
caller owner fields and do not invent a folder location that the Provider fails to return for root-wide searches.
|
|
774
|
-
Listings likewise omit search/order/direction request echoes. Ordering has no stable ID tie-breaker (PCG-
|
|
799
|
+
Listings likewise omit search/order/direction request echoes. Ordering has no stable ID tie-breaker (PCG-011, PVD-038).
|
|
775
800
|
Cloud files expose the nullable stored modification timestamp, not the Provider's duplicate display-formatted date and
|
|
776
801
|
time strings.
|
|
777
802
|
|
|
778
803
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
779
804
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
780
|
-
the Provider binds by temporary row ID without checking its owner (PVD-
|
|
805
|
+
the Provider binds by temporary row ID without checking its owner (PVD-002), and finalize atomicity/idempotency remain
|
|
781
806
|
absent. Batch move and permanent delete do not claim Provider per-item results or atomicity. Permanent
|
|
782
807
|
deletion is named `permanently_delete_files` and is non-recoverable. Cloud downloads
|
|
783
|
-
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-
|
|
808
|
+
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-015-safe
|
|
784
809
|
range subset. Cloud mutations are not automatically retried.
|
|
785
810
|
|
|
786
811
|
Owned, shared, and public catalog notebooks use one `NotebookRef`, distinguished by its
|
|
@@ -816,7 +841,7 @@ Template render metadata is also excluded from template summaries and record rea
|
|
|
816
841
|
notebook title/keywords, Provider data-server routing, or the frontend PDF-capability flag. `Record.version` identifies
|
|
817
842
|
historical content and is `None` for the current content. `Record.versions` contains refs usable for historical reads;
|
|
818
843
|
Provider lock and signature projections remain wire-only. Relation creation still checks returned data servers
|
|
819
|
-
internally to mitigate PVD-
|
|
844
|
+
internally to mitigate PVD-009.
|
|
820
845
|
|
|
821
846
|
Provider record-finalization and additional-signature mutations are intentionally outside the pinned Contract and SDK
|
|
822
847
|
interface. They require the account password to unlock a private key, combine version creation with signing, provide no
|
|
@@ -920,6 +945,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
920
945
|
```
|
|
921
946
|
|
|
922
947
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
923
|
-
byte-identical wheel and source distribution hashes. The
|
|
924
|
-
`
|
|
925
|
-
`
|
|
948
|
+
byte-identical wheel and source distribution hashes. The SDK Contract pin is immutable `matelab-spec v0.5.0`, commit
|
|
949
|
+
`4f2959472933da47d1ea3e275552884d51d4fdd9`, and OpenAPI SHA-256
|
|
950
|
+
`dee14f76e24b2d7c3d97a6f30a9369ac093d615d132db85836ab86671eadcf18`.
|