Skip to main content

Python SDK for the SnapState workflow state persistence service

Project description

snapstate-sdk (Python)

Python SDK for the Checkpoint Service — a workflow state persistence API that lets AI agents save and resume multi-step work across interruptions, crashes, and handoffs between agents.

Installation

pip install snapstate-sdk

Requires Python 3.9+ and httpx>=0.25.0 (installed automatically).

Quick start (sync)

from snapstate_sdk import SnapStateClient

client = SnapStateClient(
    api_key="snp_your_key_here",
    base_url="http://localhost:3000",
)

# Save state after each step
result = client.save(
    workflow_id="wf_research_001",
    step=1,
    label="sources_gathered",
    state={"sources": ["arxiv.org/123"], "progress": 0.25},
)
print(f"Saved: {result.checkpoint_id} (etag: {result.etag})")

# Resume a workflow — get the latest state
resumed = client.resume("wf_research_001")
print(f"Resuming from step {resumed.latest_checkpoint.step}")
state = resumed.latest_checkpoint.state

# Get full checkpoint history
history = client.replay("wf_research_001")
for cp in history.checkpoints:
    print(f"  Step {cp.step}: {cp.label}")

client.close()

Async usage

Every method has an async_ prefixed equivalent:

import asyncio
from snapstate_sdk import SnapStateClient

async def main():
    client = SnapStateClient(api_key="snp_...", base_url="http://localhost:3000")

    result = await client.async_save(
        workflow_id="wf_001",
        step=1,
        state={"status": "running"},
    )
    print(f"Saved: {result.checkpoint_id}")

    resumed = await client.async_resume("wf_001")
    print(f"Latest step: {resumed.latest_checkpoint.step}")

    await client.async_close()

asyncio.run(main())

Context managers are supported for both sync and async usage:

# Sync
with SnapStateClient(api_key="snp_...") as client:
    client.save(workflow_id="wf_001", step=1, state={})

# Async
async with SnapStateClient(api_key="snp_...") as client:
    await client.async_save(workflow_id="wf_001", step=1, state={})

Agent identity

Register your agent once at startup, then tag checkpoints with agent_id:

client = SnapStateClient(api_key="snp_...", base_url="http://localhost:3000")

# Register agent identity
client.register_agent(
    agent_id="research-bot",
    name="Research Bot",
    description="Searches and summarizes sources",
    capabilities=["web_search", "summarization"],
    metadata={"model": "claude-sonnet-4-6", "version": "2.0.0"},
)

# Tag checkpoints with agent identity
client.save(
    workflow_id="wf_collab_001",
    step=1,
    state={"findings": [...]},
    agent_id="research-bot",    # identity tag
)

# Another agent picks up the workflow
resumed = client.resume("wf_collab_001")
prior_agent = resumed.latest_checkpoint.metadata.get("agent_id")
print(f"Picking up from: {prior_agent}")

Error handling

from snapstate_sdk import SnapStateClient
from snapstate_sdk.errors import (
    AuthError,
    NotFoundError,
    ConflictError,
    RateLimitError,
    PayloadTooLargeError,
    ValidationError,
    SnapStateError,  # base class
)

client = SnapStateClient(api_key="snp_...", base_url="http://localhost:3000")

try:
    resumed = client.resume("wf_missing")
except NotFoundError:
    print("No prior state — starting fresh")

try:
    client.save(
        workflow_id="wf_001",
        step=2,
        state={"data": "..."},
        if_match="old-etag",       # optimistic concurrency
    )
except ConflictError:
    print("State was modified by another agent — re-read and retry")

try:
    client.save(workflow_id="wf_001", step=1, state={})
except AuthError:
    print("Check your API key")
except RateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}s")
except PayloadTooLargeError:
    print("State exceeds 1 MB limit — consider compressing")
except SnapStateError as e:
    print(f"Unexpected error: {e} (HTTP {e.status_code}, code={e.code})")

API reference

SnapStateClient(api_key, base_url, timeout, max_retries)

Parameter Type Default Description
api_key str required API key starting with snp_
base_url str http://localhost:3000 Checkpoint Service base URL
timeout float 30.0 Request timeout in seconds
max_retries int 3 Retry attempts on 429 before raising RateLimitError

Checkpoint methods

save(workflow_id, step, state, label, metadata, agent_id, ttl_seconds, if_match) → SaveResult

Save state for a workflow step.

Parameter Type Default Description
workflow_id str required Unique workflow identifier
step int required Sequential step number
state dict required Full state to persist (max 1 MB)
label str None Human-readable step label
metadata dict None Arbitrary metadata
agent_id str None Agent identity tag
ttl_seconds int None Override default TTL
if_match str None ETag for optimistic concurrency

Returns SaveResult(checkpoint_id, workflow_id, step, etag, created_at, diff_from_previous, size_bytes).

get(checkpoint_id) → Checkpoint

Fetch a specific checkpoint by ID.

resume(workflow_id) → WorkflowResume

Get the latest checkpoint for a workflow. Raises NotFoundError if no checkpoints exist.

Returns WorkflowResume(workflow_id, latest_checkpoint, total_checkpoints, workflow_started_at, last_activity_at).

replay(workflow_id, from_step, to_step, limit) → WorkflowReplay

Get the full ordered checkpoint history.

Returns WorkflowReplay(workflow_id, checkpoints, total, has_more).


Agent methods

register_agent(agent_id, name, description, capabilities, metadata) → Agent

Register or update an agent (upsert). Safe to call on every startup.

list_agents() → list[Agent]

List all agents for this account.


Webhook methods

register_webhook(url, events, secret) → dict

Register a webhook URL. events is a list of checkpoint.saved, workflow.resumed, workflow.expired.


Lifecycle

close()

Close the sync HTTP client.

async_close()

Close the async HTTP client.


Async equivalents

Every method above has an async_ prefixed version: async_save, async_get, async_resume, async_replay, async_register_agent, async_list_agents.


Return types

Type Fields
Checkpoint checkpoint_id, workflow_id, step, label, state, metadata, etag, created_at, diff_from_previous, size_bytes, agent_id
WorkflowResume workflow_id, latest_checkpoint, total_checkpoints, workflow_started_at, last_activity_at
WorkflowReplay workflow_id, checkpoints, total, has_more
Agent agent_id, name, description, capabilities, metadata, last_seen_at, created_at
SaveResult checkpoint_id, workflow_id, step, etag, created_at, diff_from_previous, size_bytes

Error types

Exception HTTP status When raised
AuthError 401 Invalid or missing API key
NotFoundError 404 Resource not found
ConflictError 409 ETag mismatch (optimistic concurrency)
PayloadTooLargeError 413 State exceeds 1 MB
RateLimitError 429 Rate limit exceeded after all retries
ValidationError 400 Invalid input
SnapStateError any Base class for all SDK errors

All exceptions expose .status_code (int) and .code (str, machine-readable error code).
RateLimitError additionally exposes .retry_after (int, seconds).

Running tests

pip install "snapstate-sdk[dev]"
pytest tests/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snapstate_sdk-1.0.0.tar.gz (18.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snapstate_sdk-1.0.0-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file snapstate_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: snapstate_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 18.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for snapstate_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 75b141e7a98450a60852b7ec695e2b7295518377e5f0bf96cf17049cb5ac44a4
MD5 07a3760b67e37d4be28909a9c4ac3cb8
BLAKE2b-256 8d5182fb7680c4d83db81e9e4560eac74706813536c105e94eeef49a6cfba1f4

See more details on using hashes here.

File details

Details for the file snapstate_sdk-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: snapstate_sdk-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 17.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for snapstate_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c9cb74da4816def740b412714666b909da07365be0b93ac0ce05b6dc7abd2034
MD5 7a101fa58c0ff52b899ec48a2744034e
BLAKE2b-256 5869ba7d275545fa86af5fa762ac18d31719276731629d0bff3f3d12abb4bc0c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page