mirror of
https://github.com/openai/codex.git
synced 2026-09-10 20:26:47 +00:00
Test Python SDK against the built CLI and installed runtime (#44053)
## Why Python SDK CI needs to exercise the checkout's CLI while retaining coverage of the wheel installation and its default runtime. ## What changed - Run the Python SDK test suite against the same Bazel-built CLI as the TypeScript SDK tests. Build and stage `codex-code-mode-host` alongside the CLI so it can be discovered. - Make the Python test harness prefer `CODEX_EXEC_PATH`, then a local debug build, then the installed runtime. Exclude optional turn-cost probes from recorded model requests. - Add a separate installation job that builds the Python SDK wheel and installs it in a fresh environment. ## Testing The installation smoke test verifies that imports resolve to the installed SDK and that its default runtime completes a mocked turn with the expected user input and final response. GitOrigin-RevId: 8e3126742a014e2cf042afe799bc657e1ea2a282
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import queue
|
||||
import shutil
|
||||
import threading
|
||||
@@ -204,7 +205,7 @@ class MockResponsesServer:
|
||||
|
||||
|
||||
class AppServerHarness:
|
||||
"""Test fixture that points a pinned runtime app-server at MockResponsesServer."""
|
||||
"""Test fixture that points the checkout's app-server at MockResponsesServer."""
|
||||
|
||||
def __init__(self, tmp_path: Path, *, requires_openai_auth: bool = False) -> None:
|
||||
self.tmp_path = tmp_path
|
||||
@@ -226,8 +227,14 @@ class AppServerHarness:
|
||||
shutil.rmtree(self.workspace, ignore_errors=True)
|
||||
|
||||
def app_server_config(self) -> CodexConfig:
|
||||
"""Build SDK config for an isolated pinned-runtime app-server process."""
|
||||
"""Prefer the CI binary, then a local debug build, then the installed runtime."""
|
||||
binary_name = "codex.exe" if os.name == "nt" else "codex"
|
||||
debug_binary = Path(__file__).resolve().parents[3] / "codex-rs/target/debug" / binary_name
|
||||
codex_bin = os.environ.get("CODEX_EXEC_PATH")
|
||||
if codex_bin is None and debug_binary.is_file():
|
||||
codex_bin = str(debug_binary)
|
||||
return CodexConfig(
|
||||
codex_bin=codex_bin,
|
||||
cwd=str(self.workspace),
|
||||
env={
|
||||
"CODEX_HOME": str(self.codex_home),
|
||||
@@ -304,6 +311,10 @@ class _ResponsesHandler(BaseHTTPRequestHandler):
|
||||
"""Serve queued SSE responses for `/v1/responses` requests."""
|
||||
length = int(self.headers.get("content-length", "0"))
|
||||
body = self.rfile.read(length)
|
||||
if self.path.endswith("/analytics/codex/turn-costs"):
|
||||
# Optional cost probes are not model requests.
|
||||
self.send_error(404, "turn costs are unavailable for the mock provider")
|
||||
return
|
||||
self.server.mock._record_request(self, body)
|
||||
|
||||
if not (self.path.endswith("/v1/responses") or self.path.endswith("/responses")):
|
||||
|
||||
34
sdk/python/tests/installed_sdk_smoke.py
Normal file
34
sdk/python/tests/installed_sdk_smoke.py
Normal file
@@ -0,0 +1,34 @@
|
||||
"""Exercise a built SDK's default runtime in an otherwise isolated environment."""
|
||||
|
||||
from dataclasses import replace
|
||||
from importlib.metadata import distribution, version
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from app_server_harness import AppServerHarness
|
||||
|
||||
import openai_codex
|
||||
from openai_codex import Codex
|
||||
|
||||
|
||||
def main() -> None:
|
||||
installed_root = Path(distribution("openai-codex").locate_file("")).resolve()
|
||||
assert Path(openai_codex.__file__).resolve().is_relative_to(installed_root), (
|
||||
"The smoke test must import the installed SDK, not the source checkout"
|
||||
)
|
||||
|
||||
with TemporaryDirectory() as directory, AppServerHarness(Path(directory)) as harness:
|
||||
harness.responses.enqueue_assistant_message("Installed SDK works")
|
||||
config = replace(harness.app_server_config(), codex_bin=None)
|
||||
with Codex(config=config) as codex:
|
||||
result = codex.thread_start().run("Check the installed SDK")
|
||||
assert result.final_response == "Installed SDK works"
|
||||
assert harness.responses.single_request().message_input_texts("user")[-1:] == [
|
||||
"Check the installed SDK"
|
||||
]
|
||||
|
||||
print(f"Installed SDK passed with CLI runtime {version('openai-codex-cli-bin')}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user