DEV Community

jamilxt
jamilxt

Posted on

The OpenAI Python SDK Just Dropped HTTPX for HTTPX2. Run This Checklist Before Your Next Deploy

Last week I bumped the openai package version in one of my agent projects, ran the test suite, watched every test go green, and almost pushed straight to production. Good thing I didn't. Two weeks ago, the OpenAI Python SDK quietly replaced its entire HTTP layer: it no longer uses httpx, the library most of us have never had to think about. It now uses httpx2, a new fork maintained by the Pydantic team. And one of the changes is the kind that passes every unit test and then detonates in a Docker container at 2 AM.

Your API calls still work. Your response models still parse. Your timeouts still mean what they meant. The break is somewhere sneakier: certificate verification.

I spent my evening reading the official migration guide, the HTTPX2 project docs, and the Hacker News discussion where people who maintain real deployments picked the change apart. Here is the full picture and the pre-deploy checklist I now run before touching the SDK version in any of my own infrastructure.

First, what actually happened

Three things changed at once, and it helps to separate them.

  • The OpenAI SDK switched HTTP clients. The openai package now installs and uses httpx2 for both sync and async. It no longer installs httpx at all, so the old dependency is gone from your lockfile unless you declare it yourself.
  • HTTPX2 is Pydantic's fork of HTTPX. The original HTTPX project, created by Tom Christie under the encode organization, saw limited activity in recent months. The maintainer closed off issues and discussions in February, writing that he didn't want to continue hosting an environment with the community's gender skew. A community fork called HTTPXYZ appeared first, then Pydantic started its own fork under the HTTPX2 name, and the HTTPXYZ authors publicly endorsed HTTPX2 as the blessed continuation. If you have ever used FastAPI or Pydantic, you know Pydantic ships code a lot of production systems depend on.
  • The trust store changed, and this is the part that bites. HTTPX verified TLS certificates against the certifi CA bundle that pip installed for you. HTTPX2 verifies against your operating system's trust store instead, and the SDK no longer installs certifi. Same code, same tests, completely different source of truth for "is this certificate real."

The HN thread's top comment says it in one line: "nb: operating system TLS trust store is used now (instead of certifi)." Another commenter called it immediately: "This could be a breaking change (for some corporate network environments)." They were right, and here is why.

Full disclosure: I run my own AI agent infrastructure on a VPS, all of it in Docker containers, and I use the OpenAI Python SDK daily for the agents that research and draft my articles. I have hit this exact class of failure before, the SSL-error-inside-a-minimal-container kind, which is why I recognized the blast radius the moment I read the guide. I have not yet migrated every one of my projects to the new SDK version, so treat this as an operator's checklist, not a battle-tested war story.

Why the certifi change will find you eventually

Here is the scenario that plays out in a thousand codebases over the next month.

You build a Python image FROM python:3.13-slim. The slim images ship with almost nothing in them, including a minimal set of CA certificates. Under the old SDK, it did not matter much: certifi brought its own bundle, and TLS just worked. Under the new SDK, your HTTPS call to api.openai.com goes looking for CA certificates in the OS trust store, finds nothing or finds an incomplete set, and you get a certificate verification error in an environment where the exact same code worked yesterday.

The three environments the migration guide calls out explicitly:

  • Minimal container images without system CA certificates installed.
  • Corporate networks with TLS-inspecting proxies, where your company's proxy presents its own certificates, and everyone solved this by pointing certifi at a custom bundle. That custom bundle is now ignored.
  • Deployments that pinned or patched certifi for compliance or security reasons. Whatever you did to certifi, you now have to redo it at the OS level.

And here is the truly annoying part: this only breaks at the transport layer. Your mocked tests pass, because your test suite probably never establishes a real TLS connection. That is why I almost shipped it.

The 7-point pre-deploy checklist

I keep this in my deploy notes now. Run it before upgrading any service that uses the OpenAI SDK.

  • Point 1: Audit your imports for httpx. If your code imported httpx only because the SDK installed it transitively, that import is now broken. Either add httpx as an explicit dependency or migrate those imports to httpx2. Grep for import httpx and from httpx across your repo. Do not rely on your lockfile to tell you the truth, because the lockfile will happily keep httpx if something else pulls it in.
  • Point 2: Check your base images for CA certificates. On Debian-based images, run apt-get install -y ca-certificates in your Dockerfile. Do this even if you think you don't need it. It costs you megabytes, not hours of 2 AM debugging.
  • Point 3: If you used a custom certifi bundle, migrate it. The OS-level equivalent is the SSL_CERT_FILE environment variable for a single bundle file, or SSL_CERT_DIR for a directory of certificates:
export SSL_CERT_FILE=/etc/ssl/certs/corporate-ca-bundle.pem
export SSL_CERT_DIR=/etc/ssl/corporate-certs/
Enter fullscreen mode Exit fullscreen mode

These are honored when trust_env=True, which is the default. This one environment variable is probably the highest-leverage fix in this entire article if you sit behind a corporate proxy.

  • Point 4: Update custom HTTP client construction. If you pass http_client= to the SDK, swap httpx objects for httpx2 objects. The mapping is mechanical: httpx.Client becomes httpx2.Client, httpx.Timeout becomes httpx2.Timeout, same for URL, Limits, HTTPTransport, AsyncHTTPTransport, and MockTransport. The SDK ships helpers that preserve its recommended defaults:
from openai import OpenAI, DefaultHttpx2Client

client = OpenAI(
    http_client=DefaultHttpx2Client(proxy="http://proxy.example.com:8080")
)
Enter fullscreen mode Exit fullscreen mode
  • Point 5: Pin your timeout types, not just values. Numeric timeouts are unchanged. But if you build granular timeouts anywhere, the object lives in a new module:
import httpx2
from openai import OpenAI

client = OpenAI(timeout=httpx2.Timeout(60.0, connect=5.0, read=20.0))
Enter fullscreen mode Exit fullscreen mode
  • Point 6: Check your test mocks. This is the one that produces false confidence. MockTransport handlers must now accept and return httpx2.Request and httpx2.Response objects. And if your test suite uses RESPX to intercept HTTP calls, an RESPX version that only patches legacy HTTPX will silently not intercept the SDK's new default client. Your tests will make real network calls and you will not notice until the CI runner without internet access fails. Check your RESPX version before anything else.
  • Point 7: Know the escape hatch, and use it only as a bridge. If a hard dependency still requires legacy HTTPX, you can install it yourself and inject it:
from typing import Any, cast
import httpx
from openai import OpenAI

client = OpenAI(http_client=cast(Any, httpx.Client()))
Enter fullscreen mode Exit fullscreen mode

Note the cast. Legacy clients fail static type checking now, which is the SDK team telling you, in type-checker language, that this path is temporary and may be removed. I would treat any code that lands here as carrying an expiration date.

What I would do differently if I were starting fresh

A few opinions from someone who maintains a handful of long-lived agent services and has been burned by dependency drift before.

  • Pin the SDK version in production services, upgrade deliberately. This migration shipped as a breaking change inside what looks like a routine package update. If your deploy pipeline does pip install -U openai or uses a floating range in pyproject.toml, you adopted a new TLS trust model without deciding to. Pin exact versions and upgrade on your schedule, not the package index's.
  • Put one real HTTPS smoke test in your deployment checks. Every test suite I have written mocks the transport. That means none of them would have caught the trust store change. A single health-check call to the real API endpoint as a post-deploy step would have. It costs one API call. It would have saved a lot of people a bad morning.
  • Treat the OS trust store as the single source of truth everywhere. Honestly, the certifi change is directionally correct. OS trust stores get patched by your package manager and your security team. A certifi bundle pinned in your lockfile does not. The pain is in the transition, not the destination.
  • If you maintain an internal SDK wrapper around OpenAI, update its type signatures now. If your wrapper accepts or returns httpx.Request/httpx.Response objects, every downstream team using it inherits this migration. Doing the httpx2 swap once in the wrapper is the whole point of having a wrapper.

Why this story is bigger than one SDK

The part of the HN thread that stuck with me was not the migration details. It was the reminder of how much of the modern internet runs on a handful of HTTP libraries maintained by very few people. HTTPX is, or was, one of those. When its maintenance stalled and its maintainer closed the community down, Pydantic stepping in as steward was the best available outcome. But notice what the OpenAI SDK migration guide had to do: provide compatibility shims, an escape hatch, warnings that legacy support "may be discontinued." Even a clean fork under a well-funded maintainer means a migration tax paid by thousands of teams.

The lesson I take from it: for anything in your critical path, know who actually maintains the library, and what happens the day they stop. Your dependency tree is a set of informal agreements with strangers. Occasionally one of those agreements ends, and the invoice arrives as a production incident.

I write about AI infrastructure, backend engineering, and the unglamorous operational side of shipping AI systems every week. If that sounds useful, subscribe, it's free.

Now the question back to you: have you migrated anything to the new OpenAI SDK yet? Did the trust store change bite you, or did you get lucky? Tell me in the comments, especially if you are behind a corporate proxy, because that is the case I am least able to test myself.

Top comments (0)