코드는 그대로인데 TLS가 실패한다: OpenAI SDK 3.0의 전송 계층 이전
기본 API와 사용자 지정 HTTP 객체를 나누고, 로컬·컨테이너·프록시·모킹 조건을 교차해 확인한다. 성공한 모의 응답만으로 인증서 경로를 검증할 수 없는 이유를 설명한다.

기본 API 사용법과 바뀐 전송 계층
OpenAI가 2026.08.12 공개한 openai 3.0.0의 핵심 breaking change는 기본 HTTP client를 HTTPX에서 HTTPX2로 교체한 것이다. 이제 SDK를 설치해도 httpx가 함께 자동 설치되지 않는다. 다만 OpenAI나 AsyncOpenAI에 별도 http_client를 넘기지 않았다면 parsed response model, streaming API, authentication, retry, numeric timeout 사용 방식은 그대로 유지된다.
3.0.0 문서로 한정한 이전 범위
OpenAI 공식 저장소의 3.0.0 release note와 같은 tag의 HTTPX2 migration guide를 기준으로, Python 애플리케이션의 SDK upgrade와 container CA 설정, 그리고 proxy·custom transport·event hook·test double migration을 점검한다.
운영 환경·직접 주입·테스트의 세 경계
SDK v3.0.0의 migration guide를 기준으로 실제 사용하는 transport·proxy·test double을 해당 버전의 예제와 대조해야 한다. 공식 자료 1 (https://github.com/openai/openai-python/releases/tag/v3.0.0 (새 창)) · 공식 자료 2 (https://github.com/openai/openai-python/blob/v3.0.0/httpx2.md (새 창))
세 영역은 모두 함께 검증해야 한다.
변경은 SDK 응답 모델보다 HTTP 계층에서 일어났다. 기본 경로에서는 SDK가 알아서 HTTPX2를 구성하지만, 전송 객체를 직접 주입하거나 원시 응답 타입을 검사하는 코드는 HTTPX2 객체 계열로 전환해야 한다.
의존성 목록에서는 애플리케이션이 httpx를 직접 사용하는지부터 확인한다. 이전에는 SDK의 transitive dependency로 함께 설치됐을 수 있으므로 계속 사용한다면 직접 dependency로 선언해야 한다. 다음으로 확인할 곳은 minimal container와 corporate TLS-inspecting proxy의 OS trust store다. HTTPX2는 기존 HTTPX가 쓰던 certifi CA bundle 대신 운영체제 trust store를 기본으로 사용한다.
httpx.Client, httpx.Timeout, httpx.HTTPTransport, httpx.MockTransport를 주입하던 코드는 각각 httpx2 객체로 옮긴다. event hook, authentication handler, tracing middleware, 그리고 RESPX 같은 mocking 도구도 HTTPX2의 request와 response를 정상적으로 처리하는지 확인해야 한다.
| 경로 | 확인할 대상 |
|---|---|
| 기본 경로·운영 환경 | OS 인증서 저장소와 프록시 |
| 직접 주입한 HTTP 객체 | HTTPX2 타입과 호환성 |
| 테스트·계측 도구 | 모킹·스트리밍·타임아웃 |

요청 코드가 같아도 인증서 경로는 달라진다
릴리스 노트는 기본 클라이언트가 HTTPX2로 바뀌었고 httpx는 자동 설치되지 않는다고 명시한다. 이전 가이드는 기본 클라이언트의 응답 처리 방식이 유지된다는 점과 함께 TLS 기본값의 차이를 별도로 설명한다. 단순한 요청 코드라도 컨테이너나 사내 프록시의 인증서 설정 때문에 실행에 실패할 수 있다.
custom client를 쓸 때는 단순히 이름만 바꿔서는 부족하다. Request·Response·exception family가 모두 HTTPX2로 달라지며, raw response·streaming wrapper·mock transport·instrumentation도 이 변경 경계에 걸린다. SDK exception인 APITimeoutError와 APIConnectionError를 우선 잡도록 작성하면 transport library와의 결합도를 낮출 수 있다.
사용 중인 연동에 맞춰 이전 검증하기
기본 client만 쓰고 system CA가 정상인 일반 환경이라면 3.0.0 upgrade 후 smoke test만으로 충분하다. 반면 custom transport나 proxy가 있다면 HTTPX2 객체로 먼저 바꾸고 connection·timeout·streaming test를 함께 실행해야 한다. RESPX나 third-party tracing 도구가 아직 HTTPX2를 지원하지 않는다면 legacy HTTPX client를 명시적으로 주입하는 temporary escape hatch를 쓸 수 있다. 다만 static type annotation은 HTTPX2 기준이므로 type ignore나 cast(Any, ...) 처리가 필요하다.
의존성 잠금 파일을 갱신한 뒤에는 CA 인증서, 프록시 경로, 재시도, timeout, streaming 취소, 요청 모킹을 검증한다. 이전 HTTPX 클라이언트를 주입하는 방식은 임시 이전 수단일 뿐이며 향후 지원이 중단될 수 있어 장기 설계로 삼기 어렵다.
예를 들어 개발 노트북에는 사내 루트 인증서가 설치돼 있고 최소 컨테이너 이미지에는 없다고 가정하자. 같은 Python 요청이라도 로컬에서는 성공하고 컨테이너에서는 인증서 검증에 실패할 수 있다. 이때 응답 스키마나 프롬프트를 고치는 것으로는 원인을 해결하지 못한다. 실제 전송 계층이 참조하는 신뢰 저장소와 프록시 경로부터 대조해야 한다. 이 사례는 특정 조직에서 관측한 실제 사고가 아니라 이전 검증을 돕기 위한 가상 조건이다.
시험을 네 경로로 나누면 원인을 좁히기 쉽다. 기본 클라이언트의 직접 연결, 기본 클라이언트의 운영 프록시 연결, 사용자 지정 전송 객체의 실제 연결, 요청 모킹 경로다. 모킹이 성공하더라도 실제 TLS 협상이 생략됐다면 인증서 경로는 검증되지 않는다. 반대로 실제 요청 하나가 성공하더라도 오류 훅·취소·스트리밍 종료 처리가 새 객체 타입을 제대로 지원하는지는 별도로 확인해야 한다.
각 시험에는 SDK 버전과 잠금 파일, 주입한 객체 타입, OS 인증서 설치 방식, 프록시 사용 여부를 기록한다. 신뢰 오류를 피하려고 인증서 검증을 끄는 대신, 필요한 신뢰 루트를 해당 환경에 설치하고 같은 경로로 다시 확인한다. 이 글은 3.0.0 이전을 다루며 최신 SDK의 다른 기능 변경은 함께 묶지 않는다.
외부 연동의 호환성은 별도 실행 확인이 필요하다
HTTPX2 호환을 표방하는 third-party library의 실제 동작과 각 조직의 TLS proxy 설정은 별도로 검증해야 한다.
먼저 애플리케이션이 기본 클라이언트만 쓰는지, 아니면 HTTP 객체를 직접 주입하는지 구분한다. 이 목록을 운영 CA·프록시·테스트 도구와 대조하면 3.0.0 이전에서 실제로 수정해야 할 경계를 좁힐 수 있다.
참고 자료
OpenAI Python SDK v3.0.0 release
Migrating to HTTPX2