Skip to content

codex_auth_helper API

codex-auth-helper is intentionally small. The public API is documented here so ACP examples can depend on it without requiring readers to inspect the package source first.

Functions

create_codex_responses_model(model_name, *, config=None, http_client=None, instructions, settings=None)

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/factory.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def create_codex_responses_model(
    model_name: str,
    *,
    config: CodexAuthConfig | None = None,
    http_client: httpx.AsyncClient | None = None,
    instructions: str,
    settings: OpenAIResponsesModelSettings | None = None,
) -> CodexResponsesModel:
    if instructions is None:
        raise ValueError(
            "`instructions` is required for Codex-backed Pydantic models. "
            "Pass an explicit system instruction string."
        )
    client = create_codex_async_openai(config=config, http_client=http_client)
    model_settings: OpenAIResponsesModelSettings = {"openai_store": False}
    if settings is not None:
        model_settings.update(settings)
        model_settings.setdefault("openai_store", False)
    return CodexResponsesModel(
        model_name,
        default_instructions=instructions,
        provider=OpenAIProvider(openai_client=client),
        settings=model_settings,
    )

create_codex_async_openai(*, config=None, http_client=None)

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/client.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def create_codex_async_openai(
    *,
    config: CodexAuthConfig | None = None,
    http_client: httpx.AsyncClient | None = None,
) -> CodexAsyncOpenAI:
    resolved_config = config or CodexAuthConfig()
    owns_http_client = http_client is None
    base_http_client = http_client or httpx.AsyncClient(
        follow_redirects=True,
        timeout=resolved_config.timeout_seconds,
    )
    token_manager = CodexTokenManager(
        config=resolved_config,
        store=CodexAuthStore(resolved_config.auth_path),
        http_client=base_http_client,
        owns_http_client=owns_http_client,
    )
    return CodexAsyncOpenAI(
        base_url=resolved_config.api_base_url,
        http_client=base_http_client,
        token_manager=token_manager,
        owns_http_client=owns_http_client,
    )

create_codex_openai(*, config=None, http_client=None)

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/client.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
def create_codex_openai(
    *,
    config: CodexAuthConfig | None = None,
    http_client: httpx.Client | None = None,
) -> CodexOpenAI:
    resolved_config = config or CodexAuthConfig()
    owns_http_client = http_client is None
    base_http_client = http_client or httpx.Client(
        follow_redirects=True,
        timeout=resolved_config.timeout_seconds,
    )
    token_manager = CodexTokenManager(
        config=resolved_config,
        store=CodexAuthStore(resolved_config.auth_path),
        http_client=httpx.AsyncClient(
            follow_redirects=True,
            timeout=resolved_config.timeout_seconds,
        ),
        owns_http_client=True,
    )
    return CodexOpenAI(
        base_url=resolved_config.api_base_url,
        http_client=base_http_client,
        token_manager=token_manager,
        owns_http_client=owns_http_client,
    )

create_codex_chat_openai(model_name, *, config=None, http_client=None, instructions, sync_http_client=None, include_response_headers=False, model_kwargs=None, output_version='responses/v1', reasoning=None, temperature=None, use_previous_response_id=False)

Build a Codex-backed LangChain chat model via langchain-openai.

The returned model is pinned to the OpenAI Responses API and reuses the same Codex auth flow as the Pydantic helper path.

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/factory.py
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def create_codex_chat_openai(
    model_name: str,
    *,
    config: CodexAuthConfig | None = None,
    http_client: httpx.AsyncClient | None = None,
    instructions: str,
    sync_http_client: httpx.Client | None = None,
    include_response_headers: bool = False,
    model_kwargs: dict[str, Any] | None = None,
    output_version: Literal["v0", "responses/v1"] = "responses/v1",
    reasoning: dict[str, Any] | None = None,
    temperature: float | None = None,
    use_previous_response_id: bool = False,
) -> ChatOpenAI:
    """Build a Codex-backed LangChain chat model via `langchain-openai`.

    The returned model is pinned to the OpenAI Responses API and reuses the
    same Codex auth flow as the Pydantic helper path.
    """

    try:
        from langchain_openai import ChatOpenAI
    except ModuleNotFoundError as exc:
        raise ModuleNotFoundError(
            "Install the optional LangChain dependency first: "
            'uv add "codex-auth-helper[langchain]" or '
            'pip install "codex-auth-helper[langchain]".'
        ) from exc

    async_root_client = create_codex_async_openai(config=config, http_client=http_client)
    sync_root_client = create_codex_openai(config=config, http_client=sync_http_client)
    chat_model_kwargs = dict(model_kwargs or {})
    if instructions is None:
        raise ValueError(
            "`instructions` is required for Codex-backed LangChain models. "
            "Pass an explicit system instruction string."
        )
    if "store" in chat_model_kwargs:
        raise ValueError(
            "Do not pass `model_kwargs['store']`; Codex-backed ChatOpenAI always forces "
            "`store=False`."
        )
    if "instructions" in chat_model_kwargs:
        raise ValueError(
            "Pass `instructions` either through the dedicated parameter or "
            "`model_kwargs['instructions']`, not both."
        )
    chat_model_kwargs["instructions"] = instructions
    chat_openai_kwargs: dict[str, Any] = {
        "model": model_name,
        "async_client": async_root_client.chat.completions,
        "client": sync_root_client.chat.completions,
        "include_response_headers": include_response_headers,
        "model_kwargs": chat_model_kwargs,
        "output_version": output_version,
        "reasoning": reasoning,
        "root_async_client": async_root_client,
        "root_client": sync_root_client,
        "store": False,
        "temperature": temperature,
        "use_previous_response_id": use_previous_response_id,
        "use_responses_api": True,
    }
    return ChatOpenAI(
        **chat_openai_kwargs,
    )

Classes

CodexResponsesModel(model_name, *, default_instructions, provider='openai', profile=None, settings=None)

Bases: OpenAIResponsesModel

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/model.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def __init__(
    self,
    model_name: str,
    *,
    default_instructions: str,
    provider: Any = "openai",
    profile: Any = None,
    settings: ModelSettings | None = None,
) -> None:
    self._default_instructions = default_instructions
    super().__init__(
        model_name,
        provider=provider,
        profile=profile,
        settings=settings,
    )

CodexAsyncOpenAI(*, base_url, http_client, token_manager, owns_http_client)

Bases: AsyncOpenAI

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/client.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def __init__(
    self,
    *,
    base_url: str,
    http_client: httpx.AsyncClient,
    token_manager: CodexTokenManager,
    owns_http_client: bool,
) -> None:
    self.token_manager = token_manager
    self._owns_http_client = owns_http_client
    super().__init__(
        api_key=token_manager.get_access_token,
        base_url=base_url,
        http_client=http_client,
    )

CodexOpenAI(*, base_url, http_client, token_manager, owns_http_client)

Bases: OpenAI

Source code in packages/helpers/codex-auth-helper/src/codex_auth_helper/client.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def __init__(
    self,
    *,
    base_url: str,
    http_client: httpx.Client,
    token_manager: CodexTokenManager,
    owns_http_client: bool,
) -> None:
    self.token_manager = token_manager
    self._owns_http_client = owns_http_client
    super().__init__(
        api_key=token_manager.get_access_token_sync,
        base_url=base_url,
        http_client=http_client,
    )

CodexAuthConfig(auth_path=default_auth_path(), api_base_url='https://chatgpt.com/backend-api/codex', client_id='app_EMoamEEZ73f0CkXaXp7hrann', default_token_ttl=timedelta(hours=1), issuer='https://auth.openai.com', refresh_margin=timedelta(seconds=30), timeout_seconds=30.0) dataclass

CodexAuthState(access_token, refresh_token, account_id=None, auth_mode=None, expires_at=None, id_token=None, last_refresh=None, openai_api_key=None) dataclass

CodexAuthStore(path) dataclass

CodexTokenManager(config, store, http_client, owns_http_client=False) dataclass