TuringDB Python SDK
The TuringDB Python SDK provides an easy interface for connecting to your local TuringDB server, running queries, and managing graphs programmatically.
Install the PythonSDK:
Using uv package manager (you will need to create a project first):
or using pip:
Getting Started
from turingdb import TuringDB
# Create TuringDB client
# set host parameter to the URL (as string) on which TuringDB is running,
# default "http://localhost:6666"
client = TuringDB(host="http://localhost:6666")
# List available graphs
print(client.list_available_graphs())
Client backends
TuringDB(...) is a facade over three interchangeable backends, chosen with the type argument (or the TURINGDB_TYPE environment variable, default "json"):
type | Encoding / transport | Constructor arguments |
|---|
"json" (default) | JSON payloads over HTTP against a running daemon | host="http://localhost:6666" |
"native" | Binary (Turing proto) payloads over HTTP — faster; requires the compiled extension | host="localhost", port=6666 |
"embedded" | In-process engine, no daemon or socket | data_dir="/path/to/.turing" |
Both json and native talk to a daemon over HTTP; they differ in the wire encoding (JSON vs. binary). embedded runs the engine in-process with no network at all.
# Default HTTP client
client = TuringDB(host="http://localhost:6666")
# Native binary protocol
client = TuringDB(type="native", host="localhost", port=6666)
# Embedded, in-process — no server needed
client = TuringDB(type="embedded", data_dir="~/.turing")
list_available_graphs() and the S3 helpers (s3_connect, transfer) are only supported on the default JSON backend (type="json").
Core Methods
list_available_graphs() → list[str]
Returns the graphs persisted on disk in the TuringDB data directory (JSON backend only).
client.list_available_graphs()
list_loaded_graphs() → list[str]
Returns the currently loaded graphs in memory.
client.list_loaded_graphs()
create_graph(graph_name: str)
Creates a new empty graph with the specified name.
client.create_graph("mygraph")
Internally executes CREATE GRAPH "graph_name"
load_graph(graph_name: str, raise_if_loaded: bool = True)
Loads a previously created graph into memory.
client.load_graph("mygraph")
If raise_if_loaded=False, it will silently continue if the graph is already loaded.
query(query: str) → pandas.DataFrame
Runs a Cypher query on the current graph.
df = client.query("MATCH (n:Person) RETURN n.name, n.age")
Returns results as a pandas.DataFrame, with automatic typing and parsing.
query_raw(query: str) → dict
Like query, but returns the raw server response as a dict instead of a DataFrame. Useful for inspecting result metadata or column dtypes directly.
get_graph() → str / set_graph(graph_name: str)
Get or set the active graph for subsequent queries.
is_graph_loaded() → bool
Returns whether the current graph is loaded in memory.
new_change() → int
Creates a new isolated change (equivalent to CHANGE NEW), makes it the active change, and returns its integer ID.
change = client.new_change()
client.checkout(change=change)
There is no submit() method — submit a change by running client.query("CHANGE SUBMIT").
Version Control Helpers
TuringDB supports snapshot isolation and versioned commits.
Use the following helpers to navigate graph history or work in isolated changes:
checkout(change: int | str = "main", commit: str = "HEAD")
Switches the working context to a specific change or commit.
client.checkout(change=2, commit="abc123")
client.checkout("main") # Reset to default
change: change ID or "main"
commit: commit hash or "HEAD"
set_commit(commit: str)
Manually set the commit hash to use.
client.set_commit("haax42")
set_change(change: int | str)
Manually set the change ID to use (accepts int or hex string).
set_graph(graph_name: str)
Change the current graph context.
client.set_graph("another_graph")
You can also read the current context through the current_graph, current_commit (default "HEAD"), and current_change (default "main") properties.
Connection & Timing Helpers
reconnect()
Resets the connection. A no-op for the HTTP and embedded backends; reopens the socket for the native backend.
try_reach(timeout: int = 5) / warmup(timeout: int = 5)
Probe connectivity (try_reach) or warm the connection with a lightweight query (warmup).
get_query_exec_time() → float | None / get_total_exec_time() → float | None
Return the server-side execution time and the full round-trip time (in milliseconds) of the last query.
S3 / Data Transfer
These helpers move graph data between local paths, S3, and the TuringDB server. They are only available on the JSON backend (type="json").
s3_connect(bucket_name, access_key=None, secret_key=None, region=None, use_scratch=True)
Connect an S3 client for transfers. Credentials are optional — if omitted, the machine’s configured AWS credentials are used.
client.s3_connect("my-bucket", region="eu-west-1")
transfer(src, dst)
Transfer data between a local path, an s3://… URI, or a turingdb://… path. The direction and mechanism are inferred from the URI schemes.
client.transfer("s3://graphs/data.jsonl", "turingdb://data.jsonl") # S3 → server
client.transfer("./local.gml", "turingdb://local.gml") # local → server (via scratch)
The equivalent engine commands (issued directly via query) are S3 CONNECT "<key>" "<secret>" "<region>", S3 PULL "<s3-url>" "<dst>", and S3 PUSH "<src>" "<s3-url>".
All queries return a pandas.DataFrame, typed according to schema:
| Cypher Type | pandas dtype |
|---|
String | string |
Int64 | Int64 |
UInt64 | UInt64 |
Double | float64 |
Bool | boolean |
Error Handling
All SDK errors raise a custom TuringDBException.
try:
client.query("MATCH (x) RETURN x")
except TuringDBException as e:
print("Query failed:", e)
Example Workflow
from turingdb import TuringDB
# Create TuringDB client
# set host parameter to the URL (as string) on which TuringDB is running,
# default "http://localhost:6666"
client = TuringDB(host="http://localhost:6666")
# Create a new graph called mygraph
client.create_graph("mygraph")
# Set working graph
client.set_graph("mygraph")
# Create a new change on the graph
change = client.new_change()
# Checkout into the change
client.checkout(change=change)
# Multiple nodes and edges can be created at the same time
# using the following syntax
client.query("""CREATE (apoe_gene:Gene {name: 'APOE', chromosome: '19', location: '19q13.32'}),
(apoe_protein:Protein {name: 'Apolipoprotein E', function: 'Lipid_transport', tissue: 'Brain_and_liver'}),
(alzheimers:Disease {name: 'Alzheimers_Disease', type: 'Neurodegenerative'}),
(cholesterol:Molecule {name: 'Cholesterol', type: 'Lipid'}),
(apoe_gene)-[:ENCODES]->(apoe_protein),
(apoe_protein)-[:BINDS]->(cholesterol),
(apoe_protein)-[:ASSOCIATED_WITH]->(alzheimers)
""")
# Commit the change
client.query("COMMIT")
client.query("CHANGE SUBMIT")
# Checkout into main
client.checkout()
# Query graph
df = client.query("MATCH (n:Gene {name: 'APOE'}) RETURN n.name, n.chromosome")
print(df)
Notes
- The JSON backend (
type="json") uses httpx; the native and embedded backends use a compiled extension
- Only the graph name, change ID, and commit hash are sent with HTTP requests
- The SDK supports the full TuringDB Cypher dialect, including matching by internal node ID (
WHERE n = 1234) and versioned queries against past commits
Need help writing queries? → See the TuringDB Query Cheatsheet
You can also find the TuringDB PythonSDK in Github