Skip to main content
AsyncCapsule is the async counterpart to Capsule. Every method that performs I/O — running commands, reading and writing files, pausing and resuming, opening a PTY — has an async equivalent that you await. The interface is identical to the sync API; the only difference is the await keyword and the async with context manager.

Creating an async capsule

Use await AsyncCapsule.create(...) to create a capsule, then use it as an async context manager. The capsule is destroyed automatically when the block exits.
import asyncio
from wrenn import AsyncCapsule

async def main():
    async with await AsyncCapsule.create(template="minimal", wait=True) as capsule:
        result = await capsule.commands.run("echo hello")
        print(result.stdout)  # "hello\n"

asyncio.run(main())

Commands and files

All command and file operations are awaitable:
async with await AsyncCapsule.create(template="minimal", wait=True) as capsule:
    # Run a command
    result = await capsule.commands.run("echo hello")
    print(result.stdout)

    # Write and list files
    await capsule.files.write("/app/data.txt", "hello world")
    entries = await capsule.files.list("/app")
    for entry in entries:
        print(entry.name, entry.type)

Lifecycle operations

pause and resume are awaitable just like the sync versions:
await capsule.pause()
await capsule.resume()

Async code interpreter

Import AsyncCapsule from wrenn.code_interpreter for stateful async code execution:
from wrenn.code_interpreter import AsyncCapsule

async def main():
    async with await AsyncCapsule.create(wait=True) as capsule:
        result = await capsule.run_code("2 + 2")
        print(result.text)  # "4"

Async PTY

Use capsule.pty() as an async context manager and iterate over events with async for:
import sys

async with capsule.pty(cmd="/bin/bash") as term:
    await term.write(b"ls -la\n")
    async for event in term:
        if event.type == "output":
            sys.stdout.buffer.write(event.data)
        elif event.type == "exit":
            break
AsyncCapsule mirrors the sync Capsule API exactly — every method has the same name and accepts the same parameters. The only change is adding await and using async with / async for where appropriate.