|
5 | 5 | import time |
6 | 6 | import uuid |
7 | 7 | import email |
| 8 | +import asyncio |
8 | 9 | import inspect |
9 | 10 | import logging |
10 | 11 | import platform |
@@ -672,9 +673,16 @@ def _idempotency_key(self) -> str: |
672 | 673 | return f"stainless-python-retry-{uuid.uuid4()}" |
673 | 674 |
|
674 | 675 |
|
| 676 | +class SyncHttpxClientWrapper(httpx.Client): |
| 677 | + def __del__(self) -> None: |
| 678 | + try: |
| 679 | + self.close() |
| 680 | + except Exception: |
| 681 | + pass |
| 682 | + |
| 683 | + |
675 | 684 | class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]): |
676 | 685 | _client: httpx.Client |
677 | | - _has_custom_http_client: bool |
678 | 686 | _default_stream_cls: type[Stream[Any]] | None = None |
679 | 687 |
|
680 | 688 | def __init__( |
@@ -747,15 +755,14 @@ def __init__( |
747 | 755 | custom_headers=custom_headers, |
748 | 756 | _strict_response_validation=_strict_response_validation, |
749 | 757 | ) |
750 | | - self._client = http_client or httpx.Client( |
| 758 | + self._client = http_client or SyncHttpxClientWrapper( |
751 | 759 | base_url=base_url, |
752 | 760 | # cast to a valid type because mypy doesn't understand our type narrowing |
753 | 761 | timeout=cast(Timeout, timeout), |
754 | 762 | proxies=proxies, |
755 | 763 | transport=transport, |
756 | 764 | limits=limits, |
757 | 765 | ) |
758 | | - self._has_custom_http_client = bool(http_client) |
759 | 766 |
|
760 | 767 | def is_closed(self) -> bool: |
761 | 768 | return self._client.is_closed |
@@ -1135,9 +1142,17 @@ def get_api_list( |
1135 | 1142 | return self._request_api_list(model, page, opts) |
1136 | 1143 |
|
1137 | 1144 |
|
| 1145 | +class AsyncHttpxClientWrapper(httpx.AsyncClient): |
| 1146 | + def __del__(self) -> None: |
| 1147 | + try: |
| 1148 | + # TODO(someday): support non asyncio runtimes here |
| 1149 | + asyncio.get_running_loop().create_task(self.aclose()) |
| 1150 | + except Exception: |
| 1151 | + pass |
| 1152 | + |
| 1153 | + |
1138 | 1154 | class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]): |
1139 | 1155 | _client: httpx.AsyncClient |
1140 | | - _has_custom_http_client: bool |
1141 | 1156 | _default_stream_cls: type[AsyncStream[Any]] | None = None |
1142 | 1157 |
|
1143 | 1158 | def __init__( |
@@ -1210,15 +1225,14 @@ def __init__( |
1210 | 1225 | custom_headers=custom_headers, |
1211 | 1226 | _strict_response_validation=_strict_response_validation, |
1212 | 1227 | ) |
1213 | | - self._client = http_client or httpx.AsyncClient( |
| 1228 | + self._client = http_client or AsyncHttpxClientWrapper( |
1214 | 1229 | base_url=base_url, |
1215 | 1230 | # cast to a valid type because mypy doesn't understand our type narrowing |
1216 | 1231 | timeout=cast(Timeout, timeout), |
1217 | 1232 | proxies=proxies, |
1218 | 1233 | transport=transport, |
1219 | 1234 | limits=limits, |
1220 | 1235 | ) |
1221 | | - self._has_custom_http_client = bool(http_client) |
1222 | 1236 |
|
1223 | 1237 | def is_closed(self) -> bool: |
1224 | 1238 | return self._client.is_closed |
|
0 commit comments