Skip to content

Commit a0bf49e

Browse files
committed
Update CONTRIBUTORS.md and README.md to include Python DSL support
This commit enhances the documentation by adding support for the Python DSL in both the CONTRIBUTORS.md and README.md files. The changes reflect the addition of Python as a query authoring option alongside Rust, TypeScript, and Go, and provide examples for using the Python client to build and send dynamic requests. This update improves clarity and accessibility for users utilizing the Python SDK.
1 parent e193428 commit a0bf49e

11 files changed

Lines changed: 4071 additions & 5 deletions

File tree

CONTRIBUTORS.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ The v3 CLI is a runtime orchestrator — there is no `helix compile`/`helix chec
190190

191191
1. Scaffold a project with `helix init` (writes `helix.toml` and a `.helix/` workspace).
192192
2. Start a local instance with `helix start` — a Docker/Podman container running the `enterprise-dev` image (in-memory by default, on-disk with `--disk`).
193-
3. Author queries with the Rust or TypeScript DSL; they serialize to JSON "dynamic queries".
193+
3. Author queries with the Rust, TypeScript, Go, or Python DSL; they serialize to JSON "dynamic queries".
194194
4. Send queries to a running instance via `POST /v1/query` (`helix query`); validation happens server-side.
195195
5. For production, deploy an Enterprise Cloud instance with `helix push`, managing auth/metadata via `helix auth`, `helix sync`, and the `workspace`/`project`/`cluster` commands.
196196

@@ -201,6 +201,7 @@ Client libraries that build HelixDB queries and send them to a running instance.
201201
- `rust/` - Rust DSL builder (crate `helix-db`), with the `helix-dsl-macros` procedural-macro crate
202202
- `typescript/` - TypeScript DSL (`@helix-db/helix-db`)
203203
- `go/` - Go client and DSL
204+
- `python/` - Python client and DSL (`helix-db`, imported as `helixdb`)
204205
- `tests/` - Cross-SDK parity tests and metadata registration tests
205206

206207
#### `/metrics/` - Metrics
@@ -212,7 +213,7 @@ Logos and images used in the README and docs.
212213
## Key Concepts
213214

214215
### Query Language
215-
Queries are authored with the Rust or TypeScript DSL (in `sdks/`) and serialized to JSON "dynamic queries" sent to a running instance. The legacy HelixQL `.hx` form below is still supported for reference and translation:
216+
Queries are authored with the Rust, TypeScript, Go, or Python DSL (in `sdks/`) and serialized to JSON "dynamic queries" sent to a running instance. The legacy HelixQL `.hx` form below is still supported for reference and translation:
216217
```
217218
QUERY addUser(name: String, age: I64) =>
218219
user <- AddN<User({name: name, age: age})
@@ -232,7 +233,7 @@ QUERY addUser(name: String, age: I64) =>
232233

233234
## Architecture Flow
234235

235-
1. **Definition**: Author queries with the Rust or TypeScript DSL
236+
1. **Definition**: Author queries with a Rust, TypeScript, Go, or Python DSL
236237
2. **Serialization**: The DSL produces a JSON dynamic-query AST (`POST /v1/query` body)
237238
3. **Execution**: Send to a running instance with `helix query`; the gateway validates and runs it server-side
238239
4. **Storage**: LMDB handles persistence with ACID guarantees

README.md

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ If you'd rather wire things up yourself:
7878

7979
## Writing queries with the SDKs
8080

81-
Queries are authored with the Rust or TypeScript DSL and sent straight to a running instance as dynamic requests against `POST /v1/query` — no build or deploy step. Both SDKs produce the same JSON AST. The examples below talk to a local instance on `http://localhost:6969` (the default `helix start dev` port). See the [Querying Guide](https://docs.helix-db.com/database/querying-guide/overview) for the full builder catalog and the dynamic-query wire format.
81+
Queries are authored with the Rust, TypeScript, Go, or Python DSL and sent straight to a running instance as dynamic requests against `POST /v1/query` — no build or deploy step. The SDKs produce the same JSON AST. The examples below talk to a local instance on `http://localhost:6969` (the default `helix start dev` port). See the [Querying Guide](https://docs.helix-db.com/database/querying-guide/overview) for the full builder catalog and the dynamic-query wire format.
8282

8383
### Rust
8484

@@ -197,6 +197,52 @@ const user = await fetch(HELIX_URL, {
197197
console.log("user:", user);
198198
```
199199

200+
### Python
201+
202+
Install the package from this repository:
203+
204+
```bash
205+
pip install -e sdks/python
206+
```
207+
208+
Build dynamic requests with snake_case builders, then send them with the client:
209+
210+
```python
211+
from helixdb import Client, Predicate, g, param, define_params, read_batch, write_batch
212+
213+
add_user_params = define_params({"name": param.string()})
214+
add_user = (
215+
write_batch()
216+
.var_as("user", g().add_n("User", {"name": add_user_params.name}))
217+
.returning(["user"])
218+
)
219+
220+
get_user_params = define_params({"name": param.string()})
221+
get_user = (
222+
read_batch()
223+
.var_as(
224+
"user",
225+
g()
226+
.n_with_label("User")
227+
.where(Predicate.eq("name", get_user_params.name))
228+
.value_map(["name"]),
229+
)
230+
.returning(["user"])
231+
)
232+
233+
client = Client("http://localhost:6969")
234+
235+
new_user = client.query().dynamic(
236+
add_user.to_dynamic_request(add_user_params, {"name": "John Doe"})
237+
).send()
238+
print("new user:", new_user)
239+
240+
user = client.query().dynamic(
241+
get_user.to_dynamic_request(get_user_params, {"name": "John Doe"})
242+
).send()
243+
print("user:", user)
244+
```
245+
200246
## HelixDB Cloud
201247

202248
HelixDB Cloud is an object-storage-backed deployment with integrated vector and full-text search, full ACID transactions, a single writer with auto-scaling reader nodes, and high availability (3+ gateways and DB nodes). Cloud clusters use a separate deploy path from local instances:
@@ -224,4 +270,4 @@ HelixDB is available as a distributed, high-availability, managed service. If yo
224270

225271
---
226272

227-
Just Use Helix.
273+
Just Use Helix.

sdks/python/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# HelixDB Python SDK
2+
3+
The Python SDK pairs an idiomatic query-builder DSL with a small dependency-free
4+
HTTP client for sending dynamic HelixDB queries to `POST /v1/query`.
5+
6+
```python
7+
from helixdb import Client, Predicate, g, read_batch
8+
9+
query = (
10+
read_batch()
11+
.var_as(
12+
"users",
13+
g()
14+
.n_with_label("User")
15+
.where(Predicate.eq("status", "active"))
16+
.limit(25)
17+
.value_map(["$id", "name", "status"]),
18+
)
19+
.returning(["users"])
20+
)
21+
22+
request = query.to_dynamic_request()
23+
result = Client("http://localhost:6969").query().dynamic(request).send()
24+
```
25+
26+
The DSL emits the same dynamic-query JSON AST as the Rust, TypeScript, and Go
27+
SDKs. Python methods use `snake_case`; compatibility aliases such as
28+
`nWithLabel` and `valueMap` are also available for users translating TypeScript
29+
examples directly.
30+
31+
## Dynamic Parameters
32+
33+
```python
34+
from helixdb import Predicate, define_params, g, param, read_batch
35+
36+
params = define_params({
37+
"tenant_id": param.string(),
38+
"limit": param.i64(),
39+
})
40+
41+
query = (
42+
read_batch()
43+
.var_as(
44+
"users",
45+
g()
46+
.n_with_label("User")
47+
.where(Predicate.eq("tenantId", params.tenant_id))
48+
.limit(params.limit)
49+
.value_map(["$id", "name", "tenantId"]),
50+
)
51+
.returning(["users"])
52+
)
53+
54+
body = query.to_dynamic_json(
55+
params,
56+
{"tenant_id": "acme", "limit": 10},
57+
query_name="find_users",
58+
)
59+
```
60+
61+
## Stored Queries
62+
63+
```python
64+
from helixdb import Client
65+
66+
client = Client("https://cluster.helix-db.com", api_key="hx_secret")
67+
response = client.query().body({"tenant_id": "acme"}).stored("find_users").send()
68+
```
69+
70+
Run the SDK tests from the repository root:
71+
72+
```sh
73+
PYTHONPATH=sdks/python/src python -m unittest discover sdks/python/tests
74+
```

sdks/python/pyproject.toml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[build-system]
2+
requires = ["setuptools>=68"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "helix-db"
7+
version = "0.1.0"
8+
description = "Python SDK for HelixDB dynamic query DSL and client"
9+
readme = "README.md"
10+
requires-python = ">=3.10"
11+
license = { text = "MIT" }
12+
authors = [{ name = "HelixDB" }]
13+
keywords = ["helixdb", "graph", "vector", "database", "dsl"]
14+
classifiers = [
15+
"Development Status :: 3 - Alpha",
16+
"Intended Audience :: Developers",
17+
"License :: OSI Approved :: MIT License",
18+
"Programming Language :: Python :: 3",
19+
"Programming Language :: Python :: 3.10",
20+
"Programming Language :: Python :: 3.11",
21+
"Programming Language :: Python :: 3.12",
22+
"Programming Language :: Python :: 3.13",
23+
]
24+
25+
[project.urls]
26+
Homepage = "https://github.com/HelixDB/helix-db"
27+
Repository = "https://github.com/HelixDB/helix-db"
28+
29+
[tool.setuptools.packages.find]
30+
where = ["src"]
31+
32+
[tool.setuptools.package-data]
33+
helixdb = ["py.typed"]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""Compatibility import path for the HelixDB Python SDK."""
2+
3+
from helixdb import * # noqa: F401,F403
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""HelixDB Python SDK."""
2+
3+
from .client import Client, HelixDBClient, HelixError, QueryBuilder, QueryRequest
4+
from .dsl import *
5+
6+
__all__ = [
7+
"Client",
8+
"HelixDBClient",
9+
"HelixError",
10+
"QueryBuilder",
11+
"QueryRequest",
12+
*[name for name in globals() if not name.startswith("_")],
13+
]

0 commit comments

Comments
 (0)