diff --git a/pyproject.toml b/pyproject.toml index 08e3d4d..d71fbd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,9 @@ coveralls = "^3.3.0" [tool.pytest.ini_options] asyncio_mode = "auto" addopts = "tests" +filterwarnings = [ + "ignore::DeprecationWarning", # ignore deprecation warnings globally +] [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 2f4c80e..0000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -asyncio_mode = auto 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..e00ee46 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,28 @@ 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 + headers = {"x-user-agent": "my-app/0.0.1"} + custom_client = AsyncClient( + timeout=Timeout(30), follow_redirects=True, max_redirects=5, headers=headers + ) + + # Initialize the functions client with the custom httpx client + client = AsyncFunctionsClient( + url="https://example.com", + headers={"Authorization": "Bearer token"}, + timeout=10, + 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 + assert client._client.headers.get("x-user-agent") == "my-app/0.0.1" + + # 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..577194f 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,28 @@ 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 + headers = {"x-user-agent": "my-app/0.0.1"} + custom_client = SyncClient( + timeout=Timeout(30), follow_redirects=True, max_redirects=5, headers=headers + ) + + # Initialize the functions client with the custom httpx client + client = SyncFunctionsClient( + url="https://example.com", + headers={"Authorization": "Bearer token"}, + timeout=10, + 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 + assert client._client.headers.get("x-user-agent") == "my-app/0.0.1" + + # Verify the client is properly configured with our custom client + assert client._client is custom_client