Skip to main content
BoxLite provides a streaming execution model for running commands inside boxes. Commands are executed asynchronously with separate access to stdout, stderr, and stdin streams.

Execution

boxlite.Execution

Represents a running command execution. Returned by box.exec().

Methods

MethodSignatureDescription
stdout()() -> ExecStdoutGet stdout stream (async iterator)
stderr()() -> ExecStderrGet stderr stream (async iterator)
stdin()() -> ExecStdinGet stdin writer
wait()() -> ExecResultWait for completion (async)
kill()(signal: int = 9) -> NoneSend signal to process (async)
resize_tty()(rows: int, cols: int) -> NoneResize PTY terminal for executions started with tty=True (async)

Example

# Execute with streaming output
execution = await box.exec("python", ["-c", "for i in range(5): print(i)"])

# Stream stdout
async for line in execution.stdout():
    print(f"Output: {line}")

# Wait for completion
result = await execution.wait()
print(f"Exit code: {result.exit_code}")

Streaming Output

You can stream stdout and stderr independently for real-time output processing.
# Execute a long-running command
execution = await box.exec("python", ["-c", """
import time
import sys

for i in range(10):
    print(f"Progress: {i}/10")
    sys.stdout.flush()
    time.sleep(1)

print("Done!")
"""])

# Stream stdout in real-time
async for line in execution.stdout():
    print(f"[stdout] {line}")

# Get final result
result = await execution.wait()
print(f"Exit code: {result.exit_code}")

Streaming with stderr

execution = await box.exec("python", ["-c", """
import sys
print("Normal output")
print("Error output", file=sys.stderr)
print("More normal output")
"""])

# Stream both stdout and stderr
import asyncio

async def read_stdout():
    async for line in execution.stdout():
        print(f"[stdout] {line}")

async def read_stderr():
    async for line in execution.stderr():
        print(f"[stderr] {line}")

await asyncio.gather(read_stdout(), read_stderr())
result = await execution.wait()

Interactive Input

# Start an interactive process
execution = await box.exec("cat")
stdin = execution.stdin()

# Send data to stdin
await stdin.send_input(b"Hello\n")
await stdin.send_input(b"World\n")

# Close stdin to signal EOF (process will complete)
# Wait for completion
result = await execution.wait()

Killing a Process

import asyncio

# Start a long-running process
execution = await box.exec("sleep", ["3600"])

# Kill after 5 seconds
await asyncio.sleep(5)
await execution.kill()  # Sends SIGKILL (9) by default

# Or send a specific signal
await execution.kill(signal=15)  # SIGTERM

result = await execution.wait()

TTY Resizing

For executions started with tty=True, you can dynamically resize the terminal.
execution = await box.exec("bash", tty=True)

# Resize the terminal
await execution.resize_tty(rows=40, cols=120)

# Send commands
stdin = execution.stdin()
await stdin.send_input(b"ls -la\n")

ExecStdout / ExecStderr

boxlite.ExecStdout / boxlite.ExecStderr

Async iterators for streaming output line by line.
# Stream stdout line by line
stdout = execution.stdout()
async for line in stdout:
    print(line)

# Stream stderr
stderr = execution.stderr()
async for line in stderr:
    print(f"Error: {line}", file=sys.stderr)
Each stream can only be iterated once. After iteration, the stream is consumed.

ExecStdin

boxlite.ExecStdin

Writer for sending input to a running process.

Methods

MethodSignatureDescription
send_input()(data: bytes) -> NoneWrite bytes to stdin (async)

Example

# Interactive input
execution = await box.exec("cat")
stdin = execution.stdin()

# Send data
await stdin.send_input(b"Hello\n")
await stdin.send_input(b"World\n")

# Wait for completion
result = await execution.wait()

ExecResult

boxlite.ExecResult

Result of a completed execution.
FieldTypeDescription
exit_codeintProcess exit code (0 = success)
For higher-level APIs (SimpleBox.exec()), the result also includes stdout and stderr strings, allowing you to access the full output without streaming.

Example

# Low-level API (Box.exec)
execution = await box.exec("echo", ["hello"])
result = await execution.wait()
print(result.exit_code)  # 0

# High-level API (SimpleBox.exec)
async with SimpleBox(image="python:slim") as box:
    result = await box.exec("echo", "hello")
    print(result.exit_code)  # 0
    print(result.stdout)     # "hello\n"
    print(result.stderr)     # ""

Common Patterns

Run and Capture Output

The simplest pattern for running a command and capturing its output.
async with SimpleBox(image="python:slim") as box:
    result = await box.exec("python", "-c", "print('Hello!')")

    if result.exit_code == 0:
        print(f"Output: {result.stdout}")
    else:
        print(f"Error: {result.stderr}")

Stream Large Output

For commands that produce large amounts of output, use streaming to avoid memory issues.
execution = await box.exec("find", ["/", "-type", "f"])

line_count = 0
async for line in execution.stdout():
    line_count += 1
    if "important" in line:
        print(f"Found: {line}")

result = await execution.wait()
print(f"Processed {line_count} lines")

Pipeline Pattern

Run multiple commands in sequence, passing output between them.
async with SimpleBox(image="python:slim") as box:
    # Write data
    await box.exec("bash", "-c", "echo 'line1\nline2\nline3' > /tmp/data.txt")

    # Process data
    result = await box.exec("bash", "-c", "cat /tmp/data.txt | sort | uniq")
    print(result.stdout)

Environment Variables per Execution

Pass environment variables to specific command executions.
async with SimpleBox(image="python:slim") as box:
    result = await box.exec(
        "python", "-c", "import os; print(os.environ['MY_VAR'])",
        env=[("MY_VAR", "hello")]
    )
    print(result.stdout)  # "hello\n"

Timeout with Kill

Implement a timeout for long-running commands.
import asyncio

async with SimpleBox(image="python:slim") as box:
    execution = await box.exec("sleep", ["3600"])

    try:
        result = await asyncio.wait_for(execution.wait(), timeout=10.0)
    except asyncio.TimeoutError:
        await execution.kill()
        print("Command timed out and was killed")

See Also