graphddb-runtime
The DynamoDB issuance a GraphDDB behavior module binds, for Python.
An operation is behavior: you author it as a @behavior static method over
graphddb's @leaf catalog in ordinary TypeScript, bc generate --lang python emits
the module that runs it, and graphddb-runtime supplies what one physical DynamoDB
request needs and a behavior cannot carry — the boto3 client, the logical → physical
table mapping, the AttributeValue codec, the execution bounds and the error mapping.
It interprets no specification document. Code generation and IR belong to behavior-contracts; the generated module embeds its own IR and gates its own spec version when imported.
Features
- Leaf transports —
leaf_handlers(runtime)supplies theGetItem/Query/BatchGetItem/PutItem/UpdateItem/DeleteItemissuance a compiled behavior binds. Each handler issues ONE physical request and returns the raw row(s): no ordering, no fan-out, no key derivation, no result shaping — those are the behavior's, compiled by behavior-contracts. - Cursor codecs — the opaque base64url pagination cursor, byte-identical to the TypeScript and PHP runtimes'.
Install
pip install graphddb-runtime
Requires Python 3.9+ and boto3.
Versioning.
graphddb-runtimetracks thegraphddbnpm package version: a given runtime release matches thegraphddbCLI of the same version.
Usage
Construct the runtime with a boto3 client, then hand its leaf handlers to the
generated module's bind:
import boto3
import my_behaviors as gen # bc generate --lang python --from behaviors.ts
from graphddb_runtime import GraphDDBRuntime, leaf_handlers
runtime = GraphDDBRuntime(
dynamodb_client=boto3.client("dynamodb"),
# Map logical table names to deployed physical names when they differ.
table_mapping={"UserPermissions": "UserPermissions-prod"},
)
bound = gen.bind(leaf_handlers(runtime))
user = bound["getUserByEmail"]({"email": "alice@example.com"})
groups = bound["listUserGroups"]({"userId": "alice", "limit": 20})
A write behavior returns whether it applied — a DynamoDB
ConditionalCheckFailedException is an expected outcome of a conditional write, so
it comes back as False rather than raising, and the behavior branches on it:
applied = bound["createMembership"]({"userId": "alice", "groupId": "eng", "role": "admin"})
AWS Lambda
Constructing the boto3 client and importing the generated module are both cold-start costs you want to pay once, in module scope, so they are reused across warm invocations (and frozen by SnapStart).
# handler.py — module scope runs once per execution environment (cold start).
import json
import boto3
import my_behaviors as gen
from graphddb_runtime import GraphDDBRuntime, leaf_handlers
_bound = gen.bind(
leaf_handlers(
GraphDDBRuntime(
dynamodb_client=boto3.client("dynamodb"),
table_mapping={"UserPermissions": "UserPermissions-prod"},
)
)
)
def handler(event, context):
user = _bound["getUserByEmail"]({"email": event["queryStringParameters"]["email"]})
if user is None:
return {"statusCode": 404, "body": "not found"}
return {"statusCode": 200, "body": json.dumps(user)}
SnapStart
Lambda SnapStart snapshots the initialized execution environment after the
module-scope code runs, so the client, the imported module and the bind are
captured in the snapshot and skipped on restore.
- Bind in module scope (as above), never inside the handler — that is what gets snapshotted.
- Do not cache short-lived state across the snapshot (credentials/tokens with an expiry, random seeds). The DynamoDB client and the embedded IR are safe to snapshot; refresh anything time-sensitive inside the handler.
Packaging
The deployment artifact needs three things: this runtime package, the
behavior-contracts runtime the generated module imports, and the generated module
itself. boto3/botocore are provided by the Lambda Python runtime, so they need not be
vendored (pin them only if you require a specific version).
mkdir -p build
pip install graphddb-runtime --target build # pulls in behavior-contracts
cp my_behaviors.py handler.py build/
( cd build && zip -r ../function.zip . ) # handler = handler.handler
License
MIT
Metadata
Release files for graphddb-runtime 1.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| graphddb_runtime-1.5.0.tar.gz | 42.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| graphddb_runtime-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.5 kB
Release files / graphddb_runtime-1.5.0.tar.gz
| Download URL | graphddb_runtime-1.5.0.tar.gz |
|---|---|
| Size | 42.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a9463213e187e479dd6328c90305d95d99064f358460f4291343722039510e95
|
|
BLAKE2b-256 checksum How to use checksums |
9f3803219635ce8c438afbd795f89efc5e20f9a58c56682ec7fa93c75c0a171e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / graphddb_runtime-1.5.0-py3-none-any.whl
| Download URL | graphddb_runtime-1.5.0-py3-none-any.whl |
|---|---|
| Size | 23.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59413c8cbdb3b236983fd600e585abbf55b8ed873e1507bc76648035757895e9
|
|
BLAKE2b-256 checksum How to use checksums |
338655da658d798750e7febc20c6647db04e5e47b5750bf7a6a361a1cbdffa2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Security for graphddb-runtime 1.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.