Skip to main content

Python SDK for the ExternalSoul platform — programmatic workspace mutation, event-sourced, audit-logged.

Project description

esoul — Python SDK for ExternalSoul

esoul is the official Python SDK for the ExternalSoul platform. It lets scripts mutate workspace state from anywhere Python runs — inside the platform's E2B sandboxes, on a data scientist's laptop, in a Colab notebook, in CI, in a scheduled cron job.

pip install esoul
import esoul

client = esoul.Esoul()                       # auto-detects credentials
state = client.describe()                    # what workspaces + apps + events are available
print(state.session.workspace_ids)

# Low-level dispatch
result = client.dispatch_event(
    app_id="app_abc123",
    event_name="spreadsheet_add_row",
    event_data={"cells": {"name": "Alice", "email": "a@example.com"}},
)
print(result.event_id, result.sequence_num)

Why an SDK?

ExternalSoul workspaces are event-sourced — every state mutation is a typed event on a per-workspace timeline, scrubbable and forkable. The UI, agents, and now scripts all dispatch through the same reducers; events are the source of truth, audit logging is automatic.

The SDK is the platform's universal binding for scripted workspace operations. Common use cases:

  • Bulk-import 1000 rows into a spreadsheet (one event, not 1000 LLM tool calls)
  • Run an OpenCV pipeline over Drive images and write masks back
  • Programmatic kanban / contacts load from a CSV
  • Notebook-as-workspace-builder
  • Any agent or human writing Python to mutate app state

Authentication

esoul.Esoul() auto-detects credentials in this order:

  1. Explicit token= kwarg
  2. ESOUL_TOKEN environment variable
  3. /var/run/esoul/token (the file mode 0600 token written by every E2B sandbox at boot — Esoul() inside a sandbox Just Works)
  4. ~/.config/esoul/credentials (TOML file with a [default] section containing token = "esoul_pat_...")

For off-platform use (laptop, CI), create a Personal Access Token in workspace settings → "Access Tokens", pick the workspaces it can mutate, copy the token (shown once), and either:

# Export inline:
export ESOUL_TOKEN="esoul_pat_..."

# Or write to ~/.config/esoul/credentials:
mkdir -p ~/.config/esoul
cat > ~/.config/esoul/credentials <<EOF
[default]
token = "esoul_pat_..."
EOF
chmod 600 ~/.config/esoul/credentials

Workspace isolation

A given credential is scoped to one or more specific workspaces. Cross- workspace dispatch is structurally impossible — not a permission check in your script, an architectural invariant of the server.

Idempotency

Every write is automatically idempotent. The SDK generates a UUID per call and reuses it across retries; the server caches the response under (session, key) for 24h. Same key + same body → identical cached response, not a duplicate event. You can override the key for application-level retry control:

client.dispatch_event(
    app_id=...,
    event_name=...,
    event_data=...,
    idempotency_key="my-task-2026-05-15",  # caller-controlled
)

Async client

The async client mirrors the sync API exactly:

import asyncio
import esoul

async def main():
    async with esoul.AsyncEsoul() as client:
        result = await client.dispatch_event(
            app_id=..., event_name=..., event_data=...,
        )

asyncio.run(main())

Typed errors

Failures surface as Python exception classes mapped from the server's error.code. You can catch the kind you care about, and EsoulError catches everything:

import esoul

try:
    client.dispatch_event(...)
except esoul.WorkspaceAccessDenied as e:
    print(f"This token cannot reach workspace {e.details['workspaceId']}")
except esoul.IdempotencyConflict as e:
    print("Same key was used with a different request body")
except esoul.RateLimitError as e:
    time.sleep(e.retry_after_seconds or 1)
except esoul.AuthError:
    print("Token expired or revoked — get a new one")
except esoul.EsoulError as e:
    print(f"{e.code}: {e.message}")

Status

v0.1 — alpha. Wire surface is stable; per-app typed resources are codegen'd and shipping incrementally. The low-level dispatch_event / dispatch_batch / read_state paths are production-ready.

See CHANGELOG.md for release notes.

License

MIT.

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

esoul-0.1.0.tar.gz (36.3 kB view details)

Uploaded Source

Built Distribution

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

esoul-0.1.0-py3-none-any.whl (42.9 kB view details)

Uploaded Python 3

File details

Details for the file esoul-0.1.0.tar.gz.

File metadata

  • Download URL: esoul-0.1.0.tar.gz
  • Upload date:
  • Size: 36.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for esoul-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a12d2708c4ab8a251f462ca605d5f82b020d8e4e332a72d89f611525eb740a5c
MD5 2980895d6f46a8993e8d81ed920ed4c1
BLAKE2b-256 ad162ae762cf6ab8679a78a5a8ca1cfc9123ca64ec5f8924584703476eb4b107

See more details on using hashes here.

Provenance

The following attestation bundles were made for esoul-0.1.0.tar.gz:

Publisher: publish.yml on vyomkeshj/esoul-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file esoul-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: esoul-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 42.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for esoul-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dbca60c91c05777d6f2268b45be46ccf4416c3a2709d15cc3b03e0a216b5c939
MD5 9ed190e69c9a1223fe78969c3f305b6d
BLAKE2b-256 46a92931f65916c2734d58869475f5fba1346b5ed68daf3d021c1e0ae948da2d

See more details on using hashes here.

Provenance

The following attestation bundles were made for esoul-0.1.0-py3-none-any.whl:

Publisher: publish.yml on vyomkeshj/esoul-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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