import asyncio
from boxlite import SimpleBox
API_KEY = "<YOUR_OPENAI_API_KEY>" # TODO: read from your own secret store
async def run(box, *cmd, env=None, user=None, timeout=None):
result = await box.exec(*cmd, env=env, user=user, timeout=timeout)
# exec does not raise on a non-zero exit — check it yourself
if result.exit_code != 0:
raise RuntimeError(f"`{' '.join(cmd)}` failed (exit={result.exit_code}): {result.stderr}")
return result
async def main() -> None:
try:
# glibc image; disk_size_gb leaves room for the global install and its binary
async with SimpleBox(image="node:20-slim", memory_mib=2048, disk_size_gb=8) as box:
# 1) Install system CA certificates. Slim images have none, and Codex is a
# Rust binary that reads the system trust store — without this, every
# model call fails at the TLS handshake.
await run(box, "sh", "-c",
"apt-get update -qq && apt-get install -y -qq ca-certificates",
timeout=300.0)
# 2) Install the CLI
await run(box, "npm", "install", "-g", "@openai/codex", timeout=600.0)
version = await run(box, "codex", "--version")
print(version.stdout.strip())
# 3) Authenticate. `codex login --with-api-key` reads the key from stdin,
# so the key never appears in the command line or the process list.
await run(box, "sh", "-c",
'printenv OPENAI_API_KEY | codex login --with-api-key',
env={"OPENAI_API_KEY": API_KEY}, timeout=120.0)
# 4) One-shot prompt. --skip-git-repo-check is needed because the working
# directory in a fresh box is not a git repository.
answer = await run(
box, "sh", "-c",
'codex exec "Write a one-line Python snippet that reverses a string." '
'--skip-git-repo-check < /dev/null',
timeout=300.0,
)
print(answer.stdout)
except RuntimeError as exc:
print(f"runtime error: {exc}")
if __name__ == "__main__":
asyncio.run(main())