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.
- 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
ResponseEventobjects for observability and UI. - Predictable failures: explicit error types such as
NotAuthenticatedErrorandSessionNotFoundError. - Policy control: approval/file-change/tool-input/tool-call hooks and policy engine integration.
- Thin protocol wrapper: close to
codex app-serverbehavior, easier to reason about and debug.
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)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)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())# 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 fullNote: 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.
codex app-server is Codex CLI's local JSON-RPC runtime over stdio.
For high-frequency APIs, the core model is:
- Pick a
thread_idor start a new thread. - Provide one prompt plus optional turn parameters.
- Run one turn.
- Choose how you want the result back:
responses_createfor the final aggregate,responses_eventsfor structured streaming,responses_stream_textfor text-only streaming.
Implementation-wise, one responses_create(prompt=...) call is essentially:
-
create_client()creates a sync facade (CodexAgenticClient). - Sync call forwards to
AsyncCodexAgenticClientthrough a dedicated worker thread. -
connect()startscodex app-serverand performsinitialize/initialized. -
_request(method, params)handles all JSON-RPC request/response plumbing. - 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.
Default behavior without hooks/policy:
- Command approval:
decline - File change approval:
decline - Permissions approval: empty grant with
turnscope - 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-accessremoves sandbox restrictions for command execution -
--dangerously-bypass-approvals-and-sandboxskips both approvals and sandbox protections
Those higher-permission modes should stay explicit opt-ins for externally sandboxed or highly trusted environments.
- Python
3.9+(recommended:3.12) -
uv(recommended for development workflows) -
codexCLI installed and runnable - Authentication completed via
codex login
uv add codex-python-sdk
uv run codex-python-sdk-demo --helpor
pip install codex-python-sdk
codex-python-sdk-demo --help./uv-sync.shThis bootstraps a local .venv and installs project/test/build dependencies.
Factory:
create_client(**kwargs) -> CodexAgenticClientcreate_async_client(**kwargs) -> AsyncCodexAgenticClient
Important runtime kwargs:
automatic_approval_review=True-
enabled_features=[...]/disabled_features=[...] -
enable_web_searchas a compatibility alias forweb_search="live"
High-frequency response APIs:
responses_create(...) -> AgentResponseresponses_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
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.mddocs/zh/core_mechanism.mddocs/zh/config.mddocs/zh/api.mddocs/zh/policy.mddocs/zh/app_server.md
- After
AppServerConnectionError, recreate the client instead of relying on implicit reconnect behavior. - Internal app-server
stderrbuffering 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) raiseCodexAgenticError.
./uv-sync.sh
uv run python3 -m pytest -q -m "not real"# 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 helpRecommended upload auth: ~/.pypirc with API token.
-
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
-
CodexAgenticError: base SDK error -
AppServerConnectionError: app-server transport/setup failure -
SessionNotFoundError: unknown thread/session id -
NotAuthenticatedError: auth unavailable or invalid