matelab-python-sdk 0.1.0a22__tar.gz → 0.1.0a23__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.0a23}/CHANGELOG.md +6 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/PKG-INFO +9 -3
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/README.md +8 -2
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/pyproject.toml +1 -1
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/records.py +54 -3
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_records.py +71 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/uv.lock +1 -1
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/.env.example +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/.github/workflows/release.yml +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/.gitignore +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/AGENTS.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/CONTEXT.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/LICENSE +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/NOTICE +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/contracts/matelab-integration-v1.lock.json +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/contracts/matelab-integration-v1.openapi.yaml +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/docs/agent-architecture.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/docs/agent-workflows.md +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/docs/operation-coverage.yaml +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/scripts/check_installed_package.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/scripts/check_release.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/scripts/generate_models.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_generated/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_generated/models.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_hashes.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_transport.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_wire_validation.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/client.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/__init__.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/_attachment_content.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/groups.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/literature.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/templates.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/uploads.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/users.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/errors.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/py.typed +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/session.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/streaming.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/conftest.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/provider/test_provider_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_async_attachment_upload.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_client.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_cloud_drive.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_comments_and_downloads.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_consumer_smoke.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_errors.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_extended_records.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_generation.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_groups.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_notebook_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_notebooks.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_operation_coverage.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_record_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_record_mutations.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_release.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_streaming.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_template_lifecycle.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_templates.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_transport.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_uploads_and_literature.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_users.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/typing/consumer.py +0 -0
- {matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/typing/pyproject.toml +0 -0
|
@@ -3,6 +3,12 @@
|
|
|
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.0a23 - 2026-09-04
|
|
7
|
+
|
|
8
|
+
- Temporarily accepts `readRecord` table file attachments that contain valid `filename`, `hash`, and `size` fields but
|
|
9
|
+
omit the Contract-required `timestamp`. The SDK preserves the omission instead of synthesizing a timestamp; explicit
|
|
10
|
+
null timestamps and other malformed attachment values remain rejected.
|
|
11
|
+
|
|
6
12
|
## 0.1.0a22 - 2026-09-03
|
|
7
13
|
|
|
8
14
|
- 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.0a23
|
|
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,7 +35,7 @@ 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.0a23`. `[project].version` in `pyproject.toml` is the sole SDK version source;
|
|
39
39
|
`uv.lock` only mirrors that source.
|
|
40
40
|
|
|
41
41
|
The SDK is pinned to the immutable `matelab-spec v0.4.5` Contract Release. The sole release pin is
|
|
@@ -64,7 +64,7 @@ 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.0a23-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
|
|
@@ -354,6 +354,12 @@ not accept a caption. Record reads likewise accept only one canonical attachment
|
|
|
354
354
|
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
355
355
|
differ from the current occurrence.
|
|
356
356
|
|
|
357
|
+
As a temporary Provider-compatibility exception, `records.read()` also accepts a table file attachment object whose
|
|
358
|
+
otherwise valid `filename`, `hash`, and `size` are present but whose Contract-required `timestamp` is omitted. The SDK
|
|
359
|
+
preserves that omission in `Record.modules` and does not invent a timestamp; null timestamps and all other malformed
|
|
360
|
+
attachment shapes remain response errors. This exception can be removed after the Provider canonicalizes current and
|
|
361
|
+
historical record content.
|
|
362
|
+
|
|
357
363
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
358
364
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
359
365
|
must not be called while a concurrent editor is known to be active. The Provider offers no expected hash or revision,
|
|
@@ -7,7 +7,7 @@ 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.0a23`. `[project].version` in `pyproject.toml` is the sole SDK version source;
|
|
11
11
|
`uv.lock` only mirrors that source.
|
|
12
12
|
|
|
13
13
|
The SDK is pinned to the immutable `matelab-spec v0.4.5` Contract Release. The sole release pin is
|
|
@@ -36,7 +36,7 @@ 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.0a23-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
|
|
@@ -326,6 +326,12 @@ not accept a caption. Record reads likewise accept only one canonical attachment
|
|
|
326
326
|
an attachment array violates the pinned response contract. Both replacement forms require the replacement hash to
|
|
327
327
|
differ from the current occurrence.
|
|
328
328
|
|
|
329
|
+
As a temporary Provider-compatibility exception, `records.read()` also accepts a table file attachment object whose
|
|
330
|
+
otherwise valid `filename`, `hash`, and `size` are present but whose Contract-required `timestamp` is omitted. The SDK
|
|
331
|
+
preserves that omission in `Record.modules` and does not invent a timestamp; null timestamps and all other malformed
|
|
332
|
+
attachment shapes remain response errors. This exception can be removed after the Provider canonicalizes current and
|
|
333
|
+
historical record content.
|
|
334
|
+
|
|
329
335
|
All record attachment intents reject handles from another notebook or authenticated uploader, duplicate use within one
|
|
330
336
|
finalization request, and raw Provider attachment references. Row/index-based operations use an immediate SDK read and
|
|
331
337
|
must not be called while a concurrent editor is known to be active. The Provider offers no expected hash or revision,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import secrets
|
|
3
3
|
from collections.abc import AsyncIterable, Iterable, Iterator, Mapping, Sequence
|
|
4
|
+
from copy import deepcopy
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
6
|
from html.parser import HTMLParser
|
|
6
7
|
from types import MappingProxyType
|
|
7
|
-
from typing import IO, Literal, TypeAlias, cast
|
|
8
|
+
from typing import IO, Literal, Self, TypeAlias, cast
|
|
8
9
|
from urllib.parse import unquote
|
|
9
10
|
|
|
10
|
-
from pydantic import BaseModel, JsonValue
|
|
11
|
+
from pydantic import BaseModel, JsonValue, model_validator
|
|
11
12
|
from typing_extensions import override
|
|
12
13
|
|
|
13
14
|
from matelab._generated import models as wire_models
|
|
@@ -21,6 +22,56 @@ from matelab.domains.users import UserRef
|
|
|
21
22
|
from matelab.errors import MatelabProtocolError, MatelabUsageError
|
|
22
23
|
from matelab.streaming import ByteRange, DownloadStream
|
|
23
24
|
|
|
25
|
+
_MISSING_TIMESTAMP_MARKER = "__matelab_missing_record_attachment_timestamp__"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _table_file_attachments(modules: JsonValue) -> Iterator[dict[str, JsonValue]]:
|
|
29
|
+
if not isinstance(modules, list):
|
|
30
|
+
return
|
|
31
|
+
for module in modules:
|
|
32
|
+
if not isinstance(module, dict) or module.get("type") != "table":
|
|
33
|
+
continue
|
|
34
|
+
columns = module.get("data")
|
|
35
|
+
if not isinstance(columns, list):
|
|
36
|
+
continue
|
|
37
|
+
for column in columns:
|
|
38
|
+
if not isinstance(column, dict) or column.get("type") != "file":
|
|
39
|
+
continue
|
|
40
|
+
values = column.get("data")
|
|
41
|
+
if not isinstance(values, list):
|
|
42
|
+
continue
|
|
43
|
+
for value in values:
|
|
44
|
+
if isinstance(value, dict):
|
|
45
|
+
yield value
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class _ReadRecordResponse(wire_models.ItemViewResponse):
|
|
49
|
+
"""Contain the Provider's temporary omission of stored attachment timestamps."""
|
|
50
|
+
|
|
51
|
+
@model_validator(mode="before")
|
|
52
|
+
@classmethod
|
|
53
|
+
def _allow_missing_attachment_timestamp(cls, value: object) -> object:
|
|
54
|
+
if not isinstance(value, dict):
|
|
55
|
+
return value
|
|
56
|
+
payload = deepcopy(cast(dict[str, JsonValue], value))
|
|
57
|
+
modules = payload.get("modules")
|
|
58
|
+
if modules is None:
|
|
59
|
+
return payload
|
|
60
|
+
for attachment in _table_file_attachments(modules):
|
|
61
|
+
if "timestamp" not in attachment and _MISSING_TIMESTAMP_MARKER not in attachment:
|
|
62
|
+
attachment["timestamp"] = 1
|
|
63
|
+
attachment[_MISSING_TIMESTAMP_MARKER] = True
|
|
64
|
+
return payload
|
|
65
|
+
|
|
66
|
+
@model_validator(mode="after")
|
|
67
|
+
def _restore_missing_attachment_timestamp(self) -> Self:
|
|
68
|
+
modules: JsonValue = [{"type": module.type, "data": cast(JsonValue, module.data)} for module in self.modules]
|
|
69
|
+
for attachment in _table_file_attachments(modules):
|
|
70
|
+
if attachment.pop(_MISSING_TIMESTAMP_MARKER, None) is True:
|
|
71
|
+
del attachment["timestamp"]
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
|
|
24
75
|
_LIST_RECORDS = Operation(
|
|
25
76
|
method="POST",
|
|
26
77
|
path="/eln_api/items",
|
|
@@ -68,7 +119,7 @@ _READ_RECORD = Operation(
|
|
|
68
119
|
method="GET",
|
|
69
120
|
path="/eln_items/item_view",
|
|
70
121
|
encoding=Encoding.QUERY,
|
|
71
|
-
response_model=
|
|
122
|
+
response_model=_ReadRecordResponse,
|
|
72
123
|
success_codes=frozenset({0}),
|
|
73
124
|
retry_on_access_expired=True,
|
|
74
125
|
)
|
|
@@ -303,6 +303,77 @@ async def test_read_current_record_maps_required_nullable_and_open_modules() ->
|
|
|
303
303
|
assert "74034dae" not in repr(record.attachments[0])
|
|
304
304
|
|
|
305
305
|
|
|
306
|
+
@pytest.mark.asyncio
|
|
307
|
+
async def test_read_tolerates_provider_table_attachment_without_timestamp() -> None:
|
|
308
|
+
payload = _item_view_payload(uid="REC-EXAMPLE-001")
|
|
309
|
+
attachment = {
|
|
310
|
+
"hash": "d6a8f491a743ee3c10b42b4519d7545d7f1d79a7e98ed2ef9c03c0c1d75a1a91",
|
|
311
|
+
"filename": "evidence.pdf",
|
|
312
|
+
"size": 34,
|
|
313
|
+
}
|
|
314
|
+
payload["modules"] = [
|
|
315
|
+
{
|
|
316
|
+
"type": "table",
|
|
317
|
+
"name": "Data sheet",
|
|
318
|
+
"rows": ["row-1"],
|
|
319
|
+
"data": [{"name": "File", "type": "file", "data": [attachment]}],
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
|
|
323
|
+
async def handler(_: Request) -> Response:
|
|
324
|
+
return Response(200, json=payload)
|
|
325
|
+
|
|
326
|
+
notebook = NotebookRef(notebook_id=23, title="Shared Example", owner_userid=202, scope="shared")
|
|
327
|
+
source = RecordLocator(notebook=notebook, record=RecordRef(record_id=9001, record_uid="REC-EXAMPLE-001"))
|
|
328
|
+
async with AsyncClient(base_url="https://matelab.example/api", transport=MockTransport(handler)) as http_client:
|
|
329
|
+
client = AsyncMatelab("https://ignored.example", session=_session(), http_client=http_client)
|
|
330
|
+
record = await client.records.read(source)
|
|
331
|
+
|
|
332
|
+
assert record.modules[0] == {
|
|
333
|
+
"name": "Data sheet",
|
|
334
|
+
"type": "table",
|
|
335
|
+
"data": [{"name": "File", "type": "file", "data": [attachment]}],
|
|
336
|
+
"language": None,
|
|
337
|
+
"style": None,
|
|
338
|
+
"rows": ["row-1"],
|
|
339
|
+
}
|
|
340
|
+
assert [(item.filename, item.size) for item in record.attachments] == [("evidence.pdf", 34)]
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
@pytest.mark.parametrize("invalid_change", ["filename", "hash", "size", "null_timestamp"])
|
|
344
|
+
@pytest.mark.asyncio
|
|
345
|
+
async def test_read_timestamp_compatibility_does_not_relax_other_attachment_requirements(invalid_change: str) -> None:
|
|
346
|
+
payload = _item_view_payload(uid="REC-EXAMPLE-001")
|
|
347
|
+
attachment: dict[str, object] = {
|
|
348
|
+
"hash": "d6a8f491a743ee3c10b42b4519d7545d7f1d79a7e98ed2ef9c03c0c1d75a1a91",
|
|
349
|
+
"filename": "evidence.pdf",
|
|
350
|
+
"size": 34,
|
|
351
|
+
"timestamp": 1_767_946_200_000,
|
|
352
|
+
}
|
|
353
|
+
if invalid_change == "null_timestamp":
|
|
354
|
+
attachment["timestamp"] = None
|
|
355
|
+
else:
|
|
356
|
+
del attachment[invalid_change]
|
|
357
|
+
payload["modules"] = [
|
|
358
|
+
{
|
|
359
|
+
"type": "table",
|
|
360
|
+
"name": "Data sheet",
|
|
361
|
+
"rows": ["row-1"],
|
|
362
|
+
"data": [{"name": "File", "type": "file", "data": [attachment]}],
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
|
|
366
|
+
async def handler(_: Request) -> Response:
|
|
367
|
+
return Response(200, json=payload)
|
|
368
|
+
|
|
369
|
+
notebook = NotebookRef(notebook_id=23, title="Shared Example", owner_userid=202, scope="shared")
|
|
370
|
+
source = RecordLocator(notebook=notebook, record=RecordRef(record_id=9001, record_uid="REC-EXAMPLE-001"))
|
|
371
|
+
async with AsyncClient(base_url="https://matelab.example/api", transport=MockTransport(handler)) as http_client:
|
|
372
|
+
client = AsyncMatelab("https://ignored.example", session=_session(), http_client=http_client)
|
|
373
|
+
with pytest.raises(MatelabProtocolError, match="does not match the Integration Contract"):
|
|
374
|
+
_ = await client.records.read(source)
|
|
375
|
+
|
|
376
|
+
|
|
306
377
|
@pytest.mark.asyncio
|
|
307
378
|
async def test_read_rejects_historical_table_attachment_array_at_public_boundary() -> None:
|
|
308
379
|
payload = _item_view_payload(uid="REC-EXAMPLE-001")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/scripts/check_installed_package.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_generated/__init__.py
RENAMED
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/_generated/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/cloud_drive.py
RENAMED
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/literature.py
RENAMED
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/notebooks.py
RENAMED
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/src/matelab/domains/templates.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/provider/test_provider_smoke.py
RENAMED
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_async_attachment_upload.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_comments_and_downloads.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_notebook_lifecycle.py
RENAMED
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_operation_coverage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_template_lifecycle.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matelab_python_sdk-0.1.0a22 → matelab_python_sdk-0.1.0a23}/tests/test_uploads_and_literature.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|