Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions examples/code-interpreter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,141 @@ The script creates a Sandbox + CodeInterpreter, runs a Python code snippet and p
3 + 4 = 7


=== TypeScript example ===
[TypeScript stdout] Hello from TypeScript!

[TypeScript stdout] sum = 6
```

# Code Interpreter Sandbox from pool

## Start OpenSandbox server [k8s]

Install the k8s OpenSandbox operator, and create a pool:
```yaml
apiVersion: sandbox.opensandbox.io/v1alpha1
kind: Pool
metadata:
labels:
app.kubernetes.io/name: sandbox-k8s
app.kubernetes.io/managed-by: kustomize
name: pool-sample
namespace: opensandbox
spec:
template:
metadata:
labels:
app: example
spec:
volumes:
- name: sandbox-storage
emptyDir: { }
- name: opensandbox-bin
emptyDir: { }
initContainers:
- name: task-executor-installer
image: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/task-executor:latest
command: [ "/bin/sh", "-c" ]
args:
- |
cp /workspace/server /opt/opensandbox/bin/task-executor &&
chmod +x /opt/opensandbox/bin/task-executor
volumeMounts:
- name: opensandbox-bin
mountPath: /opt/opensandbox/bin
- name: execd-installer
image: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/execd:latest
command: [ "/bin/sh", "-c" ]
args:
- |
cp ./execd /opt/opensandbox/bin/execd &&
cp ./bootstrap.sh /opt/opensandbox/bin/bootstrap.sh &&
chmod +x /opt/opensandbox/bin/execd &&
chmod +x /opt/opensandbox/bin/bootstrap.sh
volumeMounts:
- name: opensandbox-bin
mountPath: /opt/opensandbox/bin
containers:
- name: sandbox
image: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:latest
command:
- "/bin/sh"
- "-c"
- |
/opt/opensandbox/bin/task-executor -listen-addr=0.0.0.0:5758 >/tmp/task-executor.log 2>&1
env:
- name: SANDBOX_MAIN_CONTAINER
value: main
- name: EXECD_ENVS
value: /opt/opensandbox/.env
- name: EXECD
value: /opt/opensandbox/bin/execd
volumeMounts:
- name: sandbox-storage
mountPath: /var/lib/sandbox
- name: opensandbox-bin
mountPath: /opt/opensandbox/bin
tolerations:
- operator: "Exists"
capacitySpec:
bufferMax: 3
bufferMin: 1
poolMax: 5
poolMin: 0
```

Start the k8s OpenSandbox server:

```shell
git clone [email protected]:alibaba/OpenSandbox.git
cd OpenSandbox/server

# replace with your k8s cluster config, kubeconfig etc.
cp example.config.k8s.toml ~/.sandbox.toml
cp example.batchsandbox-template.yaml ~/batchsandbox-template.yaml

uv sync
uv run python -m src.main
```

## Create and access the Code Interpreter Sandbox

```shell
# Install OpenSandbox packages
uv pip install opensandbox opensandbox-code-interpreter

# Run the example (requires SANDBOX_DOMAIN / SANDBOX_API_KEY)
uv run python examples/code-interpreter/main_use_pool.py
```

The script creates a Sandbox + CodeInterpreter, runs a Python code snippet and prints stdout/result, then terminates the remote instance.

## Environment variables

- `SANDBOX_DOMAIN`: Sandbox service address (default: `localhost:8080`)
- `SANDBOX_API_KEY`: API key if your server requires authentication
- `SANDBOX_IMAGE`: Sandbox image to use (default: `sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:latest`)

## Example output

```text
=== Verify Environment Variable ===
[ENV Check] TEST_ENV value: test

[ENV Result] 'test'

=== Java example ===
[Java stdout] Hello from Java!

[Java stdout] 2 + 3 = 5

[Java result] 5

=== Go example ===
[Go stdout] Hello from Go!
3 + 4 = 7


=== TypeScript example ===
[TypeScript stdout] Hello from TypeScript!

Expand Down
117 changes: 117 additions & 0 deletions examples/code-interpreter/main_use_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Copyright 2025 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import asyncio
import os
from datetime import timedelta

from code_interpreter import CodeInterpreter, SupportedLanguage
from opensandbox import Sandbox
from opensandbox.config import ConnectionConfig


async def main() -> None:
domain = os.getenv("SANDBOX_DOMAIN", "localhost:8080")
api_key = os.getenv("SANDBOX_API_KEY")
image = os.getenv(
"SANDBOX_IMAGE",
"sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:latest",
)

config = ConnectionConfig(
domain=domain,
api_key=api_key,
request_timeout=timedelta(seconds=60),
)

sandbox = await Sandbox.create(
image,
connection_config=config,
extensions={"poolRef":"pool-sample"},
entrypoint=["/opt/opensandbox/code-interpreter.sh"],
env={
"TEST_ENV": "test",
},
)

async with sandbox:
interpreter = await CodeInterpreter.create(sandbox=sandbox)

# Verify environment variable is set
print("\n=== Verify Environment Variable ===")
env_check = await interpreter.codes.run(
"import os\n"
"test_env = os.getenv('TEST_ENV', 'NOT_SET')\n"
"print(f'TEST_ENV value: {test_env}')\n"
"test_env",
language=SupportedLanguage.PYTHON,
)
for msg in env_check.logs.stdout:
print(f"[ENV Check] {msg.text}")
if env_check.result:
for res in env_check.result:
print(f"[ENV Result] {res.text}")

# Java example: print to stdout and return the final result line.
java_exec = await interpreter.codes.run(
"System.out.println(\"Hello from Java!\");\n"
"int result = 2 + 3;\n"
"System.out.println(\"2 + 3 = \" + result);\n"
"result",
language=SupportedLanguage.JAVA,
)
print("\n=== Java example ===")
for msg in java_exec.logs.stdout:
print(f"[Java stdout] {msg.text}")
if java_exec.result:
for res in java_exec.result:
print(f"[Java result] {res.text}")
if java_exec.error:
print(f"[Java error] {java_exec.error.name}: {java_exec.error.value}")

# Go example: print logs and demonstrate a main function structure.
go_exec = await interpreter.codes.run(
"package main\n"
"import \"fmt\"\n"
"func main() {\n"
" fmt.Println(\"Hello from Go!\")\n"
" sum := 3 + 4\n"
" fmt.Println(\"3 + 4 =\", sum)\n"
"}",
language=SupportedLanguage.GO,
)
print("\n=== Go example ===")
for msg in go_exec.logs.stdout:
print(f"[Go stdout] {msg.text}")
if go_exec.error:
print(f"[Go error] {go_exec.error.name}: {go_exec.error.value}")

# TypeScript example: use typing and sum an array.
ts_exec = await interpreter.codes.run(
"console.log('Hello from TypeScript!');\n"
"const nums: number[] = [1, 2, 3];\n"
"console.log('sum =', nums.reduce((a, b) => a + b, 0));",
language=SupportedLanguage.TYPESCRIPT,
)
print("\n=== TypeScript example ===")
for msg in ts_exec.logs.stdout:
print(f"[TypeScript stdout] {msg.text}")
if ts_exec.error:
print(f"[TypeScript error] {ts_exec.error.name}: {ts_exec.error.value}")

await sandbox.kill()


if __name__ == "__main__":
asyncio.run(main())
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
app.kubernetes.io/name: sandbox-k8s
app.kubernetes.io/managed-by: kustomize
name: batchsandbox-sample
namespace: sandbox-k8s
namespace: opensandbox
spec:
replicas: 2
template:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
app.kubernetes.io/name: sandbox-k8s
app.kubernetes.io/managed-by: kustomize
name: batchsandbox-sample
namespace: sandbox-k8s
namespace: opensandbox
spec:
replicas: 1
poolRef: pool-sample
Expand Down
50 changes: 24 additions & 26 deletions kubernetes/config/samples/sandbox_v1alpha1_pool.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,61 @@ metadata:
app.kubernetes.io/name: sandbox-k8s
app.kubernetes.io/managed-by: kustomize
name: pool-sample
namespace: sandbox-k8s
namespace: opensandbox
spec:
template:
metadata:
labels:
app: example
spec:
shareProcessNamespace: true
volumes:
- name: sandbox-storage
emptyDir: { }
- name: opensandbox-bin
emptyDir: { }
initContainers:
- name: task-executor-installer
image: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/task-executor:latest
command: [ "/bin/sh", "-c" ]
args:
- |
cp /workspace/server /opt/opensandbox/bin/task-executor &&
chmod +x /opt/opensandbox/bin/task-executor
volumeMounts:
- name: opensandbox-bin
mountPath: /opt/opensandbox/bin
- name: execd-installer
image: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/execd:latest
command: [ "/bin/sh", "-c" ]
args:
- |
cp ./execd /opt/opensandbox/execd/execd &&
chmod +x /opt/opensandbox/execd/execd
cp ./execd /opt/opensandbox/bin/execd &&
cp ./bootstrap.sh /opt/opensandbox/bin/bootstrap.sh &&
chmod +x /opt/opensandbox/bin/execd &&
chmod +x /opt/opensandbox/bin/bootstrap.sh
volumeMounts:
- name: opensandbox-bin
mountPath: /opt/opensandbox/execd
mountPath: /opt/opensandbox/bin
containers:
- name: main
- name: sandbox
image: sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/code-interpreter:latest
command:
- "/bin/sh"
- "-c"
args:
- "/opt/opensandbox/execd/execd > /tmp/execd.log 2>&1"
- |
/opt/opensandbox/bin/task-executor -listen-addr=0.0.0.0:5758 >/tmp/task-executor.log 2>&1
env:
- name: SANDBOX_MAIN_CONTAINER
value: main
- name: EXECD_ENVS
value: /opt/opensandbox/.env
- name: EXECD
value: /opt/opensandbox/bin/execd
volumeMounts:
- name: sandbox-storage
mountPath: /var/lib/sandbox
- name: opensandbox-bin
mountPath: /opt/opensandbox/execd
- command:
- /workspace/server
- -listen-addr=0.0.0.0:5758
- -enable-sidecar-mode=true
image: task-executor:dev
name: task-executor
securityContext:
capabilities:
add:
- SYS_PTRACE
- SYS_ADMIN
- NET_ADMIN
volumeMounts:
- name: sandbox-storage
mountPath: /var/lib/sandbox
- name: opensandbox-bin
mountPath: /opt/opensandbox/execd
mountPath: /opt/opensandbox/bin
tolerations:
- operator: "Exists"
capacitySpec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
app.kubernetes.io/name: sandbox-k8s
app.kubernetes.io/managed-by: kustomize
name: batchsandbox-pool-sample
namespace: sandbox-k8s
namespace: opensandbox
spec:
poolRef: pool-sample
replicas: 2
Expand Down
4 changes: 0 additions & 4 deletions server/example.batchsandbox-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

# Metadata template (will be merged with runtime-generated metadata)
metadata:
annotations:
template-source: "batchsandbox-template.yaml"
managed-by: "opensandbox"

# Spec template
spec:
replicas: 1
Expand Down
1 change: 1 addition & 0 deletions server/src/services/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class SandboxErrorCodes:
UNKNOWN_ERROR = "SANDBOX::UNKNOWN_ERROR"
API_NOT_SUPPORTED = "SANDBOX::API_NOT_SUPPORTED"
INVALID_METADATA_LABEL = "SANDBOX::INVALID_METADATA_LABEL"
INVALID_PARAMETER = "SANDBOX::INVALID_PARAMETER"


__all__ = [
Expand Down
Loading
Loading