# Transactions

> UStore for Python

`import ustore`

`from ustore import Transaction`

## Watch

Whether a transaction records the keys a call touches, valued as `ustore_watch_t`.

```python
class Watch(IntEnum)
```

- `KEYS` = `0`
- `NONE` = `1`

## Isolation

How the transactions of the in-memory engine see each other's writes, valued as `ustore_isolation_t`.

```python
class Isolation(IntEnum)
```

- `STRICT_SERIALIZABLE` = `0`
- `SNAPSHOT` = `1`

## Transaction

An optimistic transaction grouping operations across collections and modalities, one call at a time.

```python
class Transaction
```

## watched

A view whose calls record the keys they touch for conflicts.

```python
def watched() -> On
```

## unwatched

A view whose calls record nothing, so they never fail the commit.

```python
def unwatched() -> On
```

## commit

Applies every staged change, or none of them, answering the commit stamp: the commit's position in commit order, which every snapshot whose read stamp is at or above it sees.

```python
def commit(durability: Durability = Durability.BUFFERED) -> int
```

## stage

Runs the first phase of a two-phase commit, answering the read stamp: the stamp the transaction reads at and its commit validates against, no greater than the commit stamp that follows.

```python
def stage() -> int
```

## rollback

Withdraws a stage, keeping the reads and writes, so the transaction can stage or commit again.

```python
def rollback() -> None
```

## reset

Drops every read and write and starts a new generation on the same handle.

```python
def reset() -> None
```

## close

Drops whatever is still staged and releases the handle, once its deferred calls finished.

```python
def close() -> None
```

## database

```python
database: Database
```

## write

Upserts a batch of binary values in one call.

```python
def write(
    keys: KeysLike,
    values: Sequence[ValueLike] | ValueLike | TapeLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

Every value is borrowed for the length of the call rather than copied, so a memory-mapped buffer reaches the engine untouched.

Raises:
TypeError: A value is None or exports no buffer.
Error: Whatever the engine reported.

- `keys`: The keys to write.
- `values`: One value per key, a tape of
them, or a single bytes-like object broadcast to every key. A tape is an Arrow
`binary`, `large_binary`, `string` or `large_string` array, such as [`Values`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#Values), or
a `(data, offsets)` tuple of buffers with unsigned 32-bit or 64-bit offsets, and
passes without a copy. None is refused, since [`remove`](#remove) removes keys.
- `collection`: The collection, by identifier or by name.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## set

Upserts one binary value.

```python
def set(
    key: KeyLike,
    value: ValueLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

Raises:
TypeError: The value is None or exports no buffer.

- `key`: The key to write.
- `value`: The bytes to store, borrowed rather than copied.
- `collection`: The collection, by identifier or by name.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## remove

Removes keys with their values, or every key of a range up to its key in `ends`.

```python
def remove(
    keys: KeyLike | KeysLike,
    *,
    collection: CollectionLike,
    ends: KeyLike | KeysLike | None = None,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## docs_write

Writes a batch of JSON documents, or one field inside each of them.

```python
def docs_write(
    keys: KeysLike | None,
    documents: Sequence[DocumentLike] | DocumentLike | TapeLike,
    *,
    collection: CollectionLike,
    field: str | None = None,
    modification: Modification = Modification.UPSERT,
    type: FieldType = FieldType.JSON,
    id_field: str | None = None,
    durability: Durability = Durability.BUFFERED,
) -> None
```

Every document is borrowed for the length of the call rather than copied.

Raises:
TypeError: A document is None.
MalformedError: A document does not parse, or its `id_field` holds no integer.
NotFoundError: A field is written inside a document that does not exist.
AlreadyExistsError: An insert names a document that already exists.

- `keys`: The keys to write; None reads every key from
`id_field` of its document.
- `documents`: One
document per key, a tape of them, or one document broadcast to every key. Text,
bytes and a tape, as [`write`](#write) takes one, are JSON already, while a dict, a list or a
number inside a sequence is serialized. None is refused: [`remove`](#remove) removes whole
documents, and a merge with a JSON null removes a field. Under a fixed-width `type`,
a contiguous buffer of one scalar per key is a column, which reaches the store
without being printed as JSON and parsed back.
- `collection`: The collection, by identifier or by name.
- `field`: A top-level key or a JSON Pointer such as '/user/name' to
write inside every document; None writes whole documents.
- `modification`: An upsert, update or insert, an RFC 6902
[`Modification.PATCH`](https://www.unum.cloud/docs/ustore/python/documents.md#PATCH) or an RFC 7386 [`Modification.MERGE`](https://www.unum.cloud/docs/ustore/python/documents.md#MERGE).
- `type`: How every document is spelled: [`FieldType.JSON`](https://www.unum.cloud/docs/ustore/python/platform-notes.md#JSON),
[`FieldType.STRING`](https://www.unum.cloud/docs/ustore/python/documents.md#STRING) for a plain string, [`FieldType.NULL`](https://www.unum.cloud/docs/ustore/python/documents.md#NULL), or the raw bytes of
[`FieldType.BOOL`](https://www.unum.cloud/docs/ustore/python/documents.md#BOOL), [`FieldType.F64`](https://www.unum.cloud/docs/ustore/python/documents.md#F64), [`FieldType.F32`](https://www.unum.cloud/docs/ustore/python/documents.md#F32), [`FieldType.I64`](https://www.unum.cloud/docs/ustore/python/documents.md#I64) through
[`FieldType.U8`](https://www.unum.cloud/docs/ustore/python/documents.md#U8).
- `id_field`: The field holding every key when [`keys`](https://www.unum.cloud/docs/ustore/python/scans.md#keys) is None.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## docs_remove

Removes whole documents, or every document of a range up to its key in `ends`.

```python
def docs_remove(
    keys: KeyLike | KeysLike,
    *,
    collection: CollectionLike,
    ends: KeyLike | KeysLike | None = None,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## strings_write

Upserts strings and the keys they map onto, one key per string.

```python
def strings_write(
    strings: TextsLike,
    keys: KeyLike | KeysLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## strings_remove

Removes strings with their keys.

```python
def strings_remove(
    strings: TextsLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## pages_import

Replaces whole pages with parsed markup, minting a key for every element.

```python
def pages_import(
    keys: KeyLike | KeysLike,
    markup: TextsLike,
    *,
    collection: CollectionLike,
    encoding: PageEncoding = PageEncoding.XML,
    durability: Durability = Durability.BUFFERED,
    progress: Progress | None = None,
) -> None
```

## import_arrow

Writes every batch of an Arrow stream through the writes of the collection's modality, answering the rows written.

```python
def import_arrow(
    source: ArrowSource,
    *,
    collection: CollectionLike,
    durability: Durability | None = None,
) -> int
```

## pages_insert

Parses fragments into elements under `parents` after `anchors`, the root and the front where None, answering the key every element ended up with, given in `elements` or minted.

```python
def pages_insert(
    keys: KeyLike | KeysLike,
    fragments: TextsLike,
    *,
    collection: CollectionLike,
    elements: KeyLike | KeysLike | None = None,
    parents: KeyLike | KeysLike | None = None,
    anchors: KeyLike | KeysLike | None = None,
    encoding: PageEncoding = PageEncoding.XML,
    durability: Durability = Durability.BUFFERED,
) -> tuple[UUID, ...]
```

## pages_remove

Removes elements with their subtrees, where the page key or no elements removes the whole page, and every page of a range up to its key in `ends`.

```python
def pages_remove(
    keys: KeyLike | KeysLike,
    elements: KeyLike | KeysLike | None = None,
    *,
    collection: CollectionLike,
    ends: KeyLike | KeysLike | None = None,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## pages_move

Moves elements with their subtrees under `parents` after `anchors`, keeping their keys.

```python
def pages_move(
    keys: KeyLike | KeysLike,
    elements: KeyLike | KeysLike,
    *,
    collection: CollectionLike,
    parents: KeyLike | KeysLike | None = None,
    anchors: KeyLike | KeysLike | None = None,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## pages_splice

Replaces [`lengths`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#lengths) bytes of the text of every element from `starts` on with `texts`.

```python
def pages_splice(
    keys: KeyLike | KeysLike,
    elements: KeyLike | KeysLike,
    starts: LengthsLike,
    lengths: LengthsLike,
    texts: TextsLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## pages_set_attributes

Sets one attribute of an element per task, adding the ones it lacks.

```python
def pages_set_attributes(
    keys: KeyLike | KeysLike,
    elements: KeyLike | KeysLike,
    fields: TextsLike,
    values: TextsLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## pages_remove_attributes

Removes one attribute of an element per task.

```python
def pages_remove_attributes(
    keys: KeyLike | KeysLike,
    elements: KeyLike | KeysLike,
    fields: TextsLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

## graph_write_edges

Inserts a batch of edges, creating the vertices they connect.

```python
def graph_write_edges(
    sources: KeysLike,
    targets: KeysLike,
    *,
    edges: KeysLike | None = None,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

An edge already present is kept, so writing the same batch twice changes nothing.

- `sources`: The vertex every edge leaves.
- `targets`: The vertex every edge enters.
- `edges`: The identifier of every edge, which tells
apart several edges between one pair; None gives every edge [`edge_id_default`](https://www.unum.cloud/docs/ustore/python/graphs.md#edge_id_default).
- `collection`: The graph collection, by identifier or by name.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## graph_remove_edges

Removes a batch of edges and keeps the vertices they connected, even once isolated.

```python
def graph_remove_edges(
    sources: KeysLike,
    targets: KeysLike,
    *,
    edges: KeysLike | None = None,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

- `sources`: The vertex every edge leaves.
- `targets`: The vertex every edge enters.
- `edges`: The identifier of every edge; None removes
the edges that were given [`edge_id_default`](https://www.unum.cloud/docs/ustore/python/graphs.md#edge_id_default).
- `collection`: The graph collection, by identifier or by name.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## graph_write_vertices

Inserts a batch of vertices without edges, keeping those already present.

```python
def graph_write_vertices(
    vertices: KeysLike,
    *,
    collection: CollectionLike,
    durability: Durability = Durability.BUFFERED,
) -> None
```

- `vertices`: The vertices to insert.
- `collection`: The graph collection, by identifier or name.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## graph_remove_vertices

Removes a batch of vertices together with every edge they take part in.

```python
def graph_remove_vertices(
    vertices: KeysLike,
    *,
    role: Role = Role.ANY,
    collection: CollectionLike,
    ends: KeysLike | None = None,
    durability: Durability = Durability.BUFFERED,
) -> None
```

With `ends`, every vertex starts a range removed up to its end, as [`remove`](#remove) takes them.

- `vertices`: The vertices to remove, or the first vertex of
every range.
- `role`: The role every vertex plays, which only a joining graph between
two collections needs; [`Role.ANY`](https://www.unum.cloud/docs/ustore/python/graphs.md#ANY) otherwise.
- `collection`: The graph collection, by identifier or by name.
- `ends`: The vertex every range stops before, one
per vertex.
- `durability`: [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED) reaches the drive before
returning.

## __getitem__

The collection [`name`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#name) addresses.

```python
def __getitem__(name: str) -> Collection
```

## read

Reads a batch of binary values in one call, which no sequence of single reads matches for throughput.

```python
def read(
    keys: KeysLike,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    offset: int = 0,
    limit: int | None = None,
) -> Values
```

Nothing is copied: the tape sits in the arena, and indexing the answer gives a memoryview over the stored bytes, or None for an absent key.

Returns:
Values: One entry per key, in the order they were asked for.
Raises:
ContendedError: The arena serves another call or exports a buffer.
Error: Whatever the engine reported.

- `keys`: The keys to read, as a sequence, a contiguous
buffer of 16-byte keys, which is read in place, or one of 64-bit integers.
- `arena`: Where the tape lands, rewound by this call.
- `collection`: The collection, by identifier or by name.
- `offset`: Byte of every value the read starts at, where an offset
past the end reads empty.
- `limit`: Most bytes of every value to read from the offset, or None
for the rest of it.

## get

Copies one value out of a one-off arena, which [`read`](https://www.unum.cloud/docs/ustore/python/snapshots.md#read) with an arena of yours avoids.

```python
def get(
    key: KeyLike,
    *,
    collection: CollectionLike,
) -> bytes | None
```

## contains

Reads one presence into a one-off arena.

```python
def contains(
    key: KeyLike,
    *,
    collection: CollectionLike,
) -> bool
```

## cursor

A walk over the keys of one collection from `start`, reading nothing until its first pull, whose every pull blocks as this receiver's calls do.

```python
def cursor(
    start: KeyLike | None = None,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    patterns: Sequence[str | bytes] | None = None,
    pattern_kind: PatternKind = PatternKind.REGEX,
    sensitivity: CaseSensitivity = CaseSensitivity.CASED,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Cursor
```

Calls `ustore_blobs_cursor_init`.

## docs_cursor

A walk over documents, keeping those `filter` matches.

```python
def docs_cursor(
    start: KeyLike | None = None,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    filter: str | bytes | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Cursor
```

Calls `ustore_docs_cursor_init`.

## pages_cursor

A walk over pages, keeping those holding a node of the XPath `filter`, whose pulls render whole pages into `outputs_encoding` when asked.

```python
def pages_cursor(
    start: KeyLike | None = None,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    filter: str | bytes | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
    outputs_encoding: PageEncoding = PageEncoding.XML,
) -> Cursor
```

Calls `ustore_pages_cursor_init`.

## graph_vertices_cursor

A walk over the vertices of one graph collection.

```python
def graph_vertices_cursor(
    start: KeyLike | None = None,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Cursor
```

Calls `ustore_graph_vertices_cursor_init`.

## scan

Lists up to `wanted` keys from `start` towards `end`.

```python
def scan(
    start: KeyLike | None,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    progress: Progress | None = None,
    patterns: Sequence[str | bytes] | None = None,
    pattern_kind: PatternKind = PatternKind.REGEX,
    sensitivity: CaseSensitivity = CaseSensitivity.CASED,
    weights: Sequence[float] | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Keys
```

Values are not exported, so a read follows the scan, or a `cursor()` walks a collection with its values instead.

Returns:
Keys: One run of keys, in the order of the direction.
Raises:
CancelledError: The progress callable stopped the scan.

- `start`: The first key the scan may return, or None for the first
key in its direction.
- `wanted`: Most keys the scan returns.
- `arena`: Where the keys land, rewound by this call.
- `collection`: The collection, by identifier or by name.
- `end`: The key the scan stops before, or None for no bound.
- `direction`: [`ScanDirection.DESCENDING`](https://www.unum.cloud/docs/ustore/python/scans.md#DESCENDING) walks down from
`start`, largest key first.
- `mode`: [`ScanMode.UNORDERED`](https://www.unum.cloud/docs/ustore/python/scans.md#UNORDERED) lets keys come out of order,
removed or repeated, to speed up the read after the scan; no engine uses it yet.
- `progress`: Called with the scans
finished and the scans in all; a falsy answer other than None cancels the call.

## scan_batch

One scan per start, reporting the scans finished to `progress`.

```python
def scan_batch(
    starts: KeysLike,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    ends: KeysLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    progress: Progress | None = None,
    patterns: Sequence[str | bytes] | None = None,
    pattern_kind: PatternKind = PatternKind.REGEX,
    sensitivity: CaseSensitivity = CaseSensitivity.CASED,
    weights: Sequence[float] | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Keys
```

## sample

Draws keys uniformly at random from one collection, which is how a workload picks entries it has no list of.

```python
def sample(
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> Keys
```

Returns:
Keys: One run of keys, in no particular order.

- `wanted`: Most keys to draw.
- `arena`: Where the keys land, rewound by this call.
- `collection`: The collection, by identifier or by name.

## sample_batch

`count` samples of up to `wanted` keys each, all drawn from the one collection named.

```python
def sample_batch(
    count: int,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> Keys
```

## measure

Estimates what a key range holds without walking it, so the answers are bounds rather than counts.

```python
def measure(
    start: KeyLike | None,
    end: KeyLike | None,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    direction: ScanDirection = ScanDirection.ASCENDING,
) -> Measurement
```

Returns:
Measurement: The lower and upper bounds on the entries, the bytes of their values,
and the space they take on disk.

- `start`: First key of the range, or None for the first key in the
direction.
- `end`: The key the range stops before, or None for no bound.
- `arena`: Where the bounds land before they are copied out, rewound by this
call.
- `collection`: The collection, by identifier or by name.
- `direction`: [`ScanDirection.DESCENDING`](https://www.unum.cloud/docs/ustore/python/scans.md#DESCENDING) ranges down from
`start`.

## docs_read

Reads whole documents, or one field of each, as JSON text or as printed strings.

```python
def docs_read(
    keys: KeysLike,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    field: str | None = None,
    outputs_type: FieldType = FieldType.JSON,
) -> Values
```

Whole documents read as JSON pass straight through from the engine, so nothing is parsed.

Returns:
Values: One entry per key, None where the document or the field is absent.

- `keys`: The keys to read.
- `arena`: Where the tape lands, rewound by this call.
- `collection`: The collection, by identifier or by name.
- `field`: A top-level key or a JSON Pointer to read inside every
document; None reads whole documents.
- `outputs_type`: [`FieldType.JSON`](https://www.unum.cloud/docs/ustore/python/platform-notes.md#JSON) for JSON text, or
[`FieldType.STRING`](https://www.unum.cloud/docs/ustore/python/documents.md#STRING) to print scalars as text.

## docs_gist

Lists every distinct path to a leaf across the requested documents, in the order they were first met, which is how a table learns the columns its documents hold.

```python
def docs_gist(
    keys: KeysLike,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> tuple[str, ...]
```

Returns:
tuple[str, ...]: One JSON Pointer per leaf, such as '/user/name'.

- `keys`: The documents to inspect.
- `arena`: Where the paths land before they are copied out, rewound by this
call.
- `collection`: The collection, by identifier or by name.

## docs_gather

Reads every field of every document into typed columns, converting each value on a best-effort basis and recording what was found, converted, or could not be.

```python
def docs_gather(
    keys: KeysLike,
    fields: Sequence[str],
    outputs_types: FieldType | Sequence[FieldType],
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> Columns
```

Returns:
Columns: One column per field, each holding one entry per document.

- `keys`: The documents, the rows of every column.
- `fields`: Top-level keys or JSON Pointers, the columns of the result.
- `outputs_types`: One type per field, or one for
every field: a fixed-width scalar from [`FieldType.BOOL`](https://www.unum.cloud/docs/ustore/python/documents.md#BOOL) to [`FieldType.U8`](https://www.unum.cloud/docs/ustore/python/documents.md#U8),
[`FieldType.UUID`](https://www.unum.cloud/docs/ustore/python/documents.md#UUID), [`FieldType.STRING`](https://www.unum.cloud/docs/ustore/python/documents.md#STRING) or [`FieldType.BINARY`](https://www.unum.cloud/docs/ustore/python/documents.md#BINARY). A [`FieldType.F16`](https://www.unum.cloud/docs/ustore/python/documents.md#F16)
column exports as a half-precision view NumPy reads as float16, and a
[`FieldType.UUID`](https://www.unum.cloud/docs/ustore/python/documents.md#UUID) column as sixteen bytes per document.
- `arena`: Where the columns land, rewound by this call.
- `collection`: The collection, by identifier or by name.

## docs_scan

Lists up to `wanted` document keys from `start` towards `end`, as [`scan`](https://www.unum.cloud/docs/ustore/python/snapshots.md#scan) lists the keys of blobs.

```python
def docs_scan(
    start: KeyLike | None,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    progress: Progress | None = None,
    filter: str | bytes | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Keys
```

Documents are not exported, so a [`docs_read`](https://www.unum.cloud/docs/ustore/python/snapshots.md#docs_read) follows the scan.

Returns:
Keys: One run of keys, in the order of the direction.
Raises:
CancelledError: The progress callable stopped the scan.

- `start`: The first key the scan may return, or None for the first
key in its direction.
- `wanted`: Most keys the scan returns.
- `arena`: Where the keys land, rewound by this call.
- `collection`: The docs collection, by identifier or by name.
- `end`: The key the scan stops before, or None for no bound.
- `direction`: Which way the scan walks, as [`scan`](https://www.unum.cloud/docs/ustore/python/snapshots.md#scan) takes it.
- `mode`: In what order the keys come, as [`scan`](https://www.unum.cloud/docs/ustore/python/snapshots.md#scan) takes it.
- `progress`: Called with the scans
finished and the scans in all; a falsy answer other than None cancels the call.

## docs_sample

Up to `wanted` document keys drawn at random, which a [`docs_read`](https://www.unum.cloud/docs/ustore/python/snapshots.md#docs_read) or a [`docs_gather`](https://www.unum.cloud/docs/ustore/python/snapshots.md#docs_gather) follows.

```python
def docs_sample(
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> Keys
```

## docs_measure

Bounds on what a range of document keys holds, as [`measure`](https://www.unum.cloud/docs/ustore/python/snapshots.md#measure) reads them for blobs.

```python
def docs_measure(
    start: KeyLike | None,
    end: KeyLike | None,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    direction: ScanDirection = ScanDirection.ASCENDING,
) -> Measurement
```

## strings_read

the key of every string, or None for a string the strings collection does not hold.

```python
def strings_read(
    strings: TextsLike,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> tuple[UUID | None, ...]
```

## strings_scan

up to `wanted` strings starting with `prefix`, in the order of their bytes.

```python
def strings_scan(
    prefix: str | bytes | None,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    start: str | bytes | None = None,
    end: str | bytes | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
) -> tuple[str, ...]
```

## strings_sample

up to `wanted` strings drawn at random.

```python
def strings_sample(
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> tuple[str, ...]
```

## strings_measure

bounds on what a range of strings holds.

```python
def strings_measure(
    start: str | bytes | None,
    end: str | bytes | None,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    direction: ScanDirection = ScanDirection.ASCENDING,
) -> Measurement
```

## pages_read

Renders whole pages, or the subtrees of `elements`, one per task, None where a page or an element is absent.

```python
def pages_read(
    keys: KeyLike | KeysLike,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    elements: KeyLike | KeysLike | None = None,
    outputs_encoding: PageEncoding = PageEncoding.XML,
) -> Values
```

## pages_scan

Up to `wanted` page keys from `start`, keeping those holding a node of the XPath `filter`.

```python
def pages_scan(
    start: KeyLike | None,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    progress: Progress | None = None,
    filter: str | bytes | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Keys
```

## pages_sample

Up to `wanted` page keys drawn at random, which a [`pages_read`](https://www.unum.cloud/docs/ustore/python/snapshots.md#pages_read) follows.

```python
def pages_sample(
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> Keys
```

## pages_measure

Bounds on what a range of page keys holds, as [`measure`](https://www.unum.cloud/docs/ustore/python/snapshots.md#measure) reads them for blobs.

```python
def pages_measure(
    start: KeyLike | None,
    end: KeyLike | None,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    direction: ScanDirection = ScanDirection.ASCENDING,
) -> Measurement
```

## graph_read_edges

Reads every edge a batch of vertices takes part in.

```python
def graph_read_edges(
    vertices: KeysLike,
    arena: Arena,
    /,
    *,
    role: Role = Role.ANY,
    collection: CollectionLike,
) -> Neighborhoods
```

The edges of one vertex come sorted by neighbour; with both roles the outgoing ones precede the incoming ones.

Returns:
Neighborhoods: One run of (source, target, edge) triples per vertex, None where it is
absent.

- `vertices`: The vertices whose edges are read.
- `arena`: Where the degrees and the edges land, rewound by this call.
- `role`: [`Role.SOURCE`](https://www.unum.cloud/docs/ustore/python/graphs.md#SOURCE) for the edges a vertex leaves by, [`Role.TARGET`](https://www.unum.cloud/docs/ustore/python/graphs.md#TARGET)
for those it is entered by, or [`Role.ANY`](https://www.unum.cloud/docs/ustore/python/graphs.md#ANY) for both, which is how an undirected
graph asks.
- `collection`: The graph collection, by identifier or by name.

## graph_degrees

Counts the edges of a batch of vertices without exporting them.

```python
def graph_degrees(
    vertices: KeysLike,
    arena: Arena,
    /,
    *,
    role: Role = Role.ANY,
    collection: CollectionLike,
) -> tuple[int | None, ...]
```

Returns:
tuple[int | None, ...]: The degree of every vertex, None where it is absent.

- `vertices`: The vertices whose edges are counted.
- `arena`: Where the degrees land before they are copied out, rewound by this
call.
- `role`: The role of every vertex, as [`graph_read_edges`](https://www.unum.cloud/docs/ustore/python/snapshots.md#graph_read_edges) takes it.
- `collection`: The graph collection, by identifier or by name.

## graph_contains

Whether the vertex is present, read as its degree through a one-off arena.

```python
def graph_contains(
    vertex: KeyLike,
    /,
    *,
    collection: CollectionLike,
) -> bool
```

## graph_scan_vertices

Lists up to `wanted` vertices from `start` towards `end`, those without edges included.

```python
def graph_scan_vertices(
    start: KeyLike | None,
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    end: KeyLike | None = None,
    direction: ScanDirection = ScanDirection.ASCENDING,
    mode: ScanMode = ScanMode.ORDERED,
    progress: Progress | None = None,
    predicate: Predicate | None = None,
    predicate_cost: PredicateCost = PredicateCost.CHEAP,
) -> Keys
```

Edges are not exported, so a [`graph_read_edges`](https://www.unum.cloud/docs/ustore/python/snapshots.md#graph_read_edges) follows the scan.

Returns:
Keys: One run of vertices, in the order of the direction.
Raises:
CancelledError: The progress callable stopped the scan.

- `start`: The first vertex the scan may return, or None for the first
vertex in its direction.
- `wanted`: Most vertices the scan returns.
- `arena`: Where the vertices land, rewound by this call.
- `collection`: The graph collection, by identifier or by name.
- `end`: The vertex the scan stops before, or None for no bound.
- `direction`: Which way the scan walks, as [`scan`](https://www.unum.cloud/docs/ustore/python/snapshots.md#scan) takes it.
- `mode`: In what order the vertices come, as [`scan`](https://www.unum.cloud/docs/ustore/python/snapshots.md#scan) takes it.
- `progress`: Called with the scans
finished and the scans in all; a falsy answer other than None cancels the call.

## graph_sample_vertices

Up to `wanted` vertices drawn at random, those without edges included.

```python
def graph_sample_vertices(
    wanted: int,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
) -> Keys
```

## graph_measure_vertices

Bounds on what a range of vertices holds, as [`measure`](https://www.unum.cloud/docs/ustore/python/snapshots.md#measure) reads them for blobs.

```python
def graph_measure_vertices(
    start: KeyLike | None,
    end: KeyLike | None,
    arena: Arena,
    /,
    *,
    collection: CollectionLike,
    direction: ScanDirection = ScanDirection.ASCENDING,
) -> Measurement
```

## on

A view whose calls block on [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor), after every call submitted to it before.

```python
def on(executor: Executor) -> On
```

## deferred

A view whose calls [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor) runs while each verb answers a [`Deferred`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#Deferred) at once.

```python
def deferred(executor: Executor) -> DeferredOn
```

