Skip to content

Commit 399b634

Browse files
stainless-app[bot]stainless-bot
authored andcommitted
feat(client): add DefaultHttpxClient and DefaultAsyncHttpxClient (#342)
1 parent feb6f25 commit 399b634

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,12 @@ You can directly override the [httpx client](https://www.python-httpx.org/api/#c
380380
- Additional [advanced](https://www.python-httpx.org/advanced/#client-instances) functionality
381381

382382
```python
383-
import httpx
384-
from finch import Finch
383+
from finch import Finch, DefaultHttpxClient
385384

386385
client = Finch(
387386
# Or use the `FINCH_BASE_URL` env var
388387
base_url="http://my.test.server.example.com:8083",
389-
http_client=httpx.Client(
388+
http_client=DefaultHttpxClient(
390389
proxies="http://my.test.proxy.example.com",
391390
transport=httpx.HTTPTransport(local_address="0.0.0.0"),
392391
),

src/finch/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
UnprocessableEntityError,
2525
APIResponseValidationError,
2626
)
27+
from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
2728
from ._utils._logs import setup_logging as _setup_logging
2829

2930
__all__ = [
@@ -62,6 +63,8 @@
6263
"DEFAULT_TIMEOUT",
6364
"DEFAULT_MAX_RETRIES",
6465
"DEFAULT_CONNECTION_LIMITS",
66+
"DefaultHttpxClient",
67+
"DefaultAsyncHttpxClient",
6568
]
6669

6770
_setup_logging()

src/finch/_base_client.py

+42-2
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,27 @@ def _idempotency_key(self) -> str:
716716
return f"stainless-python-retry-{uuid.uuid4()}"
717717

718718

719-
class SyncHttpxClientWrapper(httpx.Client):
719+
class _DefaultHttpxClient(httpx.Client):
720+
def __init__(self, **kwargs: Any) -> None:
721+
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
722+
kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
723+
kwargs.setdefault("follow_redirects", True)
724+
super().__init__(**kwargs)
725+
726+
727+
if TYPE_CHECKING:
728+
DefaultHttpxClient = httpx.Client
729+
"""An alias to `httpx.Client` that provides the same defaults that this SDK
730+
uses internally.
731+
732+
This is useful because overriding the `http_client` with your own instance of
733+
`httpx.Client` will result in httpx's defaults being used, not ours.
734+
"""
735+
else:
736+
DefaultHttpxClient = _DefaultHttpxClient
737+
738+
739+
class SyncHttpxClientWrapper(DefaultHttpxClient):
720740
def __del__(self) -> None:
721741
try:
722742
self.close()
@@ -1262,7 +1282,27 @@ def get_api_list(
12621282
return self._request_api_list(model, page, opts)
12631283

12641284

1265-
class AsyncHttpxClientWrapper(httpx.AsyncClient):
1285+
class _DefaultAsyncHttpxClient(httpx.AsyncClient):
1286+
def __init__(self, **kwargs: Any) -> None:
1287+
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
1288+
kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
1289+
kwargs.setdefault("follow_redirects", True)
1290+
super().__init__(**kwargs)
1291+
1292+
1293+
if TYPE_CHECKING:
1294+
DefaultAsyncHttpxClient = httpx.AsyncClient
1295+
"""An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
1296+
uses internally.
1297+
1298+
This is useful because overriding the `http_client` with your own instance of
1299+
`httpx.AsyncClient` will result in httpx's defaults being used, not ours.
1300+
"""
1301+
else:
1302+
DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
1303+
1304+
1305+
class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
12661306
def __del__(self) -> None:
12671307
try:
12681308
# TODO(someday): support non asyncio runtimes here

src/finch/_client.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ def __init__(
8585
max_retries: int = DEFAULT_MAX_RETRIES,
8686
default_headers: Mapping[str, str] | None = None,
8787
default_query: Mapping[str, object] | None = None,
88-
# Configure a custom httpx client. See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details.
88+
# Configure a custom httpx client.
89+
# We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
90+
# See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details.
8991
http_client: httpx.Client | None = None,
9092
# See httpx documentation for [custom transports](https://www.python-httpx.org/advanced/#custom-transports)
9193
transport: Transport | None = None,
@@ -433,7 +435,9 @@ def __init__(
433435
max_retries: int = DEFAULT_MAX_RETRIES,
434436
default_headers: Mapping[str, str] | None = None,
435437
default_query: Mapping[str, object] | None = None,
436-
# Configure a custom httpx client. See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details.
438+
# Configure a custom httpx client.
439+
# We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
440+
# See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details.
437441
http_client: httpx.AsyncClient | None = None,
438442
# See httpx documentation for [custom transports](https://www.python-httpx.org/advanced/#custom-transports)
439443
transport: AsyncTransport | None = None,

0 commit comments

Comments
 (0)