openai
Проверка сертификатов ломается после перехода на HTTPX2
Promtime
openaiOpenAI перевела Python-SDK на HTTPX2: синхронный и асинхронный HTTP-клиенты работают на новом пакете, который устанавливается вместе с openai, тогда как прежний httpx SDK за собой не тянет. Руководство по миграции опубликовано в репозитории SDK на Github.
Коротко
- Проверка сертификатов теперь опирается на хранилище операционной системы: certifi в зависимости SDK не входит, и в минимальных образах, за TLS-инспектирующими прокси и с правленым набором certifi верификация падает.
- Лечится установкой CA в системное хранилище либо переменными SSL_CERT_FILE и SSL_CERT_DIR, которые читаются при trust_env=True, а на своём клиенте контекст ssl.SSLContext передаётся через параметр verify.
- Тестовые наборы на RESPX перестают перехватывать запросы, пока не обновятся до версии с поддержкой HTTPX2, а объекты httpx.Timeout, httpx.Limits и httpx.MockTransport заменяются одноимёнными классами из httpx2.
Смена доверенного хранилища бьёт по тем, кто не трогал HTTP-слой вообще: приложение на дефолтном клиенте работает до первого запроса из минимального образа без системных сертификатов. Судя по перечню сломанных сценариев, основная нагрузка ложится на корпоративные развёртывания с перехватывающими прокси и на сборки с собственным набором CA. Совместимость по именам классов и рантайм-путь для старого httpx выглядят как попытка растянуть миграцию, но статическая типизация этот путь не поддерживает.
Сертификаты проверяются по хранилищу ОС, а certifi SDK не устанавливает
Клиенты OpenAI и AsyncOpenAI, созданные без параметра http_client, продолжают работать как прежде: вызовы API, разобранные модели ответов, стриминговые интерфейсы, аутентификация, ретраи и числовые таймауты не меняются. Отдельного extra для HTTPX2 не требуется, достаточно pip install openai. Приложениям, которые импортировали httpx только потому, что его тянул прежний SDK, придётся объявить эту зависимость самим или перевести импорты на httpx2.
Смена затрагивает и дефолтный клиент: HTTPX сверял сертификаты с набором certifi, HTTPX2 обращается к хранилищу операционной системы, а certifi SDK не ставит. В документации OpenAI перечислены три сценария поломки: минимальные контейнерные образы без системных CA, окружения с корпоративными TLS-инспектирующими прокси и развёртывания, опиравшиеся на собственный или изменённый набор certifi.
DefaultHttpx2Client сохраняет рекомендованные таймауты, пул соединений и редиректы
Помощники DefaultHttpx2Client и DefaultAsyncHttpx2Client удерживают рекомендованные SDK значения таймаутов, пула соединений и редиректов и принимают параметры вроде proxy, transport и timeout. Напрямую созданные httpx2.Client и httpx2.AsyncClient тоже поддерживаются, но тогда действуют их собственные умолчания. Имена DefaultHttpxClient и DefaultAsyncHttpxClient сохранены и создают клиенты HTTPX2.
Объекты меняются один в один: httpx.Timeout, httpx.URL, httpx.Limits, httpx.HTTPTransport, httpx.AsyncHTTPTransport и httpx.MockTransport на одноимённые классы из httpx2. Числовые значения таймаутов и строковые URL остаются прежними. Подклассы транспортов, смонтированные транспорты, интеграции с прокси, инструментирование пула, обработчики аутентификации и event hooks должны работать с интерфейсами и объектами HTTPX2.
Extra openai[aiohttp] использует нативный для HTTPX2 транспорт и не ставит ни старый HTTPX, ни внешний адаптер httpx-aiohttp. DefaultAioHttpClient представляет собой httpx2.AsyncClient, поэтому импортировать транспорт вручную не нужно, а TLS-настройки у него те же, что у остальных клиентов HTTPX2.
Моки на RESPX без поддержки HTTPX2 не перехватывают запросы дефолтного клиента
Моки обязаны перехватывать запросы HTTPX2 и возвращать httpx2.Response, для чего используется httpx2.MockTransport. Набор тестов на RESPX, пропатченный только под старый HTTPX, дефолтный клиент SDK не перехватит, и нужна совместимая с HTTPX2 версия или форк. Разобранные модели ответов не меняются, но http_response и http_request у сырых ответов становятся объектами HTTPX2, а непарсенный ответ запрашивается через cast_to=httpx2.Response.
Приложения, завязанные на HTTPX-транспорт или мок-библиотеку, могут поставить старый httpx вручную и передать его клиент через cast(Any, ...). Поддержка легаси-клиента работает только в рантайме: публичные аннотации SDK принимают клиенты HTTPX2, поэтому mypy и Pyright на такой передаче ругаются, а cast_to=httpx2.Response не превращает ответ httpx в httpx2.
Судьба легаси-пути
Сроков отключения совместимости в документации нет: поддержка старого HTTPX описана как временная помощь при миграции и может быть прекращена, а устанавливать и обновлять эту зависимость приходится самостоятельно. Путь с httpx-aiohttp через HttpxAiohttpClient покрыт отдельными тестами совместимости, включая реальный запрос через транспорт aiohttp, но для нового кода OpenAI рекомендует openai[aiohttp] и DefaultAioHttpClient.
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите через Google, чтобы оставить комментарий. Имя и аватар подставятся из вашего профиля Google, а комментарий появится после модерации.
Из Google мы используем только имя и аватар. Почту не сохраняем.
