Skip to main content

Unofficial, natively async Python SDK for Codex app-server over JSON-RPC v2 on stdio.

Project description

Unofficial Codex Python SDK (codex-python-sdk-unofficial)

Unofficial Python SDK for the Codex app-server protocol.

The package launches codex app-server --listen stdio://, speaks JSON-RPC v2 over stdio, and keeps Codex concepts such as threads, turns, items, and approval requests visible in the Python API.

Status: preview. The low-level AppServerClient, the one-shot async query() helper, the stateful async CodexSDKClient, and the synchronous SyncCodexSDKClient wrapper are all usable today. The sync client runs the async client on a private event loop thread, so it is convenient for synchronous call sites but less natural than using the native async APIs directly.

Highlights

  • Native asyncio transport for the local Codex app-server.
  • Typed request and response models generated from vendored schema snapshots.
  • Streamed turn events for assistant text, reasoning text, command output, item lifecycle, approvals, token usage, and raw passthrough envelopes.
  • First-class approval helpers built around ApprovalRequest and ApprovalDecision.
  • A small query() helper for single-turn scripts and automation jobs.
  • A stateful CodexSDKClient for higher-level async thread workflows.
  • A SyncCodexSDKClient wrapper for synchronous Python.
  • A lower-level AppServerClient for full control over thread and turn lifecycle calls.
  • A scheduled meta-agent workflow that uses this SDK to track openai/codex branch and release drift.

Requirements

  • Python 3.11+
  • A working codex CLI on PATH
  • Whatever authentication your local Codex CLI already requires

Install

Install from PyPI:

pip install codex-python-sdk-unofficial

Or with uv:

uv add codex-python-sdk-unofficial

Install from a checkout for local development:

uv sync

That creates .venv/, installs the package in editable mode, and includes the default contributor tooling.

If you only want the runtime dependency set:

uv sync --no-dev

Quick Start

Use query() when you want one turn, an ephemeral thread, and streamed events from async code:

import asyncio

from codex_agent_sdk import AgentTextDeltaEvent, CodexOptions, TurnCompletedEvent, query


async def main() -> None:
    async for event in query(
        prompt="Summarize the purpose of this repository.",
        options=CodexOptions(
            cwd=".",
            approval_policy="on-request",
            model="gpt-5.4",
        ),
    ):
        if isinstance(event, AgentTextDeltaEvent):
            print(event.text_delta, end="", flush=True)
        elif isinstance(event, TurnCompletedEvent):
            print(f"\n\nturn status: {event.turn_status}")


asyncio.run(main())

Use SyncCodexSDKClient when you need synchronous Python. It wraps the async client on a private background loop, so it is practical for non-async scripts but still not as natural as the native async surface:

from codex_agent_sdk import AgentTextDeltaEvent, CodexOptions, SyncCodexSDKClient


with SyncCodexSDKClient(
    options=CodexOptions(
        cwd=".",
        approval_policy="never",
        model="gpt-5.4",
    )
) as client:
    turn = client.query("Summarize the purpose of this repository.")
    for event in turn:
        if isinstance(event, AgentTextDeltaEvent):
            print(event.text_delta, end="", flush=True)

    result = turn.wait()
    print(f"\n\nturn status: {result.status}")

Use CodexSDKClient when you want a long-lived async client that manages an active thread across multiple turns. Drop down to AppServerClient when you need explicit control over app-server requests:

import asyncio

from codex_agent_sdk import AppServerClient, AppServerConfig


async def main() -> None:
    async with AppServerClient(AppServerConfig()) as client:
        await client.initialize()
        thread = await client.thread_start(ephemeral=True)
        turn = await client.turn_start(
            thread_id=thread.thread.id,
            input="List the highest-risk files in this repository.",
        )
        completion = await client.wait_for_turn_completed(
            thread_id=thread.thread.id,
            turn_id=turn.turn.id,
        )
        print(completion.status)


asyncio.run(main())

Examples

The repository ships a few runnable examples under examples:

  • uv run python examples/workspace_brief.py streams a short brief for the current workspace with the one-shot helper.
  • uv run python examples/file_brief.py path/to/file.txt summarizes a single UTF-8 text file.
  • uv run python examples/interactive_thread.py runs a small interactive loop on top of AppServerClient, including manual approval handling.

See examples/README.md for details and command-line options.

Documentation

Development

Common verification commands:

uv run pytest
uv run mypy
uv run ruff check .
uv run ruff format --check .
uv build

Contributor setup, code generation, and schema refresh workflows are documented in CONTRIBUTING.md.

Automated Upstream Tracking

This repository now ships a daily GitHub Actions workflow at .github/workflows/version-tracker.yml.

The workflow:

  • checks the latest stable openai/codex GitHub release every day and on manual dispatch
  • compares that release tag against the committed .github/codex-upstream-state.json
  • uses python -m codex_meta_agent plus SyncCodexSDKClient to let Codex reconcile local code, docs, tests, and release metadata for that release
  • keeps the automation runtime on a controller checkout while Codex edits a separate clean target checkout
  • runs the repository verification commands
  • commits release-tracking changes to puck/frontier-realese--v<version> from a fresh main checkout
  • opens a pull request for that prepared frontier release branch
  • ships a separate manual workflow for backporting older releases on puck/backport-release--v<version>
  • marks backport branch heads with backport-v<version> tags instead of merging them back to main
  • publishes a GitHub release tagged v<version> and publishes the matching PyPI release when that branch is merged to main

See docs/upstream-tracking.md for the detailed workflow contract, local dry-run command, and required GitHub Actions secrets.

License

This project is licensed under the Apache License 2.0. See LICENSE.

Project Notes

  • This project is unofficial and is not affiliated with OpenAI
  • This was implemented and released by the project maintainers
  • All PRs merged to main must be approved by the maintainers
  • Stable protocol artifacts are generated from vendored schema snapshots checked into this repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codex_python_sdk_unofficial-0.128.0.tar.gz (111.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_python_sdk_unofficial-0.128.0-py3-none-any.whl (128.7 kB view details)

Uploaded Python 3

File details

Details for the file codex_python_sdk_unofficial-0.128.0.tar.gz.

File metadata

File hashes

Hashes for codex_python_sdk_unofficial-0.128.0.tar.gz
Algorithm Hash digest
SHA256 0ada10d34f95386314f03208656ee761dc4fe67e44092c532464593c314ba7aa
MD5 aa9fae12c6ee3f7660047e26f118ea78
BLAKE2b-256 d12ea3e5f4c3ebf5f9df3585b6e161cc27503d5c59b50201782ca922a7fee6bb

See more details on using hashes here.

File details

Details for the file codex_python_sdk_unofficial-0.128.0-py3-none-any.whl.

File metadata

File hashes

Hashes for codex_python_sdk_unofficial-0.128.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8e1aa73126839f4a785fc599ede55ac5deec8041bf8b0ae675346034f0611118
MD5 e2951e68bbbb76ea121116602e2d8edf
BLAKE2b-256 9a37e53fb60bb49c2846e1012e91558c7672347fe63e5bb42cbf7dca3c882a30

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page