import asyncio
import os
from datetime import timedelta
from opensandbox import Sandbox
from opensandbox.config import ConnectionConfig
from opensandbox.models.execd import RunCommandOpts
async def _print_logs(label: str, execution) -> None:
"""Helper to print execution logs"""
for msg in execution.logs.stdout:
print(f"[{label} stdout] {msg.text}")
for msg in execution.logs.stderr:
print(f"[{label} stderr] {msg.text}")
if execution.error:
print(f"[{label} error] {execution.error.name}: {execution.error.value}")
async def main() -> None:
domain = os.getenv("SANDBOX_DOMAIN", "localhost:8080")
api_key = os.getenv("SANDBOX_API_KEY")
image = os.getenv(
"SANDBOX_IMAGE",
"opensandbox/vscode:latest",
)
python_version = os.getenv("PYTHON_VERSION", "3.11")
code_port = int(os.getenv("CODE_PORT", "8443"))
config = ConnectionConfig(
domain=domain,
api_key=api_key,
request_timeout=timedelta(seconds=60),
)
# Create sandbox with environment variables
env = {"PYTHON_VERSION": python_version}
sandbox = await Sandbox.create(
image,
connection_config=config,
env=env,
)
async with sandbox:
# Start code-server with authentication disabled
start_exec = await sandbox.commands.run(
f"code-server --bind-addr 0.0.0.0:{code_port} --auth none /workspace",
opts=RunCommandOpts(background=True),
)
await _print_logs("code-server", start_exec)
# Get the proxied endpoint
endpoint = await sandbox.get_endpoint(code_port)
print("\nVS Code Web endpoint:")
print(f" http://{endpoint.endpoint}/")
print("\nKeeping sandbox alive for 10 minutes. Press Ctrl+C to exit sooner.")
try:
await asyncio.sleep(600)
except KeyboardInterrupt:
print("Stopping...")
finally:
await sandbox.kill()
if __name__ == "__main__":
asyncio.run(main())