ServicesCatalog

Select an Exact State

Pin a branch head or resolve a tag to one commit, then read Tables at that commit.

Available

A training run that reads frames on Monday and again on Tuesday should see the same rows, even if someone appends in between. To guarantee that, resolve your branch or tag to one commit ID up front and read every Table through it. Table versions never change, so the commit ID is also the record that lets you rerun the job later.

Before you start

  • A Project demo with the Table frames.
  • An access token in $SPIRAL_TOKEN. See authentication.
  • For Rust, a configured Client. See the Rust SDK.

Pin a branch head

Read the branch to get its stable ID and its current head commit.

head = client.project("demo").branch("experiment")
print(f"experiment head: {head.commit_id}")
for page in client.catalog.read_state_pages("demo", head.commit_id):
    for resource in page.resources:
        descriptor = resource.descriptor
        print(f"{descriptor.kind} {descriptor.resource_id} at version {resource.version_id}")

The head commit stays valid after the branch moves. Use it for every read in the same workflow.

Resolve a tag to a commit

Send a commit selector. A selector names a commit, a branch, or a tag. The Catalog resolves it once and returns the commit ID.

request = CatalogResolveCommitRequest(selector=CatalogCommitSelector(tag=CatalogTagTarget(tag="training-v7")))
resolved = client.catalog.resolve_commit("demo", request)
print(f"training-v7 is {resolved.commit_id}")

For a branch, send {"type": "branch", "branch": {"branch": "main"}}. For a commit, send {"type": "commit", "commit": {"commitId": "..."}}. Relative expressions such as main~3 are not supported.

The Rust SDK does not resolve tags. Resolve the tag with another client, then use the commit ID in Rust.

Read Tables at the commit

Resolve a Resource path at the commit to get its exact version:

tables = client.project("demo").branch("main")
on_branch = tables.table("frames@experiment")
at_commit = tables.table(f"frames@c{commit}")
print(f"experiment selects {on_branch.version_id}")
print(f"the commit selects {at_commit.version_id}")

rows = at_commit.scan(limit=10).to_table().num_rows

In Python and Rust, a Table address has an optional reference after @:

AddressSelects
framesThe default snapshot of the Table session
frames@experimentThe head of experiment, pinned on first use
frames@c<commit>The Table at one Project commit
frames@v<version>One exact Table version

A commit or version reference is c or v followed by the ID as 32 lowercase hexadecimal digits, without dashes. HTTP returns IDs with dashes, so remove them first. See Addresses.

Verify the result

Read frames@c<commit> before and after another writer publishes on the branch. Both reads return the same Table version. A new Table session with a branch address, such as frames@main, returns the new head.

Troubleshooting

ErrorCause
BranchNotFoundThe branch name does not exist, or the branch was deleted.
TagNotFoundThe tag name does not exist in this Project.
CommitNotFoundThe commit ID does not belong to this Project.
resource not found (Rust)The path has no binding at the selected commit.

To read the Tables with SQL, register the Table session with DataFusion.

Found a problem? Edit this page or report an issue.

On this page