[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
@@ -258,6 +258,34 @@ def test_source_sdk_package_pins_published_runtime() -> None:
}
def test_source_sdk_package_declares_beta_documentation_and_release_files() -> None:
"""Public package metadata should link beta docs and ship package metadata."""
pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text())
readme = (ROOT / "README.md").read_text()
assert {
"description": pyproject["project"]["description"],
"is_beta": "Development Status :: 4 - Beta" in pyproject["project"]["classifiers"],
"license": pyproject["project"]["license"],
"documentation": pyproject["project"]["urls"]["Documentation"],
"sdist_include": pyproject["tool"]["hatch"]["build"]["targets"]["sdist"]["include"],
"readme_is_beta": "# OpenAI Codex Python SDK (Beta)" in readme,
"local_license_file": (ROOT / "LICENSE").exists(),
} == {
"description": "Python SDK for Codex",
"is_beta": True,
"license": "Apache-2.0",
"documentation": "https://github.com/openai/codex/tree/main/sdk/python/docs",
"sdist_include": [
"src/openai_codex/**",
"README.md",
"pyproject.toml",
],
"readme_is_beta": True,
"local_license_file": False,
}
def test_release_metadata_retries_without_invalid_auth(
monkeypatch: pytest.MonkeyPatch,
) -> None:
@@ -211,6 +211,30 @@ def test_package_and_default_client_versions_follow_project_version() -> None:
assert CodexConfig().client_version == openai_codex.__version__
def test_curated_public_api_has_builtin_help_documentation() -> None:
"""The package's normal ``help()`` surface should explain common first-use APIs."""
documented = {
"module": openai_codex,
"Codex": Codex,
"AsyncCodex": AsyncCodex,
"CodexConfig": CodexConfig,
"Thread": Thread,
"AsyncThread": AsyncThread,
"TurnHandle": TurnHandle,
"AsyncTurnHandle": AsyncTurnHandle,
"TurnResult": TurnResult,
"Sandbox": Sandbox,
"thread_start": Codex.thread_start,
"thread_resume": Codex.thread_resume,
"thread_run": Thread.run,
"thread_turn": Thread.turn,
}
assert {name: inspect.getdoc(value) is not None for name, value in documented.items()} == (
dict.fromkeys(documented, True)
)
def test_package_includes_py_typed_marker() -> None:
"""The wheel should advertise that inline type information is available."""
marker = resources.files("openai_codex").joinpath("py.typed")