Files
codex/sdk/python
Michael Bolin 3e77859d0a sdk: launch packaged Codex runtimes
## Why

The Python and TypeScript SDKs launch the native Codex runtime directly, so they need to understand the same package layout that the release artifacts now use. Without this, SDK runtime wheels would keep carrying only a loose `bin/codex` plus ad hoc helper binaries, the TypeScript SDK would keep resolving the legacy optional-dependency layout, and bundled `codex-path` tools such as `rg` would not be prepended when the SDK starts Codex.

## What Changed

- Stage `openai-codex-cli-bin` from a Codex package directory, including `codex-package.json`, `bin/`, `codex-resources/`, and `codex-path/`.
- Make `stage-runtime` package-dir-only; legacy loose-binary wrapping now happens in `_runtime_setup.py` before calling the staging script.
- Expose Python runtime helpers for the bundled package directory and `codex-path`, and prepend that path when `openai_codex` launches the installed runtime without duplicating Windows `Path`/`PATH` keys.
- Teach the TypeScript SDK to resolve package-layout optional dependencies while keeping the legacy layout fallback, and preserve the existing Windows path variable casing when prepending `codex-path`.
- Update the Rust release workflows to build Python runtime wheels from the generated Codex package directories instead of loose binaries.

## Test Plan

- `python3 -m py_compile sdk/python/scripts/update_sdk_artifacts.py sdk/python/_runtime_setup.py sdk/python/src/openai_codex/client.py sdk/python-runtime/src/codex_cli_bin/__init__.py`
- `uv run --frozen --project sdk/python --extra dev ruff check sdk/python/scripts/update_sdk_artifacts.py sdk/python/_runtime_setup.py sdk/python/src/openai_codex/client.py sdk/python/tests/test_artifact_workflow_and_binaries.py sdk/python-runtime/src/codex_cli_bin/__init__.py`
- `uv run --frozen --project sdk/python --extra dev pytest sdk/python/tests/test_artifact_workflow_and_binaries.py`
- `pnpm eslint src/exec.ts tests/exec.test.ts`
- `pnpm test --runInBand tests/exec.test.ts`
2026-05-20 17:36:53 -07:00
..
2026-05-20 17:36:53 -07:00
2026-05-12 16:24:54 +02:00

OpenAI Codex Python SDK (Experimental)

Experimental Python SDK for codex app-server JSON-RPC v2 over stdio, with a small default surface optimized for real scripts and apps.

The generated wire-model layer is sourced from the pinned openai-codex-cli-bin runtime package and exposed as Pydantic models with snake_case Python fields that serialize back to the app-servers camelCase wire format. The package root exports the ergonomic client API; public app-server value and event types live in openai_codex.types.

Install

cd sdk/python
uv sync
source .venv/bin/activate

Published SDK builds pin an exact openai-codex-cli-bin runtime dependency with the same version as the SDK. Pass AppServerConfig(codex_bin=...) only when you intentionally want to run against a specific local app-server binary.

Quickstart

from openai_codex import Codex

with Codex() as codex:
    # Call login_api_key(...) first when this app-server session is not
    # already authenticated.
    thread = codex.thread_start(model="gpt-5")
    result = thread.run("Say hello in one sentence.")
    print(result.final_response)
    print(len(result.items))

thread.run(...) and thread.turn(...).run() return TurnResult. Its final_response is None when the turn completes without a final-answer or phase-less assistant message item.

Login

Use the auth helper that matches your app:

from openai_codex import Codex

with Codex() as codex:
    codex.login_api_key("sk-...")
    account = codex.account()
    print(account.account)

Interactive ChatGPT login returns a handle. Open the provided URL or device-code page, then wait for the matching completion event:

with Codex() as codex:
    login = codex.login_chatgpt()
    print(login.auth_url)
    completed = login.wait()
    print(completed.success)

Use login_chatgpt_device_code() for device-code auth, handle.cancel() to stop an in-progress interactive login, and logout() to clear the active app-server account session.

Docs map

  • Golden path tutorial: docs/getting-started.md
  • API reference (signatures + behavior): docs/api-reference.md
  • Common decisions and pitfalls: docs/faq.md
  • Runnable examples index: examples/README.md
  • Jupyter walkthrough notebook: notebooks/sdk_walkthrough.ipynb

Examples

Start here:

cd sdk/python
python examples/01_quickstart_constructor/sync.py
python examples/01_quickstart_constructor/async.py

Runtime

Published SDK builds are pinned to an exact openai-codex-cli-bin package version, and that runtime package carries the platform-specific binary for the target wheel. The SDK package version and runtime package version must match.

Compatibility and versioning

  • Package: openai-codex
  • Runtime package: openai-codex-cli-bin
  • Python: >=3.10
  • Target protocol: Codex app-server JSON-RPC v2
  • Versioning rule: the SDK package version is the underlying Codex runtime version

Notes

  • Codex() is eager and performs startup + initialize in the constructor.
  • Use context managers (with Codex() as codex:) to ensure shutdown.
  • Plain strings are accepted anywhere a turn input is accepted; they are shorthand for TextInput(...).
  • Prefer thread.run("...") for the common case. Use thread.turn(...) when you need streaming, steering, or interrupt control.
  • For transient overload, use retry_on_overload from the package root.