diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index 992b035c..d552f2cb 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -9,7 +9,6 @@ import inspect import logging import platform -import warnings import email.utils from types import TracebackType from random import random @@ -36,7 +35,7 @@ import httpx import distro import pydantic -from httpx import URL, Limits +from httpx import URL from pydantic import PrivateAttr from . import _exceptions @@ -51,13 +50,10 @@ Timeout, NotGiven, ResponseT, - Transport, AnyMapping, PostParser, - ProxiesTypes, RequestFiles, HttpxSendArgs, - AsyncTransport, RequestOptions, HttpxRequestFiles, ModelBuilderProtocol, @@ -338,9 +334,6 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]): _base_url: URL max_retries: int timeout: Union[float, Timeout, None] - _limits: httpx.Limits - _proxies: ProxiesTypes | None - _transport: Transport | AsyncTransport | None _strict_response_validation: bool _idempotency_header: str | None _default_stream_cls: type[_DefaultStreamT] | None = None @@ -353,9 +346,6 @@ def __init__( _strict_response_validation: bool, max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None = DEFAULT_TIMEOUT, - limits: httpx.Limits, - transport: Transport | AsyncTransport | None, - proxies: ProxiesTypes | None, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, ) -> None: @@ -363,9 +353,6 @@ def __init__( self._base_url = self._enforce_trailing_slash(URL(base_url)) self.max_retries = max_retries self.timeout = timeout - self._limits = limits - self._proxies = proxies - self._transport = transport self._custom_headers = custom_headers or {} self._custom_query = custom_query or {} self._strict_response_validation = _strict_response_validation @@ -801,46 +788,11 @@ def __init__( base_url: str | URL, max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, - transport: Transport | None = None, - proxies: ProxiesTypes | None = None, - limits: Limits | None = None, http_client: httpx.Client | None = None, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, _strict_response_validation: bool, ) -> None: - kwargs: dict[str, Any] = {} - if limits is not None: - warnings.warn( - "The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead", - category=DeprecationWarning, - stacklevel=3, - ) - if http_client is not None: - raise ValueError("The `http_client` argument is mutually exclusive with `connection_pool_limits`") - else: - limits = DEFAULT_CONNECTION_LIMITS - - if transport is not None: - kwargs["transport"] = transport - warnings.warn( - "The `transport` argument is deprecated. The `http_client` argument should be passed instead", - category=DeprecationWarning, - stacklevel=3, - ) - if http_client is not None: - raise ValueError("The `http_client` argument is mutually exclusive with `transport`") - - if proxies is not None: - kwargs["proxies"] = proxies - warnings.warn( - "The `proxies` argument is deprecated. The `http_client` argument should be passed instead", - category=DeprecationWarning, - stacklevel=3, - ) - if http_client is not None: - raise ValueError("The `http_client` argument is mutually exclusive with `proxies`") - if not is_given(timeout): # if the user passed in a custom http client with a non-default # timeout set then we use that timeout. @@ -861,12 +813,9 @@ def __init__( super().__init__( version=version, - limits=limits, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), - proxies=proxies, base_url=base_url, - transport=transport, max_retries=max_retries, custom_query=custom_query, custom_headers=custom_headers, @@ -876,9 +825,6 @@ def __init__( base_url=base_url, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), - limits=limits, - follow_redirects=True, - **kwargs, # type: ignore ) def is_closed(self) -> bool: @@ -1387,45 +1333,10 @@ def __init__( _strict_response_validation: bool, max_retries: int = DEFAULT_MAX_RETRIES, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, - transport: AsyncTransport | None = None, - proxies: ProxiesTypes | None = None, - limits: Limits | None = None, http_client: httpx.AsyncClient | None = None, custom_headers: Mapping[str, str] | None = None, custom_query: Mapping[str, object] | None = None, ) -> None: - kwargs: dict[str, Any] = {} - if limits is not None: - warnings.warn( - "The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead", - category=DeprecationWarning, - stacklevel=3, - ) - if http_client is not None: - raise ValueError("The `http_client` argument is mutually exclusive with `connection_pool_limits`") - else: - limits = DEFAULT_CONNECTION_LIMITS - - if transport is not None: - kwargs["transport"] = transport - warnings.warn( - "The `transport` argument is deprecated. The `http_client` argument should be passed instead", - category=DeprecationWarning, - stacklevel=3, - ) - if http_client is not None: - raise ValueError("The `http_client` argument is mutually exclusive with `transport`") - - if proxies is not None: - kwargs["proxies"] = proxies - warnings.warn( - "The `proxies` argument is deprecated. The `http_client` argument should be passed instead", - category=DeprecationWarning, - stacklevel=3, - ) - if http_client is not None: - raise ValueError("The `http_client` argument is mutually exclusive with `proxies`") - if not is_given(timeout): # if the user passed in a custom http client with a non-default # timeout set then we use that timeout. @@ -1447,11 +1358,8 @@ def __init__( super().__init__( version=version, base_url=base_url, - limits=limits, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), - proxies=proxies, - transport=transport, max_retries=max_retries, custom_query=custom_query, custom_headers=custom_headers, @@ -1461,9 +1369,6 @@ def __init__( base_url=base_url, # cast to a valid type because mypy doesn't understand our type narrowing timeout=cast(Timeout, timeout), - limits=limits, - follow_redirects=True, - **kwargs, # type: ignore ) def is_closed(self) -> bool: diff --git a/src/finch/_client.py b/src/finch/_client.py index 0dbecdff..a40f8c5f 100644 --- a/src/finch/_client.py +++ b/src/finch/_client.py @@ -19,7 +19,6 @@ NotGiven, Transport, ProxiesTypes, - AsyncTransport, RequestOptions, ) from ._utils import ( @@ -32,11 +31,8 @@ from ._exceptions import APIStatusError from ._base_client import ( DEFAULT_MAX_RETRIES, - DEFAULT_CONNECTION_LIMITS, SyncAPIClient, AsyncAPIClient, - SyncHttpxClientWrapper, - AsyncHttpxClientWrapper, ) from .resources.hris import hris from .resources.jobs import jobs @@ -82,12 +78,6 @@ def __init__( # We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`. # See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details. http_client: httpx.Client | None = None, - # See httpx documentation for [custom transports](https://www.python-httpx.org/advanced/#custom-transports) - transport: Transport | None = None, - # See httpx documentation for [proxies](https://www.python-httpx.org/advanced/#http-proxying) - proxies: ProxiesTypes | None = None, - # See httpx documentation for [limits](https://www.python-httpx.org/advanced/#pool-limit-configuration) - connection_pool_limits: httpx.Limits | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. @@ -130,9 +120,6 @@ def __init__( max_retries=max_retries, timeout=timeout, http_client=http_client, - transport=transport, - proxies=proxies, - limits=connection_pool_limits, custom_headers=default_headers, custom_query=default_query, _strict_response_validation=_strict_response_validation, @@ -217,7 +204,6 @@ def copy( base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.Client | None = None, - connection_pool_limits: httpx.Limits | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, @@ -246,24 +232,7 @@ def copy( elif set_default_query is not None: params = set_default_query - if connection_pool_limits is not None: - if http_client is not None: - raise ValueError("The 'http_client' argument is mutually exclusive with 'connection_pool_limits'") - - if not isinstance(self._client, SyncHttpxClientWrapper): - raise ValueError( - "A custom HTTP client has been set and is mutually exclusive with the 'connection_pool_limits' argument" - ) - - http_client = None - else: - if self._limits is not DEFAULT_CONNECTION_LIMITS: - connection_pool_limits = self._limits - else: - connection_pool_limits = None - - http_client = http_client or self._client - + http_client = http_client or self._client return self.__class__( access_token=access_token or self.access_token, client_id=client_id or self.client_id, @@ -272,7 +241,6 @@ def copy( base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, - connection_pool_limits=connection_pool_limits, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, @@ -352,12 +320,6 @@ def __init__( # We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`. # See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details. http_client: httpx.AsyncClient | None = None, - # See httpx documentation for [custom transports](https://www.python-httpx.org/advanced/#custom-transports) - transport: AsyncTransport | None = None, - # See httpx documentation for [proxies](https://www.python-httpx.org/advanced/#http-proxying) - proxies: ProxiesTypes | None = None, - # See httpx documentation for [limits](https://www.python-httpx.org/advanced/#pool-limit-configuration) - connection_pool_limits: httpx.Limits | None = None, # Enable or disable schema validation for data returned by the API. # When enabled an error APIResponseValidationError is raised # if the API responds with invalid data for the expected schema. @@ -400,9 +362,6 @@ def __init__( max_retries=max_retries, timeout=timeout, http_client=http_client, - transport=transport, - proxies=proxies, - limits=connection_pool_limits, custom_headers=default_headers, custom_query=default_query, _strict_response_validation=_strict_response_validation, @@ -487,7 +446,6 @@ def copy( base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.AsyncClient | None = None, - connection_pool_limits: httpx.Limits | None = None, max_retries: int | NotGiven = NOT_GIVEN, default_headers: Mapping[str, str] | None = None, set_default_headers: Mapping[str, str] | None = None, @@ -516,24 +474,7 @@ def copy( elif set_default_query is not None: params = set_default_query - if connection_pool_limits is not None: - if http_client is not None: - raise ValueError("The 'http_client' argument is mutually exclusive with 'connection_pool_limits'") - - if not isinstance(self._client, AsyncHttpxClientWrapper): - raise ValueError( - "A custom HTTP client has been set and is mutually exclusive with the 'connection_pool_limits' argument" - ) - - http_client = None - else: - if self._limits is not DEFAULT_CONNECTION_LIMITS: - connection_pool_limits = self._limits - else: - connection_pool_limits = None - - http_client = http_client or self._client - + http_client = http_client or self._client return self.__class__( access_token=access_token or self.access_token, client_id=client_id or self.client_id, @@ -542,7 +483,6 @@ def copy( base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, - connection_pool_limits=connection_pool_limits, max_retries=max_retries if is_given(max_retries) else self.max_retries, default_headers=headers, default_query=params, diff --git a/tests/test_client.py b/tests/test_client.py index 52d6f178..a52f63d4 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -18,7 +18,6 @@ import httpx import pytest -import packaging.version as version from respx import MockRouter from pydantic import ValidationError @@ -645,113 +644,6 @@ def test_absolute_request_url(self, client: Finch) -> None: ) assert request.url == "https://myapi.com/foo" - @pytest.mark.skipif( - version.parse(httpx.__version__) >= version.parse("0.28.0"), - reason="Test is only relevant for httpx versions < 0.28.0", - ) - def test_transport_option_is_deprecated(self) -> None: - with pytest.warns( - DeprecationWarning, - match="The `transport` argument is deprecated. The `http_client` argument should be passed instead", - ): - transport = httpx.MockTransport( - lambda: None, # type: ignore - ) - - client = Finch( - base_url=base_url, access_token=access_token, _strict_response_validation=True, transport=transport - ) - - assert client._client._transport is transport - - def test_transport_option_mutually_exclusive_with_http_client(self) -> None: - with httpx.Client() as http_client: - with pytest.raises(ValueError, match="The `http_client` argument is mutually exclusive with `transport`"): - with pytest.warns(DeprecationWarning): - Finch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - transport=httpx.MockTransport( - lambda: None, # type: ignore - ), - http_client=http_client, - ) - - @pytest.mark.skipif( - version.parse(httpx.__version__) >= version.parse("0.28.0"), - reason="Test is only relevant for httpx versions < 0.28.0", - ) - def test_connection_pool_limits_option_is_deprecated(self) -> None: - with pytest.warns( - DeprecationWarning, - match="The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead", - ): - connection_pool_limits = httpx.Limits( - max_connections=101, max_keepalive_connections=76, keepalive_expiry=23 - ) - - client = Finch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - connection_pool_limits=connection_pool_limits, - ) - - assert isinstance(client._client._transport, httpx.HTTPTransport) - assert client._client._transport._pool._max_connections == 101 - assert client._client._transport._pool._max_keepalive_connections == 76 - assert client._client._transport._pool._keepalive_expiry == 23 - - def test_connection_pool_limits_option_mutually_exclusive_with_http_client(self) -> None: - with httpx.Client() as http_client: - with pytest.raises( - ValueError, match="The `http_client` argument is mutually exclusive with `connection_pool_limits`" - ): - with pytest.warns(DeprecationWarning): - Finch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - connection_pool_limits=httpx.Limits( - max_connections=101, max_keepalive_connections=76, keepalive_expiry=23 - ), - http_client=http_client, - ) - - @pytest.mark.skipif( - version.parse(httpx.__version__) >= version.parse("0.28.0"), - reason="Test is only relevant for httpx versions < 0.28.0", - ) - def test_proxies_option_is_deprecated(self) -> None: - with pytest.warns( - DeprecationWarning, - match="The `proxies` argument is deprecated. The `http_client` argument should be passed instead", - ): - proxies = "https://www.example.com/proxy" - - client = Finch( - base_url=base_url, access_token=access_token, _strict_response_validation=True, proxies=proxies - ) - - mounts = list(client._client._mounts.keys()) - assert len(mounts) == 1 - - pattern = mounts[0].pattern - assert pattern == "all://" - - def test_proxies_option_mutually_exclusive_with_http_client(self) -> None: - with httpx.Client() as http_client: - with pytest.raises(ValueError, match="The `http_client` argument is mutually exclusive with `proxies`"): - with pytest.warns(DeprecationWarning): - Finch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - proxies="https://www.example.com/proxy", - http_client=http_client, - ) - def test_copied_client_does_not_close_http(self) -> None: client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) assert not client.is_closed() @@ -1541,113 +1433,6 @@ def test_absolute_request_url(self, client: AsyncFinch) -> None: ) assert request.url == "https://myapi.com/foo" - @pytest.mark.skipif( - version.parse(httpx.__version__) >= version.parse("0.28.0"), - reason="Test is only relevant for httpx versions < 0.28.0", - ) - def test_transport_option_is_deprecated(self) -> None: - with pytest.warns( - DeprecationWarning, - match="The `transport` argument is deprecated. The `http_client` argument should be passed instead", - ): - transport = httpx.MockTransport( - lambda: None, # type: ignore - ) - - client = AsyncFinch( - base_url=base_url, access_token=access_token, _strict_response_validation=True, transport=transport - ) - - assert client._client._transport is transport - - async def test_transport_option_mutually_exclusive_with_http_client(self) -> None: - async with httpx.AsyncClient() as http_client: - with pytest.raises(ValueError, match="The `http_client` argument is mutually exclusive with `transport`"): - with pytest.warns(DeprecationWarning): - AsyncFinch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - transport=httpx.MockTransport( - lambda: None, # type: ignore - ), - http_client=http_client, - ) - - @pytest.mark.skipif( - version.parse(httpx.__version__) >= version.parse("0.28.0"), - reason="Test is only relevant for httpx versions < 0.28.0", - ) - def test_connection_pool_limits_option_is_deprecated(self) -> None: - with pytest.warns( - DeprecationWarning, - match="The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead", - ): - connection_pool_limits = httpx.Limits( - max_connections=101, max_keepalive_connections=76, keepalive_expiry=23 - ) - - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - connection_pool_limits=connection_pool_limits, - ) - - assert isinstance(client._client._transport, httpx.AsyncHTTPTransport) - assert client._client._transport._pool._max_connections == 101 - assert client._client._transport._pool._max_keepalive_connections == 76 - assert client._client._transport._pool._keepalive_expiry == 23 - - async def test_connection_pool_limits_option_mutually_exclusive_with_http_client(self) -> None: - async with httpx.AsyncClient() as http_client: - with pytest.raises( - ValueError, match="The `http_client` argument is mutually exclusive with `connection_pool_limits`" - ): - with pytest.warns(DeprecationWarning): - AsyncFinch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - connection_pool_limits=httpx.Limits( - max_connections=101, max_keepalive_connections=76, keepalive_expiry=23 - ), - http_client=http_client, - ) - - @pytest.mark.skipif( - version.parse(httpx.__version__) >= version.parse("0.28.0"), - reason="Test is only relevant for httpx versions < 0.28.0", - ) - def test_proxies_option_is_deprecated(self) -> None: - with pytest.warns( - DeprecationWarning, - match="The `proxies` argument is deprecated. The `http_client` argument should be passed instead", - ): - proxies = "https://www.example.com/proxy" - - client = AsyncFinch( - base_url=base_url, access_token=access_token, _strict_response_validation=True, proxies=proxies - ) - - mounts = list(client._client._mounts.keys()) - assert len(mounts) == 1 - - pattern = mounts[0].pattern - assert pattern == "all://" - - async def test_proxies_option_mutually_exclusive_with_http_client(self) -> None: - async with httpx.AsyncClient() as http_client: - with pytest.raises(ValueError, match="The `http_client` argument is mutually exclusive with `proxies`"): - with pytest.warns(DeprecationWarning): - AsyncFinch( - base_url=base_url, - access_token=access_token, - _strict_response_validation=True, - proxies="https://www.example.com/proxy", - http_client=http_client, - ) - async def test_copied_client_does_not_close_http(self) -> None: client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) assert not client.is_closed()