Official Python client for ThemisDB - A high-performance multi-model database.
- ✅ Type Hints - Full type annotations (PEP 484)
- ✅ Transaction Support - BEGIN/COMMIT/ROLLBACK with isolation levels
- ✅ LLM Integration - Native support for LLM interactions (v1.4.0+) 🆕
- ✅ Context Manager - Pythonic
withstatement support - ✅ Multi-Model - Relational, Graph, Vector operations
- ✅ Query Support - AQL (Advanced Query Language)
- ✅ Topology-Aware - Automatic shard routing
- ✅ Batch Operations - Efficient bulk operations
- ✅ Vector Search - Similarity search
- ✅ Retry Logic - Automatic retries
pip install themisdb-clientOr for development:
pip install -e .[dev]from themis import ThemisClient
client = ThemisClient(endpoints=["http://localhost:8080"])
# Basic CRUD
client.put("relational", "users", "user1", {"name": "Alice"})
user = client.get("relational", "users", "user1")
print(user)
# Transactions (NEW!)
tx = client.begin_transaction()
try:
tx.put("relational", "accounts", "acc1", {"balance": 1000})
tx.put("relational", "accounts", "acc2", {"balance": 500})
tx.commit()
except Exception:
tx.rollback()
raiseThemisDB now supports ACID transactions with BEGIN/COMMIT/ROLLBACK semantics.
from themis import ThemisClient
client = ThemisClient(endpoints=["http://localhost:8080"])
# Begin a transaction
tx = client.begin_transaction()
try:
# Perform operations within the transaction
tx.put("relational", "accounts", "acc1", {"balance": 1000})
tx.put("relational", "accounts", "acc2", {"balance": 500})
# Read within transaction
acc1 = tx.get("relational", "accounts", "acc1")
print(acc1) # {"balance": 1000}
# Commit the transaction
tx.commit()
except Exception as error:
# Rollback on error
tx.rollback()
raiseThe recommended way to use transactions in Python is with the with statement:
# Automatically commits on success, rolls back on exception
with client.begin_transaction() as tx:
tx.put("relational", "accounts", "acc1", {"balance": 1000})
tx.put("relational", "accounts", "acc2", {"balance": 500})
acc1 = tx.get("relational", "accounts", "acc1")
print(acc1) # {"balance": 1000}
# Transaction is automatically committed hereIf an exception occurs, the transaction is automatically rolled back:
try:
with client.begin_transaction() as tx:
tx.put("relational", "users", "user1", {"name": "Alice"})
raise ValueError("Something went wrong")
except ValueError:
pass
# Transaction was automatically rolled backThemisDB supports two isolation levels:
READ_COMMITTED(default) - Prevents dirty readsSNAPSHOT- Provides a consistent snapshot of the database
# Use SNAPSHOT isolation for repeatable reads
tx = client.begin_transaction(isolation_level="SNAPSHOT")
try:
user1 = tx.get("relational", "users", "user1")
user2 = tx.get("relational", "users", "user2")
# These reads are from the same snapshot
# even if other transactions modify the data
tx.commit()
except Exception:
tx.rollback()with client.begin_transaction() as tx:
# Execute AQL query within transaction
result = tx.query("FOR user IN users FILTER user.active == true RETURN user")
# Update based on query results
for user in result.items:
user["last_seen"] = "2025-11-20T12:00:00Z"
tx.put("relational", "users", user["id"], user)
# Automatically committeddef transfer_money(client, from_account: str, to_account: str, amount: float):
"""Transfer money between accounts using a transaction."""
with client.begin_transaction(isolation_level="SNAPSHOT") as tx:
# Read both accounts
from_acc = tx.get("relational", "accounts", from_account)
to_acc = tx.get("relational", "accounts", to_account)
if not from_acc or not to_acc:
raise ValueError("Account not found")
if from_acc["balance"] < amount:
raise ValueError("Insufficient funds")
# Update balances
from_acc["balance"] -= amount
to_acc["balance"] += amount
tx.put("relational", "accounts", from_account, from_acc)
tx.put("relational", "accounts", to_account, to_acc)
# Transaction automatically committed
# Usage
transfer_money(client, "alice", "bob", 100.0)ThemisDB v1.8.0-rc1 introduces native LLM integration with support for various models and features like prefix caching, response caching, multi-GPU, and more.
from themis import ThemisClient
client = ThemisClient(endpoints=["http://localhost:8080"])
# Create an LLM interaction
result = client.llm_interaction(
model="gpt-4o",
messages=[
{"role": "user", "content": "Explain MVCC in databases"}
]
)
print(f"Interaction ID: {result.id}")
print(f"Success: {result.success}")# Create interaction with chain-of-thought reasoning
result = client.llm_interaction(
model="llama-3.1",
messages=[
{"role": "system", "content": "You are a database expert"},
{"role": "user", "content": "How does ThemisDB handle transactions?"}
],
reasoning_steps=[
{
"type": "chain_of_thought",
"content": [
"MVCC allows parallel reading/writing",
"Each transaction gets a snapshot",
"Commit checks for conflicts"
]
}
],
metadata={"use_case": "documentation", "version": "1.4.0"}
)# Get a specific interaction
interaction = client.get_llm_interaction("interaction_id_123")
if interaction:
print(f"Model: {interaction.model}")
print(f"Created: {interaction.created_at}")
for msg in interaction.messages:
print(f"{msg.role}: {msg.content}")
if interaction.reasoning_steps:
for step in interaction.reasoning_steps:
print(f"Reasoning ({step.type}): {step.content}")# List all interactions
interactions = client.list_llm_interactions(limit=50, offset=0)
for interaction in interactions:
print(f"{interaction.id}: {interaction.model} - {interaction.created_at}")
# Filter by model
gpt4_interactions = client.list_llm_interactions(model="gpt-4o", limit=10)# Vision model interaction (requires v1.4.0+ with vision support)
result = client.llm_interaction(
model="gpt-4-vision",
messages=[
{
"role": "user",
"content": "What's in this image?",
"image_url": "https://example.com/image.jpg" # Or base64 encoded
}
]
)ThemisClient(
endpoints: list[str],
*,
namespace: str = "default",
timeout: float = 30.0,
max_retries: int = 3,
metadata_endpoint: str | None = None,
metadata_path: str = "/_admin/cluster/topology",
max_workers: int | None = None,
transport: httpx.BaseTransport | None = None
)get(model, collection, uuid)- Retrieve an entityput(model, collection, uuid, data)- Create/update an entitydelete(model, collection, uuid)- Delete an entitybatch_get(model, collection, uuids)- Batch retrievebatch_put(model, collection, items)- Batch create/updatebatch_delete(model, collection, uuids)- Batch deletequery(aql, *, params=None)- Execute AQL queryvector_search(embedding, top_k=10)- Vector similarity searchgraph_traverse(start_node, max_depth=3)- Graph traversalhealth(endpoint=None)- Health checkbegin_transaction(*, isolation_level="READ_COMMITTED")- Start transactionllm_interaction(model, messages, *, reasoning_steps=None, metadata=None)- NEW: Create LLM interactionget_llm_interaction(interaction_id)- NEW: Retrieve LLM interactionlist_llm_interactions(*, model=None, limit=100, offset=0)- NEW: List LLM interactions
transaction_id: str- Unique transaction identifieris_active: bool- Whether the transaction is active
get(model, collection, uuid)- Retrieve within transactionput(model, collection, uuid, data)- Update within transactiondelete(model, collection, uuid)- Delete within transactionquery(aql, *, params=None)- Query within transactioncommit()- Commit the transactionrollback()- Rollback the transaction
with client.begin_transaction() as tx:
# Operations here
pass
# Automatically commits on success, rolls back on exception# Install with dev dependencies
pip install -e .[dev]
# Run tests
pytest tests/
# Run tests with coverage
pytest --cov=themis tests/Apache-2.0