Skip to content
This repository was archived by the owner on Aug 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
2 changes: 0 additions & 2 deletions pytest.ini

This file was deleted.

51 changes: 40 additions & 11 deletions supabase_functions/_async/functions_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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,
Expand Down
51 changes: 40 additions & 11 deletions supabase_functions/_sync/functions_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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,
Expand Down
27 changes: 26 additions & 1 deletion tests/_async/test_function_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__


Expand Down Expand Up @@ -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
27 changes: 26 additions & 1 deletion tests/_sync/test_function_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__


Expand Down Expand Up @@ -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