python

OpenAI Python SDK’s HTTPX2 Migration: What Actually Changes

OpenAI Python SDK’s HTTPX2 Migration: What Actually Changes

Picture a routine dependency update: you run pip install -U openai, the resolver finishes, and your application still appears to do the same thing. Underneath, though, the OpenAI Python software development kit (SDK) has changed the library that opens connections, sends requests, verifies certificates, and turns network failures into Python exceptions.

The change is an HTTPX2 migration, not a switch to the HTTP/2 network protocol. HTTPX2 is the name of the Python HTTP client package; HTTP/2 is a wire protocol that a client may or may not use. The migration shipped in openai-python 3.0.0 on August 12, 2026. As of August 28, 2026, the 3.5.0 package metadata lists httpx2>=2.7.0,<3 and requires Python 3.10 or newer. HTTPX2 supports synchronous and asynchronous clients, along with HTTP/1.1 and HTTP/2, but the SDK migration is mainly about package imports and object types. (github.com)

Most applications do not need a code change

If you create an OpenAI or AsyncOpenAI client without passing http_client, the high-level SDK surface remains familiar. Parsed response models, streaming APIs, authentication, retries, and numeric timeout values continue to work.

from openai import OpenAI

client = OpenAI(timeout=30.0)
response = client.responses.create(
 model='gpt-5.5',
 input='Hello from the new transport',
)

That path needs no separate HTTPX2 installation; pip install openai is the intended setup. The trap is a transitive dependency, meaning a package installed indirectly for you: if your application imported httpx only because an older SDK brought it along, either declare httpx in your own project or change those imports to httpx2. (raw.githubusercontent.com)

TLS is the migration detail that shows up in production

Transport Layer Security (TLS) encrypts the connection between your application and the API. Before this change, HTTPX commonly verified server certificates against the certificate bundle shipped by certifi. HTTPX2 uses the operating system’s trust store instead, and the OpenAI SDK no longer installs certifi for you.

That difference matters in slim container images, company networks that inspect encrypted traffic, and deployments with a private certificate authority (CA). A common post-upgrade search is: why did my OpenAI request start failing with a certificate error?

You can point the process at a CA bundle with SSL_CERT_FILE or SSL_CERT_DIR. For a per-client setting, create an ssl.SSLContext, a Python object that carries TLS verification settings:

import ssl
from openai import DefaultHttpx2Client, OpenAI

context = ssl.create_default_context(
 cafile='/path/to/ca-bundle.pem',
)

client = OpenAI(
 http_client=DefaultHttpx2Client(verify=context),
)

Do not treat verify=False as a migration fix. It removes certificate verification rather than teaching the client which certificates your environment trusts. (raw.githubusercontent.com)

Custom HTTP clients are the real boundary

A custom HTTP client is an explicitly supplied network client used for settings such as a proxy, connection limits, special routing, or request instrumentation. A proxy is an intermediary server that forwards traffic. A transport is the lower-level component that decides how a request leaves the process.

The common replacements are mechanical: httpx.Client becomes httpx2.Client, httpx.AsyncClient becomes httpx2.AsyncClient, and configuration objects such as httpx.Timeout, httpx.Limits, and httpx.HTTPTransport move to the httpx2 namespace.

import httpx2
from openai import DefaultHttpx2Client, OpenAI

client = OpenAI(
 http_client=DefaultHttpx2Client(
 proxy='http://proxy.example.com:8080',
 timeout=httpx2.Timeout(60.0, connect=5.0, read=20.0),
 )
)

The DefaultHttpx2Client helper preserves the SDK’s recommended timeout, connection-pool, and redirect defaults. A connection pool reuses open network connections instead of creating a fresh one for every request. Directly constructing httpx2.Client is also supported, but then HTTPX2’s own defaults apply. The older DefaultHttpxClient names continue to work; the new names make the client family explicit. (raw.githubusercontent.com)

Hooks and raw responses expose the new types

An event hook is a callback that runs when a request or response reaches a particular point in the client. If your logging, authentication, tracing, or metrics code annotates HTTPX objects, update those annotations and any subclasses to httpx2:

import httpx2
from openai import DefaultHttpx2Client, OpenAI

def log_request(request: httpx2.Request) -> None:
 print(request.method, request.url)

client = OpenAI(
 http_client=DefaultHttpx2Client(
 event_hooks={'request': [log_request]},
 )
)

The parsed SDK models do not change, but transport-facing objects do. A raw response is the underlying HTTP response before the SDK turns it into a typed model:

raw = client.models.with_raw_response.list
assert isinstance(raw.http_response, httpx2.Response)

For error handling, prefer SDK exceptions such as openai.APITimeoutError and openai.APIConnectionError. When the client is native HTTPX2, the underlying transport cause belongs to the HTTPX2 exception family. (raw.githubusercontent.com)

Tests need to intercept HTTPX2 requests

A mock transport is a test-only transport that returns a programmed response instead of contacting the network. Its handler should accept and return HTTPX2 objects:

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),
 )
)

The same boundary affects RESPX, a library used to intercept HTTP requests in tests. A version that patches only legacy HTTPX will not see requests from the SDK’s default HTTPX2 client. For asynchronous applications, the supported openai[aiohttp] extra provides DefaultAioHttpClient, an HTTPX2-native async client, so new code does not need the old external adapter. (raw.githubusercontent.com)

Keep the legacy bridge temporary

Some applications cannot update a proxy adapter, mock library, or custom transport immediately. The SDK still allows an explicitly injected legacy HTTPX client, but you must install httpx yourself:

from typing import Any, cast

import httpx
from openai import OpenAI

client = OpenAI(
 http_client=cast(Any, httpx.Client),
)

This is a runtime compatibility path, not the new public type contract. Static type checkers such as mypy and Pyright need the cast because the SDK expects HTTPX2 clients. A cast also does not convert an httpx.Response into an httpx2.Response; the request, response, and exception families remain legacy HTTPX. (raw.githubusercontent.com)

A practical migration pass

  • Search for import httpx, httpx. types, custom transports, authentication classes, and HTTPX-only test tools.
  • Run the suite in a clean environment so an old transitive httpx install does not hide missing dependencies.
  • Test a production-like container and any corporate proxy path, especially certificate verification.
  • Update type annotations and instrumentation before removing the compatibility bridge.

The main lesson is reassuring: ordinary OpenAI API calls are not the difficult part of this change. The migration becomes visible where an application reaches below the SDK and takes control of the HTTP layer. Replace those boundary objects, verify the trust store, and let the high-level client keep doing the work it did before.

ahsan

ahsan

Hello! I am Mr Ahsan, the writer of the Website. I am from Netherland. I like to write about technology and the news around it.

Comments (0)

No comments yet. Be the first to respond!

Leave a Comment

Your comment will be visible after review.