Stream stdout and stderr

def on_stdout(data: str) -> None:
    print(data, end="")

def on_stderr(data: str) -> None:
    print(data, end="")

result = machine.commands.run_streaming(
    "for i in 1 2 3; do echo tick-$i; sleep 1; done",
    shell=True,
    on_stdout=on_stdout,
    on_stderr=on_stderr,
)
print(result.exit_code)
Streaming command output is not a plain REST call: SDK callers stream over GET /v1/machines/{id}/ws?channel=exec (sending exec_start and reading exec_stdout/exec_stderr/exec_exit), so there is no curl equivalent. The non-streaming POST /v1/machines/{id}/exec endpoint returns only the final result. Passing callbacks to machine.commands.run(...) without background=True uses the same streaming path:
result = machine.commands.run(
    "python3 -u script.py",
    shell=True,
    on_stdout=on_stdout,
    on_stderr=on_stderr,
)

Connect to a running process

process = machine.commands.connect(
    pid=1234,
    on_stdout=on_stdout,
    on_stderr=on_stderr,
)
result = process.wait()
print(result.exit_code)
Attaching to a running process is not a plain REST call: it reconnects over GET /v1/machines/{id}/ws?channel=exec with an exec_connect message, so there is no curl equivalent. Use connect(pid) for background processes that are still running. It attaches to the exec WebSocket and waits for the process exit event when possible.

Live background streaming

worker = machine.commands.run(
    "python3 -u worker.py",
    shell=True,
    background=True,
    on_stdout=on_stdout,
    on_stderr=on_stderr,
)

worker.disconnect()
Combining background=True with callbacks starts the command through the exec WebSocket and returns a BackgroundCommand after an exec_started message. The CLI equivalent is nullspace machine process stream with --cwd, --env, and --timeout flags.

Behavior

Streaming uses GET /v1/machines/{id}/ws?channel=exec. SDK callers send exec_start for new commands or exec_connect for existing PIDs and then read exec_started, exec_stdout, exec_stderr, exec_exit, and error messages. Use the REST get_logs endpoint when you only need logs after the process has started.