Session

class aerospike_sdk.aio.session.Session[source]

Bases: SessionBase[WriteSegmentBuilder, QueryBuilder, TransactionalSession, DataSetWriteBuilder]

Perform reads and writes against Aerospike with a fixed Behavior.

A session binds a connected Client to policy defaults (timeouts, retries, replica preferences) for every operation started from it. Create sessions with Client.create_session(); do not construct Session directly.

Example:

async with Client("localhost:3000") as client:
    session = client.create_session(Behavior.DEFAULT)
    users = DataSet.of("test", "users")
    stream = await session.query(users.id(1)).execute()
    first = await stream.first_or_raise()
    await session.upsert(users.id(2)).put({"name": "Tim"}).execute()

See also

Client.create_session(): How to obtain a session. query(): Point reads, batch reads, and secondary-index queries. upsert(): Create-or-update writes.

__init__(client, behavior)[source]

Attach a client and behavior; prefer Client.create_session().

Parameters:
  • client (Client) – Connected (or not yet connected) Client.

  • behavior (Behavior) – Policy bundle for operations from this session.

Note

Application code should not call Session(...) directly.

See also

Client.create_session().

session_for(behavior)[source]

A new session on the same cluster with a different behavior.

Shorthand for cluster.create_session(behavior); this session is left as it is. Called on a transactional session it returns a plain session, outside the transaction.

Parameters:

behavior (Behavior) – The behavior for the new session.

Return type:

Session

Returns:

A new Session.

Example:

reads = session.session_for(Behavior.READ_FAST)
row = await (await reads.query(key).execute()).first_or_raise()
async get(key, bins=None)[source]

Direct single-key point read — returns Record or raises.

Bypasses the builder chain (session.query(key).execute()) and the RecordStream wrapper: one await reaches the underlying client and the resulting Record is returned unwrapped. Use when you have a single key and want minimum per-op overhead; use query() when you need filters, projections, or streaming.

Parameters:
  • key (Key) – Target Key.

  • bins (Optional[List[str]]) – Optional bin-name projection. None (default) reads all bins.

Return type:

Record

Returns:

The Record for key.

Raises:

AerospikeError – Server or client errors (including KEY_NOT_FOUND_ERROR) are raised as the SDK exception type for the failure, without being wrapped in a RecordResult.

Example:

users = DataSet.of("test", "users")
rec = await session.get(users.id(1))
name = rec.bins["name"]

See also

query(): Builder-based reads for projections, streams, and secondary-index queries. put(): Direct single-key upsert.

async put(key, bins)[source]

Direct single-key upsert — returns None or raises.

Bypasses the builder chain (session.upsert(key).put(...).execute()) and the RecordStream wrapper: one await reaches the underlying client. Use when you have a single key and want minimum per-op overhead; use upsert() when you need atomic multi-op semantics, TTL overrides, generation checks, durable delete, or filter expressions.

Parameters:
  • key (Key) – Target Key.

  • bins (Dict[str, Any]) – Mapping of bin name to value to write. An empty mapping is permitted.

Return type:

None

Returns:

None on success.

Raises:

AerospikeError – Server or client errors are raised as the SDK exception type for the failure.

Example:

users = DataSet.of("test", "users")
await session.put(users.id(1), {"name": "Tim", "age": 30})

See also

upsert(): Builder-based writes with full feature set. get(): Direct single-key point read.

async get_many(keys, bins=None)[source]

Direct point reads for a window of keys — one await, one result list.

Client-side fusion of independent single-record reads: one call submits the whole window and one completion delivers all results, so per-op submission and wakeup overhead is amortized across the window. These are NOT a server batch request — each key remains an independent wire op (use query() with a key list for wire batching).

Parameters:
  • keys (List[Key]) – Target keys; results are positional.

  • bins (Optional[List[str]]) – Optional bin-name projection shared by the window.

Return type:

List[Union[Record, AerospikeError]]

Returns:

A list the same length as keys. Each slot is the Record for that key, or the AerospikeError instance (not raised) for that key — check with isinstance(slot, AerospikeError). One failed key never fails its window-mates.

Records are handed back raw rather than wrapped in RecordResult: a wrapper per slot would cost one allocation per key, which is the per-op cost this API exists to amortize. The asymmetry with the builder surface is deliberate.

Raises:

AerospikeError – When the whole-window submission fails (for example, the client was closed); per-key failures land in result slots instead.

Example:

users = DataSet.of("test", "users")
records = await session.get_many([users.id(i) for i in range(16)])
found = [r for r in records if not isinstance(r, AerospikeError)]

See also

get(): Single-key point read. put_many(): Window counterpart for writes.

async put_many(keys, bins)[source]

Direct upserts of one payload to a window of keys — one await.

Write counterpart of get_many(): the bins payload is converted once and written to every key in the window as independent wire ops with client-side fused submission/completion.

Parameters:
  • keys (List[Key]) – Target keys; results are positional.

  • bins (Dict[str, Any]) – Mapping of bin name to value written to every key.

Returns:

None for each success, or the AerospikeError instance (not raised) for that key. Slots are bare rather than RecordResult for the same allocation reason as get_many().

Return type:

List[Optional[AerospikeError]]

Raises:

AerospikeError – When the whole-window submission fails; per-key failures land in result slots instead.

Example:

users = DataSet.of("test", "users")
outcomes = await session.put_many(
    [users.id(i) for i in range(16)], {"active": True})
errors = [e for e in outcomes if e is not None]

See also

put(): Single-key upsert. get_many(): Window counterpart for reads.

background_task()[source]

Configure a server-side background job (query + scan scope) on a dataset.

Call update, delete, touch, or execute_udf on the returned object, add optional filters (for example where on supported builders), then await ...execute() to start work and receive an async task handle.

Return type:

BackgroundTaskSession

Returns:

A BackgroundTaskSession for chaining the operation type and execution.

Raises:

RuntimeError – If the client is not connected.

Example:

task = await (
    session.background_task()
    .delete(DataSet.of("test", "scratch"))
    .where("$.flag == 1")
    .execute()
)
await task.wait_till_complete(sleep_time=0.2, timeout=10.0)

See also

execute_udf(): Foreground UDF on explicit keys.

execute_udf(*keys)[source]

Run a registered server-side UDF on one or more keys (foreground).

Chain function(package, name) (package is the registered module name without .lua), optional passing(*args) for Lua parameters, optional where for a filter expression, then await ...execute() to obtain a RecordStream. Multiple keys use a batch UDF; results preserve per-key order where applicable.

Parameters:

*keys (Key) – One or more Key targets in the same namespace and set.

Return type:

UdfFunctionBuilder

Returns:

UdfFunctionBuilder — call function next.

Raises:

Example:

users = DataSet.of("test", "users")
stream = await (
    session.execute_udf(users.id("a"))
    .function("my_module", "my_fn")
    .passing("binName", 42)
    .execute()
)
value = await stream.first_udf_result()

See also

query(): Read bins without UDF. background_task(): Dataset-scoped background UDF.

index(dataset, /)[source]

Create a secondary index builder for a dataset.

Parameters:

dataset (DataSet) – Namespace and set to index; a set-less DataSet covers the whole namespace.

Return type:

IndexBuilder

Returns:

IndexBuilder for

chaining index definition and creation.

Raises:

TypeError – If dataset is not a DataSet.

Example:

users = DataSet.of("test", "users")
await session.index(users).on_bin("age").named("age_idx").integer().create()

See also

create_index(): The same in one call. drop_index()

async create_index(dataset, index_name, bin_name=None, index_type=None, collection_type=None, ctx=None, expression=None)[source]

Create a secondary index in one call.

The short form of the index() builder: each argument stands in for one chain step, and the same rules apply. A bin index needs bin_name and index_type; an expression index needs expression and index_type; a dataset and a name alone create a set index.

Parameters:
  • dataset (DataSet) – Namespace and set to index.

  • index_name (str) – Name the cluster stores the index under.

  • bin_name (Optional[str]) – Bin to index; mutually exclusive with expression.

  • index_type (Optional[IndexType]) – Value type indexed, such as IndexType.STRING.

  • collection_type (Optional[CollectionIndexType]) – Collection variant for list or map bins; scalar when omitted.

  • ctx (Optional[List[CTX]]) – CDT context path to a nested element; bin indexes only.

  • expression (Union[str, FilterExpression, None]) – A FilterExpression or an AEL string whose result is indexed; mutually exclusive with bin_name.

Return type:

IndexTask

Returns:

An IndexTask; await wait_till_complete() before querying through the index.

Raises:
  • ValueError – If the arguments do not describe one index shape, for example a bin with no type, or a bin and an expression together.

  • AerospikeError – On server or transport failure.

Example:

users = DataSet.of("test", "users")
task = await session.create_index(users, "users_city_idx", "city", IndexType.STRING)
await task.wait_till_complete()

# A dataset and a name alone make a set index.
await session.create_index(users, "users_set_idx")

See also

index(): The builder this call drives. drop_index()

async drop_index(dataset, index_name)[source]

Drop a secondary index by name.

The short form of index(dataset).named(index_name).drop().

Parameters:
  • dataset (DataSet) – Namespace and set the index was created on.

  • index_name (str) – Name the index was created with.

Return type:

DropIndexTask

Returns:

A DropIndexTask; await wait_till_complete() until every node has removed it.

Raises:

AerospikeError – On server or transport failure.

Example:

task = await session.drop_index(users, "users_city_idx")
await task.wait_till_complete()

See also

create_index()

async register_udf(body, server_path, language=UDFLang.LUA, *, policy=None)[source]

Register a UDF package from in-memory bytes or text on the cluster.

Parameters:
  • body (bytes | str) – Raw module source (for example UTF-8 encoded Lua).

  • server_path (str) – Path name stored on the server (often ends .lua).

  • language (UDFLang) – UDFLang; default is Lua.

  • policy (Optional[AdminPolicy]) – Optional AdminPolicy; keyword-only.

Return type:

RegisterTask

Returns:

A RegisterTask; await wait_till_complete(...) until propagation finishes.

Raises:

Example:

source = b"function echo(rec, v) return v end\n"
task = await session.register_udf(source, "echo.lua")
await task.wait_till_complete()
async register_udf_from_file(client_path, server_path, language=UDFLang.LUA, *, policy=None)[source]

Register a UDF by reading module bytes from a local file.

Parameters:
  • client_path (str) – Filesystem path to the module on the client machine.

  • server_path (str) – Path name stored on the server (often ends .lua).

  • language (UDFLang) – UDFLang; default is Lua.

  • policy (Optional[AdminPolicy]) – Optional AdminPolicy; keyword-only.

Return type:

RegisterTask

Returns:

A RegisterTask; await wait_till_complete(...) until propagation finishes.

Raises:

Example:

task = await session.register_udf_from_file("udfs/echo.lua", "echo.lua")
await task.wait_till_complete()

See also

register_udf(): Register from in-memory bytes.

async register_udf_from_resource(package, resource, server_path, language=UDFLang.LUA, *, policy=None)[source]

Register a UDF from a Python package resource.

Reads the resource bytes via importlib.resources and registers them — the Pythonic analog of registering a module shipped as package data.

Parameters:
  • package (str) – Importable package holding the resource (e.g. "myapp.udfs").

  • resource (str) – Resource name within the package (e.g. "echo.lua").

  • server_path (str) – Path name stored on the server.

  • language (UDFLang) – UDFLang; default is Lua.

  • policy (Optional[AdminPolicy]) – Optional AdminPolicy; keyword-only.

Return type:

RegisterTask

Returns:

A RegisterTask; await wait_till_complete(...) until propagation finishes.

Raises:

Example:

task = await session.register_udf_from_resource(
    "myapp.udfs", "echo.lua", "echo.lua")
await task.wait_till_complete()
async remove_udf(server_path, *, policy=None)[source]

Remove a registered UDF package from the cluster.

Parameters:
  • server_path (str) – The server path used when the module was registered.

  • policy (Optional[AdminPolicy]) – Optional AdminPolicy; keyword-only.

Return type:

UdfRemoveTask

Returns:

A UdfRemoveTask; await wait_till_complete(...) until propagation finishes.

Raises:

Example:

task = await session.remove_udf("echo.lua")
await task.wait_till_complete()
async list_udf()[source]

List the UDF modules registered on the cluster.

Return type:

list[dict[str, str]]

Returns:

One dict per module with name / hash / type keys; an empty list when nothing is registered.

Raises:

Example:

for module in await session.list_udf():
    print(module["name"], module["type"])
async list_indexes()[source]

List the secondary indexes defined on the cluster.

Return type:

list[dict[str, str]]

Returns:

One dict per index with namespace / set / bin / name keys, plus type / index_type / context when the server reports them (context is present for CDT indexes). An empty list when no secondary indexes are defined.

Raises:

Example:

for idx in await session.list_indexes():
    print(idx["name"], idx["namespace"], idx["bin"])

See also

index(): Create or drop a secondary index.

info(command=None)[source]

Execute info commands or get the InfoCommands helper.

Overloads:
  • self → InfoCommands

  • self, command (str) → Awaitable[Dict[str, str]]

With no argument, returns an InfoCommands instance for high-level helpers (namespaces(), namespace_details(), etc.) and for info_on_all_nodes().

With a command string, runs the raw info command and returns its result (awaitable).

Parameters:

command (Optional[str]) – Optional. If given, the raw info command to run (e.g. “sindex-list”, “build”).

Returns:

InfoCommands instance. If command is given: awaitable dict (node -> response).

Return type:

If command is None

Example:

# Raw command (no double .info)
response = await session.info("sindex-list")

# High-level helpers
info = session.info()
namespaces = await info.namespaces()
by_node = await info.info_on_all_nodes("build")
async namespace_sc_status(namespace)[source]

Describe whether a namespace is configured for strong consistency (SC).

Uses the namespace/<name> info command. Prefer this over is_namespace_sc() when you need a human-readable reason for why a namespace is treated as non-SC (missing namespace vs AP mode).

Parameters:

namespace (str) – Namespace name to inspect.

Return type:

NamespaceScStatus

Returns:

NamespaceScStatus with is_sc and detail.

Raises:
async is_namespace_sc(namespace)[source]

Check if a namespace is in strong consistency (SC) mode.

Strong consistency mode provides linearizable reads and writes at the cost of availability during network partitions.

Parameters:

namespace (str) – The namespace name to check.

Return type:

bool

Returns:

True if the namespace is in strong consistency mode, False otherwise.

Raises:

Example:

if await session.is_namespace_sc("test"):
    print("Namespace 'test' is in strong consistency mode")
else:
    print("Namespace 'test' is in AP (availability) mode")

See also

namespace_sc_status(): Same check with a detail message when false.

async do_in_transaction(operation, *, max_attempts=None, sleep_between_retries=None)[source]

Run an async callable inside a retrying multi-record transaction.

Creates a TransactionalSession, invokes operation(tx) inside async with, and retries the whole block when the attempt ends in a transient conflict (MRT_BLOCKED or MRT_VERSION_MISMATCH) or in a failed commit. On any non-transient failure the transaction is aborted and the exception re-raised.

Parameters:
  • operation (Callable[[TransactionalSession], Awaitable[Any]]) – Async callable accepting a TransactionalSession and performing zero or more operations on it. Its return value is returned from do_in_transaction().

  • max_attempts (Optional[int]) – Maximum total attempts (initial + retries). Must be >= 1. Omit to use the cluster’s TransactionSettings.

  • sleep_between_retries (Union[float, timedelta, None]) – How long to wait before retrying a blocked record or failed commit, as seconds or a datetime.timedelta; each wait is jittered +/- 50%. A version mismatch always retries immediately. Omit to use the cluster’s transaction settings; pass 0 to never wait.

Return type:

Any

Returns:

Whatever operation returns on the successful attempt.

Raises:
  • ValueError – If max_attempts < 1.

  • CommitError – The commit’s roll-forward was abandoned (not retried: the server will eventually commit those writes).

  • AerospikeError – The last-seen transient error after max_attempts exhausted retries, or any non-transient error raised by operation.

Example:

async def transfer(tx):
    await tx.upsert(accounts.id("A")).bin("bal").add(-10).execute()
    await tx.upsert(accounts.id("B")).bin("bal").add(10).execute()
    return "ok"

result = await session.do_in_transaction(transfer)

See also

transaction(): Manual MRT lifecycle. TransactionalSession

property behavior: Behavior

Policy bundle applied to operations created from this session.

Returns:

The Behavior bound to this session at creation.

Example:

session = client.create_session(Behavior.DEFAULT)
assert session.behavior is Behavior.DEFAULT

See also

current_transaction: The session’s active transaction, if any.

property current_transaction: Txn | None

The active transaction for this session, or None.

Regular sessions always hold None; only a transactional session inside its active block exposes a live Txn. Builders spawned from the session read this and thread the result through every policy they hand to the PNC, so operations started inside a transaction auto-participate.

Returns:

The active Txn, or None outside a transaction.

Example:

session = client.create_session()
assert session.current_transaction is None

See also

behavior: The session’s policy bundle.

delete(arg1, /, *keys)

Start a delete for one or more keys.

Key resolution matches upsert().

Return type:

TypeVar(_WSB, bound= _WriteSegmentBuilderBase)

Returns:

A write-segment builder.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
session.delete(users.id(1)).execute()

See also

upsert(): Create or update the same keys.

exists(arg1, /, *keys)

Start an existence check for one or more keys.

Key resolution matches upsert(). A single key always yields one row, reading False when the record is absent; a batch omits absent keys unless include_missing_keys() is set on the builder.

Return type:

TypeVar(_WSB, bound= _WriteSegmentBuilderBase)

Returns:

A write-segment builder whose result reports presence per key.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
present = session.exists(users.id(1)).execute().first().as_bool()

See also

query(): Fetch the record instead of just presence.

insert(arg1, /, *keys)

Start a create-only write; fails on execute if the record already exists.

Overloads:
  • self, arg1 (DataSet) → _DSWB

  • self, arg1 (Union[Key, List[Key]]), keys (Key) → _WSB

Key resolution matches upsert().

Returns:

A write-segment builder.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
session.insert(users.id(99)).put({"name": "new"}).execute()

See also

upsert(): Create or update.

query(arg1, /, *keys)

Start a read or secondary-index query for keys or a whole set.

This session’s behavior is applied to the underlying query builder; use session_for() to run a query under a different one. Supported shapes: a DataSet (set-wide query), a single Key, or multiple keys (varargs or a list). Multi-key queries are split into per-node sub-batches, and a node whose sub-batch holds a single key is sent a regular single-record command automatically — size-1 batches need no special-casing by the caller.

Parameters:
  • arg1 (Union[DataSet, Key, List[Key]]) – A dataset, a key, or a list of keys.

  • *keys (Key) – Additional keys when arg1 is a key.

Return type:

TypeVar(_QB, bound= _QueryBuilderBase)

Returns:

A query builder to chain where, bins, execute, etc. The terminal execute() is awaited on async sessions and blocking on sync sessions.

Raises:
  • TypeError – If the arguments are not a dataset, keys, or a list of keys.

  • ValueError – If a key list is empty.

Example:

users = DataSet.of("test", "users")
rs = await session.query(users.id(1)).bins(["name"]).execute()
row = await rs.first_or_raise()

# A whole set, or a whole namespace with DataSet.of("test"):
rs = await session.query(users).where("$.age > 30").execute()

See also

upsert(): Writes for the same keys.

replace(arg1, /, *keys)

Start a replace-entire-record write (create or replace).

Overloads:
  • self, arg1 (DataSet) → _DSWB

  • self, arg1 (Union[Key, List[Key]]), keys (Key) → _WSB

Key resolution matches upsert().

Returns:

A write-segment builder.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
session.replace(users.id(1)).put({"name": "Tim"}).execute()

See also

replace_if_exists(): Replace only when the record exists. upsert(): Merge instead of replace.

replace_if_exists(arg1, /, *keys)

Start a replace-entire-record write that fails if the record is absent.

Key resolution matches upsert().

Return type:

TypeVar(_WSB, bound= _WriteSegmentBuilderBase)

Returns:

A write-segment builder.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
session.replace_if_exists(users.id(1)).put({"name": "Tim"}).execute()

See also

replace(): Create or replace. update(): Merge only when the record exists.

touch(arg1, /, *keys)

Start a touch (bump generation / reset TTL) for one or more keys.

Key resolution matches upsert().

Return type:

TypeVar(_WSB, bound= _WriteSegmentBuilderBase)

Returns:

A write-segment builder.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
session.touch(users.id(1)).execute()

See also

update(): Modify bins as well as metadata.

transaction()

Start a multi-record transaction (MRT) using this session’s behavior.

Returns a context manager that allocates a fresh Txn. Every operation run on the returned session auto-participates — builders stamp policy.txn under the hood, so user code never touches a policy object. On clean exit the transaction is committed; if an exception propagates out of the block it is aborted.

Defined once here so this session’s behavior is always threaded into the transactional session — the two trees cannot re-drift into dropping it on one side.

Return type:

TypeVar(_TS)

Returns:

The tree’s transactional session (async or sync), bound to this session’s client and behavior.

Example:

async with session.transaction() as tx:
    await tx.upsert(accounts.id("A")).bin("balance").set_to(100).execute()
    await tx.upsert(accounts.id("B")).bin("balance").set_to(200).execute()

See also

current_transaction: The active transaction, if any.

async truncate(dataset, before_nanos=None)[source]

Truncate (delete all records) from a set; this cannot be undone.

Warning

A dataset with no set truncates the entire namespace, every set and the null set. DataSet.of("prod") and DataSet.of("prod", None) both mean that. Name the set unless a namespace-wide truncate is what you intend.

Parameters:
  • dataset (DataSet) – The DataSet to truncate. With no set name, the whole namespace is truncated.

  • before_nanos (Optional[int]) – Optional timestamp in nanoseconds. Only records with last update time (LUT) less than this value are truncated. If None, all records in the set are truncated.

Return type:

None

Returns:

None

Raises:

RuntimeError – If the client is not connected.

Example:

users = DataSet.of("test", "users")
await session.truncate(users)

cutoff_time = time.time_ns() - (24 * 60 * 60 * 10**9)  # 24 hours ago
await session.truncate(users, before_nanos=cutoff_time)
update(arg1, /, *keys)

Start an update-only write; fails on execute if the record does not exist.

Overloads:
  • self, arg1 (DataSet) → _DSWB

  • self, arg1 (Union[Key, List[Key]]), keys (Key) → _WSB

Key resolution matches upsert().

Returns:

A write-segment builder.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys or a list of keys.

Example:

users = DataSet.of("test", "users")
session.update(users.id(1)).bin("age").set_to(31).execute()

See also

upsert(): Create or update. replace_if_exists(): Replace-entire-record only if present.

upsert(arg1, /, *keys)

Start a create-or-replace write for one or more keys.

Overloads:
  • self, arg1 (DataSet) → _DSWB

  • self, arg1 (Union[Key, List[Key]]), keys (Key) → _WSB

If the record exists, bins are merged according to the chained operations; if it does not exist, it is created. Use insert() when the record must not already exist.

Parameters:
  • arg1 (Union[DataSet, Key, List[Key]]) – A single Key, a list of keys, or a DataSet for a tabular write (rows follow via bins(...)).

  • *keys (Key) – Additional keys when arg1 is a key.

Returns:

A write-segment builder for put, bin, where, execute, etc.

Raises:
  • ValueError – If a key list is empty.

  • TypeError – If the arguments are not keys, a list of keys, or a dataset.

Example:

users = DataSet.of("test", "users")
session.upsert(users.id(1)).put({"name": "Tim", "age": 30}).execute()

# Several records with the same bins, as rows under a column schema:
session.upsert(users).bins("name", "age").row(1, "Tim", 30).row(2, "Bob", 25).execute()

See also

insert(): Fails if the record already exists. update(): Fails if the record does not exist. replace(): Replace-entire-record semantics when configured.