Python
The Python binding is an early prototype, version 0.0.1. It is a PyO3 module that embeds the engine inside the Python process - the same shape as Rust (Embedded), not a remote client - and it was written against an engine API that has since been replaced. This page documents what the prototype is, why you should not build on it yet, and how to use ReifyDB from Python today while it waits for its rewrite.
What exists today
The package lives at pkg/python/reifydb in the engine repository and is built with maturin (PyO3, abi3, Python 3.10+). It exposes exactly one class with one method:
from reifydb import Embedded
db = Embedded() # in-memory engine, in-process
results = db.tx('FROM app::users')Embedded() starts a blocking in-memory engine as the root identity; there is no persistence option and no way to run as another identity. tx(rql) executes RQL and returns a list with one plain dict per statement result, tagged by kind: a query result is {'type': 'Query', 'headers': [...], 'rows': [...]}, and schema and insert statements return CreateNamespace/CreateTable/InsertIntoTable dicts naming what they touched. Every cell in rows is a string - the prototype formats values on the way out rather than mapping engine types to Python types. There is no query/command split, no parameters, no subscriptions, and no error surface beyond the exception PyO3 raises.
How it was meant to be used
The repository ships one example, a hello world that pretty-prints a query result with tabulate. It is reproduced here as a record of intent - note that even its RQL predates the current syntax:
from reifydb import Embedded
from tabulate import tabulate
db = Embedded()
r = db.tx('map 1, 1 + 4')
print(tabulate(r[0]['rows'], headers=r[0]['headers']))The development notes describe the standard maturin workflow - maturin build, pip install . - but that workflow does not currently produce a working module, for the reasons below. The package is not published; there is no pip install reifydb from PyPI.
Current status
ReifyDB::embedded_blocking() and reifydb::variant::Embedded, both long gone from the crate (the current embedded surface is embedded::memory() and sessions, see Rust (Embedded)). The crate is excluded from the engine workspace, its dependency on the engine is commented out, and its entire implementation sits behind an include-python-workspace feature flag - it does not compile against the current engine. The API will change completely when it is brought up to date.Concretely, as of engine 0.8.1: embedded only, no remote client; in-memory only, no persistence; root identity only; results are stringified, not typed; and the shipped type stubs do not even match the module (they declare a ReifyDB class with query(), while the module exposes Embedded with tx()). Treat the whole package as a preview of intent, not a foundation.
Using ReifyDB from Python today
Until the binding is rewritten, the practical route is to run the server and speak the HTTP wire protocol directly - it is plain JSON over POST, so the standard requests package is all you need. This is not an official SDK, just the protocol every client uses underneath. Statements go to /v1/query (reads) and /v1/command (writes) on the application port 8090; ?format=json asks for row-shaped JSON, one list of row dicts per result frame:
import requests
resp = requests.post(
'http://localhost:8090/v1/query',
params={'format': 'json'},
json={'rql': 'FROM app::users FILTER age >= $min', 'params': {
# Parameters travel as typed pairs; the value is always a string.
'min': {'type': 'Int4', 'value': '18'},
}},
)
resp.raise_for_status()
frames = resp.json() # one entry per result frame
for row in frames[0]: # each row is a plain dict
print(row['id'], row['name'])Positional parameters ($1, $2, ...) are a JSON array of the same typed pairs, and omitting params means none. To run as a real identity, POST the login to /v1/authenticate and send the returned token as an Authorization: Bearer <token> header on every request. Admin statements need the loopback-only admin listener on port 9090 - ports and the login flow are covered on Connect, and the full request and response encodings on Wire Formats. HTTP has no subscriptions; live data needs the WebSocket protocol.
