graphddb-runtime 0.4.3__tar.gz → 0.5.0__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 (44) hide show
  1. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/PKG-INFO +1 -1
  2. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime.egg-info/PKG-INFO +1 -1
  3. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime.egg-info/SOURCES.txt +1 -0
  4. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/pyproject.toml +1 -1
  5. graphddb_runtime-0.5.0/tests/test_ttl.py +57 -0
  6. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/README.md +0 -0
  7. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/__init__.py +0 -0
  8. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/async_runtime.py +0 -0
  9. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/batch.py +0 -0
  10. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/concurrency.py +0 -0
  11. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/cursor.py +0 -0
  12. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/errors.py +0 -0
  13. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/filters.py +0 -0
  14. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/hydration.py +0 -0
  15. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/limits.py +0 -0
  16. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/middleware.py +0 -0
  17. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/per_key_cursor.py +0 -0
  18. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/relations.py +0 -0
  19. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/runtime.py +0 -0
  20. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/templates.py +0 -0
  21. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime/transactions.py +0 -0
  22. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime.egg-info/dependency_links.txt +0 -0
  23. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime.egg-info/requires.txt +0 -0
  24. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/graphddb_runtime.egg-info/top_level.txt +0 -0
  25. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/setup.cfg +0 -0
  26. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_concurrency.py +0 -0
  27. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_contract_runtime.py +0 -0
  28. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_description.py +0 -0
  29. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration.py +0 -0
  30. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_command.py +0 -0
  31. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_compose.py +0 -0
  32. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_contract.py +0 -0
  33. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_edge_derive.py +0 -0
  34. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_edge_write.py +0 -0
  35. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_events.py +0 -0
  36. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_maintain.py +0 -0
  37. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_middleware.py +0 -0
  38. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_referential.py +0 -0
  39. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_relations.py +0 -0
  40. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_integration_unique.py +0 -0
  41. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_maintain.py +0 -0
  42. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_middleware.py +0 -0
  43. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_relations.py +0 -0
  44. {graphddb_runtime-0.4.3 → graphddb_runtime-0.5.0}/tests/test_unit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphddb-runtime
3
- Version: 0.4.3
3
+ Version: 0.5.0
4
4
  Summary: Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44).
5
5
  License: MIT
6
6
  Requires-Python: >=3.9
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphddb-runtime
3
- Version: 0.4.3
3
+ Version: 0.5.0
4
4
  Summary: Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44).
5
5
  License: MIT
6
6
  Requires-Python: >=3.9
@@ -38,4 +38,5 @@ tests/test_integration_unique.py
38
38
  tests/test_maintain.py
39
39
  tests/test_middleware.py
40
40
  tests/test_relations.py
41
+ tests/test_ttl.py
41
42
  tests/test_unit.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "graphddb-runtime"
7
- version = "0.4.3"
7
+ version = "0.5.0"
8
8
  description = "Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44)."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,57 @@
1
+ """Issue #172 (Epic #167 — CFn generator C4): DynamoDB TTL.
2
+
3
+ The `@ttl` field decorator marks a model's Time-To-Live attribute. Because TTL is a
4
+ **physical schema** fact (unlike the maintenance/stream signals kept off the
5
+ manifest) and the CloudFormation emitter consumes the manifest, the TTL attribute
6
+ name flows into `manifest.json` as `entities.<Model>.ttlAttribute`.
7
+
8
+ This module locks the **Python-visible** manifest value: the Python bridge reads the
9
+ SAME `manifest.json` the TS generator emitted, so this asserts the TTL fact reaches
10
+ Python identically (TS↔Python parity — a single producer, so byte-identical by
11
+ construction). A model without `@ttl` carries no `ttlAttribute` key (backward
12
+ compatible). The corresponding TS-side assertions live in
13
+ `__tests__/spec/ttl-manifest.test.ts` and `__tests__/codegen/cloudformation.snapshot.test.ts`.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+
20
+ import conftest
21
+
22
+
23
+ def _manifest() -> dict:
24
+ with open(conftest.MANIFEST_PATH, encoding="utf-8") as fh:
25
+ return json.load(fh)
26
+
27
+
28
+ def test_manifest_carries_ttl_attribute_for_ttl_model() -> None:
29
+ session = _manifest()["entities"]["SessionModel"]
30
+ # The `@ttl expiresAt!: number` field is the table's TTL attribute.
31
+ assert session["ttlAttribute"] == "expiresAt"
32
+ # It is a NON-key attribute, stored as a Number (epoch seconds).
33
+ assert session["fields"]["expiresAt"]["type"] == "number"
34
+
35
+
36
+ def test_non_ttl_model_has_no_ttl_attribute_key() -> None:
37
+ # A model with no `@ttl` field carries no `ttlAttribute` key (byte-identical to
38
+ # the pre-#172 manifest — backward compatible).
39
+ user = _manifest()["entities"]["UserModel"]
40
+ assert "ttlAttribute" not in user
41
+
42
+
43
+ def test_at_most_one_ttl_attribute_per_physical_table() -> None:
44
+ # DynamoDB allows exactly one TTL attribute per table; the generator enforces
45
+ # this at manifest build. Confirm the whole manifest never lands two distinct
46
+ # TTL attributes on one physical table.
47
+ manifest = _manifest()
48
+ by_table: dict[str, set[str]] = {}
49
+ for entity in manifest["entities"].values():
50
+ attr = entity.get("ttlAttribute")
51
+ if attr is None:
52
+ continue
53
+ by_table.setdefault(entity["physicalName"], set()).add(attr)
54
+ for physical, attrs in by_table.items():
55
+ assert len(attrs) == 1, (
56
+ f"physical table {physical!r} has multiple TTL attributes: {attrs}"
57
+ )