datumesh 0.4.0__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.
Files changed (41) hide show
  1. {datumesh-0.4.0 → datumesh-0.4.2}/PKG-INFO +11 -6
  2. {datumesh-0.4.0 → datumesh-0.4.2}/README.md +7 -2
  3. {datumesh-0.4.0 → datumesh-0.4.2}/pyproject.toml +4 -4
  4. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/__init__.py +19 -7
  5. datumesh-0.4.2/src/datumesh/_envelope.py +599 -0
  6. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_errors.py +7 -0
  7. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_json.py +15 -0
  8. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_lexical.py +3 -2
  9. datumesh-0.4.2/src/datumesh/_mesh.py +174 -0
  10. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_model.py +3 -3
  11. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_unitlist.py +2 -2
  12. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_uri.py +17 -2
  13. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh.egg-info/PKG-INFO +11 -6
  14. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh.egg-info/SOURCES.txt +3 -0
  15. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_api.py +4 -4
  16. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_conformance.py +38 -7
  17. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_envelope.py +3 -3
  18. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_spec_0_4_0.py +0 -2
  19. datumesh-0.4.2/tests/test_spec_0_4_1.py +391 -0
  20. datumesh-0.4.2/tests/test_spec_0_4_2.py +460 -0
  21. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_uri.py +2 -2
  22. datumesh-0.4.0/src/datumesh/_envelope.py +0 -241
  23. {datumesh-0.4.0 → datumesh-0.4.2}/LICENSE +0 -0
  24. {datumesh-0.4.0 → datumesh-0.4.2}/setup.cfg +0 -0
  25. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_keys.py +0 -0
  26. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_ucd15.py +0 -0
  27. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_unicode.py +0 -0
  28. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_units.py +0 -0
  29. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/_verify.py +0 -0
  30. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh/py.typed +0 -0
  31. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh.egg-info/dependency_links.txt +0 -0
  32. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh.egg-info/requires.txt +0 -0
  33. {datumesh-0.4.0 → datumesh-0.4.2}/src/datumesh.egg-info/top_level.txt +0 -0
  34. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_bitflips.py +0 -0
  35. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_blob.py +0 -0
  36. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_jcs.py +0 -0
  37. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_keys.py +0 -0
  38. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_spec_0_2_1.py +0 -0
  39. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_spec_0_3_0.py +0 -0
  40. {datumesh-0.4.0 → datumesh-0.4.2}/tests/test_unicode.py +0 -0
  41. {datumesh-0.4.0 → 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.0
4
- Summary: Verify Datumesh receipts (spec-0.4.0): RFC 8785 canonical JSON, Ed25519 signatures, slice-as-lineage, blobs, units, cell URIs, response envelopes, key documents.
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.0), https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.0/SPEC.md
10
- Keywords: datumesh,spec-0.4.0,receipt,verification,ed25519,rfc8785,jcs,canonical-json
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.0/SPEC.md) (revision `spec-0.4.0`) defines. It also checks a mesh's response envelope and resolves the unit of a cell's value.
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.0 https://github.com/datumesh-com/datumesh-spec && cd datumesh-spec
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
@@ -51,6 +51,11 @@ Website: https://datumesh.com · Specification: https://github.com/datumesh-com/
51
51
 
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
+ - 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`.
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.
54
59
  - `resolved_unit(descriptor, cell) -> str | None`: the unit of a cell's value, such as `USD/EUR` (SPEC 7.1, units.md).
55
60
  - `keys_from_response(host, status, body) -> KeysResult`: interprets a response for `https://<host>/.well-known/datumesh.json` (SPEC 9.3).
56
61
  - `fetch_keys(host, timeout=10.0) -> KeysResult`: the only function that uses the network. One GET, TLS verified, redirects not followed.
@@ -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.0/SPEC.md) (revision `spec-0.4.0`) defines. It also checks a mesh's response envelope and resolves the unit of a cell's value.
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.0 https://github.com/datumesh-com/datumesh-spec && cd datumesh-spec
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
@@ -24,6 +24,11 @@ Website: https://datumesh.com · Specification: https://github.com/datumesh-com/
24
24
 
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
+ - 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`.
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.
27
32
  - `resolved_unit(descriptor, cell) -> str | None`: the unit of a cell's value, such as `USD/EUR` (SPEC 7.1, units.md).
28
33
  - `keys_from_response(host, status, body) -> KeysResult`: interprets a response for `https://<host>/.well-known/datumesh.json` (SPEC 9.3).
29
34
  - `fetch_keys(host, timeout=10.0) -> KeysResult`: the only function that uses the network. One GET, TLS verified, redirects not followed.
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "datumesh"
7
- version = "0.4.0"
8
- description = "Verify Datumesh receipts (spec-0.4.0): RFC 8785 canonical JSON, Ed25519 signatures, slice-as-lineage, blobs, units, cell URIs, response envelopes, key documents."
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.0", "receipt", "verification", "ed25519", "rfc8785", "jcs", "canonical-json"]
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.0)" = "https://github.com/datumesh-com/datumesh-spec/blob/spec-0.4.0/SPEC.md"
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,11 +1,14 @@
1
1
  """datumesh: verify Datumesh receipts (signed answers for addressable data cells).
2
2
 
3
- Implements the Datumesh protocol specification, revision ``spec-0.4.0``
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, key documents, and slice-as-lineage (slice entries,
7
- slice objects and manifests). It evaluates no function, formulas included: the
8
- evaluated value comes from the caller. Only :func:`fetch_keys` touches the network.
6
+ cell URIs (pins included), response envelopes, slice pages and batches, key
7
+ documents, and slice-as-lineage (slice entries,
8
+ slice objects and manifests), and, separately from verification, cross-mesh
9
+ resolution of a host's mesh document (:func:`resolve_mesh`). It evaluates no
10
+ function, formulas included: the evaluated value comes from the caller. Only
11
+ :func:`fetch_keys` touches the network.
9
12
  """
10
13
 
11
14
  from __future__ import annotations
@@ -14,16 +17,17 @@ import hashlib
14
17
  from typing import Any, Dict, Optional
15
18
 
16
19
  from . import _model, _units
17
- from ._envelope import EnvelopeResult, check_envelope
20
+ from ._envelope import TRUST, BatchResult, EnvelopeResult, MemberResult, check_batch, check_envelope
18
21
  from ._errors import ERROR_CODES, FAULT_CODES, SUCCESS_CODES, DatumeshError, fail
19
22
  from ._json import jcs_bytes
20
23
  from ._keys import Key, KeysResult, fetch_keys, key_id, keys_from_response
24
+ from ._mesh import MESH_ENDPOINTS, MESH_WELL_KNOWN_PATH, MeshResult, resolve_mesh
21
25
  from ._uri import format_uri, parse_uri, uri_to_https
22
26
  from ._verify import VerifyResult, load, payload_bytes, verify
23
27
 
24
- __version__ = "0.4.0"
28
+ __version__ = "0.4.2"
25
29
  #: The specification revision this package conforms to.
26
- SPEC_VERSION = "spec-0.4.0"
30
+ SPEC_VERSION = "spec-0.4.2"
27
31
  #: Every literal unit listed in units.md (index units, ``index:<period>=<value>``, are a pattern and not listed).
28
32
  UNITS = tuple(sorted(_units.LITERALS))
29
33
  #: The currency codes of units.md 2.1.
@@ -35,6 +39,9 @@ KINDS = ("scalar", "cell", "ref", "function", "receipt", "slice", "manifest")
35
39
 
36
40
  __all__ = [
37
41
  "SPEC_VERSION",
42
+ "BatchResult",
43
+ "MemberResult",
44
+ "TRUST",
38
45
  "CURRENCIES",
39
46
  "ERROR_CODES",
40
47
  "FAULT_CODES",
@@ -43,11 +50,15 @@ __all__ = [
43
50
  "EnvelopeResult",
44
51
  "Key",
45
52
  "KeysResult",
53
+ "MESH_ENDPOINTS",
54
+ "MESH_WELL_KNOWN_PATH",
55
+ "MeshResult",
46
56
  "SUCCESS_CODES",
47
57
  "UNITS",
48
58
  "VerifyResult",
49
59
  "canonicalize",
50
60
  "cell_hash",
61
+ "check_batch",
51
62
  "check_envelope",
52
63
  "fetch_keys",
53
64
  "format_uri",
@@ -60,6 +71,7 @@ __all__ = [
60
71
  "parse_uri",
61
72
  "receipt_hash",
62
73
  "receipt_payload",
74
+ "resolve_mesh",
63
75
  "resolved_unit",
64
76
  "slice_entry",
65
77
  "slice_id",