httpx types cross the public API through Client(**kwargs), which decides the cost of an httpx2 move

Author: abraaozCreated Sep 2, 2026Updated Sep 2, 2026

httpx has a successor line, httpx2, published under a different import name, and other packages in this ecosystem have started to move: authlib now emits a deprecation warning when it falls back to httpx, and httpx-aiohttp shipped optional httpx2 support in 0.2.0 behind an httpx2 extra. This is not a request to migrate today, it is about one part of the public API that decides how expensive that migration will be later.

The error surface is already insulated, and that is worth keeping

_client.py converts httpx exceptions into ollama's own types at the boundary:

python
except httpx.HTTPStatusError as e:
  raise ResponseError(e.response.text, e.response.status_code) from None
except httpx.ConnectError:
  raise ConnectionError(CONNECTION_ERROR_MESSAGE) from None

So callers catch ResponseError and ConnectionError, never an httpx type. Whichever module the client is built from is invisible to them, which is exactly what makes a future swap cheap on this side.

The constructor is the part that is not insulated

BaseClient.__init__ forwards **kwargs straight into the httpx client, and says so:

python
"""
Creates a httpx client. Default parameters are the same as those defined in httpx
...
`kwargs` are passed to the httpx client.
"""
self._client = client(base_url=..., follow_redirects=..., timeout=timeout, headers=headers, **kwargs)

timeout and everything in kwargs are httpx-typed values in practice: httpx.Timeout, a custom transport, limits, auth, mounts. httpx2 ships classes with the same names that are distinct types, so code passing ollama.Client(timeout=httpx.Timeout(...)) or a custom transport would break the day the client is constructed from httpx2, and it would break at the call site rather than inside this library.

The question

Not "please migrate", but: is the intended path an optional extra like httpx-aiohttp took (both clients available, the caller choosing), or a major version that swaps the underlying module outright? Saying which one, even without a timeline, tells users passing httpx objects through kwargs today whether they are relying on something that is meant to keep working.

Migration guide, for the type-boundary details: https://httpx2.pydantic.dev/migration/

Versions

  • ollama 0.6.2
  • httpx 0.28.1 (httpx2 not installed)
  • Python 3.14