Skip to main content

English | 简体中文

eci-as-sandbox

ECI-backed sandbox manager built on alibabacloud-eci20180808 with a lightweight API for managing container-group sandboxes.

Install

pdm add eci-as-sandbox

Environment

The client auto-loads a .env file (searching upward from the working directory). You can also pass env_file=... or explicit credentials.

Required Alibaba Cloud credentials:

set ALIBABA_CLOUD_ACCESS_KEY_ID=...
set ALIBABA_CLOUD_ACCESS_KEY_SECRET=...
set ALIBABA_CLOUD_REGION_ID=cn-shanghai

Optional overrides:

set ECI_SANDBOX_ACCESS_KEY_ID=...
set ECI_SANDBOX_ACCESS_KEY_SECRET=...
set ECI_SANDBOX_REGION_ID=cn-shanghai
set ECI_SANDBOX_ENDPOINT=eci.cn-shanghai.aliyuncs.com
set ECI_SANDBOX_TIMEOUT_MS=60000

If you use a private image, configure registry credentials in ECI.

Quick start (sync)

from eci_as_sandbox import EciSandbox

client = EciSandbox()
result = client.create(
    image="registry.cn-hangzhou.aliyuncs.com/eci_open/nginx:latest",
    name="sandbox-demo",
    cpu=1.0,
    memory=2.0,
    v_switch_id="vsw-xxx",
    security_group_id="sg-xxx",
    ports=[{"port": 8080, "protocol": "TCP"}],
)

if result.success and result.sandbox:
    sandbox = result.sandbox
    info = sandbox.info()
    print(info.data.status)
    sandbox.delete()

Async quick start

import asyncio
from eci_as_sandbox import AsyncEciSandbox


async def main() -> None:
    client = AsyncEciSandbox()
    result = await client.create(
        image="registry.cn-hangzhou.aliyuncs.com/eci_open/nginx:latest",
        name="sandbox-demo",
        cpu=1.0,
        memory=2.0,
        v_switch_id="vsw-xxx",
        security_group_id="sg-xxx",
    )
    if result.success and result.sandbox:
        info = await result.sandbox.info()
        print(info.data.status)


asyncio.run(main())

Command helpers

exec_command runs a list-form command. With sync=True (default) it uses the ECI WebSocket stream to collect output. timeout is in seconds and caps the stream duration (default 600 seconds, max 600). Use sync=False if you want the WebSocket/HTTP URLs without waiting.

result = sandbox.exec_command(
    ["/bin/sh", "-c", "for i in 1 2 3; do echo tick-$i; sleep 2; done"],
    timeout=3,
)
print(result.output)

bash runs a shell command via bash -lc and supports exec_dir.

result = sandbox.bash(
    command="pwd; ls -la",
    exec_dir="/tmp",
    timeout=5,
)
print(result.output)

Listing

result = client.list(limit=10, status="Running")
print(result.sandbox_ids)

Long command execution (WebSocket)

ECI's API has a 2048-byte command limit. For longer commands, use bash_ws which sends commands through WebSocket stdin (no length limit).

# Execute a very long command (e.g., inline Python script)
long_script = """python3 << 'EOF'
import json
# ... hundreds of lines of code ...
print(json.dumps({"status": "done"}))
EOF
"""

result = client.bash_ws(
    sandbox_id=sandbox_id,
    command=long_script,
    exec_dir="/workspace",
    timeout=60,
)
print(result.output)

write_file_ws writes large content to a file via WebSocket:

result = client.write_file_ws(
    sandbox_id=sandbox_id,
    file_path="/tmp/large_script.py",
    content="# Very long file content...\n" * 1000,
    timeout=30,
)

Tmux session management

For non-blocking command execution with output capture, use tmux methods. Long commands are automatically handled via WebSocket file transfer.

# Start a command in tmux (non-blocking)
start_result = client.tmux_start(
    sandbox_id=sandbox_id,
    command="python train.py --epochs 100",
    exec_dir="/workspace",
)
print(f"Session: {start_result.session_id}")

# Poll for status and partial output
poll_result = client.tmux_poll(
    sandbox_id=sandbox_id,
    session_id=start_result.session_id,
)
print(f"Status: {poll_result.status}")  # RUNNING, COMPLETED, NOT_FOUND
print(f"Output: {poll_result.output}")

# Wait for completion with exponential backoff
wait_result = client.tmux_wait(
    sandbox_id=sandbox_id,
    session_id=start_result.session_id,
    timeout=300,  # max wait time
)
print(f"Exit code: {wait_result.exit_code}")
print(f"Output: {wait_result.output}")

# Kill a session manually
client.tmux_kill(sandbox_id=sandbox_id, session_id=start_result.session_id)

# List all tmux sessions
list_result = client.tmux_list(sandbox_id=sandbox_id)
print(list_result.data)  # [{"session_id": "...", "created": "...", "attached": False}]

API Reference

Client Methods

Method Description
create(image, name, cpu, memory, ...) Create a new sandbox container
get(sandbox_id) Get sandbox instance by ID
get_sandbox(sandbox_id) Get sandbox info
list(limit, status, tags, ...) List sandboxes
delete(sandbox_id, force) Delete a sandbox
restart(sandbox_id) Restart a sandbox
exec_command(sandbox_id, command, ...) Execute command (list form)
bash(sandbox_id, command, exec_dir, ...) Execute bash command
bash_ws(sandbox_id, command, exec_dir, ...) Execute bash via WebSocket (unlimited length)
write_file_ws(sandbox_id, file_path, content, ...) Write file via WebSocket (unlimited length)
tmux_start(sandbox_id, command, ...) Start command in tmux session
tmux_poll(sandbox_id, session_id, ...) Poll tmux session status
tmux_wait(sandbox_id, session_id, timeout, ...) Wait for tmux session completion
tmux_kill(sandbox_id, session_id) Kill tmux session
tmux_list(sandbox_id) List all tmux sessions

Download files

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

Source Distribution

eci_as_sandbox-0.2.3.tar.gz (28.6 kB view details)

Uploaded Source

Built Distribution

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

eci_as_sandbox-0.2.3-py3-none-any.whl (31.9 kB view details)

Uploaded Python 3

File details

Details for the file eci_as_sandbox-0.2.3.tar.gz.

File metadata

  • Download URL: eci_as_sandbox-0.2.3.tar.gz
  • Upload date:
  • Size: 28.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for eci_as_sandbox-0.2.3.tar.gz
Algorithm Hash digest
SHA256 ffcd1fbe1b0d5d72ca7e12721fddf74b91f853fa68eff07cf73d274dcea10d82
MD5 163294f5092d23aa5093b7ddbf85da1c
BLAKE2b-256 c36446c5c302a6e261c2b0bcc818ac8ed9d099e44adf52d30aef2b15bcc32668

See more details on using hashes here.

Provenance

The following attestation bundles were made for eci_as_sandbox-0.2.3.tar.gz:

Publisher: publish.yml on AndersonBY/eci-as-sandbox

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

File details

Details for the file eci_as_sandbox-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: eci_as_sandbox-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 31.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for eci_as_sandbox-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8ded8ada2b1104801c373a82fe7e491d00c1f343289fcba6495a7c2021261059
MD5 1e1e13c4c351d7059b1fab3c88fbd3f6
BLAKE2b-256 22134d393ca395a11717fd1964888c1ecb1d871d92b97273d1dff7d3015425fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for eci_as_sandbox-0.2.3-py3-none-any.whl:

Publisher: publish.yml on AndersonBY/eci-as-sandbox

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

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page