graphddb-runtime 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: graphddb-runtime
3
+ Version: 0.1.0
4
+ Summary: Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44).
5
+ License: MIT
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: boto3>=1.26
9
+ Provides-Extra: test
10
+ Requires-Dist: pytest>=7.0; extra == "test"
11
+
12
+ # graphddb-runtime
13
+
14
+ Thin DynamoDB executor for [GraphDDB](https://www.npmjs.com/package/graphddb)-generated
15
+ Python repositories.
16
+
17
+ `graphddb-runtime` is the small, hand-written package that generated
18
+ `repositories.py` modules import as `from graphddb_runtime import GraphDDBRuntime`.
19
+ It interprets the `manifest.json` / `operations.json` specifications produced by
20
+ `graphddb generate python` and executes the validated access patterns against
21
+ DynamoDB through boto3 — no scans, no hand-written key logic.
22
+
23
+ ## Features
24
+
25
+ - **Single-operation core** — `GetItem` / `Query` reads and
26
+ `PutItem` / `UpdateItem` / `DeleteItem` writes.
27
+ - **Relations & assembly** — relation traversal, multi-operation assembly,
28
+ `BatchGetItem`, result limits, and `explain`.
29
+ - **Conditional & transactional writes** — conditional writes, declarative
30
+ transactions (`execute_transaction`, with `forEach` / `when` expansion and
31
+ `TransactWriteItems` batching up to 25 items).
32
+ - **Async adapter** — `AsyncGraphDDBRuntime` exposes an `await`-able surface
33
+ with behavior identical to the synchronous runtime.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install graphddb-runtime
39
+ ```
40
+
41
+ Requires Python 3.9+ and boto3.
42
+
43
+ > **Versioning.** `graphddb-runtime` tracks the `graphddb` npm package version:
44
+ > a given runtime release matches the `graphddb` CLI of the same version, so the
45
+ > generated `manifest.json` / `operations.json` and the runtime that interprets
46
+ > them always stay in sync. Install the `graphddb-runtime` whose version equals
47
+ > the `graphddb` CLI you generated with.
48
+
49
+ ## Usage
50
+
51
+ Point the runtime at the two JSON specs emitted by `graphddb generate python`
52
+ and pass a boto3 DynamoDB client. The generated repositories wrap it with typed
53
+ methods:
54
+
55
+ ```python
56
+ import boto3
57
+ from graphddb_runtime import GraphDDBRuntime
58
+ from generated import UserRepository
59
+
60
+ runtime = GraphDDBRuntime(
61
+ dynamodb_client=boto3.client("dynamodb"),
62
+ manifest_path="generated/manifest.json",
63
+ operations_path="generated/operations.json",
64
+ # Map logical table names to deployed physical names when they differ.
65
+ table_mapping={"UserPermissions": "UserPermissions-prod"},
66
+ )
67
+
68
+ users = UserRepository(runtime)
69
+ user = users.get_user_by_email(email="alice@example.com")
70
+ ```
71
+
72
+ ### Async
73
+
74
+ boto3 is a synchronous SDK, so the runtime core is synchronous.
75
+ `AsyncGraphDDBRuntime` is a thin adapter that runs each blocking call in a worker
76
+ thread via `asyncio.to_thread`, giving an `await`-able surface with identical
77
+ behavior (same params, specs, results, and error types). It does not require
78
+ `aioboto3`.
79
+
80
+ ```python
81
+ import boto3
82
+ from graphddb_runtime import GraphDDBRuntime, AsyncGraphDDBRuntime
83
+
84
+ sync = GraphDDBRuntime(
85
+ dynamodb_client=boto3.client("dynamodb"),
86
+ manifest_path="generated/manifest.json",
87
+ operations_path="generated/operations.json",
88
+ )
89
+ runtime = AsyncGraphDDBRuntime(sync)
90
+
91
+ user = await runtime.execute_query("getUser", {"userId": "alice"})
92
+ await runtime.execute_transaction("addManyMembers", {"groupId": "eng", "members": [...]})
93
+ ```
94
+
95
+ The wrapped synchronous runtime is available as `runtime.sync` for callers that
96
+ need the blocking API directly.
97
+
98
+ ## AWS Lambda
99
+
100
+ The runtime loads the JSON specs from disk and constructs a boto3 client — both
101
+ are cold-start costs you want to pay **once**, in module scope, so they are
102
+ reused across warm invocations (and frozen by SnapStart).
103
+
104
+ ```python
105
+ # handler.py — module scope runs once per execution environment (cold start).
106
+ import json
107
+ import boto3
108
+ from graphddb_runtime import GraphDDBRuntime
109
+ from generated import UserRepository
110
+
111
+ _runtime = GraphDDBRuntime(
112
+ dynamodb_client=boto3.client("dynamodb"),
113
+ manifest_path="generated/manifest.json",
114
+ operations_path="generated/operations.json",
115
+ table_mapping={"UserPermissions": "UserPermissions-prod"},
116
+ )
117
+ _users = UserRepository(_runtime)
118
+
119
+
120
+ def handler(event, context):
121
+ user = _users.get_user_by_email(email=event["queryStringParameters"]["email"])
122
+ if user is None:
123
+ return {"statusCode": 404, "body": "not found"}
124
+ return {"statusCode": 200, "body": json.dumps(user)}
125
+ ```
126
+
127
+ ### SnapStart
128
+
129
+ Lambda SnapStart snapshots the initialized execution environment after the
130
+ module-scope code runs, so the global client + `GraphDDBRuntime(...)` construction
131
+ is captured in the snapshot and skipped on restore.
132
+
133
+ - **Initialize the runtime and repositories in module scope** (as above), never
134
+ inside the handler — that is what gets snapshotted.
135
+ - **Do not cache short-lived state across the snapshot** (credentials/tokens with
136
+ an expiry, random seeds). The DynamoDB client and the loaded specs are safe to
137
+ snapshot; refresh anything time-sensitive inside the handler.
138
+
139
+ ### Packaging
140
+
141
+ The deployment artifact needs three things: this runtime package, the generated
142
+ bindings, and the two JSON specs. boto3/botocore are provided by the Lambda Python
143
+ runtime, so they need not be vendored (pin them only if you require a specific
144
+ version).
145
+
146
+ ```bash
147
+ mkdir -p build
148
+ pip install graphddb-runtime --target build # the runtime
149
+ cp -r generated build/generated # manifest.json, operations.json, *.py
150
+ cp handler.py build/
151
+ ( cd build && zip -r ../function.zip . ) # handler = handler.handler
152
+ ```
153
+
154
+ Make sure the `manifest_path` / `operations_path` you pass to `GraphDDBRuntime`
155
+ resolve relative to the deployed working directory (e.g. `generated/...` when the
156
+ specs are zipped under a `generated/` folder at the artifact root).
157
+
158
+ ## License
159
+
160
+ MIT
@@ -0,0 +1,18 @@
1
+ graphddb_runtime/__init__.py,sha256=vPHDIK7NUKoeZrMeDkv0XNj0BJ2Sa9tonskJWBIHax4,1584
2
+ graphddb_runtime/async_runtime.py,sha256=uNncUcrbXFyFL6PcpwguA2iluzeLxJwgRYKm2LO3xp8,3807
3
+ graphddb_runtime/batch.py,sha256=N2xbzDR1_69CUlUhM2GrRp3qEYUnh2jrRQlikUABNMs,7919
4
+ graphddb_runtime/concurrency.py,sha256=zvw-VXuRar8z0Rne4Fo3cuczpXkhTRSaVaJlw7mYS6U,3975
5
+ graphddb_runtime/cursor.py,sha256=sAIPsOkY0xPi9TJOv1oZEUYkfH4CgYUvkrFT9W0umHA,1935
6
+ graphddb_runtime/errors.py,sha256=7x5Qq73trwNmYA6N7Z8rmmIy6J4kd2yVdEMniOaaRGQ,2828
7
+ graphddb_runtime/filters.py,sha256=RKQgBSM019xXBQYbmmLvVTATOJYnwUmU73MBBarW5rI,6190
8
+ graphddb_runtime/hydration.py,sha256=JOqBfsNLnttyA3v3vQ9TLsI_sEiFw3aELP-L5cv1_yo,2660
9
+ graphddb_runtime/limits.py,sha256=gx8UycrSM3RM2xEMr9wTEE23VCPK18F36f4M0Fqc0O4,613
10
+ graphddb_runtime/per_key_cursor.py,sha256=qxN-nK86ZHwAYttmil1Zkjgf_y3qaEEpq7xjWIoHqeY,4469
11
+ graphddb_runtime/relations.py,sha256=XgSYTVcmY9W1zTV4Dsr6Bm-WK7qwD8w0YUC073D4ULo,8175
12
+ graphddb_runtime/runtime.py,sha256=eZTleUqpje2qcqU5ZAKs_-J_ozrVZ9K-8ewXK4dcfJw,73895
13
+ graphddb_runtime/templates.py,sha256=4CY7MHHf3I7BdsfRbjnc5RTj_YkSbmdQokc1kYCkGMQ,5270
14
+ graphddb_runtime/transactions.py,sha256=qUq0d0MXXHficuN12Loj_kflN4tomakx6-EMnHfYvfg,19971
15
+ graphddb_runtime-0.1.0.dist-info/METADATA,sha256=eQd3mp9l0XjJ-hTKrKYsMhpmaR0VGmdywGzijBPVyEU,5793
16
+ graphddb_runtime-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
17
+ graphddb_runtime-0.1.0.dist-info/top_level.txt,sha256=UwvRUZAyjTrHzBVaj4g8M4DNlwavxVs88i16Tv-4JqU,17
18
+ graphddb_runtime-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ graphddb_runtime