codex-python-sdk

Python wrapper for Codex app-server JSON-RPC interface


License
MIT
Install
pip install codex-python-sdk==0.2.1

Documentation

codex-python-sdk

GitHub | English | 简体中文 | Docs

Production-focused Python SDK for running Codex agents through codex app-server.

codex-python-sdk gives you a stable Python interface over Codex JSON-RPC so you can automate agent workflows, stream structured runtime events, and enforce runtime policy from your own applications.

Why This SDK

  • Script-first API: built for automation pipelines, not only interactive CLI sessions.
  • Sync + async parity: same mental model and similar method names in both clients.
  • Structured streaming: consume normalized ResponseEvent objects for observability and UI.
  • Predictable failures: explicit error types such as NotAuthenticatedError and SessionNotFoundError.
  • Policy control: approval/file-change/tool-input/tool-call hooks and policy engine integration.
  • Thin protocol wrapper: close to codex app-server behavior, easier to reason about and debug.

30-Second Quick Start

from codex_python_sdk import create_client

with create_client() as client:
    result = client.responses_create(prompt="Reply with exactly: READY")
    print(result.thread_id)
    print(result.text)

Core Workflows

Stream events (for logs/UI)

from codex_python_sdk import create_client, render_exec_style_events

with create_client() as client:
    events = client.responses_events(prompt="Summarize this repository")
    render_exec_style_events(events)

Async flow

import asyncio
from codex_python_sdk import create_async_client


async def main() -> None:
    async with create_async_client() as client:
        result = await client.responses_create(prompt="Reply with exactly: ASYNC_READY")
        print(result.text)


asyncio.run(main())

Smoke and demo runner

# Quick health check (default mode)
codex-python-sdk-demo --mode smoke

# Stable API showcase
codex-python-sdk-demo --mode demo

# Demo + unstable remote/interrupt/compact paths
codex-python-sdk-demo --mode full

Note: the demo runner uses explicit permissive hooks (accept for command/file approvals and empty tool-input answers) so it can run unattended. The SDK defaults are now fail-closed; keep permissive behavior explicit in demos and automation.

Mental Model: Thread History + Turn

codex app-server is Codex CLI's local JSON-RPC runtime over stdio.

For high-frequency APIs, the core model is:

  1. Pick a thread_id or start a new thread.
  2. Provide one prompt plus optional turn parameters.
  3. Run one turn.
  4. Choose how you want the result back: responses_create for the final aggregate, responses_events for structured streaming, responses_stream_text for text-only streaming.

Implementation-wise, one responses_create(prompt=...) call is essentially:

  1. create_client() creates a sync facade (CodexAgenticClient).
  2. Sync call forwards to AsyncCodexAgenticClient through a dedicated worker thread.
  3. connect() starts codex app-server and performs initialize/initialized.
  4. _request(method, params) handles all JSON-RPC request/response plumbing.
  5. One shared turn runner performs thread/start|resume -> turn/start -> notification stream; responses_create() only aggregates the result.

For a deeper walkthrough, see docs/core_mechanism.md.

Safety Defaults (Important)

Default behavior without hooks/policy:

  • Command approval: decline
  • File change approval: decline
  • Permissions approval: empty grant with turn scope
  • MCP elicitation: decline
  • Tool user input: empty answers
  • Tool call: failure response with explanatory text

This is production-safer by default, but may block unattended workflows unless you opt into looser hooks.

Recommended setup: rely on native automatic approval review and keep local policy deterministic.

from codex_python_sdk import RuleBasedPolicyEngine, create_client

engine = RuleBasedPolicyEngine(
    {
        "system_rubric": "Allow read-only operations. Decline unknown write operations.",
        "command_rules": [
            {"name": "readonly-shell", "when": {"command_regex": r"^(pwd|ls|cat|rg)\\b"}, "decision": "accept"}
        ],
        "defaults": {"command": "decline", "file_change": "decline", "tool_input": "auto_empty"},
    }
)

with create_client(
    automatic_approval_review=True,
    policy_engine=engine,
) as client:
    result = client.responses_create(prompt="Show git status.")
    print(result.text)

automatic_approval_review=True enables the runtime's native approval reviewer (guardian_approval).

Recommended default operating mode for most repository automation:

  • automatic_approval_review=True
  • thread sandbox remains workspace-write
  • thread approval policy remains on-request

This gives the agent writable access inside the workspace while keeping sandboxing and approval flows intact. It is usually the right default for coding agents that only need to read and write within the current repo.

Do not treat this as equivalent to bypass mode:

  • danger-full-access removes sandbox restrictions for command execution
  • --dangerously-bypass-approvals-and-sandbox skips both approvals and sandbox protections

Those higher-permission modes should stay explicit opt-ins for externally sandboxed or highly trusted environments.

Install

Prerequisites

  • Python 3.9+ (recommended: 3.12)
  • uv (recommended for development workflows)
  • codex CLI installed and runnable
  • Authentication completed via codex login

Install from PyPI

uv add codex-python-sdk
uv run codex-python-sdk-demo --help

or

pip install codex-python-sdk
codex-python-sdk-demo --help

Developer setup (for contributors)

./uv-sync.sh

This bootstraps a local .venv and installs project/test/build dependencies.

API Snapshot

Factory:

  • create_client(**kwargs) -> CodexAgenticClient
  • create_async_client(**kwargs) -> AsyncCodexAgenticClient

Important runtime kwargs:

  • automatic_approval_review=True
  • enabled_features=[...] / disabled_features=[...]
  • enable_web_search as a compatibility alias for web_search="live"

High-frequency response APIs:

  • responses_create(...) -> AgentResponse
  • responses_events(...) -> Iterator[ResponseEvent] / AsyncIterator[ResponseEvent]
  • responses_stream_text(...) -> Iterator[str] / AsyncIterator[str]

Core thread APIs:

  • thread_start, thread_read, thread_list
  • thread_fork, thread_rollback
  • turn_interrupt, turn_steer

Runtime discovery:

  • experimental_feature_list(limit=None, cursor=None)

Account basics:

  • account_read, account_rate_limits_read

Documentation Map

English:

  • docs/tutorial.md: practical workflows and end-to-end usage
  • docs/core_mechanism.md: architecture-level core control flow
  • docs/config.md: server/thread/turn configuration model
  • docs/api.md: full API reference (sync + async)
  • docs/policy.md: hooks and policy engine integration
  • docs/app_server.md: app-server concepts and protocol mapping

简体中文:

  • docs/zh/tutorial.md
  • docs/zh/core_mechanism.md
  • docs/zh/config.md
  • docs/zh/api.md
  • docs/zh/policy.md
  • docs/zh/app_server.md

Notes

  • After AppServerConnectionError, recreate the client instead of relying on implicit reconnect behavior.
  • Internal app-server stderr buffering keeps only the latest 500 lines in SDK-captured diagnostics.
  • review_start(...) is for code review flows; it is not the same feature as runtime approval review.
  • Invalid command/file policy decision values (allowed: accept, acceptForSession, decline, cancel) raise CodexAgenticError.

Development

./uv-sync.sh
uv run python3 -m pytest -q -m "not real"

Release

# Default: test + build + twine check (no upload)
./build.sh

# Build only
./build.sh build

# Release to pypi (upload enabled explicitly)
TWINE_UPLOAD=1 ./build.sh release --repo pypi

# Release to testpypi
TWINE_UPLOAD=1 ./build.sh release --repo testpypi

# Upload existing artifacts only
./build.sh upload --repo pypi

# Help
./build.sh help

Recommended upload auth: ~/.pypirc with API token.

Project Layout

  • codex_python_sdk/: SDK source code
  • codex_python_sdk/examples/: runnable demo code
  • tests/: unit and real-runtime integration tests
  • uv-sync.sh: dev environment bootstrap
  • build.sh: build/release script

Error Types

  • CodexAgenticError: base SDK error
  • AppServerConnectionError: app-server transport/setup failure
  • SessionNotFoundError: unknown thread/session id
  • NotAuthenticatedError: auth unavailable or invalid