From 9cc01492efa55d41fe4383a982dd0e5f135cc77d Mon Sep 17 00:00:00 2001 From: Kyle Kelley Date: Tue, 27 Jan 2026 11:24:46 -0800 Subject: [PATCH] Add support for custom httpx client instances Allow passing a pre-configured `httpx.Client` or `httpx.AsyncClient` instance to reuse connections and custom configurations. ```python import httpx from ollama import Client custom_httpx_client = httpx.Client(timeout=30.0) client = Client(client=custom_httpx_client) messages = [ { 'role': 'user', 'content': 'Why is the sky blue?', }, ] for part in client.chat('gpt-oss:120b-cloud', messages=messages, stream=True): print(part.message.content, end='', flush=True) ``` Note: this is an updated minimal version of https://github.com/ollama/ollama-python/pull/380 to support a custom `httpx` client. I took the approach of checking for the class instead of isinstance so that nothing has to be a direct instance of an httpx.Client or httpx.AsyncClient. It's up to the user to provide the right custom client. --- ollama/_client.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ollama/_client.py b/ollama/_client.py index 18cb0fb..afaeb2a 100644 --- a/ollama/_client.py +++ b/ollama/_client.py @@ -1,4 +1,5 @@ import contextlib +import inspect import ipaddress import json import os @@ -93,8 +94,18 @@ def __init__( - `follow_redirects`: True - `timeout`: None `kwargs` are passed to the httpx client. + + Args: + client: Either a httpx.Client/AsyncClient class, or an instance """ + if not inspect.isclass(client): + assert follow_redirects is True, 'Cannot provide `follow_redirects` with custom client instance' + assert timeout is None, 'Cannot provide `timeout` with custom client instance' + assert not kwargs, 'Cannot provide additional kwargs with custom client instance' + self._client = client + return + headers = { k.lower(): v for k, v in { @@ -128,8 +139,8 @@ async def __aexit__(self, exc_type, exc_val, exc_tb): class Client(BaseClient): - def __init__(self, host: Optional[str] = None, **kwargs) -> None: - super().__init__(httpx.Client, host, **kwargs) + def __init__(self, host: Optional[str] = None, *, client: Optional[httpx.Client] = None, **kwargs) -> None: + super().__init__(client or httpx.Client, host, **kwargs) def close(self): self._client.close() @@ -721,8 +732,8 @@ def web_fetch(self, url: str) -> WebFetchResponse: class AsyncClient(BaseClient): - def __init__(self, host: Optional[str] = None, **kwargs) -> None: - super().__init__(httpx.AsyncClient, host, **kwargs) + def __init__(self, host: Optional[str] = None, *, client: Optional[httpx.AsyncClient] = None, **kwargs) -> None: + super().__init__(client or httpx.AsyncClient, host, **kwargs) async def close(self): await self._client.aclose()