OpenAI:迁移到 HTTPX2
OpenAI Python SDK 的同步与异步 HTTP 客户端现在改用 HTTPX2。安装 openai 时会自动安装 HTTPX2,而之前的 httpx 包则不再随之安装。本指南说明与 SDK HTTP 层交互的应用会受哪些变化影响。
如果你使用 SDK 的默认 HTTP 客户端
如果你在构造 OpenAI 或 AsyncOpenAI 客户端时不传入 http_client,那么现有的 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 依赖,或将这些导入迁移到 httpx2。安装 SDK 不再会顺带装上 httpx。
TLS 证书与信任库
HTTPX2 更改了默认的 TLS 信任库,即使是使用 SDK 默认 HTTP 客户端的应用也受影响。HTTPX 此前使用 certifi 提供的 CA 证书包来验证证书,而 HTTPX2 改用操作系统的信任库,SDK 也不再安装 certifi。
在没有系统 CA 证书的精简容器镜像中、在使用公司 TLS 审查(TLS-inspecting)代理的环境中,以及依赖自定义或修改过的 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 transport 也采用同样的 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、transport 与连接设置
请把 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 超时设置变为:
import httpx2 from openai import OpenAI client = OpenAI(timeout=httpx2.Timeout(60.0, connect=5.0, read=20.0))
数值型超时值不变。现有的字符串 URL 也不变。自定义 transport 子类、挂载的 transport、代理集成以及连接池埋点必须改用 HTTPX2 的 transport 接口。
认证与事件钩子
认证处理器与钩子接收到的将是 HTTPX2 的请求和响应对象。请相应更新自定义认证类和类型注解:
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]}))
如果你继承了 HTTP 认证或 transport 接口,请改为继承对应的 httpx2 类。第三方埋点、链路追踪中间件和认证集成必须显式支持 HTTPX2。
原始响应、流式与异常
SDK 解析后的响应模型没有变化。使用原生 HTTPX2 客户端时,面向传输层的对象都属于 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)
使用原生客户端时,请求未解析的 HTTP 响应要用 cast_to=httpx2.Response。流式响应包装器暴露的也是 HTTPX2 响应对象。应用代码通常应捕获 openai.APITimeoutError、openai.APIConnectionError 之类的 SDK 异常;在原生客户端下,异常的底层传输层原因是 HTTPX2 异常。
这些类型保证只适用于原生 HTTPX2 客户端。注入旧版 HTTPX 客户端时,得到的将是 httpx.Request、httpx.Response 和 HTTPX transport 异常,即使传入了 cast_to=httpx2.Response 也是如此。
aiohttp
受支持的 aiohttp extra 使用 HTTPX2 原生 transport,不会安装旧版 HTTPX,也不会安装外部的 httpx-aiohttp 适配器:
pip install 'openai[aiohttp]'
from openai import AsyncOpenAI, DefaultAioHttpClient client = AsyncOpenAI(http_client=DefaultAioHttpClient())
DefaultAioHttpClient() 就是一个 httpx2.AsyncClient。使用这个辅助类的应用无需直接构造或导入 transport。
请求 Mock 与测试
Mock 必须拦截 HTTPX2 请求并返回 HTTPX2 响应。例如:
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 == []
如果你的测试套件使用 RESPX,请升级到兼容 HTTPX2 的 RESPX 版本或分支。只补丁旧版 HTTPX 的 RESPX 版本无法拦截 SDK 默认的 HTTPX2 客户端。如果暂时无法迁移该集成,下文的临时旧版客户端逃生通道可以让仅支持 HTTPX 的 RESPX 环境在迁移期间继续工作。
临时逃生通道:旧版 HTTPX 客户端
依赖仅支持 HTTPX 的 transport、集成或 mock 库的应用,可以显式安装旧版 HTTPX 并注入旧版客户端:
pip install openai httpx
旧版 HTTPX 支持仅限运行时。SDK 的公开类型注解只接受 HTTPX2 客户端,因此直接传入旧版客户端将无法通过 mypy、Pyright 等工具的静态类型检查。在刻意选择这条兼容路径时,请使用 cast(Any, ...) 或有针对性的 type-ignore:
from typing import Any, cast import httpx from openai import OpenAI client = OpenAI(http_client=cast(Any, httpx.Client()))
异步形式需要同样的变通处理:
from typing import Any, cast import httpx from openai import AsyncOpenAI client = AsyncOpenAI(http_client=cast(Any, httpx.AsyncClient()))
旧版客户端保留 HTTPX 的请求、响应和异常体系。请求原始响应时使用 httpx.Response,并对旧版响应类套用同样的类型检查变通处理:
from typing import Any, cast
import httpx
from openai import OpenAI
client = OpenAI(http_client=cast(Any, httpx.Client()))
response = client.get("/models", cast_to=cast(Any, httpx.Response))
assert isinstance(response, httpx.Response)
传入 cast_to=httpx2.Response 并不会把旧版 HTTPX 响应转换为 HTTPX2 响应。旧版依赖需要你自行安装和维护。提供旧版 HTTPX 支持只是迁移辅助,后续可能停止。
现有的旧版 aiohttp 适配器
如果必须保留现有的 httpx-aiohttp 集成,请显式安装它并注入其旧版客户端:
pip install openai httpx-aiohttp
from typing import Any, cast from httpx_aiohttp import HttpxAiohttpClient from openai import AsyncOpenAI client = AsyncOpenAI(http_client=cast(Any, HttpxAiohttpClient()))
这条路径有专门的兼容性测试覆盖(包括通过 aiohttp transport 发起真实请求),但它仍是临时逃生通道。新代码建议使用 openai[aiohttp] 和 DefaultAioHttpClient()。