Skip to content

feat: add sync and async sandbox SDK - #595

Open
KAJdev wants to merge 6 commits into
mainfrom
zeke/con-1525-create-sandbox-domain
Open

KAJdev wants to merge 6 commits into
mainfrom
zeke/con-1525-create-sandbox-domain

Conversation

@KAJdev

@KAJdev KAJdev commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

This brings sandbox support to the Python SDK, with a regular Sandbox API and an async AsyncioSandbox API. Both share the same lifecycle and execution logic.

use a context manager for a short-lived sandbox:

from runpod import Sandbox

with Sandbox(image_name="python:3.12-slim") as sandbox:
    result = sandbox.exec(["python", "-c", "print('hello from the sandbox')"], check=True)
    print(result.output)

The async version works the same way:

import asyncio
from runpod import AsyncioSandbox

async def main():
    async with AsyncioSandbox(image_name="python:3.12-slim") as sandbox:
        result = await sandbox.exec(["python", "-c", "print('hello')"], check=True)
        print(result.output)

asyncio.run(main())

To work with a sandbox that's already running, use get(sandbox_id) or list(...). Those handles only close their local connections when you leave the context. they don't terminate the sandbox. You can call terminate() explicitly when you're finished with it.

exec() returns command output, and check=True raises on command failure while keeping any partial output. logs() streams container or system logs and supports resuming with an event's id through last_event_id. Use a context manager around the log stream too if you might stop reading early.

While working on this, I discovered an edge case in log streaming on host that should be addressed as well: CON-1557 / runpod/host#2820.

Linear: CON-1523, CON-1524, CON-1525, CON-1526

Implements CON-1523, CON-1524, CON-1525, and CON-1526.

Based on REST migration PR #584. Keep this draft local until that PR is merged.

Includes managed ownership, bounded startup handling, closeable SSE streams,
and cancellation-safe synchronous and asynchronous resource cleanup.
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread runpod/sandbox/asyncio.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread runpod/sandbox/asyncio.py
Comment thread runpod/sandbox/asyncio.py
Comment thread runpod/sandbox/asyncio.py
Comment thread runpod/sandbox/sync.py
Comment thread runpod/sandbox/sync.py
Comment thread tests/test_sandbox.py Fixed
Comment thread tests/test_sandbox.py Fixed
Comment thread runpod/sandbox/asyncio.py
Comment thread runpod/sandbox/asyncio.py
Comment thread runpod/sandbox/asyncio.py
Comment thread runpod/sandbox/sync.py
Comment thread runpod/sandbox/sync.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants