matelab-python-sdk 0.1.0a18__tar.gz → 0.1.0a20__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.0a18 → matelab_python_sdk-0.1.0a20}/CHANGELOG.md +26 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/PKG-INFO +34 -32
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/README.md +33 -31
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/contracts/matelab-integration-v1.openapi.yaml +128 -67
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/docs/operation-coverage.yaml +2 -2
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/_generated/models.py +166 -43
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/records.py +8 -18
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_async_attachment_upload.py +2 -1
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_generation.py +155 -3
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_record_mutations.py +20 -19
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_records.py +103 -12
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_transport.py +1 -1
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_uploads_and_literature.py +2 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/CONTEXT.md +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/scripts/generate_models.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/literature.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a18 → matelab_python_sdk-0.1.0a20}/tests/typing/pyproject.toml +0 -0
|
@@ -3,6 +3,32 @@
|
|
|
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.0a20 - 2026-08-24
|
|
7
|
+
|
|
8
|
+
- Adopts immutable `matelab-spec v0.4.3` at commit `7965ac9803505ae35dc5ce36f52afc3c2c133c45` and OpenAPI
|
|
9
|
+
SHA-256 `6576812dd13f92ad58131f4edb8dc919d1b1fe0f19a695c2d25fbe6d13a8445b`, aligned with Provider evidence
|
|
10
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`.
|
|
11
|
+
- Breaking: tightens record readback to one canonical attachment object or `null` per table file cell, removing the
|
|
12
|
+
obsolete attachment-array compatibility path. Template decoding now accepts nullable JSON-code data and preserves
|
|
13
|
+
empty-string number/boolean cells alongside their scalar and null forms.
|
|
14
|
+
- Records PVD-046 while keeping `templates.save_content()` deliberately narrower than the Provider: the request remains
|
|
15
|
+
a canonical module list, and every table file cell remains one canonical attachment object or `null`, never an
|
|
16
|
+
arbitrary or multi-attachment array.
|
|
17
|
+
|
|
18
|
+
## 0.1.0a19 - 2026-08-23
|
|
19
|
+
|
|
20
|
+
- Re-adopts the force-rewritten `matelab-spec v0.4.2` at commit
|
|
21
|
+
`1a4b77721d782fccd2b1f26bcc16a7d876347686` and OpenAPI SHA-256
|
|
22
|
+
`1e737421aac636356487122ea89e20d54de07c8b9c0651cf6970a7123fe3b72b`. The published `0.1.0a18` entry below remains
|
|
23
|
+
historical evidence for the former `v0.4.2` target at `a51483f`; it is not rewritten.
|
|
24
|
+
- Aligns with current Provider evidence: comment attachment multipart uses `file`; temporary-file and comment identifiers
|
|
25
|
+
allow 100 characters; code-4 `errs` accepts opaque array or object containers; and DOI extraction validates
|
|
26
|
+
`^10\.[0-9]+/\S+$` before transport.
|
|
27
|
+
- Breaking: removes `RecordValueAddition.path` and `RecordFilesAttachmentAppend.folder_path` because the current
|
|
28
|
+
Provider's add-value shape no longer accepts `path`; files-module append now targets only the module root. Search
|
|
29
|
+
excludes encrypted records, and callers of arbitrary template-shaped imports must omit unset file-valued keys because
|
|
30
|
+
the Provider rejects their explicit `null`.
|
|
31
|
+
|
|
6
32
|
## 0.1.0a18 - 2026-08-23
|
|
7
33
|
|
|
8
34
|
- Adopts immutable `matelab-spec v0.4.2` at commit `a51483f910440fbbbc3693cc32566482064bb3ab` 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.0a20
|
|
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,10 +35,10 @@ 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.0a20`. `[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.4.
|
|
41
|
+
The SDK is pinned to the immutable `matelab-spec v0.4.3` Contract Release. The sole release pin is
|
|
42
42
|
`contracts/matelab-integration-v1.lock.json`, which records
|
|
43
43
|
the source tag, commit, OpenAPI path, local snapshot path, and SHA-256.
|
|
44
44
|
|
|
@@ -64,17 +64,15 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
66
|
uv build --no-build-isolation --out-dir dist/release
|
|
67
|
-
python -m pip install dist/release/matelab_python_sdk-0.1.
|
|
67
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a20-py3-none-any.whl
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
71
71
|
tag, commit, and checksum recorded below.
|
|
72
72
|
|
|
73
|
-
The Contract and public SDK interface
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
differences are documented alongside the affected interfaces below; do not treat a successful Contract adoption as
|
|
77
|
-
proof that this newer Provider revision is interchangeable.
|
|
73
|
+
The Contract and public SDK interface track the current reviewed Provider at
|
|
74
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`. Provider limitations that remain relevant to integrations are documented
|
|
75
|
+
alongside the affected interfaces below.
|
|
78
76
|
|
|
79
77
|
## Design
|
|
80
78
|
|
|
@@ -123,8 +121,8 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
123
121
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
124
122
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
125
123
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
126
|
-
The pinned v0.4.
|
|
127
|
-
|
|
124
|
+
The pinned v0.4.3 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record opaque array/object
|
|
125
|
+
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
128
126
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
129
127
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
130
128
|
means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
|
|
@@ -318,8 +316,8 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
318
316
|
result cannot be retried through the same client.
|
|
319
317
|
|
|
320
318
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
321
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
322
|
-
|
|
319
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root; the current Provider does
|
|
320
|
+
not accept a files-folder path (PVD-044):
|
|
323
321
|
|
|
324
322
|
```python
|
|
325
323
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -350,7 +348,9 @@ await client.records.update(
|
|
|
350
348
|
|
|
351
349
|
For a files occurrence, `caption=None` preserves the observed string caption (an observed null caption normalizes to
|
|
352
350
|
the required empty string). Table replacement requires exactly one current attachment in the selected cell and does
|
|
353
|
-
not accept a caption.
|
|
351
|
+
not accept a caption. Record reads likewise accept only one canonical attachment object or `null` in a table file cell;
|
|
352
|
+
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
353
|
+
differ from the current occurrence.
|
|
354
354
|
|
|
355
355
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
356
356
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
@@ -502,9 +502,12 @@ await client.templates.save_content(template, modules)
|
|
|
502
502
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
503
503
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
504
504
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
505
|
-
types.
|
|
506
|
-
|
|
507
|
-
|
|
505
|
+
types. A JSON-language code module with style metadata may return its JSON string or explicit `null`; number and boolean
|
|
506
|
+
table cells preserve the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
507
|
+
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
508
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-046).
|
|
509
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-007),
|
|
510
|
+
so a read-modify-save sequence can overwrite a concurrent change.
|
|
508
511
|
|
|
509
512
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
510
513
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
@@ -544,7 +547,7 @@ relations = await client.records.relations(source)
|
|
|
544
547
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
545
548
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
546
549
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
547
|
-
The
|
|
550
|
+
The current Provider excludes encrypted records from search (PVD-043); an empty search result therefore does
|
|
548
551
|
not prove that no matching encrypted record exists.
|
|
549
552
|
|
|
550
553
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
@@ -595,9 +598,10 @@ UID. Import validates the complete batch with generated wire models but cannot m
|
|
|
595
598
|
individual inputs or promise atomicity (PCG-008); it therefore returns only the tuple of database IDs actually
|
|
596
599
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
597
600
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
598
|
-
missing folders. The
|
|
599
|
-
|
|
600
|
-
|
|
601
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-045). Because the SDK accepts
|
|
602
|
+
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
603
|
+
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
604
|
+
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
601
605
|
|
|
602
606
|
`records.copy()` accepts an optional `new_record_uid`; when omitted, the SDK generates one locally. The Provider
|
|
603
607
|
returns only the copied row's database ID, so retaining that UID lets the SDK return a complete `RecordLocator`
|
|
@@ -614,9 +618,8 @@ returns the acknowledgement classification
|
|
|
614
618
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
615
619
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
616
620
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
617
|
-
password lifecycle remain unexposed.
|
|
618
|
-
(PVD-044)
|
|
619
|
-
staged attachment as indeterminate once the write has started.
|
|
621
|
+
password lifecycle remain unexposed. Files-module attachment append is root-only because the current Provider rejects
|
|
622
|
+
folder-path segments (PVD-044). A staged attachment is indeterminate once the write has started.
|
|
620
623
|
|
|
621
624
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
622
625
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -628,8 +631,7 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
628
631
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
629
632
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
630
633
|
|
|
631
|
-
Comment upload follows the
|
|
632
|
-
that field (PVD-037), but the SDK retains the Contract-compatible `upload` encoding. Comment mutations return `None`
|
|
634
|
+
Comment upload follows the current Provider's literal one-request `file` field (PVD-037). Comment mutations return `None`
|
|
633
635
|
after acknowledgement. Edit first verifies that the selected
|
|
634
636
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
635
637
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
@@ -709,9 +711,9 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
709
711
|
`extract_metadata()` directly and handle an unavailable or failing optional backend as a Provider error. Extraction
|
|
710
712
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
711
713
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
712
|
-
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF.
|
|
713
|
-
|
|
714
|
-
|
|
714
|
+
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
715
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-042).
|
|
716
|
+
Literature list
|
|
715
717
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
716
718
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
717
719
|
JSON produces the Provider's empty-array fallback; otherwise it contains decoded stored metadata without arbitrary
|
|
@@ -915,6 +917,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
915
917
|
```
|
|
916
918
|
|
|
917
919
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
918
|
-
byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.
|
|
919
|
-
|
|
920
|
-
`
|
|
920
|
+
byte-identical wheel and source distribution hashes. The release is bound to immutable `matelab-spec v0.4.3`, commit
|
|
921
|
+
`7965ac9803505ae35dc5ce36f52afc3c2c133c45`, and OpenAPI SHA-256
|
|
922
|
+
`6576812dd13f92ad58131f4edb8dc919d1b1fe0f19a695c2d25fbe6d13a8445b`.
|
|
@@ -7,10 +7,10 @@ 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.1.
|
|
10
|
+
The current alpha is `0.1.0a20`. `[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 v0.4.
|
|
13
|
+
The SDK is pinned to the immutable `matelab-spec v0.4.3` Contract Release. The sole release pin is
|
|
14
14
|
`contracts/matelab-integration-v1.lock.json`, which records
|
|
15
15
|
the source tag, commit, OpenAPI path, local snapshot path, and SHA-256.
|
|
16
16
|
|
|
@@ -36,17 +36,15 @@ To test the same artifact a downstream Consumer will install, build and install
|
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
uv build --no-build-isolation --out-dir dist/release
|
|
39
|
-
python -m pip install dist/release/matelab_python_sdk-0.1.
|
|
39
|
+
python -m pip install dist/release/matelab_python_sdk-0.1.0a20-py3-none-any.whl
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
Do not infer Provider compatibility from the SDK version alone. A release is also bound to the Contract
|
|
43
43
|
tag, commit, and checksum recorded below.
|
|
44
44
|
|
|
45
|
-
The Contract and public SDK interface
|
|
46
|
-
`
|
|
47
|
-
|
|
48
|
-
differences are documented alongside the affected interfaces below; do not treat a successful Contract adoption as
|
|
49
|
-
proof that this newer Provider revision is interchangeable.
|
|
45
|
+
The Contract and public SDK interface track the current reviewed Provider at
|
|
46
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`. Provider limitations that remain relevant to integrations are documented
|
|
47
|
+
alongside the affected interfaces below.
|
|
50
48
|
|
|
51
49
|
## Design
|
|
52
50
|
|
|
@@ -95,8 +93,8 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
95
93
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
96
94
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
97
95
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
98
|
-
The pinned v0.4.
|
|
99
|
-
|
|
96
|
+
The pinned v0.4.3 Contract also declares optional code-4 `errs`, but PVD-041 and PCG-015 record opaque array/object
|
|
97
|
+
containers and insufficient evidence for requiredness, cardinality, or exclusion from other codes. The SDK
|
|
100
98
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
101
99
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
102
100
|
means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
|
|
@@ -290,8 +288,8 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
290
288
|
result cannot be retried through the same client.
|
|
291
289
|
|
|
292
290
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
293
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
294
|
-
|
|
291
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root; the current Provider does
|
|
292
|
+
not accept a files-folder path (PVD-044):
|
|
295
293
|
|
|
296
294
|
```python
|
|
297
295
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -322,7 +320,9 @@ await client.records.update(
|
|
|
322
320
|
|
|
323
321
|
For a files occurrence, `caption=None` preserves the observed string caption (an observed null caption normalizes to
|
|
324
322
|
the required empty string). Table replacement requires exactly one current attachment in the selected cell and does
|
|
325
|
-
not accept a caption.
|
|
323
|
+
not accept a caption. Record reads likewise accept only one canonical attachment object or `null` in a table file cell;
|
|
324
|
+
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
325
|
+
differ from the current occurrence.
|
|
326
326
|
|
|
327
327
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
328
328
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
@@ -474,9 +474,12 @@ await client.templates.save_content(template, modules)
|
|
|
474
474
|
`TemplateModule.data_present` distinguishes a missing `data` property from an explicit null value, while
|
|
475
475
|
`attributes` prevents additive canonical properties from being dropped during a read/save cycle. The SDK does not
|
|
476
476
|
synthesize frontend editor UIDs, layout widths, rows, folders, option encoding, or a fixed set of display module
|
|
477
|
-
types.
|
|
478
|
-
|
|
479
|
-
|
|
477
|
+
types. A JSON-language code module with style metadata may return its JSON string or explicit `null`; number and boolean
|
|
478
|
+
table cells preserve the Provider's empty string as distinct from scalar and `null` values. The Provider accepts some
|
|
479
|
+
non-canonical module roots and arbitrary table file arrays, but the SDK does not expose that behavior: saved content
|
|
480
|
+
must remain a canonical module list, and a table file cell must be one canonical attachment object or `null` (PVD-046).
|
|
481
|
+
The Provider supports only whole-content replacement and has no atomic patch or compare-and-swap operation (PCG-007),
|
|
482
|
+
so a read-modify-save sequence can overwrite a concurrent change.
|
|
480
483
|
|
|
481
484
|
The market result retains the Provider's `total_count` and derives `has_more` without echoing the caller's page
|
|
482
485
|
arguments; it does not claim a stable order or continuation token. Template reads remain experimental
|
|
@@ -516,7 +519,7 @@ relations = await client.records.relations(source)
|
|
|
516
519
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
517
520
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
518
521
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
519
|
-
The
|
|
522
|
+
The current Provider excludes encrypted records from search (PVD-043); an empty search result therefore does
|
|
520
523
|
not prove that no matching encrypted record exists.
|
|
521
524
|
|
|
522
525
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
@@ -567,9 +570,10 @@ UID. Import validates the complete batch with generated wire models but cannot m
|
|
|
567
570
|
individual inputs or promise atomicity (PCG-008); it therefore returns only the tuple of database IDs actually
|
|
568
571
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
569
572
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
570
|
-
missing folders. The
|
|
571
|
-
|
|
572
|
-
|
|
573
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-045). Because the SDK accepts
|
|
574
|
+
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
575
|
+
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
576
|
+
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
573
577
|
|
|
574
578
|
`records.copy()` accepts an optional `new_record_uid`; when omitted, the SDK generates one locally. The Provider
|
|
575
579
|
returns only the copied row's database ID, so retaining that UID lets the SDK return a complete `RecordLocator`
|
|
@@ -586,9 +590,8 @@ returns the acknowledgement classification
|
|
|
586
590
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
587
591
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
588
592
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
589
|
-
password lifecycle remain unexposed.
|
|
590
|
-
(PVD-044)
|
|
591
|
-
staged attachment as indeterminate once the write has started.
|
|
593
|
+
password lifecycle remain unexposed. Files-module attachment append is root-only because the current Provider rejects
|
|
594
|
+
folder-path segments (PVD-044). A staged attachment is indeterminate once the write has started.
|
|
592
595
|
|
|
593
596
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
594
597
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -600,8 +603,7 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
600
603
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
601
604
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
602
605
|
|
|
603
|
-
Comment upload follows the
|
|
604
|
-
that field (PVD-037), but the SDK retains the Contract-compatible `upload` encoding. Comment mutations return `None`
|
|
606
|
+
Comment upload follows the current Provider's literal one-request `file` field (PVD-037). Comment mutations return `None`
|
|
605
607
|
after acknowledgement. Edit first verifies that the selected
|
|
606
608
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
607
609
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
@@ -681,9 +683,9 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
681
683
|
`extract_metadata()` directly and handle an unavailable or failing optional backend as a Provider error. Extraction
|
|
682
684
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
683
685
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
684
|
-
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF.
|
|
685
|
-
|
|
686
|
-
|
|
686
|
+
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
687
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-042).
|
|
688
|
+
Literature list
|
|
687
689
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
688
690
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
689
691
|
JSON produces the Provider's empty-array fallback; otherwise it contains decoded stored metadata without arbitrary
|
|
@@ -887,6 +889,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
887
889
|
```
|
|
888
890
|
|
|
889
891
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
890
|
-
byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.
|
|
891
|
-
|
|
892
|
-
`
|
|
892
|
+
byte-identical wheel and source distribution hashes. The release is bound to immutable `matelab-spec v0.4.3`, commit
|
|
893
|
+
`7965ac9803505ae35dc5ce36f52afc3c2c133c45`, and OpenAPI SHA-256
|
|
894
|
+
`6576812dd13f92ad58131f4edb8dc919d1b1fe0f19a695c2d25fbe6d13a8445b`.
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"contract_line": "integration-v1",
|
|
4
4
|
"release": {
|
|
5
|
-
"tag": "v0.4.
|
|
6
|
-
"commit": "
|
|
5
|
+
"tag": "v0.4.3",
|
|
6
|
+
"commit": "7965ac9803505ae35dc5ce36f52afc3c2c133c45"
|
|
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": "6576812dd13f92ad58131f4edb8dc919d1b1fe0f19a695c2d25fbe6d13a8445b"
|
|
12
12
|
}
|
|
13
13
|
}
|