메뉴
HN
Hacker News • 29일 전

OpenAI, 파이썬 SDK를 HTTPX2로 전환

IMP
6/10
핵심 요약

OpenAI 파이썬 SDK가 동기/비동기 HTTP 클라이언트를 HTTPX2로 전환했습니다. 기존 httpx 패키지는 더 이상 자동 설치되지 않으며, TLS 신뢰 저장소가 OS 기본값으로 바뀌어 최소 컨테이너 환경이나 기업 프록시 환경에서 인증서 검증 오류가 발생할 수 있습니다. 커스텀 HTTP 클라이언트를 사용하는 경우 httpx 객체를 httpx2 객체로 교체해야 합니다.

번역된 본문

HTTPX2로 마이그레이션하기

OpenAI 파이썬 SDK가 이제 동기 및 비동기 HTTP 클라이언트에 HTTPX2를 사용합니다. HTTPX2는 openai 설치 시 자동으로 함께 설치되지만, 기존의 httpx 패키지는 설치되지 않습니다. 이 가이드는 SDK의 HTTP 계층과 상호작용하는 애플리케이션에서 무엇이 변경되는지 설명합니다.

SDK의 기본 HTTP 클라이언트를 사용하는 경우

http_client를 지정하지 않고 OpenAI 또는 AsyncOpenAI 클라이언트를 생성했다면, 기존 API 호출, 파싱된 응답 모델, 스트리밍 API, 인증, 재시도, 숫자 타임아웃은 모두 계속 동작합니다:

from openai import OpenAI

client = OpenAI(timeout=30.0) response = client.responses.create(model="gpt-5.5", input="Hello")

HTTPX2 extra나 별도 설치가 필요하지 않습니다:

pip install openai

만약 이전 SDK가 httpx를 의존성으로 함께 설치해줘서 httpx를 import했었다면, 직접 httpx 의존성을 추가하거나 해당 import를 httpx2로 마이그레이션하세요. 이제 SDK를 설치해도 httpx가 설치되지 않습니다.

TLS 인증서 및 신뢰 저장소

HTTPX2는 기본 TLS 신뢰 저장소를 변경하며, 이는 SDK의 기본 HTTP 클라이언트를 사용하는 애플리케이션에도 영향을 줍니다. HTTPX는 이전에 certifi가 제공하는 CA 번들을 기준으로 인증서를 검증했습니다. 반면 HTTPX2는 운영체제의 신뢰 저장소를 사용하며, SDK는 더 이상 certifi를 설치하지 않습니다. 이로 인해 시스템 CA 인증서가 없는 최소 컨테이너 이미지, 기업의 TLS 검사 프록시를 사용하는 환경, 커스텀 또는 수정된 certifi 번들에 의존하던 배포 환경에서 인증서 검증이 실패할 수 있습니다.

운영체제 신뢰 저장소에 필요한 CA 인증서를 설치하거나, 명시적인 인증서 번들을 설정하세요:

export SSL_CERT_FILE=/path/to/ca-bundle.pem

또는 신뢰할 CA 인증서 디렉토리를 설정할 수도 있습니다:

export SSL_CERT_DIR=/path/to/ca-directory

이 환경 변수들은 trust_env=True(기본값)일 때 적용됩니다. 커스텀 클라이언트에서 명시적으로 제어하려면 verify에 ssl.SSLContext를 전달하세요:

import ssl from openai import OpenAI, DefaultHttpx2Client

ssl_context = ssl.create_default_context(cafile="/path/to/ca-bundle.pem") client = OpenAI(http_client=DefaultHttpx2Client(verify=ssl_context))

비동기 설정에 해당하는 것은 DefaultAsyncHttpx2Client(verify=ssl_context)입니다. SDK의 aiohttp 트랜스포트도 동일한 HTTPX2 TLS 설정을 사용합니다.

커스텀 HTTP 클라이언트를 제공하는 경우

HTTPX2 클라이언트와 HTTPX2 설정 객체를 사용하세요. SDK는 권장 타임아웃, 커넥션 풀, 리다이렉트 기본값을 유지해주는 헬퍼를 제공합니다:

import httpx2 from openai import OpenAI, AsyncOpenAI, DefaultHttpx2Client, DefaultAsyncHttpx2Client

proxy_client = OpenAI(http_client=DefaultHttpx2Client(proxy="http://proxy.example.com:8080"))

transport_client = OpenAI(http_client=DefaultHttpx2Client(transport=httpx2.HTTPTransport(local_address="0.0.0.0"), timeout=httpx2.Timeout(30.0, connect=5.0)))

async_client = AsyncOpenAI(http_client=DefaultAsyncHttpx2Client(timeout=httpx2.Timeout(30.0)))

httpx2.Client와 httpx2.AsyncClient 인스턴스를 직접 생성하는 것도 지원됩니다. 클라이언트를 직접 생성하면 직접 설정하지 않는 한 해당 클라이언트 자체의 HTTPX2 기본값이 적용됩니다. 기존의 DefaultHttpxClient와 DefaultAsyncHttpxClient 이름도 계속 동작하지만, 이제 HTTPX2 클라이언트를 생성합니다. HTTP 클라이언트 계열을 명확히 하려면 DefaultHttpx2Client와 DefaultAsyncHttpx2Client를 사용하는 것을 권장합니다.

모듈 수준 설정도 동일한 규칙을 따릅니다:

import openai openai.http_client = openai.DefaultHttpx2Client()

타임아웃, URL, 트랜스포트, 커넥션 설정

HTTPX 전용 객체를 해당하는 HTTPX2 객체로 교체하세요:

기존 객체 → HTTPX2 객체 httpx.Client → httpx2.Client httpx.AsyncClient → httpx2.AsyncClient httpx.Timeout → httpx2.Timeout httpx.URL → httpx2.URL httpx.Limits → httpx2.Limits httpx.HTTPTransport → httpx2.HTTPTransport httpx.AsyncHTTPTransport → httpx2.AsyncHTTPTransport httpx.MockTransport → httpx2.MockTransport

예를 들어, 세분화된 SDK 타임아웃 설정은 [본문 여기서 잘림]

원문 보기
원문 보기 (영어)
Migrating to HTTPX2 The OpenAI Python SDK now uses HTTPX2 for its synchronous and asynchronous HTTP clients. HTTPX2 is installed automatically with openai ; the previous httpx package is not. This guide explains what changes for applications that interact with the SDK's HTTP layer. If you use the SDK's default HTTP client If you construct an OpenAI or AsyncOpenAI client without providing http_client , your existing API calls, parsed response models, streaming APIs, authentication, retries, and numeric timeouts continue to work: from openai import OpenAI client = OpenAI ( timeout = 30.0 ) response = client . responses . create ( model = "gpt-5.5" , input = "Hello" ) No HTTPX2 extra or separate installation is required: pip install openai If your application imported httpx only because an earlier SDK installed it transitively, add your own httpx dependency or migrate those imports to httpx2 . Installing the SDK no longer installs httpx for you. TLS certificates and trust stores HTTPX2 changes the default TLS trust store, including for applications that use the SDK's default HTTP client. HTTPX previously verified certificates against the CA bundle provided by certifi . HTTPX2 instead uses the operating-system trust store, and the SDK no longer installs certifi . This can break certificate verification in minimal container images without system CA certificates, environments using corporate TLS-inspecting proxies, and deployments that relied on a custom or modified certifi bundle. Install the required CA certificates in the operating-system trust store, or configure an explicit certificate bundle: export SSL_CERT_FILE=/path/to/ca-bundle.pem Alternatively, configure a directory of trusted CA certificates: export SSL_CERT_DIR=/path/to/ca-directory These environment variables are honored when trust_env=True , which is the default. To control trust explicitly on a custom client, pass an ssl.SSLContext through verify : import ssl from openai import OpenAI , DefaultHttpx2Client ssl_context = ssl . create_default_context ( cafile = "/path/to/ca-bundle.pem" ) client = OpenAI ( http_client = DefaultHttpx2Client ( verify = ssl_context )) Use DefaultAsyncHttpx2Client(verify=ssl_context) for the equivalent async configuration. The SDK's aiohttp transport uses the same HTTPX2 TLS settings. If you provide a custom HTTP client Use HTTPX2 clients and HTTPX2 configuration objects. The SDK provides helpers that preserve its recommended timeout, connection-pool, and redirect defaults: import httpx2 from openai import OpenAI , AsyncOpenAI , DefaultHttpx2Client , DefaultAsyncHttpx2Client proxy_client = OpenAI ( http_client = DefaultHttpx2Client ( proxy = "http://proxy.example.com:8080" )) transport_client = OpenAI ( http_client = DefaultHttpx2Client ( transport = httpx2 . HTTPTransport ( local_address = "0.0.0.0" ), timeout = httpx2 . Timeout ( 30.0 , connect = 5.0 ), ) ) async_client = AsyncOpenAI ( http_client = DefaultAsyncHttpx2Client ( timeout = httpx2 . Timeout ( 30.0 ))) Directly constructed httpx2.Client and httpx2.AsyncClient instances are also supported. When you construct a client directly, its own HTTPX2 defaults apply unless you configure them yourself. The existing DefaultHttpxClient and DefaultAsyncHttpxClient names continue to work, but now construct HTTPX2 clients. Prefer DefaultHttpx2Client and DefaultAsyncHttpx2Client when making the HTTP client family explicit. Module-level configuration follows the same rule: import openai openai . http_client = openai . DefaultHttpx2Client () Timeouts, URLs, transports, and connection settings Replace HTTPX-specific objects with the corresponding HTTPX2 objects: Previous object HTTPX2 object httpx.Client httpx2.Client httpx.AsyncClient httpx2.AsyncClient httpx.Timeout httpx2.Timeout httpx.URL httpx2.URL httpx.Limits httpx2.Limits httpx.HTTPTransport httpx2.HTTPTransport httpx.AsyncHTTPTransport httpx2.AsyncHTTPTransport httpx.MockTransport httpx2.MockTransport For example, a granular SDK timeout becomes: import httpx2 from openai import OpenAI client = OpenAI ( timeout = httpx2 . Timeout ( 60.0 , connect = 5.0 , read = 20.0 )) Numeric timeout values do not change. Existing string URLs do not change. Custom transport subclasses, mounted transports, proxy integrations, and connection-pool instrumentation must target HTTPX2's transport interfaces. Authentication and event hooks Authentication handlers and hooks receive HTTPX2 request and response objects. Update custom auth classes and annotations accordingly: import httpx2 from openai import OpenAI , DefaultHttpx2Client def log_request ( request : httpx2 . Request ) -> None : print ( request . method , request . url ) client = OpenAI ( http_client = DefaultHttpx2Client ( event_hooks = { "request" : [ log_request ]})) If you subclass an HTTP authentication or transport interface, subclass the matching httpx2 class. Third-party instrumentation, tracing middleware, and auth integrations must explicitly support HTTPX2. Raw responses, streaming, and exceptions Parsed SDK response models are unchanged. When using a native HTTPX2 client, transport-facing objects belong to HTTPX2: import httpx2 from openai import OpenAI client = OpenAI () response = client . models . with_raw_response . list () assert isinstance ( response . http_response , httpx2 . Response ) assert isinstance ( response . http_request , httpx2 . Request ) With a native client, use cast_to=httpx2.Response when requesting an unparsed HTTP response. Streaming response wrappers also expose HTTPX2 response objects. Application code should usually catch SDK exceptions such as openai.APITimeoutError and openai.APIConnectionError ; with a native client, an exception's underlying transport cause is an HTTPX2 exception. These type guarantees apply only to native HTTPX2 clients. An injected legacy HTTPX client produces httpx.Request , httpx.Response , and HTTPX transport exceptions instead, even if cast_to=httpx2.Response is supplied. aiohttp The supported aiohttp extra uses an HTTPX2-native transport. It does not install legacy HTTPX or the external httpx-aiohttp adapter: pip install ' openai[aiohttp] ' from openai import AsyncOpenAI , DefaultAioHttpClient client = AsyncOpenAI ( http_client = DefaultAioHttpClient ()) DefaultAioHttpClient() is an httpx2.AsyncClient . Applications using this helper do not need to construct or import the transport directly. Request mocking and tests Mocks must intercept HTTPX2 requests and return HTTPX2 responses. For example: import httpx2 from openai import OpenAI def handler ( request : httpx2 . Request ) -> httpx2 . Response : return httpx2 . Response ( 200 , request = request , json = { "object" : "list" , "data" : []}, ) client = OpenAI ( http_client = httpx2 . Client ( transport = httpx2 . MockTransport ( handler ))) assert client . models . list (). data == [] If your test suite uses RESPX, update to an HTTPX2-compatible RESPX version or fork. A RESPX version that patches only legacy HTTPX cannot intercept the SDK's default HTTPX2 client. If you cannot migrate that integration immediately, the temporary legacy-client escape hatch below lets existing HTTPX-only RESPX setups continue to work while you migrate. Temporary escape hatch: a legacy HTTPX client Applications that depend on an HTTPX-only transport, integration, or mocking library can explicitly install legacy HTTPX and inject a legacy client: pip install openai httpx Legacy HTTPX support is runtime-only. The SDK's public type annotations accept HTTPX2 clients, so passing a legacy client directly fails static type checking in mypy, Pyright, and similar tools. Use cast(Any, ...) or a targeted type-ignore when deliberately choosing this compatibility path: from typing import Any , cast import httpx from openai import OpenAI client = OpenAI ( http_client = cast ( Any , httpx . Client ())) The asynchronous form requires the same workaround: from typing import Any , cast import httpx from openai import AsyncOpenAI client = AsyncOp
관련 소식