Automate with Python and CLI
Use SandboxClient in synchronous Python applications and AsyncSandboxClient in async harnesses or agents. The CLI provides the same operations for shell scripts and manual work.
Both interfaces connect to an existing Polyaxon service with plugins.sandbox enabled. A sandbox is a capability of that service, not a separate kind of Polyaxon resource.
This page continues from the Sandbox Quick Start and uses its quick-start project, /workspace directory, and RUN_UUID variable.
Run commands
The Python example binds every operation to the same project and run. The CLI tab shows the equivalent shell commands.
import os
from polyaxon.client import SandboxClient
with SandboxClient(
project="quick-start",
run_uuid=os.environ["RUN_UUID"],
) as sandbox:
sandbox.ping()
sandbox.fs.upload_file(
"./sandbox/smoke.py",
"/workspace/smoke.py",
)
result = sandbox.process.exec(
command=["python", "-V"],
timeout_ms=30_000,
)
print(result.stdout, end="")
print(result.stderr, end="")
with sandbox.process.exec_stream(
command=["python", "/workspace/smoke.py"],
) as events:
for event in events:
print(event)polyaxon sandbox ping -p quick-start -uid $RUN_UUID
polyaxon sandbox upload -p quick-start -uid $RUN_UUID \
./sandbox/smoke.py /workspace/smoke.py
polyaxon sandbox exec -p quick-start -uid $RUN_UUID -- python -V
polyaxon sandbox exec -p quick-start -uid $RUN_UUID --stream -- python /workspace/smoke.pyRun background work
Start a detached process and keep its execution ID:
import os
from polyaxon.client import SandboxClient
with SandboxClient(
project="quick-start",
run_uuid=os.environ["RUN_UUID"],
) as sandbox:
sandbox.fs.upload_file(
"./sandbox/profile.py",
"/workspace/profile.py",
)
process = sandbox.process.exec_bg(
command=["python", "/workspace/profile.py"],
)
print(process.id)
for chunk in process.iter_stdout(timeout=300, interval=0.5):
print(chunk, end="")
status = process.wait(timeout=300)
print(status.state, status.exit_code)polyaxon sandbox upload -p quick-start -uid $RUN_UUID \
./sandbox/profile.py /workspace/profile.py
EXEC_ID=$(polyaxon sandbox exec -p quick-start -uid $RUN_UUID --detach -- python /workspace/profile.py)
polyaxon sandbox logs -p quick-start -uid $RUN_UUID $EXEC_IDMove files
import os
from polyaxon.client import SandboxClient
with SandboxClient(
project="quick-start",
run_uuid=os.environ["RUN_UUID"],
) as sandbox:
sandbox.fs.upload_file(
"./sandbox/config.yaml",
"/workspace/config.yaml",
)
sandbox.fs.download_file(
"/workspace/profile.json",
"./sandbox/profile.downloaded.json",
)polyaxon sandbox upload -p quick-start -uid $RUN_UUID \
./sandbox/config.yaml /workspace/config.yaml
polyaxon sandbox download -p quick-start -uid $RUN_UUID \
/workspace/profile.json ./sandbox/profile.downloaded.jsonRemote paths are absolute paths inside the service container. Replace /workspace with a directory that exists in your image.
Use the async Python client
AsyncSandboxClient exposes coroutine methods and async iterators for applications that already use asyncio. Target the service explicitly so the harness does not depend on cached project or run context:
import asyncio
import os
from polyaxon.client import AsyncSandboxClient
async def main():
async with AsyncSandboxClient(
project="quick-start",
run_uuid=os.environ["RUN_UUID"],
) as sandbox:
await sandbox.ping()
await sandbox.fs.upload_file(
"./sandbox/smoke.py",
"/workspace/smoke.py",
)
result = await sandbox.process.exec(
command=["python", "-V"],
timeout_ms=30_000,
)
print(result.stdout, end="")
print(result.stderr, end="")
stream = await sandbox.process.exec_stream(
command=["python", "/workspace/smoke.py"],
)
async with stream as events:
async for event in events:
print(event)
asyncio.run(main())Commands must be argument lists. Polyaxon does not pass them through a shell unless you explicitly run a shell such as sh -c.
The sync and async clients provide the same process, filesystem, and terminal APIs. See the client, process, filesystem, and PTY references for the full interface.
Drive a sandbox with an AI agent
Use the Connect LLMs guide to execute generated Python code or connect OpenAI, Anthropic, and LangChain through a shared command tool. It includes provider setup, tool-result handling, and bounded execution with host approval.
Stop the service
Stop the service when your automation finishes:
import os
from polyaxon.client import RunClient
run_client = RunClient(
project="quick-start",
run_uuid=os.environ["RUN_UUID"],
)
run_client.stop()polyaxon ops stop -p quick-start -uid $RUN_UUIDContainer files disappear when the run is removed. Upload durable outputs to artifact storage or commit them to Git before stopping the service.
SandboxClient.create() creates a service run but does not approve it or wait for it to become ready. This tutorial attaches to a running service so the first tool call cannot race startup.