[codex] Prepare Python SDK beta documentation and package metadata (#24836)

## Why

The initial public `openai-codex` beta should read and install like a
normal published Python package before a release tag is created. This
follows merged PR #24828, which establishes the independent SDK beta
release plumbing and exact runtime dependency.

## What changed

- Rewrote `sdk/python/README.md` as a compact PyPI-facing beta package
page: published installation, one quickstart, short login examples,
built-in help, and links to deeper guides.
- Updated the getting-started guide, API reference, FAQ, and examples
index to present the published beta consistently without repeating
onboarding in the package landing page or reference page.
- Made `pip install openai-codex` the primary install path while beta
releases are the only published SDK releases, with `--pre` documented
for opting into prereleases after a stable release exists.
- Added curated `help()` / `pydoc` docstrings across the public API and
generated public convenience methods through
`scripts/update_sdk_artifacts.py`.
- Declared the repository `Apache-2.0` license expression and
Documentation URL in package metadata, without introducing a duplicated
SDK-local license file.
- Kept the source distribution focused on installable package material
(`src/openai_codex`, `README.md`, and `pyproject.toml`); the repository
docs and runnable examples remain linked from the PyPI README.
- Built release artifacts in an Alpine container on the Ubuntu runner,
matching Python SDK CI and allowing type generation to install the
published `musllinux` runtime wheel.
- Added `twine check --strict` to the release workflow so malformed PyPI
metadata or rendered README content fails before publishing.
- Added focused SDK assertions for beta metadata, the exact runtime pin,
source distribution contents, and the built-in Python documentation
surface.

## Validation

- Ran `uv run --frozen --extra dev ruff check
scripts/update_sdk_artifacts.py src/openai_codex
tests/test_public_api_signatures.py
tests/test_artifact_workflow_and_binaries.py` before the final
README-only reductions and review-fix follow-ups.
- Built `openai_codex-0.1.0b1-py3-none-any.whl` and
`openai_codex-0.1.0b1.tar.gz` before the final README-only reductions
and review-fix follow-ups.
- Ran `python -m twine check --strict` on both built artifacts before
the final README-only reductions and review-fix follow-ups.
- Verified artifact metadata reports `Apache-2.0` without a duplicated
SDK-local license file.
- Verified `inspect.getdoc(...)` resolves documentation for the package,
`Codex`, `CodexConfig`, and key generated thread methods.
- Rebased the documentation/readiness change onto merged PR #24828
without changing the intended SDK or workflow file contents.
- Final verification is delegated to online CI for this PR.
This commit is contained in:
Ahmed Ibrahim
2026-05-27 18:29:05 -07:00
committed by GitHub
Unverified
parent 4d0c4cd058
commit eb1cc3824c
16 changed files with 365 additions and 239 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
# OpenAI Codex SDK — API Reference
# OpenAI Codex Python SDK (Beta) - API Reference
Public surface of `openai_codex` for Codex workflows.
This SDK surface is experimental. Turn streams are routed by turn ID so one client can consume multiple active turns concurrently.
This SDK is in beta. Public APIs may change before `1.0`. Turn streams are routed by turn ID so one client can consume multiple active turns concurrently.
Thread starts default to `ApprovalMode.auto_review`; turn starts accept an optional `approval_mode` override.
## Package Entry
+17 -3
View File
@@ -1,5 +1,18 @@
# FAQ
## Is the Python SDK stable?
`openai-codex` is a public beta. Install it with
`pip install openai-codex`; public APIs may change before `1.0`. While beta
releases are the only published SDK releases, pip selects the latest beta.
After a stable release exists, pass `--pre` to opt into newer prereleases.
## Why does the SDK install a runtime package?
The SDK and runtime packages are versioned independently. Each SDK release
pins one compatible runtime dependency, so `openai-codex==0.1.0b1` installs
`openai-codex-cli-bin==0.132.0` automatically.
## Thread vs turn
- A `Thread` is conversation state.
@@ -84,9 +97,9 @@ This avoids duplicate ways to do the same operation and keeps behavior explicit.
Common causes:
- published runtime package (`openai-codex-cli-bin`) is not installed
- installation is incomplete and the pinned `openai-codex-cli-bin` dependency is missing
- local `codex_bin` override points to a missing file
- installed Codex runtime version older than the SDK schema
- a custom local Codex executable does not support the SDK operation being used
## Why does a turn "hang"?
@@ -99,7 +112,8 @@ A turn is complete only when `turn/completed` arrives for that turn ID.
Use `retry_on_overload(...)` for transient overload failures (`ServerBusyError`).
Do not blindly retry all errors. For `InvalidParamsError` or `MethodNotFoundError`, fix inputs or update the runtime/schema version instead.
Do not blindly retry all errors. For `InvalidParamsError` or
`MethodNotFoundError`, fix the input or use the runtime pinned by the SDK.
## Common pitfalls
+98 -90
View File
@@ -1,68 +1,70 @@
# Getting Started
This is the fastest path from install to a multi-turn thread using the public SDK surface.
This guide gets a published OpenAI Codex Python SDK beta installation running
with a multi-turn thread.
The SDK is experimental, so the public API and runtime requirements may keep evolving before the first public release.
## 1. Install
## 1) Install
From repo root:
Install the SDK:
```bash
cd sdk/python
uv sync
source .venv/bin/activate
pip install openai-codex
```
For a reproducible install of this release:
```bash
pip install openai-codex==0.1.0b1
```
Requirements:
- Python `>=3.10`
- uv
- installed `openai-codex-cli-bin` runtime package, or an explicit `codex_bin` override
- An existing Codex account session, or one of the login flows below
## 2) Authenticate when needed
The SDK installs its compatible `openai-codex-cli-bin` runtime dependency
automatically. While beta releases are the only published SDK releases, this
normal install command selects the latest beta. After a stable release exists,
use `pip install --pre openai-codex` to opt into a newer prerelease.
Existing Codex auth state is reused automatically. To authenticate from the SDK,
use the flow that fits your app:
## 2. Authenticate When Needed
```python
from openai_codex import Codex, Sandbox
with Codex() as codex:
codex.login_api_key("sk-...")
account = codex.account()
print(account.account)
```
Interactive ChatGPT browser login returns a handle that carries the URL and the
matching completion event:
```python
with Codex() as codex:
login = codex.login_chatgpt()
print(login.auth_url)
completed = login.wait()
print(completed.success)
```
Device-code login works the same way with
`login_chatgpt_device_code()`, which exposes `verification_url`, `user_code`,
and `wait()`.
## 3) Run your first turn (sync)
Existing Codex authentication is reused automatically. For ChatGPT browser
login:
```python
from openai_codex import Codex
with Codex() as codex:
server = codex.metadata.serverInfo
print("Server:", None if server is None else server.name, None if server is None else server.version)
login = codex.login_chatgpt()
print(login.auth_url)
print(login.wait().success)
```
thread = codex.thread_start(
model="gpt-5.4",
config={"model_reasoning_effort": "high"},
sandbox=Sandbox.workspace_write,
)
For device-code login:
```python
with Codex() as codex:
login = codex.login_chatgpt_device_code()
print(login.verification_url, login.user_code)
print(login.wait().success)
```
For API-key login:
```python
with Codex() as codex:
codex.login_api_key("sk-...")
print(codex.account().account)
```
## 3. Run A Turn
```python
from openai_codex import Codex, Sandbox
with Codex() as codex:
thread = codex.thread_start(sandbox=Sandbox.workspace_write)
result = thread.run("Say hello in one sentence.")
print("Thread:", thread.id)
@@ -70,19 +72,15 @@ with Codex() as codex:
print("Items:", len(result.items))
```
What happened:
`Thread.run(...)` starts a turn, waits for completion, and returns
`TurnResult`. Plain strings are shorthand for `TextInput(...)`.
- `Codex()` started and initialized `codex app-server`.
- `thread_start(...)` created a thread.
- `thread.run("...")` started a turn, consumed events until completion, and returned `TurnResult` with turn metadata, final assistant response, collected items, and usage.
- `result.final_response` is `None` when no final-answer or phase-less assistant message item completes for the turn.
- plain strings are accepted anywhere a turn input is accepted; typed inputs are still available for multimodal and structured cases
- use `thread.turn(...)` when you need a `TurnHandle` for streaming, steering, or interrupting before collecting `TurnResult`
- one client can consume multiple active turns concurrently; turn streams are routed by turn ID
Use `Thread.turn(...)` when you need a `TurnHandle` for streaming, steering,
or interrupting an active turn.
## 4) Change sandbox access
## 4. Choose Sandbox Access
Use one enum for the initial sandbox and for later turn overrides:
Use one enum for the initial thread and later turn overrides:
```python
from openai_codex import Codex, Sandbox
@@ -96,40 +94,44 @@ with Codex() as codex:
Available presets:
- `Sandbox.read_only`: read files without allowing writes.
- `Sandbox.workspace_write`: the normal default for projects with a recorded trust decision; read files and write inside the workspace and configured writable roots.
- `Sandbox.workspace_write`: read files and write inside the workspace and
configured writable roots; this is the normal default for workspace work.
- `Sandbox.full_access`: run without filesystem access restrictions.
When `sandbox=` is omitted, Codex uses its configured default. A turn
override also becomes the sandbox for subsequent turns on that thread.
When `sandbox=` is omitted, Codex uses its configured default. A turn override
also applies to subsequent turns on that thread.
## 5) Continue the same thread (multi-turn)
## 5. Continue A Thread
```python
from openai_codex import Codex
with Codex() as codex:
thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})
first = thread.run("Summarize Rust ownership in 2 bullets.")
second = thread.run("Now explain it to a Python developer.")
print("first:", first.final_response)
print("second:", second.final_response)
thread = codex.thread_start()
thread.run("Summarize Rust ownership in two bullets.")
result = thread.run("Now explain it to a Python developer.")
print(result.final_response)
```
## 6) Async parity
To resume a stored thread later:
Use `async with AsyncCodex()` as the normal async entrypoint. `AsyncCodex`
initializes lazily, and context entry makes startup/shutdown explicit.
```python
with Codex() as codex:
thread = codex.thread_resume("thr_123")
print(thread.run("Continue where we left off.").final_response)
```
## 6. Use The Async Client
```python
import asyncio
from openai_codex import AsyncCodex
from openai_codex import AsyncCodex, Sandbox
async def main() -> None:
async with AsyncCodex() as codex:
thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"})
thread = await codex.thread_start(sandbox=Sandbox.workspace_write)
result = await thread.run("Continue where we left off.")
print(result.final_response)
@@ -137,30 +139,36 @@ async def main() -> None:
asyncio.run(main())
```
## 7) Resume an existing thread
## 7. Get Help
Python's built-in documentation tools cover the curated SDK surface:
```python
from openai_codex import Codex
import openai_codex
from openai_codex import Codex, CodexConfig
THREAD_ID = "thr_123" # replace with a real id
with Codex() as codex:
thread = codex.thread_resume(THREAD_ID)
result = thread.run("Continue where we left off.")
print(result.final_response)
help(openai_codex)
help(Codex)
help(CodexConfig)
```
## 8) Public Codex protocol types
The convenience wrappers live at the package root. Public Codex protocol value and
event types live under:
```python
from openai_codex.types import ThreadReadResponse, Turn, TurnStatus
```bash
python -m pydoc openai_codex
```
## 9) Next stops
## Developing From This Repository
- API surface and signatures: `docs/api-reference.md`
- Common decisions/pitfalls: `docs/faq.md`
- End-to-end runnable examples: `examples/README.md`
Contributors working from a checkout can install development dependencies from
the repository:
```bash
cd sdk/python
uv sync --extra dev
source .venv/bin/activate
```
## Next Stops
- [API reference](https://github.com/openai/codex/blob/main/sdk/python/docs/api-reference.md)
- [FAQ](https://github.com/openai/codex/blob/main/sdk/python/docs/faq.md)
- [Runnable examples](https://github.com/openai/codex/blob/main/sdk/python/examples/README.md)