Skip to main content

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):
uv add turingdb
or using pip:
pip install turingdb

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"):
typeEncoding / transportConstructor arguments
"json" (default)JSON payloads over HTTP against a running daemonhost="http://localhost:6666"
"native"Binary (Turing proto) payloads over HTTP — faster; requires the compiled extensionhost="localhost", port=6666
"embedded"In-process engine, no daemon or socketdata_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).
client.set_change(3)

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>".

Response Format

All queries return a pandas.DataFrame, typed according to schema:
Cypher Typepandas dtype
Stringstring
Int64Int64
UInt64UInt64
Doublefloat64
Boolboolean

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