| sidebarTitle | Python |
|---|
pip install oxiaPyDoc documentation is available at https://oxia-db.github.io/oxia-client-python/latest
To use the Oxia client, you need to create a client instance. Once created, a client instance will be valid until it's explicitly closed, and it can be used from different threads.
import oxia
client = oxia.Client("localhost:6648")When creating the client it is possible to pass several options, such as:
client = oxia.Client("localhost:6648",
namespace="my-namespace",
client_identifier="my-client-identity",
)Available Client constructor options:
| Option | Type | Description | Default |
|---|---|---|---|
namespace |
str |
Oxia namespace to use. | "default" |
session_timeout_ms |
int |
Session timeout for ephemeral records, in milliseconds. | 30000 |
client_identifier |
str |
Stable client identity attached to ephemeral records. | Random UUID |
request_timeout_ms |
int |
Deadline for each unary RPC. Long-lived streams are unbounded. | 30000 |
authentication |
oxia.defs.Authentication |
Credentials attached as gRPC metadata. See oxia.auth.TokenAuthentication. |
None |
For the full parameter list see the Client constructor docs.
# Write a record to Oxia with the specified key and value, and with the expectation
# that the record does not already exist.
key, version1 = client.put("my-key", "value-1",
expected_version_id=oxia.EXPECTED_RECORD_DOES_NOT_EXIST)
# Write a record with the expectation that it has not changed since the previous write.
# If there was any change, the operation will fail.
key, version2 = client.put("my-key", "value-2",
expected_version_id=version1.version_id())
# Ephemeral record: deleted automatically when the client session ends.
client.put("/workers/worker-1", b"host:port", ephemeral=True)
# Atomic sequence key: server appends a monotonic suffix; requires a partition key.
key, version = client.put("/events/", b"event-data",
sequence_keys_deltas=[1],
partition_key="/events/")
# Attach a secondary index entry at write time.
client.put("/offset/12345", b"...",
secondary_indexes={"partition": "p-17"})put() options:
| Option | Description |
|---|---|
partition_key |
Route to a specific shard (co-locate related keys). |
expected_version_id |
Conditional write; use oxia.EXPECTED_RECORD_DOES_NOT_EXIST to assert absence. |
ephemeral |
Bind the record to the client session — see ephemerals. |
sequence_keys_deltas |
Server-assigned monotonic suffixes — see sequence keys. |
secondary_indexes |
{index_name: secondary_key} — see secondary indexes. |
Full reference: put() method docs.
Reading the value of a record:
key, value, version = client.get("my-key")
# Metadata-only read (skips the value payload).
key, _, version = client.get("my-key", include_value=False)
# Range-style Get: returns the closest key ≤ the lookup key.
from oxia import ComparisonType
key, value, version = client.get("/users/50",
comparison_type=ComparisonType.FLOOR)get() options:
| Option | Description |
|---|---|
comparison_type |
EQUAL (default), FLOOR, CEILING, LOWER, HIGHER. Non-equal modes scan all shards unless partition_key is set. |
include_value |
Set to False for a metadata-only read. |
partition_key |
Route to a specific shard. |
use_index |
Look up via a named secondary index. |
Full reference: get() method docs.
Delete a single record by key. Supports conditional deletes using version-based expectations.
# Unconditional delete
client.delete("my-key")
# Conditional delete: only succeed if the version matches
client.delete("my-key", expected_version_id=version.version_id())All the options for the delete operation are available in the delete() method docs.
Delete all records whose keys fall within [min, max):
client.delete_range("/users/", "/users//")Without partition_key, the call fans out to every shard. Pass partition_key to scope
the delete to a single shard.
List keys in [min, max) without fetching values:
keys = client.list("/users/", "/users//")
for key in keys:
print(key)
# Narrow to a single shard via partition_key, or query a secondary index via use_index.
keys = client.list("/users/", "/users//", partition_key="/users/")
keys = client.list("", "\xff", use_index="email")Scan records in a key range, returning keys and values:
for key, value, version in client.range_scan("/users/", "/users//"):
print(f"key: {key}, value: {value}, version: {version}")
# With a secondary index.
for key, value, version in client.range_scan(
"", "\xff", use_index="email"):
print(key)list() and range_scan() both accept partition_key and use_index.
Sessions are managed transparently: the first put(..., ephemeral=True) creates a
per-shard session, the client SDK heartbeats it, and ephemerals are cleaned up when the
client closes or the session expires. See ephemerals for
the lifecycle details.
Both streams are exposed as plain Python iterators:
# Change feed for the namespace.
for notification in client.get_notifications():
print(notification)
# Updates for a specific sequence prefix.
for key in client.get_sequence_updates("/events/", partition_key="/events/"):
print(f"New sequence key: {key}")See notifications and sequence keys for semantics.
For the complete reference see the PyDoc reference.