Skip to main content

VSwarm Python SDK

The VSwarm Python SDK provides typed, asynchronous access to VSwarm workspaces, sandboxes, processes, browser sessions, traces, artifacts, and runtime APIs.

Install the published SDK from PyPI:

pip install vswarm

For local VSwarm monorepo development, install this SDK in editable mode:

pip install -e "sdks/python[test]"

The Python SDK is distributed under the Apache License 2.0. That license applies to this SDK distribution; it does not change the licensing or visibility of the VSwarm server, gateway, deployment, or other private monorepo components.

Recommended browser sandbox flow:

from vswarm import Admission, BrowserPolicy, RequestOptions, Viewport, VSwarmClient

async with VSwarmClient(base_url="http://127.0.0.1:8080", token="secret") as client:
    async with client.browser.session(
        template="browser-chromium",
        policy=BrowserPolicy(allowed_domains=["example.com"]),
        viewport=Viewport(width=1440, height=900),
        admission=Admission.fail_fast(),
    ) as browser:
        obs = await browser.observe_for_agent(screenshot=True, compact_elements=True)

        await browser.click(
            obs.element(text="Go"),
            observe_after=True,
            observation={"include": {"screenshot": True, "dom": True}},
        )

This is the primary SDK UX: the SDK asks VSwarm to create an owned browser session, the server creates or claims the sandbox, and cleanup is automatic on success, error, or cancellation. If the server has a compatible warm browser-chromium sandbox available, this path can avoid cold container startup. client.browser_session(...) remains as a compatibility alias for the same owned workflow.

Production services that create a session in one request and destroy it later can use detached owned session creation while still relying on SDK cleanup semantics:

browser = await client.browser.create_session(
    template="browser-chromium",
    policy=BrowserPolicy(allowed_domains=["example.com"]),
    viewport=Viewport(width=1440, height=900),
    admission=Admission.queue(timeout_seconds=30),
    options=RequestOptions(request_id="agent-task-create-123"),
)

try:
    obs = await browser.observe_for_agent(
        options=RequestOptions(request_id="agent-task-observe-123"),
    )
finally:
    await browser.cleanup(missing_ok=True)

RequestOptions.request_id sets X-VSwarm-Request-ID for correlation. It does not imply idempotency.

Workspace and sandbox creation support explicit, persisted idempotency keys. Reusing a key with equivalent normalized input returns the original resource with idempotent_replay=true; reusing it with different input raises VSwarmConflictError with code idempotency_conflict. This makes a caller-controlled retry after an ambiguous transport failure safe:

async with VSwarmClient(
    base_url="http://vswarm.internal:8080",
    token="secret",
    connect_timeout=10,
    timeout=60,
) as client:
    workspace = await client.workspaces.create(
        client_action_id="my-service:operation-123:workspace",
        source={"type": "empty"},
    )
    sandbox = await client.sandboxes.create(
        client_action_id="my-service:operation-123:sandbox",
        template="base-ubuntu",
        workspace={"id": workspace.id, "mount_path": "/workspace", "mode": "read_write"},
    )

The SDK does not retry creates automatically. Callers should retry only operations carrying a stable idempotency key, and should keep retry counts bounded.

Advanced lifecycle control is still available when a caller needs to attach browser sessions to a long-lived sandbox:

sandbox = await client.sandboxes.create(template="browser-chromium")
browser = await sandbox.browser.sessions.create(policy=BrowserPolicy(block_localhost=True))
try:
    obs = await browser.observe()
    await browser.action("click", target={"selector": "button"})
finally:
    await browser.close()
    await sandbox.destroy()

One-shot run execution uses the canonical runs namespace:

result = await client.runs.execute(
    template="code-runner-multilang",
    profile="python",
    files={"/workspace/main.py": "print(input())"},
    stdin="hello",
    timeout_seconds=20,
)

Run-scoped trace context is available through the canonical traces namespace and the client.trace(...) async context manager:

async with VSwarmClient(base_url="http://127.0.0.1:8080", token="secret") as client:
    async with client.trace(name="browser-login-task", capture_profile="debug", client_run_id="eval-42") as trace:
        await trace.event("client.agent.step.started", {"step": "open-login"}, step_id="step-open-login")

        async with client.browser.session(template="browser-chromium", trace=trace) as browser:
            obs = await browser.observe_for_agent()
            await browser.click(obs.element(text="Sign in"), observe_after=True)

        await trace.download_bundle("vswarm-trace-browser-login-task.zip")

While a trace context is active, the SDK propagates X-VSwarm-Trace-ID, X-VSwarm-Client-Run-ID, and optional step/parent headers on VSwarm calls. Client-side events stay under client.* ownership and are stored alongside VSwarm runtime/browser/artifact events in the same ordered trace.

Available SDK surface:

  • VSwarmClient.health()
  • VSwarmClient.browser_capacity()
  • VSwarmClient.reconcile_browser()
  • client.browser.session(...)
  • client.browser.create_session(...)
  • client.browser.capacity()
  • client.browser.reconcile()
  • client.browser.attach(...)
  • client.browser_session(...)
  • client.runs.execute(...)
  • client.trace(...)
  • client.traces.create/list/get/events/artifacts/export/download_bundle(...)
  • client.templates.list() and client.templates.get(name)
  • client.sandboxes.create(...), get(id), and destroy(id)
  • sandbox.exec(...)
  • sandbox.files.list/read/write(...)
  • sandbox.browser.sessions.create(...) and sandbox.browser.create_session(...)
  • typed browser.observe(...) returning BrowserObservation
  • browser.observe_for_agent(...)
  • typed helpers: browser.navigate, click, double_click, hover, fill, type, press, scroll, drag, select_option, wait, get_text, find_text, extract_page, extract_section, capture_page, query_elements, screenshot, upload_file, evaluate
  • typed browser.act(...) for browser action objects
  • raw browser.action(...) escape hatch
  • browser.batch(...)
  • browser.actions() and browser.observations()
  • browser.cleanup(missing_ok=True), browser.close(missing_ok=True), and public browser.sandbox_id / browser.session_id
  • observation.compact_elements() and observation.element(...)
  • browser.latest_screenshot_base64(observation)
  • client.artifacts.get(id), download_bytes(id), and download_base64(id)

Workspace capability contract

client.contract_version is currently workspace.v1, and client.sdk_surface_descriptor describes the methods and models implemented by this SDK release. It is a static SDK-surface descriptor, not a claim about the connected server. The descriptor is immutable and can also be imported as SDK_SURFACE_CAPABILITIES. client.capability_descriptor and WORKSPACE_CAPABILITIES remain backward-compatible aliases. Use await client.features() or server-specific discovery to inspect capabilities reported by the connected server.

Methods present in 0.1.0 continue to return ordinary mutable dictionaries. Additive methods ending in _typed return detached, recursively immutable response models that also support mapping-style reads such as process["state"]:

  • client.workspaces.list_typed and workspace.usage_typed
  • client.sessions.list_typed/get_typed plus close
  • client.sandboxes.list_typed and sandbox.exec_typed
  • sandbox.files.list_typed/stat_typed/search_typed
  • process, runtime-state, listener, process-group, and log *_typed methods
  • route, preview attachment, PTY, artifact, and event *_typed methods

native_process_restart is False in the SDK-surface descriptor. The existing ProcessClient.restart helper is a compatibility composition that stops a process group and starts a new process; it is not an identity-preserving server restart operation. The SDK parser supports runtime-state contract version 4, including aggregate version and runtime_generation_version fields.

Request helpers build detached payloads and do not mutate caller-owned command, intent, endpoint, metadata, or options mappings.

Snapshots are intentionally reported as unsupported in workspace.v1: VSwarm does not currently expose a public workspace snapshot API. Worker administration, deployment administration, billing, and future snapshot/restore operations are also outside this SDK contract until corresponding public APIs are available. The SDK does not issue raw fallback requests for these future capabilities.

The default transport uses httpx.AsyncClient lazily. Tests and downstream apps can inject a fake async transport with a compatible request(...) method.

browser.observe_for_agent(...) is the bounded prompt/multimodal path. It sends server-side limits for max_elements, max_dom_bytes, and max_screenshot_bytes, requests compact elements, and only asks for screenshot base64 when screenshot_base64=True.

Browser actions return BrowserActionResult objects for page-state failures as well as successes. Recoverable failures such as stale_element_ref, selector_not_found, action_timeout, and policy_blocked are exposed through result.code, result.message, and result.recoverable.

Admission and capacity

Browser sessions support typed admission options:

async with client.browser.session(
    template="browser-chromium",
    admission=Admission.fail_fast(),
) as browser:
    ...
async with client.browser.session(
    template="browser-chromium",
    admission=Admission.queue(timeout_seconds=30),
) as browser:
    ...

Capacity can be inspected before or after requests:

capacity = await client.browser.capacity(template="browser-chromium")
print(capacity.available_slots)
print(capacity.raw.get("warm_pool_ready"))

Capacity failures expose retry metadata when the server provides it:

from vswarm import VSwarmCapacityError

try:
    async with client.browser.session(admission=Admission.fail_fast()) as browser:
        ...
except VSwarmCapacityError as exc:
    print(exc.retry_after_seconds)
    print(exc.capacity)

Run the live local browser smoke test against a running VSwarm API:

PYTHONPATH=sdks/python python sdks/python/scripts/live_browser_smoke.py --api http://127.0.0.1:8080

Compatibility and releases

The SDK requires Python 3.10 or newer. Public SDK versions follow Semantic Versioning. While the SDK remains on the 0.x release line, minor releases may intentionally evolve provisional APIs; patch releases remain backward-compatible.

Use min_api_version with compatibility="strict" when an application must fail closed against an older VSwarm API:

async with VSwarmClient(
    base_url="https://api.example.com",
    token="secret",
    min_api_version="0.1.0",
    compatibility="strict",
) as client:
    await client.health()

License

The VSwarm Python SDK is licensed under the Apache License 2.0. This SDK license does not apply to the private VSwarm server or other monorepo components.

Download files

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

Source Distribution

vswarm-0.1.1.tar.gz (51.4 kB view details)

Uploaded Source

Built Distribution

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

vswarm-0.1.1-py3-none-any.whl (52.7 kB view details)

Uploaded Python 3

File details

Details for the file vswarm-0.1.1.tar.gz.

File metadata

  • Download URL: vswarm-0.1.1.tar.gz
  • Upload date:
  • Size: 51.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for vswarm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c42c492d3703d37834206b4a5eaf2dcb7a6108bd826f57ad98d5dceb610155c1
MD5 1a4f3fd0561911eadd219d19c984fb89
BLAKE2b-256 f20b92eb83b1618bb1f0f343947fe06e05b003e35cd54626e73f4740358867ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for vswarm-0.1.1.tar.gz:

Publisher: python-sdk-release.yml on akshaypainjane/vswarm

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

File details

Details for the file vswarm-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: vswarm-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 52.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for vswarm-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c8b7e03f14a9de2646bc8fb3e4d2bd49fdcdff79f7b4e09afa96237240f80f8
MD5 f5ae8eec48c4a42a2f1fdcd71394ffa9
BLAKE2b-256 893871a65a9b0a19d91dcea0926c6f0e36c5fb139d52e67e19d94c1a9ca952ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for vswarm-0.1.1-py3-none-any.whl:

Publisher: python-sdk-release.yml on akshaypainjane/vswarm

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 Sentry Error logging StatusPage Status page