# Quickstart

> UStore for Python

Every verb whose outputs scale with the call takes a `ustore.Arena` as its last positional argument and answers results viewing it:

```python
import numpy as np
import ustore
from ustore.graph_view import DiGraph
from ustore.table_view import Table

with ustore.Database.open_ram() as database:
    arena = ustore.Arena()                              # host pages for calls on the calling thread
    blobs = database.collection_create("blobs", modality=ustore.Modality.BLOBS)  # none exists until created
    database.write([1, 2], [b"a", b"bb"], collection=blobs)
    values = database.read([1, 2], arena, collection=blobs)  # Values, indexed as memoryviews over the arena
    database.scan_batch([1, 100], 16, arena, collection=blobs)  # Keys, rewinding the arena: `values` goes stale
    with database.cursor(collection=blobs) as cursor:   # a walk over one collection, page by page
        while page := cursor.next(1024, arena, values=True):
            list(page), page.values                     # UUID keys and their Values, in one call per page

    people = database.collection_create("people", modality=ustore.Modality.DOCS)
    database.docs_write([10, 11], ['{"name": "Lex", "tweets": 2221}', '{"name": "Joe"}'], collection=people)
    database.docs_gist([10, 11], arena, collection=people)  # ("/name", "/tweets")
    types = [ustore.FieldType.STRING, ustore.FieldType.I64]
    columns = database.docs_gather([10, 11], ["name", "tweets"], types, arena, collection=people)
    columns[1], columns.validities(1)                   # memoryview of "q", bitmap bytes
    prices = np.array([1.5, 2.5], dtype=np.float64)
    database.docs_write([10, 11], prices, field="price", type=ustore.FieldType.F64, collection=people)

    follows = database.collection_create("follows", modality=ustore.Modality.GRAPH)
    database.graph_write_edges(np.array([1, 2]), np.array([2, 3]), collection=follows)
    neighborhoods = database.graph_read_edges([1, 2, 3], arena, role=ustore.Role.ANY, collection=follows)
    np.asarray(neighborhoods)                           # (edges, 3, 16) bytes of source, target, edge

    database.get(1, collection=blobs), 1 in database["blobs"].blobs  # one-off arena copies: b"a", True
    graph = DiGraph(database, "graph", nodes="nodes", edges="edges")
    graph.add_edge(1, 2, weight=3)
    list(graph.edges(data=True))                        # [(UUID(int=1), UUID(int=2), {"weight": 3})]
    Table(database, people).astype({"tweets": "int64"}).to_pandas(page=1 << 16)
```

A document or a vertex is a value like any other, so documents, graphs and binary values each keep collections of their own.

`import ustore`

`from ustore import Database`

## Engine

The engine serving a database, as `describe()` reports it, valued as `ustore_engine_t`.

```python
class Engine(IntEnum)
```

- `RAM` = `0`
- `ROCKSDB` = `1`
- `LEVELDB` = `2`
- `NVME` = `3`

## PathLikeOrStr

```python
type PathLikeOrStr = str | bytes | PathLike[str]
```

## DataDirectory

```python
type DataDirectory = PathLikeOrStr | tuple[PathLikeOrStr, int]
```

## Database

An embedded database, opened through one class method per engine.

```python
class Database
```

## open_ram

An in-memory database, persisted as one image when it names a directory, opened blocking on [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor) and confined to `cpu_class`.

```python
@classmethod
def open_ram(
    directory: PathLikeOrStr | None = None,
    *,
    isolation: Isolation = Isolation.STRICT_SERIALIZABLE,
    executor: Executor | None = None,
    cpu_class: CPUClass = CPUClass.AUTOMATIC,
) -> Self
```

## open_rocksdb

A database on RocksDB, whose table files may spread over data directories, opened blocking on [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor).

```python
@classmethod
def open_rocksdb(
    directory: PathLikeOrStr,
    *,
    data_directories: Sequence[DataDirectory] = (),
    executor: Executor | None = None,
) -> Self
```

## view_rocksdb

A read-only database on RocksDB, refusing every change with [`ReadOnlyError`](https://www.unum.cloud/docs/ustore/python/errors.md#ReadOnlyError) while snapshots and their saves still serve, opened blocking on [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor).

```python
@classmethod
def view_rocksdb(
    directory: PathLikeOrStr,
    *,
    data_directories: Sequence[DataDirectory] = (),
    executor: Executor | None = None,
) -> Self
```

## open_leveldb

A database on LevelDB, opened blocking on [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor).

```python
@classmethod
def open_leveldb(
    directory: PathLikeOrStr,
    *,
    executor: Executor | None = None,
) -> Self
```

## open_nvme

A database on the NVMe engine, named by its `manifest`, `<database>.ustore.json` in an existing directory or the raw address of its first slot, where every zero size keeps the engine's default, opened blocking on [`executor`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#executor), which tells it how to move bytes when [`Executor.for_nvme`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#for_nvme) made it, merging on the device of `compactions` when [`Executor.for_vram`](https://www.unum.cloud/docs/ustore/python/batches-and-arenas.md#for_vram) made it.

```python
@classmethod
def open_nvme(
    manifest: PathLikeOrStr,
    *,
    executor: Executor | None = None,
    data_directories: Sequence[DataDirectory] = (),
    compactions: Executor | None = None,
    cpu_class: CPUClass = CPUClass.AUTOMATIC,
    memory_limit: int = 0,
    transaction_max_bytes: int = 0,
    transaction_max_deltas: int = 0,
    collection_concurrency_limit: int = 0,
    collection_cache_limit: int = 0,
    collection_memory_runs_max_bytes: int = 0,
    collection_memory_runs_max_deltas: int = 0,
    collection_level_enlarge_factor: int = 0,
    collection_value_size: int = 0,
    collection_value_max_size: int = 0,
) -> Self
```

## ingest_arrow

Lands every batch of an Arrow stream as one commit of its own at the head, answering the rows landed.

```python
def ingest_arrow(
    source: ArrowSource,
    *,
    collection: CollectionLike,
    order: IngestOrder = 'sorted',
    durability: Durability | None = None,
) -> int
```

## close

Closes the database once every deferred call on it finished, while its open transactions and snapshots keep working, each holding the database open until it closes too.

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

## clear

Empties every collection at once: its pairs, every collection with its name, or its values.

```python
def clear(mode: DropMode, /) -> None
```

## compact

Reclaims the space overwritten and removed data takes, one collection at a time, reporting bytes where the engine measures them and collections elsewhere.

```python
def compact(*, progress: Progress | None = None) -> None
```

## flush

Makes every commit that returned before the call durable, as if each had asked for [`Durability.FLUSHED`](https://www.unum.cloud/docs/ustore/python/reads-and-writes.md#FLUSHED).

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

## describe

The engine, its capabilities and isolation, and the keys, memory and disk it holds.

```python
def describe() -> Description
```

## collection_create

Creates an empty collection holding [`modality`](https://www.unum.cloud/docs/ustore/python/collections.md#modality) and records the name for it, which may not start with `_`.

```python
def collection_create(name: str, *, modality: Modality) -> UUID
```

## collection_find

The collection ID the name addresses.

```python
def collection_find(name: str, arena: Arena, /) -> UUID
```

## collection_contains

Whether a collection carries the name, read into a one-off arena.

```python
def collection_contains(name: str) -> bool
```

## collection_list

The IDs of every collection, never a system one.

```python
def collection_list(arena: Arena, /) -> tuple[UUID, ...]
```

## collection_names

One page of the names recorded for collections, in the order of their text.

```python
def collection_names(
    arena: Arena,
    /,
    *,
    after: str | None = None,
    limit: int = 1024,
) -> tuple[str, ...]
```

## collection_drop

Removes a collection, or empties its pairs or its values.

```python
def collection_drop(
    collection: UUID | str,
    mode: DropMode = DropMode.COLLECTION,
) -> None
```

## snapshot

Pins a point-in-time state of the whole database, which the snapshot's read verbs see.

```python
def snapshot() -> Snapshot
```

## changes_cursor

A feed of the changes committed to `collection` after the commit stamp `since`, oldest first.

```python
def changes_cursor(
    since: int = 0,
    /,
    *,
    collection: CollectionLike,
) -> ChangesCursor
```

## transaction

Begins a transaction over this database, recording the keys its verbs touch unless [`Watch.NONE`](https://www.unum.cloud/docs/ustore/python/transactions.md#NONE).

```python
def transaction(watch: Watch = Watch.KEYS) -> Transaction
```

## capabilities

```python
capabilities: Capabilities
```

## 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`](https://www.unum.cloud/docs/ustore/python/transactions.md#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`](https://www.unum.cloud/docs/ustore/python/transactions.md#write) takes one, are JSON already, while a dict, a list or a
number inside a sequence is serialized. None is refused: [`remove`](https://www.unum.cloud/docs/ustore/python/transactions.md#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`](https://www.unum.cloud/docs/ustore/python/transactions.md#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
```

