matelab-python-sdk 0.1.0a17__tar.gz → 0.1.0a19__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.0a17 → matelab_python_sdk-0.1.0a19}/CHANGELOG.md +25 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/PKG-INFO +30 -19
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/README.md +29 -18
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/contracts/matelab-integration-v1.lock.json +3 -3
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/contracts/matelab-integration-v1.openapi.yaml +98 -55
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/docs/operation-coverage.yaml +24 -24
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/_generated/models.py +35 -34
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/records.py +7 -11
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_async_attachment_upload.py +2 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_generation.py +34 -3
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_record_mutations.py +4 -11
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_transport.py +1 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_uploads_and_literature.py +2 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/CONTEXT.md +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/scripts/generate_models.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/literature.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_records.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a17 → matelab_python_sdk-0.1.0a19}/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.0a19 - 2026-08-23
|
|
7
|
+
|
|
8
|
+
- Re-adopts the force-rewritten `matelab-spec v0.4.2` at commit
|
|
9
|
+
`1a4b77721d782fccd2b1f26bcc16a7d876347686` and OpenAPI SHA-256
|
|
10
|
+
`1e737421aac636356487122ea89e20d54de07c8b9c0651cf6970a7123fe3b72b`. The published `0.1.0a18` entry below remains
|
|
11
|
+
historical evidence for the former `v0.4.2` target at `a51483f`; it is not rewritten.
|
|
12
|
+
- Aligns with current Provider evidence: comment attachment multipart uses `file`; temporary-file and comment identifiers
|
|
13
|
+
allow 100 characters; code-4 `errs` accepts opaque array or object containers; and DOI extraction validates
|
|
14
|
+
`^10\.[0-9]+/\S+$` before transport.
|
|
15
|
+
- Breaking: removes `RecordValueAddition.path` and `RecordFilesAttachmentAppend.folder_path` because the current
|
|
16
|
+
Provider's add-value shape no longer accepts `path`; files-module append now targets only the module root. Search
|
|
17
|
+
excludes encrypted records, and callers of arbitrary template-shaped imports must omit unset file-valued keys because
|
|
18
|
+
the Provider rejects their explicit `null`.
|
|
19
|
+
|
|
20
|
+
## 0.1.0a18 - 2026-08-23
|
|
21
|
+
|
|
22
|
+
- Adopts immutable `matelab-spec v0.4.2` at commit `a51483f910440fbbbc3693cc32566482064bb3ab` and OpenAPI
|
|
23
|
+
SHA-256 `4c92b96ba3dfe7122b30b4db2e2c8054c06018291c8c52c15482112b51a32920`. The wire schema, methods,
|
|
24
|
+
paths, encodings, operation count, and public interface are unchanged.
|
|
25
|
+
- Records that compatibility evidence remains the stable Provider revision
|
|
26
|
+
`59101f006e9fd6d6ce0b951dfd34695a7949b54f`; the latest reviewed revision
|
|
27
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27` is incompatible. The SDK retains the stable multipart comment-upload
|
|
28
|
+
field, while integrations must account for that Provider's DOI rejection, encrypted-search omission, valid
|
|
29
|
+
files-folder-path rejection, and explicit-null table-file-import failure.
|
|
30
|
+
|
|
6
31
|
## 0.1.0a17 - 2026-08-20
|
|
7
32
|
|
|
8
33
|
- Adopts immutable `matelab-spec v0.4.1` at commit `6f8ab3d14797385d0075d0aba38bf3bf529e674d` 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.0a19
|
|
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.0a19`. `[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
|
|
41
|
+
The SDK is pinned to the rewritten `matelab-spec v0.4.2` 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,12 +64,16 @@ 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.0a19-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 track the current reviewed Provider at
|
|
74
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`. Provider limitations that remain relevant to integrations are documented
|
|
75
|
+
alongside the affected interfaces below.
|
|
76
|
+
|
|
73
77
|
## Design
|
|
74
78
|
|
|
75
79
|
The public module is intentionally small:
|
|
@@ -117,8 +121,8 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
117
121
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
118
122
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
119
123
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
120
|
-
The pinned v0.4.
|
|
121
|
-
|
|
124
|
+
The pinned v0.4.2 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
|
|
122
126
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
123
127
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
124
128
|
means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
|
|
@@ -312,8 +316,8 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
312
316
|
result cannot be retried through the same client.
|
|
313
317
|
|
|
314
318
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
315
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
316
|
-
|
|
319
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root; the current Provider does
|
|
320
|
+
not accept a files-folder path (PVD-044):
|
|
317
321
|
|
|
318
322
|
```python
|
|
319
323
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -446,7 +450,7 @@ targets = await client.users.search("Example Researcher", global_scope=False)
|
|
|
446
450
|
`groups.list()` returns the `GroupSummary` tuple directly. Ordering remains Provider-unspecified and is documented
|
|
447
451
|
rather than repeated as a constant result field. The Provider's members for an unstable first group remain wire-only;
|
|
448
452
|
`users.search()` is the public recipient-discovery interface. These two discovery interfaces are experimental because
|
|
449
|
-
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029
|
|
453
|
+
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029).
|
|
450
454
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
451
455
|
exposing the Provider's data-server routing value.
|
|
452
456
|
|
|
@@ -538,6 +542,8 @@ relations = await client.records.relations(source)
|
|
|
538
542
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
539
543
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
540
544
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
545
|
+
The current Provider excludes encrypted records from search (PVD-043); an empty search result therefore does
|
|
546
|
+
not prove that no matching encrypted record exists.
|
|
541
547
|
|
|
542
548
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
543
549
|
`RecordFolder`, `RecordSummary.folder_id`, and the `folders` returned with record listings. A top-level folder has
|
|
@@ -587,7 +593,9 @@ UID. Import validates the complete batch with generated wire models but cannot m
|
|
|
587
593
|
individual inputs or promise atomicity (PCG-008); it therefore returns only the tuple of database IDs actually
|
|
588
594
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
589
595
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
590
|
-
missing folders.
|
|
596
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-045). Because the SDK accepts
|
|
597
|
+
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
598
|
+
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
591
599
|
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
592
600
|
|
|
593
601
|
`records.copy()` accepts an optional `new_record_uid`; when omitted, the SDK generates one locally. The Provider
|
|
@@ -605,7 +613,8 @@ returns the acknowledgement classification
|
|
|
605
613
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
606
614
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
607
615
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
608
|
-
password lifecycle remain unexposed.
|
|
616
|
+
password lifecycle remain unexposed. Files-module attachment append is root-only because the current Provider rejects
|
|
617
|
+
folder-path segments (PVD-044). A staged attachment is indeterminate once the write has started.
|
|
609
618
|
|
|
610
619
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
611
620
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -617,8 +626,8 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
617
626
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
618
627
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
619
628
|
|
|
620
|
-
Comment upload follows the Provider's literal one-request `
|
|
621
|
-
|
|
629
|
+
Comment upload follows the current Provider's literal one-request `file` field (PVD-037). Comment mutations return `None`
|
|
630
|
+
after acknowledgement. Edit first verifies that the selected
|
|
622
631
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
623
632
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
624
633
|
caller ownership. Neither operation performs a post-write read. Staged comment attachments have no Contract abort
|
|
@@ -697,7 +706,9 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
697
706
|
`extract_metadata()` directly and handle an unavailable or failing optional backend as a Provider error. Extraction
|
|
698
707
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
699
708
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
700
|
-
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF.
|
|
709
|
+
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
710
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-042).
|
|
711
|
+
Literature list
|
|
701
712
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
702
713
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
703
714
|
JSON produces the Provider's empty-array fallback; otherwise it contains decoded stored metadata without arbitrary
|
|
@@ -722,7 +733,7 @@ canonical update preflights the raw item response and refuses to drop top-level
|
|
|
722
733
|
`allow_source_metadata_loss=True` explicitly skips that preflight and sends the canonical replacement directly. The
|
|
723
734
|
default read/check/write protection is best effort rather than atomic because the Provider offers no revision or
|
|
724
735
|
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-027).
|
|
725
|
-
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata
|
|
736
|
+
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata.
|
|
726
737
|
Permanent personal deletion is named `permanently_delete`, returns `None`, and is non-recoverable. Sharing requires
|
|
727
738
|
list-observed item summaries, user-search summaries and a
|
|
728
739
|
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-012, PVD-036).
|
|
@@ -759,7 +770,7 @@ time strings.
|
|
|
759
770
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
760
771
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
761
772
|
the Provider binds by temporary row ID without checking its owner (PVD-031), and finalize atomicity/idempotency remain
|
|
762
|
-
absent
|
|
773
|
+
absent. Batch move and permanent delete do not claim Provider per-item results or atomicity. Permanent
|
|
763
774
|
deletion is named `permanently_delete_files` and is non-recoverable. Cloud downloads
|
|
764
775
|
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-002-safe
|
|
765
776
|
range subset. Cloud mutations are not automatically retried.
|
|
@@ -901,6 +912,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
901
912
|
```
|
|
902
913
|
|
|
903
914
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
904
|
-
byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.
|
|
905
|
-
commit `
|
|
906
|
-
`
|
|
915
|
+
byte-identical wheel and source distribution hashes. The release is bound to the rewritten `matelab-spec v0.4.2`,
|
|
916
|
+
commit `1a4b77721d782fccd2b1f26bcc16a7d876347686`, and OpenAPI SHA-256
|
|
917
|
+
`1e737421aac636356487122ea89e20d54de07c8b9c0651cf6970a7123fe3b72b`.
|
|
@@ -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.0a19`. `[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
|
|
13
|
+
The SDK is pinned to the rewritten `matelab-spec v0.4.2` 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,12 +36,16 @@ 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.0a19-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 track the current reviewed Provider at
|
|
46
|
+
`a3e6b961800f6b1ab666f0d3f6cd4c64c2a3ce27`. Provider limitations that remain relevant to integrations are documented
|
|
47
|
+
alongside the affected interfaces below.
|
|
48
|
+
|
|
45
49
|
## Design
|
|
46
50
|
|
|
47
51
|
The public module is intentionally small:
|
|
@@ -89,8 +93,8 @@ success code it does not allow raises `MatelabProtocolError` rather than assigni
|
|
|
89
93
|
`MatelabTransportError.status_code` remains available for HTTP failures. Provider response bodies, top-level `msg`,
|
|
90
94
|
legacy `errmsg`, opaque `errs`, uncontracted debug fields, and request payloads are not attached to exceptions because
|
|
91
95
|
Provider-authored diagnostics may contain stack traces, credentials, or submitted values.
|
|
92
|
-
The pinned v0.4.
|
|
93
|
-
|
|
96
|
+
The pinned v0.4.2 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
|
|
94
98
|
therefore keeps those diagnostics wire-only and does not expose `errs` as stable public metadata. A typed detail
|
|
95
99
|
interface remains blocked until a future Contract release can define one from stronger Provider evidence. `retryable`
|
|
96
100
|
means the identical SDK call is safe to replay without further interpretation. It is conservatively `False` for every
|
|
@@ -284,8 +288,8 @@ supports one file column. A locally rejected target does not spend the handle; o
|
|
|
284
288
|
result cannot be retried through the same client.
|
|
285
289
|
|
|
286
290
|
Files-module append and table/files replacement use the general record attachment intents and may be combined with
|
|
287
|
-
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root
|
|
288
|
-
|
|
291
|
+
other non-conflicting record changes. `RecordFilesAttachmentAppend` targets the module root; the current Provider does
|
|
292
|
+
not accept a files-folder path (PVD-044):
|
|
289
293
|
|
|
290
294
|
```python
|
|
291
295
|
from matelab import RecordAttachmentReplacement, RecordFilesAttachmentAppend, RecordValueUpdate
|
|
@@ -418,7 +422,7 @@ targets = await client.users.search("Example Researcher", global_scope=False)
|
|
|
418
422
|
`groups.list()` returns the `GroupSummary` tuple directly. Ordering remains Provider-unspecified and is documented
|
|
419
423
|
rather than repeated as a constant result field. The Provider's members for an unstable first group remain wire-only;
|
|
420
424
|
`users.search()` is the public recipient-discovery interface. These two discovery interfaces are experimental because
|
|
421
|
-
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029
|
|
425
|
+
group order is unstable and user search is unpaged, unordered and not field-minimized (PVD-006, PVD-029).
|
|
422
426
|
`GroupSummary.notebook_creation_available` expresses whether the group can currently host notebook creation without
|
|
423
427
|
exposing the Provider's data-server routing value.
|
|
424
428
|
|
|
@@ -510,6 +514,8 @@ relations = await client.records.relations(source)
|
|
|
510
514
|
as `modules`; it is not the template-shaped `RecordImportItem.data` accepted by record import.
|
|
511
515
|
`records.search()` maps each requested field name to a stored record path. A match exposes only Provider-returned
|
|
512
516
|
entries in `values`, so key membership distinguishes an absent result from an explicit JSON `null`.
|
|
517
|
+
The current Provider excludes encrypted records from search (PVD-043); an empty search result therefore does
|
|
518
|
+
not prove that no matching encrypted record exists.
|
|
513
519
|
|
|
514
520
|
The Provider calls its notebook directory tree `subtype`; that name remains wire-only. The SDK exposes
|
|
515
521
|
`RecordFolder`, `RecordSummary.folder_id`, and the `folders` returned with record listings. A top-level folder has
|
|
@@ -559,7 +565,9 @@ UID. Import validates the complete batch with generated wire models but cannot m
|
|
|
559
565
|
individual inputs or promise atomicity (PCG-008); it therefore returns only the tuple of database IDs actually
|
|
560
566
|
reported by the Provider. `RecordImportItem.keywords` is a tuple; the adapter owns the Provider's
|
|
561
567
|
legacy semicolon encoding. Folder paths are ordered existing folder titles from the notebook root; they do not create
|
|
562
|
-
missing folders.
|
|
568
|
+
missing folders. The current Provider rejects explicit-null table-file imports (PVD-045). Because the SDK accepts
|
|
569
|
+
arbitrary template-shaped data and cannot identify file columns without the template definition, integrations must omit
|
|
570
|
+
an unset file-valued key instead of sending it as `None`. Delete means moving records into the recycle bin, not permanent
|
|
563
571
|
deletion. Delete and restore return `None`; record mutations are not automatically retried.
|
|
564
572
|
|
|
565
573
|
`records.copy()` accepts an optional `new_record_uid`; when omitted, the SDK generates one locally. The Provider
|
|
@@ -577,7 +585,8 @@ returns the acknowledgement classification
|
|
|
577
585
|
issue a post-write read. Database, active-browser, and unclassified acknowledgements remain distinct, and mutation
|
|
578
586
|
retries stay disabled. Encrypted record content is outside the SDK's public read/update interface: the list-level
|
|
579
587
|
`RecordSummary.encrypted` flag lets callers identify and skip it, while the Provider password field and frontend-only
|
|
580
|
-
password lifecycle remain unexposed.
|
|
588
|
+
password lifecycle remain unexposed. Files-module attachment append is root-only because the current Provider rejects
|
|
589
|
+
folder-path segments (PVD-044). A staged attachment is indeterminate once the write has started.
|
|
581
590
|
|
|
582
591
|
Relation addition reads both endpoints and checks their resolved data server before writing; this reduces PVD-019
|
|
583
592
|
risk but is not an atomic Provider authorization guarantee. It does not list relations merely to inspect the
|
|
@@ -589,8 +598,8 @@ ignores target notebook identity (PVD-020); its mutation likewise performs autho
|
|
|
589
598
|
`records.comments()`. Each returned `RecordRelationRef` carries only the relation row and declared target IDs.
|
|
590
599
|
Deletion accepts the source `RecordLocator` and one of those observed refs.
|
|
591
600
|
|
|
592
|
-
Comment upload follows the Provider's literal one-request `
|
|
593
|
-
|
|
601
|
+
Comment upload follows the current Provider's literal one-request `file` field (PVD-037). Comment mutations return `None`
|
|
602
|
+
after acknowledgement. Edit first verifies that the selected
|
|
594
603
|
comment is currently observed and caller-owned because the Provider otherwise reports a false success for a missing or
|
|
595
604
|
other-user ID (PVD-004). Delete sends the typed ref directly because the Provider mutation itself enforces record and
|
|
596
605
|
caller ownership. Neither operation performs a post-write read. Staged comment attachments have no Contract abort
|
|
@@ -669,7 +678,9 @@ The Provider's static literature form definition and extraction deployment flag
|
|
|
669
678
|
`extract_metadata()` directly and handle an unavailable or failing optional backend as a Provider error. Extraction
|
|
670
679
|
returns a `PublicationMetadataCandidate`: unstored, rich publication evidence rather than metadata already attached to
|
|
671
680
|
a literature item. Its structured authors are `PublicationAuthorCandidate` values. Extraction accepts a DOI, a
|
|
672
|
-
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF.
|
|
681
|
+
completed staged PDF, or both; a supplied DOI takes precedence over the staged PDF. A non-empty DOI must match
|
|
682
|
+
`^10\.[0-9]+/\S+$`; the generated request model rejects other values before sending them to the Provider (PVD-042).
|
|
683
|
+
Literature list
|
|
673
684
|
results likewise exclude Provider-generated citation HTML and author-highlight fragments; Consumers receive the
|
|
674
685
|
underlying citation fields instead of presentation markup. `LiteratureDetail.metadata` is `None` when invalid legacy
|
|
675
686
|
JSON produces the Provider's empty-array fallback; otherwise it contains decoded stored metadata without arbitrary
|
|
@@ -694,7 +705,7 @@ canonical update preflights the raw item response and refuses to drop top-level
|
|
|
694
705
|
`allow_source_metadata_loss=True` explicitly skips that preflight and sends the canonical replacement directly. The
|
|
695
706
|
default read/check/write protection is best effort rather than atomic because the Provider offers no revision or
|
|
696
707
|
compare-and-swap condition; this Provider-specific behavior remains internal to the update operation (PVD-027).
|
|
697
|
-
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata
|
|
708
|
+
PDF replace/delete are separate acknowledged mutations and are not presented as atomic with metadata.
|
|
698
709
|
Permanent personal deletion is named `permanently_delete`, returns `None`, and is non-recoverable. Sharing requires
|
|
699
710
|
list-observed item summaries, user-search summaries and a
|
|
700
711
|
valid caller identity, then returns `None` because the Provider supplies no per-recipient IDs (PVD-012, PVD-036).
|
|
@@ -731,7 +742,7 @@ time strings.
|
|
|
731
742
|
Folder create returns a `CloudFolderRef` built from the Provider ID. Other folder and file mutations return `None`
|
|
732
743
|
after acknowledgement and do not automatically list the drive. Staged finalize accepts a completed `StagedFile`;
|
|
733
744
|
the Provider binds by temporary row ID without checking its owner (PVD-031), and finalize atomicity/idempotency remain
|
|
734
|
-
absent
|
|
745
|
+
absent. Batch move and permanent delete do not claim Provider per-item results or atomicity. Permanent
|
|
735
746
|
deletion is named `permanently_delete_files` and is non-recoverable. Cloud downloads
|
|
736
747
|
resolve bytes from the final file identity and reuse `DownloadStream`, thumbnail/preview choices and the PVD-002-safe
|
|
737
748
|
range subset. Cloud mutations are not automatically retried.
|
|
@@ -873,6 +884,6 @@ uv run python scripts/check_release.py dist/release/*.whl dist/release/*.tar.gz
|
|
|
873
884
|
```
|
|
874
885
|
|
|
875
886
|
Rebuilding the same commit with the same locked environment and `SOURCE_DATE_EPOCH` must produce
|
|
876
|
-
byte-identical wheel and source distribution hashes. The release is bound to `matelab-spec v0.4.
|
|
877
|
-
commit `
|
|
878
|
-
`
|
|
887
|
+
byte-identical wheel and source distribution hashes. The release is bound to the rewritten `matelab-spec v0.4.2`,
|
|
888
|
+
commit `1a4b77721d782fccd2b1f26bcc16a7d876347686`, and OpenAPI SHA-256
|
|
889
|
+
`1e737421aac636356487122ea89e20d54de07c8b9c0651cf6970a7123fe3b72b`.
|
|
@@ -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.2",
|
|
6
|
+
"commit": "1a4b77721d782fccd2b1f26bcc16a7d876347686"
|
|
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": "1e737421aac636356487122ea89e20d54de07c8b9c0651cf6970a7123fe3b72b"
|
|
12
12
|
}
|
|
13
13
|
}
|