multicloud.docstore¶
Document operations and fluent action lists. The public entry point is
DocStoreClient; query/filter/pagination APIs are not present in this public
client. See the roadmap for the
current surface.
Cloud-agnostic document store client package.
Public entry point — :class:DocStoreClient::
from multicloud.docstore.docstore_client import DocStoreClient
with DocStoreClient(
provider="aws",
table_name="my-table",
partition_key="pk",
region="us-west-2",
) as client:
client.actions().create({"pk": "alice", "name": "Alice"}).run()
Provider classes (AwsDocStore, ...) live in sibling distributions
(multicloud-docstore-aws, ...) and are discovered at runtime via
setuptools entry points.
DocStoreClient
¶
DocStoreClient(
*,
provider: str,
table_name: str,
partition_key: str,
sort_key: Optional[str] = None,
revision_field: Optional[str] = None,
allow_scans: bool = True,
max_outstanding_action_rpcs: int = 0,
region: Optional[str] = None,
endpoint: Optional[str] = None,
credentials_overrider: Optional[
Callable[..., Any]
] = None
)
Cloud-agnostic document store client.
Resolves a provider-specific driver from :data:DOCSTORE_REGISTRY at
construction time and forwards every operation to it. All arguments
are keyword-only; only provider, table_name, and
partition_key are required.
:param provider: Provider id (e.g. "aws").
:param table_name: Name of the underlying table / collection.
:param partition_key: Attribute name that holds the partition key.
:param sort_key: Optional attribute name for the sort key.
:param revision_field: Attribute used for optimistic-concurrency
revisions. None uses the driver default
("DocstoreRevision").
:param allow_scans: Whether scans (unindexed full-table reads) are
permitted on this collection.
:param max_outstanding_action_rpcs: Upper bound on in-flight backend
RPCs when run_actions fans out. 0 uses the executor
default.
:param region: Provider region (e.g. "us-west-2").
:param endpoint: Provider endpoint URI override.
:param credentials_overrider: Optional provider-specific credentials
callback.
:raises KeyError: If provider is not registered.
create
¶
Insert a new row for document.
Fails if a row with the same key already exists. The document
must not carry the revision field; the driver stamps a fresh
revision back onto document on success.
:param document: A dict (wrapped automatically) or a
:class:Document instance.
:raises ResourceAlreadyExistsException: If the key already
exists.
:raises InvalidArgumentException: If the document carries the
revision field, or the primary key shape is invalid.
replace
¶
Overwrite an existing row with document.
Requires the row to already exist. When document carries the
revision field, the write additionally asserts that the stored
revision matches; the driver stamps a fresh revision back onto
document on success.
:param document: A dict (wrapped automatically) or a
:class:Document instance.
:raises ResourceNotFoundException: If the row does not exist or
the revision precondition fails.
put
¶
Upsert document — insert or overwrite unconditionally.
When document carries the revision field the write is
promoted to a conditional REPLACE that requires the stored
revision to match. The driver stamps a fresh revision back onto
document on success in that case.
:param document: A dict (wrapped automatically) or a
:class:Document instance.
:raises ResourceNotFoundException: If a revision was supplied
and the stored revision does not match (or the row is
absent).
delete
¶
Delete the row identified by document's primary key.
When document carries the revision field the delete is
conditional on the stored revision matching.
:param document: A dict (wrapped automatically) or a
:class:Document carrying the primary key.
:raises ResourceNotFoundException: If a revision was supplied
and the stored revision does not match.
get
¶
Read a row by its primary key and merge fields into document.
The document's primary-key attributes are used as the lookup
key; retrieved attributes are written back onto document
in place.
:param document: A dict (wrapped automatically) or a
:class:Document instance carrying the primary key.
:param field_paths: Optional dotted projection paths (e.g.
"a.b.c"). Empty means "return the full item".
batch_get
¶
Read many rows in a single :class:ActionList run.
Each document must carry its primary key; retrieved attributes
are merged back onto the same document instances in place.
Projection is not supported here — use :meth:actions for
per-row field_paths.
:param documents: Iterable of dict / :class:Document items.
batch_put
¶
Upsert many rows in a single :class:ActionList run.
Each row is inserted if absent or overwritten if present, using
the same revision-aware semantics as :meth:put.
:param documents: Iterable of dict / :class:Document items.
batch_delete
¶
Delete many rows in a single :class:ActionList run.
Each document must carry its primary key. When a document carries
the revision field, that delete is conditional on the stored
revision matching — same semantics as :meth:delete.
:param documents: Iterable of dict / :class:Document items.
Action
dataclass
¶
Action(
kind: ActionKind,
document: Document,
field_paths: Optional[List[List[str]]] = None,
mods: Optional[List[Any]] = None,
in_atomic_write: bool = False,
key: Any = None,
index: int = 0,
)
A single pending operation on a document.
A value type produced by the fluent :class:ActionList and consumed
by the driver's :meth:BaseDocStore.run_actions.
key and index are populated by
:meth:BaseDocStore._to_driver_action and used by
:func:group_actions to keep the caller-supplied order.
ActionKind
¶
Bases: Enum
The kind of write / read that an :class:Action represents.
ActionList
¶
Fluent builder for a batch of document operations.
Users call .create(doc) (etc.) any number of times, then
.run(). run() first shapes each pending action via
:meth:BaseDocStore._to_driver_action (which assigns keys and
validates), then dispatches the whole batch through
:meth:BaseDocStore.run_actions.
create
¶
Queue a CREATE action for document.
CREATE inserts a new row and fails with
:class:ResourceAlreadyExistsException at :meth:run time if
the key already exists. The document must not carry the
revision field; the driver stamps a fresh revision on success.
:param document: A dict (wrapped automatically) or a
:class:Document.
:return: This :class:ActionList for fluent chaining.
replace
¶
Queue a REPLACE action for document.
REPLACE requires the row to already exist. If document
carries a revision, the write additionally asserts that the
stored revision matches; the driver stamps a fresh revision on
success.
:param document: A dict (wrapped automatically) or a
:class:Document.
:return: This :class:ActionList for fluent chaining.
put
¶
Queue a PUT (upsert) action for document.
PUT is an unconditional upsert. When document carries the
revision field the action is promoted to REPLACE by
:meth:BaseDocStore._to_driver_action, adding a
matching-revision precondition.
:param document: A dict (wrapped automatically) or a
:class:Document.
:return: This :class:ActionList for fluent chaining.
delete
¶
Queue a DELETE action for document.
The document's primary-key attributes are used as the target
key. When document carries the revision field the write
additionally asserts that the stored revision matches.
:param document: A dict (wrapped automatically) or a
:class:Document carrying the primary key.
:return: This :class:ActionList for fluent chaining.
get
¶
Queue a GET action for document with optional field projection.
The document's primary-key attributes are used as the lookup
key; retrieved attributes are merged back into it in place at
:meth:run time.
:param document: A dict (wrapped automatically) or a
:class:Document carrying the primary key.
:param field_paths: Optional dotted projection paths (e.g.
"a.b.c"). Empty means "return the full item".
:return: This :class:ActionList for fluent chaining.
run
¶
Validate every queued action and dispatch the batch.
First shapes each pending action via
:meth:BaseDocStore._to_driver_action (assigns keys, promotes
PUT-with-revision to REPLACE, rejects duplicates), then hands
the whole list to :meth:BaseDocStore.run_actions. Any
provider-side error surfaces as a
:class:SubstrateSdkException; unexpected exceptions are
re-raised as :class:InvalidArgumentException.
:raises SubstrateSdkException: Any translated backend error.
BaseDocStore
¶
BaseDocStore(
collection_options: CollectionOptions,
*,
credentials_overrider: Optional[
Callable[..., Any]
] = None
)
Bases: Provider, ABC
Abstract driver a provider (e.g. the AWS provider) implements.
Owns the collection options, the internal executor used to fan action lists out to their backend, and the CREATE-path helpers that are agnostic of the backing store (key extraction, validation, executor sizing).
get_key
¶
Extract the primary key from document.
Returns None when the partition key is missing so the CREATE
path can decide whether to synthesize a UUID. On a table with a
sort key, both parts must be present or the result is None.
:param document: The document being written or read.
:return: The raw partition-key value when no sort key is
configured, a (pk, sk) tuple when one is, or None
when a required part is missing.
run_actions
abstractmethod
¶
run_actions(
actions: Sequence[Action],
before_do: Optional[
Callable[[Callable[[Any], bool]], None]
] = None,
) -> None
Execute a driver-shaped list of actions.
CollectionOptions
dataclass
¶
CollectionOptions(
table_name: str,
partition_key: str,
sort_key: Optional[str] = None,
allow_scans: bool = True,
revision_field: Optional[str] = None,
max_outstanding_action_rpcs: int = 0,
)
Immutable configuration for a document collection (table).
table_name names the underlying table or collection,
partition_key / sort_key name the primary key attributes,
allow_scans gates full-table scans on the read path,
revision_field is the attribute used for optimistic concurrency
control (empty ⇒ use :data:DEFAULT_REVISION_FIELD), and
max_outstanding_action_rpcs bounds the internal thread pool that
services :meth:BaseDocStore.run_actions (0 ⇒ pick a sensible
default).
Document
¶
Wraps either a dict or a plain object with attributes.
Provides the operations the driver needs on the caller's data: reading a top-level field, setting a top-level field, walking nested dotted paths, and enumerating field names for encoding.
A Document never represents an atomic value on its own — it is
always a container of named fields.
get
¶
Read a nested field by dotted-path parts.
Traverses dict values by key and objects by attribute; a
missing segment short-circuits to None instead of raising.
:param field_path: Path segments; ["a", "b", "c"] walks
source["a"]["b"]["c"].
:return: The leaf value, or None if any segment is missing.
set
¶
Write a value at a nested dotted path, creating intermediates.
Any missing intermediate is replaced with a fresh dict so
the write always succeeds when field_path is non-empty. On
object sources, intermediates are set via setattr.
:param field_path: Path segments; must be non-empty.
:param value: Leaf value to store at the last segment.
:raises InvalidArgumentException: If field_path is empty.
group_actions
¶
group_actions(
actions: Sequence[Action],
) -> Tuple[
List[Action],
List[Action],
List[Action],
List[Action],
List[Action],
]
Split an action list into five buckets, preserving user-provided order.
Returns (before_gets, get_list, write_list, atomic_write_list,
after_gets).
Any GET targeting the same key as a pending write becomes an
after_gets (must run after the write); any GET whose key is
later written by a non-atomic write is promoted to before_gets.
Actions with a None key stream through to the write bucket
directly (they will be assigned a key later on the CREATE path).
group_by_field_path
¶
Group GET actions with identical field-path sets into batches.
Backend batch-get APIs typically accept only a single projection per request, so gets that project different fields cannot ride in the same batch.
serialize_object
¶
Serialize an object into a stable string for key comparison.
Used as the dedup key across an action list — two actions targeting the same key must produce the same string here even if the caller passed a fresh instance.
validate_field_path
¶
Validate that field_path is non-empty and has no empty segments.