datumesh 0.4.1__tar.gz → 0.4.2__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.
- {datumesh-0.4.1 → datumesh-0.4.2}/PKG-INFO +9 -6
- {datumesh-0.4.1 → datumesh-0.4.2}/README.md +5 -2
- {datumesh-0.4.1 → datumesh-0.4.2}/pyproject.toml +4 -4
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/__init__.py +10 -5
- datumesh-0.4.2/src/datumesh/_envelope.py +599 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_errors.py +5 -2
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_json.py +15 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_lexical.py +3 -2
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_mesh.py +1 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_model.py +3 -3
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_unitlist.py +2 -2
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_uri.py +17 -2
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh.egg-info/PKG-INFO +9 -6
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh.egg-info/SOURCES.txt +1 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_api.py +4 -4
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_conformance.py +38 -8
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_envelope.py +1 -1
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_spec_0_4_1.py +2 -4
- datumesh-0.4.2/tests/test_spec_0_4_2.py +460 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_uri.py +2 -2
- datumesh-0.4.1/src/datumesh/_envelope.py +0 -313
- {datumesh-0.4.1 → datumesh-0.4.2}/LICENSE +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/setup.cfg +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_keys.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_ucd15.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_unicode.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_units.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/_verify.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh/py.typed +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh.egg-info/dependency_links.txt +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh.egg-info/requires.txt +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/src/datumesh.egg-info/top_level.txt +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_bitflips.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_blob.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_jcs.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_keys.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_spec_0_2_1.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_spec_0_3_0.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_spec_0_4_0.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_unicode.py +0 -0
- {datumesh-0.4.1 → datumesh-0.4.2}/tests/test_units.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datumesh
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary: Verify Datumesh receipts (spec-0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
|
+
Summary: Verify Datumesh receipts (spec-0.4.2): RFC 8785 canonical JSON, Ed25519 signatures, slice-as-lineage, blobs, units, cell URIs, response envelopes (pending jobs, pins, slice pages, batches), key documents, mesh documents.
|
|
5
5
|
Author: Datumesh
|
|
6
6
|
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, https://datumesh.com
|
|
8
8
|
Project-URL: Repository, https://github.com/datumesh-com/datumesh-verify-py
|
|
9
|
-
Project-URL: Specification (spec-0.4.
|
|
10
|
-
Keywords: datumesh,spec-0.4.
|
|
9
|
+
Project-URL: Specification (spec-0.4.2), https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.2/SPEC.md
|
|
10
|
+
Keywords: datumesh,spec-0.4.2,receipt,verification,ed25519,rfc8785,jcs,canonical-json
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
@@ -27,11 +27,11 @@ Dynamic: license-file
|
|
|
27
27
|
|
|
28
28
|
# datumesh
|
|
29
29
|
|
|
30
|
-
Verify [Datumesh](https://datumesh.com) receipts in Python. A receipt is a signed answer for one addressable data cell; this library checks its canonical form (RFC 8785 JSON) and its Ed25519 signature against the signer's published keys, and optionally the recomputation checks (function descriptor, input receipts and slice manifests, and a value you computed) and the content of a blob value, as the [Datumesh specification](https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.
|
|
30
|
+
Verify [Datumesh](https://datumesh.com) receipts in Python. A receipt is a signed answer for one addressable data cell; this library checks its canonical form (RFC 8785 JSON) and its Ed25519 signature against the signer's published keys, and optionally the recomputation checks (function descriptor, input receipts and slice manifests, and a value you computed) and the content of a blob value, as the [Datumesh specification](https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.2/SPEC.md) (revision `spec-0.4.2`) defines. It also checks a mesh's response envelope (including `pending` jobs), resolves the unit of a cell's value, and checks a host's mesh document for cross-mesh use.
|
|
31
31
|
|
|
32
32
|
```sh
|
|
33
33
|
pip install datumesh
|
|
34
|
-
git clone --depth 1 --branch spec-0.4.
|
|
34
|
+
git clone --depth 1 --branch spec-0.4.2 https://github.com/datumesh-com/datumesh-spec && cd datumesh-spec
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
```python
|
|
@@ -52,6 +52,9 @@ Website: https://datumesh.com · Specification: https://github.com/datumesh-com/
|
|
|
52
52
|
- `verify(receipt, keys, recompute=None, blob=None) -> VerifyResult`: runs the verification procedure of SPEC 10.1. Never raises for an invalid receipt or bad key material; the result has `ok`, `code` (`"OK"` or an error code), `level` (`"signed"` or `"recomputed"`), `hash`, `key`, `detail` and `path`. Two codes come with success, at level `signed` (SPEC 10.1 step 7.6): `"E_EVAL_UNAVAILABLE"` when you pass `recompute` without a `value` because you could not evaluate the function (the other recomputation checks still run first), and `"E_INPUT_SUPERSEDED"` when your value differs but the evaluation's `lineage` shows that an input was replaced by a later version (the receipt is historical, not wrong). It uses no network: keys are an argument (a key document, a `KeysResult`, a `{key id: public key}` mapping, or a list of these). `recompute` takes the descriptor (leave it out if you have none; `None` is a JSON null and fails the hash check), the input receipts (slice members included), the manifests of slice entries (`slice:<slice id>:<members hash>`), the value you computed and optionally the evaluation's lineage (the library does not evaluate functions, formulas included); `blob` takes the content bytes of a blob value, whose length and SHA-256 are then checked (step 7.7, reported as `blob_checked`).
|
|
53
53
|
- `check_envelope(status, body, keys, request) -> EnvelopeResult`: checks a mesh's response to `https://<mesh>/cell/...` (SPEC 5.5), verifies the receipt inside it, and checks that it answers your request (`request` is `{"cell_id": ..., "asof": ...}`, `asof` only if you asked for one; the receipt's `asof` must be at or before it, for `ok` and `stale` alike). A `not_covered` envelope may carry a formula evaluation `fault` (exposed as `fault`). The envelope itself is unsigned: `stale`, `superseded_by`, a `verified` label and the currency `ok` asserts remain the mesh's claims.
|
|
54
54
|
- Jobs (spec-0.4.1): a `pending` envelope (HTTP 202) carries `job`, `estimate_seconds` and `poll` (exposed on the result) and echoes your request, which must match. When you poll, pass the original request plus `"job": <the job id>`: the answer is checked against the original cell and `asof`, never the job URL, and only then may it be `bad_request` with `E_JOB_UNKNOWN` (ask again).
|
|
55
|
+
- Pins, trust and the mesh asked (spec-0.4.2): a request description may carry `fn_hash` (you pinned the function: `parse_uri`/`format_uri` handle `fn_hash=`) and `mesh` (the host you asked). Answers to a pinned request must echo the pin; with `mesh`, `computed` (this mesh evaluated and signed it) is checked against the signer, and `poll` against the host. Without `mesh`, comparing them with the host you asked is your own check.
|
|
56
|
+
- Slice pages (spec-0.4.2): `check_envelope` with `{"slice_id", "asof"?, "fn_hash"?, "mesh"?, "after"?}` checks a page of the slice endpoint: every member's receipt, its membership, `asof`, trust and key order (`result.members`, `result.next`).
|
|
57
|
+
- `check_batch(status, body, keys, requests) -> BatchResult` (spec-0.4.2): the answer to `POST /cells`, checked as a whole, then item by item against each request (`result.items`); a refusal of the whole batch gives `result.outcome`.
|
|
55
58
|
- `resolve_mesh(host, keys, mesh) -> MeshResult`: checks a host's key document and mesh document (`/.well-known/datumesh-mesh.json`, SPEC 9.6) together, given each response as a `(status, body)` pair; the result has `bindings` and the known `endpoints`, or `E_KEY_UNAVAILABLE`, `E_KEY_DOC` or `E_MESH_DOC`. It uses no network, and verification never needs it.
|
|
56
59
|
- `resolved_unit(descriptor, cell) -> str | None`: the unit of a cell's value, such as `USD/EUR` (SPEC 7.1, units.md).
|
|
57
60
|
- `keys_from_response(host, status, body) -> KeysResult`: interprets a response for `https://<host>/.well-known/datumesh.json` (SPEC 9.3).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# datumesh
|
|
2
2
|
|
|
3
|
-
Verify [Datumesh](https://datumesh.com) receipts in Python. A receipt is a signed answer for one addressable data cell; this library checks its canonical form (RFC 8785 JSON) and its Ed25519 signature against the signer's published keys, and optionally the recomputation checks (function descriptor, input receipts and slice manifests, and a value you computed) and the content of a blob value, as the [Datumesh specification](https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.
|
|
3
|
+
Verify [Datumesh](https://datumesh.com) receipts in Python. A receipt is a signed answer for one addressable data cell; this library checks its canonical form (RFC 8785 JSON) and its Ed25519 signature against the signer's published keys, and optionally the recomputation checks (function descriptor, input receipts and slice manifests, and a value you computed) and the content of a blob value, as the [Datumesh specification](https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.2/SPEC.md) (revision `spec-0.4.2`) defines. It also checks a mesh's response envelope (including `pending` jobs), resolves the unit of a cell's value, and checks a host's mesh document for cross-mesh use.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
pip install datumesh
|
|
7
|
-
git clone --depth 1 --branch spec-0.4.
|
|
7
|
+
git clone --depth 1 --branch spec-0.4.2 https://github.com/datumesh-com/datumesh-spec && cd datumesh-spec
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
```python
|
|
@@ -25,6 +25,9 @@ Website: https://datumesh.com · Specification: https://github.com/datumesh-com/
|
|
|
25
25
|
- `verify(receipt, keys, recompute=None, blob=None) -> VerifyResult`: runs the verification procedure of SPEC 10.1. Never raises for an invalid receipt or bad key material; the result has `ok`, `code` (`"OK"` or an error code), `level` (`"signed"` or `"recomputed"`), `hash`, `key`, `detail` and `path`. Two codes come with success, at level `signed` (SPEC 10.1 step 7.6): `"E_EVAL_UNAVAILABLE"` when you pass `recompute` without a `value` because you could not evaluate the function (the other recomputation checks still run first), and `"E_INPUT_SUPERSEDED"` when your value differs but the evaluation's `lineage` shows that an input was replaced by a later version (the receipt is historical, not wrong). It uses no network: keys are an argument (a key document, a `KeysResult`, a `{key id: public key}` mapping, or a list of these). `recompute` takes the descriptor (leave it out if you have none; `None` is a JSON null and fails the hash check), the input receipts (slice members included), the manifests of slice entries (`slice:<slice id>:<members hash>`), the value you computed and optionally the evaluation's lineage (the library does not evaluate functions, formulas included); `blob` takes the content bytes of a blob value, whose length and SHA-256 are then checked (step 7.7, reported as `blob_checked`).
|
|
26
26
|
- `check_envelope(status, body, keys, request) -> EnvelopeResult`: checks a mesh's response to `https://<mesh>/cell/...` (SPEC 5.5), verifies the receipt inside it, and checks that it answers your request (`request` is `{"cell_id": ..., "asof": ...}`, `asof` only if you asked for one; the receipt's `asof` must be at or before it, for `ok` and `stale` alike). A `not_covered` envelope may carry a formula evaluation `fault` (exposed as `fault`). The envelope itself is unsigned: `stale`, `superseded_by`, a `verified` label and the currency `ok` asserts remain the mesh's claims.
|
|
27
27
|
- Jobs (spec-0.4.1): a `pending` envelope (HTTP 202) carries `job`, `estimate_seconds` and `poll` (exposed on the result) and echoes your request, which must match. When you poll, pass the original request plus `"job": <the job id>`: the answer is checked against the original cell and `asof`, never the job URL, and only then may it be `bad_request` with `E_JOB_UNKNOWN` (ask again).
|
|
28
|
+
- Pins, trust and the mesh asked (spec-0.4.2): a request description may carry `fn_hash` (you pinned the function: `parse_uri`/`format_uri` handle `fn_hash=`) and `mesh` (the host you asked). Answers to a pinned request must echo the pin; with `mesh`, `computed` (this mesh evaluated and signed it) is checked against the signer, and `poll` against the host. Without `mesh`, comparing them with the host you asked is your own check.
|
|
29
|
+
- Slice pages (spec-0.4.2): `check_envelope` with `{"slice_id", "asof"?, "fn_hash"?, "mesh"?, "after"?}` checks a page of the slice endpoint: every member's receipt, its membership, `asof`, trust and key order (`result.members`, `result.next`).
|
|
30
|
+
- `check_batch(status, body, keys, requests) -> BatchResult` (spec-0.4.2): the answer to `POST /cells`, checked as a whole, then item by item against each request (`result.items`); a refusal of the whole batch gives `result.outcome`.
|
|
28
31
|
- `resolve_mesh(host, keys, mesh) -> MeshResult`: checks a host's key document and mesh document (`/.well-known/datumesh-mesh.json`, SPEC 9.6) together, given each response as a `(status, body)` pair; the result has `bindings` and the known `endpoints`, or `E_KEY_UNAVAILABLE`, `E_KEY_DOC` or `E_MESH_DOC`. It uses no network, and verification never needs it.
|
|
29
32
|
- `resolved_unit(descriptor, cell) -> str | None`: the unit of a cell's value, such as `USD/EUR` (SPEC 7.1, units.md).
|
|
30
33
|
- `keys_from_response(host, status, body) -> KeysResult`: interprets a response for `https://<host>/.well-known/datumesh.json` (SPEC 9.3).
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "datumesh"
|
|
7
|
-
version = "0.4.
|
|
8
|
-
description = "Verify Datumesh receipts (spec-0.4.
|
|
7
|
+
version = "0.4.2"
|
|
8
|
+
description = "Verify Datumesh receipts (spec-0.4.2): RFC 8785 canonical JSON, Ed25519 signatures, slice-as-lineage, blobs, units, cell URIs, response envelopes (pending jobs, pins, slice pages, batches), key documents, mesh documents."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = "Apache-2.0"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [{ name = "Datumesh" }]
|
|
14
|
-
keywords = ["datumesh", "spec-0.4.
|
|
14
|
+
keywords = ["datumesh", "spec-0.4.2", "receipt", "verification", "ed25519", "rfc8785", "jcs", "canonical-json"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Development Status :: 3 - Alpha",
|
|
17
17
|
"Intended Audience :: Developers",
|
|
@@ -30,7 +30,7 @@ dependencies = ["pynacl>=1.5.0"]
|
|
|
30
30
|
[project.urls]
|
|
31
31
|
Homepage = "https://datumesh.com"
|
|
32
32
|
Repository = "https://github.com/datumesh-com/datumesh-verify-py"
|
|
33
|
-
"Specification (spec-0.4.
|
|
33
|
+
"Specification (spec-0.4.2)" = "https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.2/SPEC.md"
|
|
34
34
|
|
|
35
35
|
[tool.setuptools.packages.find]
|
|
36
36
|
where = ["src"]
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""datumesh: verify Datumesh receipts (signed answers for addressable data cells).
|
|
2
2
|
|
|
3
|
-
Implements the Datumesh protocol specification, revision ``spec-0.4.
|
|
3
|
+
Implements the Datumesh protocol specification, revision ``spec-0.4.2``
|
|
4
4
|
(https://github.com/datumesh-com/datumesh-spec), as a verifier library: RFC 8785
|
|
5
5
|
canonical JSON, SHA-256 hashes, Ed25519 receipt signatures, blob content, units,
|
|
6
|
-
cell URIs, response envelopes,
|
|
6
|
+
cell URIs (pins included), response envelopes, slice pages and batches, key
|
|
7
|
+
documents, and slice-as-lineage (slice entries,
|
|
7
8
|
slice objects and manifests), and, separately from verification, cross-mesh
|
|
8
9
|
resolution of a host's mesh document (:func:`resolve_mesh`). It evaluates no
|
|
9
10
|
function, formulas included: the evaluated value comes from the caller. Only
|
|
@@ -16,7 +17,7 @@ import hashlib
|
|
|
16
17
|
from typing import Any, Dict, Optional
|
|
17
18
|
|
|
18
19
|
from . import _model, _units
|
|
19
|
-
from ._envelope import EnvelopeResult, check_envelope
|
|
20
|
+
from ._envelope import TRUST, BatchResult, EnvelopeResult, MemberResult, check_batch, check_envelope
|
|
20
21
|
from ._errors import ERROR_CODES, FAULT_CODES, SUCCESS_CODES, DatumeshError, fail
|
|
21
22
|
from ._json import jcs_bytes
|
|
22
23
|
from ._keys import Key, KeysResult, fetch_keys, key_id, keys_from_response
|
|
@@ -24,9 +25,9 @@ from ._mesh import MESH_ENDPOINTS, MESH_WELL_KNOWN_PATH, MeshResult, resolve_mes
|
|
|
24
25
|
from ._uri import format_uri, parse_uri, uri_to_https
|
|
25
26
|
from ._verify import VerifyResult, load, payload_bytes, verify
|
|
26
27
|
|
|
27
|
-
__version__ = "0.4.
|
|
28
|
+
__version__ = "0.4.2"
|
|
28
29
|
#: The specification revision this package conforms to.
|
|
29
|
-
SPEC_VERSION = "spec-0.4.
|
|
30
|
+
SPEC_VERSION = "spec-0.4.2"
|
|
30
31
|
#: Every literal unit listed in units.md (index units, ``index:<period>=<value>``, are a pattern and not listed).
|
|
31
32
|
UNITS = tuple(sorted(_units.LITERALS))
|
|
32
33
|
#: The currency codes of units.md 2.1.
|
|
@@ -38,6 +39,9 @@ KINDS = ("scalar", "cell", "ref", "function", "receipt", "slice", "manifest")
|
|
|
38
39
|
|
|
39
40
|
__all__ = [
|
|
40
41
|
"SPEC_VERSION",
|
|
42
|
+
"BatchResult",
|
|
43
|
+
"MemberResult",
|
|
44
|
+
"TRUST",
|
|
41
45
|
"CURRENCIES",
|
|
42
46
|
"ERROR_CODES",
|
|
43
47
|
"FAULT_CODES",
|
|
@@ -54,6 +58,7 @@ __all__ = [
|
|
|
54
58
|
"VerifyResult",
|
|
55
59
|
"canonicalize",
|
|
56
60
|
"cell_hash",
|
|
61
|
+
"check_batch",
|
|
57
62
|
"check_envelope",
|
|
58
63
|
"fetch_keys",
|
|
59
64
|
"format_uri",
|