diff --git a/supabase_functions/_async/functions_client.py b/supabase_functions/_async/functions_client.py index ba12dbb..72f3bb2 100644 --- a/supabase_functions/_async/functions_client.py +++ b/supabase_functions/_async/functions_client.py @@ -19,9 +19,10 @@ def __init__( self, url: str, headers: Dict, - timeout: int, - verify: bool = True, + timeout: Optional[int] = None, + verify: Optional[bool] = None, proxy: Optional[str] = None, + http_client: Optional[AsyncClient] = None, ): if not is_http_url(url): raise ValueError("url must be a valid HTTP URL string") @@ -30,15 +31,43 @@ 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 http client instead.", + DeprecationWarning, + stacklevel=2, + ) + if verify is not None: + warn( + "The 'verify' parameter is deprecated. Please configure it in the http client instead.", + DeprecationWarning, + stacklevel=2, + ) + if proxy is not None: + warn( + "The 'proxy' parameter is deprecated. Please configure it in the http 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 http_client is not None: + http_client.base_url = self.url + http_client.headers.update({**self.headers}) + self._client = http_client + 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/supabase_functions/_sync/functions_client.py b/supabase_functions/_sync/functions_client.py index d8a410f..1e607b2 100644 --- a/supabase_functions/_sync/functions_client.py +++ b/supabase_functions/_sync/functions_client.py @@ -19,9 +19,10 @@ def __init__( self, url: str, headers: Dict, - timeout: int, - verify: bool = True, + timeout: Optional[int] = None, + verify: Optional[bool] = None, proxy: Optional[str] = None, + http_client: Optional[SyncClient] = None, ): if not is_http_url(url): raise ValueError("url must be a valid HTTP URL string") @@ -30,15 +31,43 @@ def __init__( "User-Agent": f"supabase-py/functions-py v{__version__}", **headers, } - self._client = SyncClient( - 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 http client instead.", + DeprecationWarning, + stacklevel=2, + ) + if verify is not None: + warn( + "The 'verify' parameter is deprecated. Please configure it in the http client instead.", + DeprecationWarning, + stacklevel=2, + ) + if proxy is not None: + warn( + "The 'proxy' parameter is deprecated. Please configure it in the http 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 http_client is not None: + http_client.base_url = self.url + http_client.headers.update({**self.headers}) + self._client = http_client + else: + self._client = SyncClient( + base_url=self.url, + headers=self.headers, + verify=self.verify, + timeout=self.timeout, + proxy=proxy, + follow_redirects=True, + http2=True, + ) def _request( self, diff --git a/tests/_async/test_function_client.py b/tests/_async/test_function_client.py index e2ee513..158b6fe 100644 --- a/tests/_async/test_function_client.py +++ b/tests/_async/test_function_client.py @@ -6,7 +6,7 @@ # Import the class to test from supabase_functions import AsyncFunctionsClient from supabase_functions.errors import FunctionsHttpError, FunctionsRelayError -from supabase_functions.utils import FunctionRegion +from supabase_functions.utils import AsyncClient, FunctionRegion from supabase_functions.version import __version__ @@ -197,3 +197,26 @@ 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, + http_client=custom_client, + ) + + # Verify the custom client options are preserved + assert client._client.timeout == Timeout(30) + 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 diff --git a/tests/_sync/test_function_client.py b/tests/_sync/test_function_client.py index d11bc11..037ea07 100644 --- a/tests/_sync/test_function_client.py +++ b/tests/_sync/test_function_client.py @@ -6,7 +6,7 @@ # Import the class to test from supabase_functions import SyncFunctionsClient from supabase_functions.errors import FunctionsHttpError, FunctionsRelayError -from supabase_functions.utils import FunctionRegion +from supabase_functions.utils import FunctionRegion, SyncClient from supabase_functions.version import __version__ @@ -181,3 +181,26 @@ def test_invoke_with_json_body(client: SyncFunctionsClient): _, kwargs = mock_request.call_args assert kwargs["headers"]["Content-Type"] == "application/json" + + +def test_init_with_httpx_client(): + # Create a custom httpx client with specific options + custom_client = SyncClient( + timeout=Timeout(30), follow_redirects=True, max_redirects=5 + ) + + # Initialize the functions client with the custom httpx client + client = SyncFunctionsClient( + url="https://example.com", + headers={"Authorization": "Bearer token"}, + timeout=30, + http_client=custom_client, + ) + + # Verify the custom client options are preserved + assert client._client.timeout == Timeout(30) + 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