DocsOverview
SandboxesOverview
v1.16+

Sandboxes

Polyaxon's sandbox plugin exposes process, filesystem, and PTY access inside the main container of a running service. It does not create a separate workload kind or isolation boundary: the image, container user, mounts, connections, and network policy remain those of the service run.

Use sandboxes when you need to inspect a live environment, run commands against the same image and connections as your workload, iterate on code in-cluster, or automate runtime actions from the CLI.

Start with the Sandbox Quick Start. It continues from the main quick start and establishes the quick-start project, sandbox.yaml, /workspace, and RUN_UUID used throughout this section.

CLI: Open an interactive shell inside a running workload — same image, connections, and credentials as the run.

polyaxon sandbox shell -p owner/project -uid <run-uuid>

Python: Use the PTY client when automation needs to create and attach to an interactive terminal session.

from polyaxon.client import SandboxClient

sandbox = SandboxClient(owner="owner", project="project", run_uuid="<run-uuid>")
pty = sandbox.pty.create(command=["sh"], cols=120, rows=30, tag="debug")

with sandbox.pty.attach(pty.pty_id, replay_bytes=1024) as ws:
    ws.send_stdin(b"pwd\n")
    print(ws.recv())

CLI: Run one-off commands against a live run with polyaxon sandbox exec, and stream the output.

polyaxon sandbox exec -p owner/project -uid <run-uuid> -- python -V
polyaxon sandbox exec -p owner/project -uid <run-uuid> --stream -- \
  sh -lc 'pytest tests/smoke'

Python: Use the process client for buffered command results or streaming events.

from polyaxon.client import SandboxClient

sandbox = SandboxClient(owner="owner", project="project", run_uuid="<run-uuid>")
result = sandbox.process.exec(command=["python", "-V"])
print(result.exit_code, result.stdout)

with sandbox.process.exec_stream(command=["sh", "-lc", "pytest tests/smoke"]) as events:
    for event in events:
        print(event)

CLI: Upload, download, and list files in the sandbox to move code, data, and artifacts in and out.

polyaxon sandbox ls -p owner/project -uid <run-uuid> /workspace
polyaxon sandbox upload -p owner/project -uid <run-uuid> ./config.yaml /workspace/config.yaml
polyaxon sandbox download -p owner/project -uid <run-uuid> /workspace/results.json ./results.json

Python: Use the filesystem client for reads, writes, directory listing, and file transfer.

from polyaxon.client import SandboxClient

sandbox = SandboxClient(owner="owner", project="project", run_uuid="<run-uuid>")
sandbox.fs.mkdir("/workspace/evals", parents=True)
sandbox.fs.write_text("/workspace/evals/config.yaml", "batch_size: 64\n")
print(sandbox.fs.ls("/workspace"))
sandbox.fs.upload_file("suite.py", "/workspace/suite.py")
sandbox.fs.download_file("/workspace/results.json", "results.json")

CLI: Connect local terminals, IDEs, SFTP, and tunnels over SSH — debug and develop in-cluster from your own tools.

polyaxon ssh setup -p owner/project -uid <run-uuid>
polyaxon ssh connect -p owner/project -uid <run-uuid>
polyaxon ssh connect -p owner/project -uid <run-uuid> -- -L 8888:127.0.0.1:8888 -N

Python: Use PTY sessions for programmatic terminal control from Python; use the CLI/OpenSSH commands above for native IDE, SFTP, and port-forward workflows.

from polyaxon.client import SandboxClient

sandbox = SandboxClient(owner="owner", project="project", run_uuid="<run-uuid>")
pty = sandbox.pty.create(command=["sh"], tag="python-terminal")

with sandbox.pty.attach(pty.pty_id) as ws:
    ws.send_stdin(b"python -V\n")
    print(ws.recv())

CLI: Launch detached background commands and tail their logs with polyaxon sandbox logs.

EXEC_ID=$(
  polyaxon sandbox exec -p owner/project -uid <run-uuid> --detach -- \
    sh -lc 'python scripts/profile.py'
)
polyaxon sandbox logs -p owner/project -uid <run-uuid> "$EXEC_ID"

Python: Use background exec handles to poll status, stream logs, and wait for completion.

from polyaxon.client import SandboxClient

sandbox = SandboxClient(owner="owner", project="project", run_uuid="<run-uuid>")
bg = sandbox.process.exec_bg(
    command=["sh", "-lc", "python scripts/profile.py"],
    tag="profile",
)

for chunk in bg.iter_logs(stream="stdout", timeout=60):
    print(chunk, end="")

status = bg.wait(timeout=60)
print(status.state, status.exit_code)

Where Sandboxes Fit

Sandboxes are an end-user workflow. They sit between regular workload docs and operator setup:

Capabilities

Sandbox-enabled runs can support:

  • Health checks with polyaxon sandbox ping.
  • One-off commands with polyaxon sandbox exec.
  • Detached commands with polyaxon sandbox exec --detach, with output read through polyaxon sandbox logs.
  • Interactive shells with polyaxon sandbox shell.
  • File upload, download, and directory listing.
  • SSH access for local terminals, IDEs, SFTP, SCP, and tunnels.
  • Reconnectable terminal sessions when plugins.tmux is enabled.

Typical Workflow

  1. Start a service run with the access plugins required by your workflow (sandbox, SSH, or tmux).
  2. Wait until the run reaches a running state.
  3. Connect with the CLI, SSH, or a notebook service.
  4. Inspect files, run commands, install temporary packages, or debug runtime state.
  5. Persist useful outputs to the run's outputs path or commit code changes back to a Git remote.
  6. Stop the service run when the session is done.

Minimal Polyaxonfile

kind: component
version: 1.1
name: sandbox-dev

plugins:
  sandbox: true

run:
  kind: service
  container:
    image: python:3.11
    command: ["sh", "-lc", "mkdir -p /workspace && exec sleep infinity"]

This creates a regular long-running service with sandbox process and file access. Add plugins.ssh: true for native SSH access or plugins.tmux: true for reconnectable polyaxon ops shell sessions. These plugins add capabilities to the service; they do not create a separate sandbox workload.