[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
+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)