Skip to main content

CreateOS Python SDK

Launch an isolated cloud sandbox, run real commands, stream output, move files, open a preview URL, and tear everything down from Python.

Your first sandbox

pip install createos-sandbox

Python 3.10 or newer is required.

from createos import Client, CreateSandboxRequest, RunCommandRequest


with Client(api_key="your-api-key") as client:
    sandbox = client.create_sandbox(
        CreateSandboxRequest(
            name="hello-python",
            shape="s-4vcpu-4gb",
            rootfs="devbox:1",
        )
    )
    try:
        response = sandbox.run_command(
            RunCommandRequest(
                command="sh",
                arguments=[
                    "-c",
                    'printf "Python says hello from $(uname -m)\\n"',
                ],
            )
        )
        print(response.result.standard_output, end="")
    finally:
        sandbox.destroy()
Python says hello from x86_64

Do not commit a real API key to source control; inject it through your application's secret manager. You can configure the endpoint and default request timeout when constructing the client:

client = Client(
    api_key=api_key,
    base_url="http://localhost:8080",
    timeout=30,
)

As an alternative, Client() reads CREATEOS_SANDBOX_API_KEY and CREATEOS_SANDBOX_BASE_URL. Explicit constructor arguments take precedence.

Documentation

Stream output as it happens

Long-running commands do not need to disappear behind a buffered HTTP call:

import sys

from createos import ExecStreamEventType, RunCommandRequest


request = RunCommandRequest(
    command="sh",
    arguments=[
        "-c",
        'for n in 1 2 3; do echo "step $n"; sleep 1; done',
    ],
)

with sandbox.stream_command(request) as stream:
    for event in stream:
        if event.type is ExecStreamEventType.STDOUT:
            print(event.data, end="")
        elif event.type is ExecStreamEventType.STDERR:
            print(event.data, end="", file=sys.stderr)
        elif event.type is ExecStreamEventType.EXIT:
            print(f"exit code: {event.exit_code}")

Stopping early is safe: leaving the with block closes the response body and releases the underlying HTTP connection.

Move files without shell escaping

sandbox.files.upload(
    "/workspace/config.json",
    b'{"mode":"production"}',
)

with sandbox.files.download("/workspace/config.json") as download:
    contents = download.read()

upload() also accepts a binary file-like object, allowing large files to be transferred without reading them all into memory first.

Keep a process alive after disconnecting

Managed processes are resources rather than fragile terminal sessions. Start one, reconnect from its output sequence, send input or signals, and wait for either the leader or its complete process tree:

from createos import (
    ManagedProcessCreateRequest,
    ManagedProcessWaitOptions,
    ManagedProcessWaitScope,
)


process = sandbox.processes.create(
    ManagedProcessCreateRequest(
        command="sh",
        arguments=["-c", "sleep 1; echo managed process finished"],
    )
)

finished = sandbox.processes.wait(
    process.process_id,
    ManagedProcessWaitOptions(
        scope=ManagedProcessWaitScope.TREE,
        wait_timeout=30,
    ),
)

Turn a service into a URL

Create a sandbox with ingress enabled, wait for the server to listen, then ask the instance for its public URL:

from createos import CreateSandboxRequest, ManagedProcessCreateRequest


sandbox = client.create_sandbox(
    CreateSandboxRequest(
        shape="s-4vcpu-4gb",
        rootfs="devbox:1",
        ingress_enabled=True,
    )
)

sandbox.processes.create(
    ManagedProcessCreateRequest(
        command="python3",
        arguments=[
            "-m",
            "http.server",
            "8080",
            "--bind",
            "0.0.0.0",
        ],
    )
)

sandbox.wait_for_port(8080, host="127.0.0.1", timeout=15)
print(sandbox.preview_url(8080))

Everything is already connected

Account-level services are initialized by Client:

templates = client.templates
networks = client.networks
disks = client.disks

custom_templates = templates.list()
print(
    f"{len(custom_templates)} templates ready; "
    f"networks={type(networks).__name__} disks={type(disks).__name__}"
)

Instance-level services are initialized when a sandbox handle is created or retrieved:

sandbox.files
sandbox.processes
sandbox.computer.mouse
sandbox.computer.keyboard
sandbox.computer.windows
sandbox.computer.screens

Connect sandboxes on a private network

Create an overlay network, attach a running sandbox, and inspect the resulting membership. Cleanup runs in reverse order, so the sandbox detaches before the network is deleted:

from createos import NetworkCreateRequest


network = client.networks.create(NetworkCreateRequest(name="agent-mesh"))
try:
    sandbox.attach_network(network.id)
    try:
        connected = client.networks.get(network.id)
        for member in connected.members:
            print(
                f"sandbox={member.sandbox_id} "
                f"private-ip={member.ip_address} "
                f"status={member.status}"
            )
    finally:
        sandbox.detach_network(network.id)
finally:
    client.networks.delete(network.id)

Lifecycle reads like the domain

sandbox.pause().wait_until_paused()

clone = sandbox.fork()
try:
    sandbox.resume().wait_until_running()
finally:
    clone.destroy()

sandbox.destroy()

The SandboxInstance handle safely caches the latest server projection. Lifecycle mutations and refresh() update it, while id, name, status, ip_address, and data provide safe reads.

Errors stay inspectable

from createos import APIError, OperationTimeout


try:
    sandbox.wait_until_running()
except APIError as error:
    print(
        f"HTTP {error.status_code}, code={error.code}, "
        f"request={error.request_id}"
    )
except OperationTimeout:
    # A lifecycle or readiness wait exhausted its budget.
    pass

GET, HEAD, PUT, and DELETE requests are retried for transient network failures and retryable server responses. HTTP 429 and 503 are retried for every method. Configure the client with RetryOptions, or disable retries for one request with RequestOptions(disable_retry=True).

Examples

Runnable examples live under examples/:

Together these examples cover command execution, file transfer, streaming, ingress, snapshots, networking, templates, managed processes, and desktop use.

Development

Create a virtual environment and install the development dependencies:

python -m venv .venv
.venv/bin/pip install -e '.[dev]'

Run the same checks used while developing the SDK:

.venv/bin/ruff format --check src tests examples
.venv/bin/ruff check src tests examples
.venv/bin/mypy src/createos --ignore-missing-imports
.venv/bin/pytest --cov=createos --cov-fail-under=70

The project follows the Google Python Style Guide. Formatting, import ordering, public docstrings, and static analysis are enforced through the project configuration.

GitHub Actions runs these quality checks, tests Python 3.10 through 3.14, builds both package distributions, and verifies that the generated wheel imports.

Commits follow Conventional Commits. See CONTRIBUTING.md for accepted types, examples, and the checks to run before opening a pull request.

Package layout

src/createos/client.py      client configuration and account-level operations
src/createos/instance.py    stateful sandbox lifecycle and command operations
src/createos/services.py    files, processes, desktop, templates, disks, networks
src/createos/models.py      public requests, responses, options, and enums
src/createos/_transport.py  HTTP, authentication, retries, and JSend handling
src/createos/_streams.py    NDJSON, SSE, command, process, and binary streams
examples/                   runnable Python programs
tests/                      mocked API contract tests

About CreateOS

CreateOS is an execution and governance platform for AI agents and applications. Learn more about isolated Firecracker-based workloads on the CreateOS Sandbox product page.

License

This SDK is available under the MIT License.

Download files

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

Source Distribution

createos_sandbox-0.1.0.tar.gz (40.2 kB view details)

Uploaded Source

Built Distribution

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

createos_sandbox-0.1.0-py3-none-any.whl (28.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: createos_sandbox-0.1.0.tar.gz
  • Upload date:
  • Size: 40.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for createos_sandbox-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8fe12d593fa761aa40fe2b2c97705d0eb997cf458cfe9315b33dda0693ea296d
MD5 5d8a428de5917f94d6f9e726d1def867
BLAKE2b-256 88cbf1f0fee3e63fe669e49dbddae1217a371c70356204769bd164f649203d05

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for createos_sandbox-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0077512029641b1473c4164252ccd7e8c0c04538c1385d608b0d4631f8fbbf6d
MD5 f58caba8e0dd120f1641d3d18df9057e
BLAKE2b-256 5bb23390e18543a8e9c64b958ef10effc5c7e724c16995ed1519cce6eba46f26

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page