diff --git a/supabase_functions/_async/functions_client.py b/supabase_functions/_async/functions_client.py index ba12dbb..65e5407 100644 --- a/supabase_functions/_async/functions_client.py +++ b/supabase_functions/_async/functions_client.py @@ -1,11 +1,10 @@ from typing import Any, Dict, Literal, Optional, Union from warnings import warn -from httpx import HTTPError, Response +from httpx import AsyncClient, HTTPError, Response from ..errors import FunctionsHttpError, FunctionsRelayError from ..utils import ( - AsyncClient, FunctionRegion, is_http_url, is_valid_jwt, @@ -19,8 +18,9 @@ def __init__( self, url: str, headers: Dict, - timeout: int, - verify: bool = True, + httpx: Optional[AsyncClient] = None, + timeout: Optional[int] = None, + verify: Optional[bool] = None, proxy: Optional[str] = None, ): if not is_http_url(url): @@ -30,15 +30,33 @@ def __init__( "User-Agent": f"supabase-py/functions-py v{__version__}", **headers, } - self._client = AsyncClient( - base_url=self.url, - headers=self.headers, - verify=bool(verify), - timeout=int(abs(timeout)), - proxy=proxy, - follow_redirects=True, - http2=True, - ) + + if timeout is not None: + warn("The 'timeout' parameter is deprecated. Please configure it in the httpx client instead.", DeprecationWarning, stacklevel=2) + if verify is not None: + warn("The 'verify' parameter is deprecated. Please configure it in the httpx client instead.", DeprecationWarning, stacklevel=2) + if proxy is not None: + warn("The 'proxy' parameter is deprecated. Please configure it in the httpx client instead.", DeprecationWarning, stacklevel=2) + + self.verify = bool(verify) if verify is not None else True + self.timeout = int(abs(timeout)) if timeout is not None else 60 + + if httpx is not None: + self._client = httpx + self._client.base_url = self.url + self._client.headers = self.headers + self._client.follow_redirects = True + self._client.http2 = True + else: + self._client = AsyncClient( + base_url=self.url, + headers=self.headers, + verify=self.verify, + timeout=self.timeout, + proxy=proxy, + follow_redirects=True, + http2=True, + ) async def _request( self, diff --git a/tests/_async/test_function_client.py b/tests/_async/test_function_client.py index e2ee513..14f1503 100644 --- a/tests/_async/test_function_client.py +++ b/tests/_async/test_function_client.py @@ -1,7 +1,7 @@ from unittest.mock import AsyncMock, Mock, patch import pytest -from httpx import HTTPError, Response, Timeout +from httpx import AsyncClient, HTTPError, Response, Timeout # Import the class to test from supabase_functions import AsyncFunctionsClient @@ -197,3 +197,27 @@ async def test_invoke_with_json_body(client: AsyncFunctionsClient): _, kwargs = mock_request.call_args assert kwargs["headers"]["Content-Type"] == "application/json" + + +async def test_init_with_httpx_client(): + # Create a custom httpx client with specific options + custom_client = AsyncClient( + timeout=Timeout(30), follow_redirects=True, max_redirects=5 + ) + + # Initialize the functions client with the custom httpx client + client = AsyncFunctionsClient( + url="https://example.com", + headers={"Authorization": "Bearer token"}, + timeout=30, + httpx=custom_client, + ) + + # Verify the custom client options are preserved + assert client._client.timeout == Timeout(30) + assert client._client.verify is True + assert client._client.follow_redirects is True + assert client._client.max_redirects == 5 + + # Verify the client is properly configured with our custom client + assert client._client is custom_client