From 5446dc18eedd90d4b8c732a6f76e871ea4a2fa77 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:37:33 +0000 Subject: [PATCH] feat(api): manual updates --- .stats.yml | 2 +- README.md | 15 +- src/openint/_client.py | 54 +-- .../types/client_create_magic_link_params.py | 6 +- tests/api_resources/test_client.py | 10 +- tests/conftest.py | 11 +- tests/test_client.py | 348 +++--------------- 7 files changed, 60 insertions(+), 386 deletions(-) diff --git a/.stats.yml b/.stats.yml index e4a0143..133e0bf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 7 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openint%2Fopenint-1774a01e29ee20fa16ce371374b9a675da3d1a0a5d3cb911a4acf067d3c7351e.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openint%2Fopenint-ed263d82a28e8475a7ebc5eaa4dfe53255fcd3342d12ec956bf331b169407b3b.yml diff --git a/README.md b/README.md index ebb01d3..d417fb7 100644 --- a/README.md +++ b/README.md @@ -24,34 +24,23 @@ pip install --pre openint The full API of this library can be found in [api.md](api.md). ```python -import os from openint import Openint -client = Openint( - api_key=os.environ.get("OPENINT_API_KEY"), # This is the default and can be omitted -) +client = Openint() response = client.get_connection() print(response.items) ``` -While you can provide an `api_key` keyword argument, -we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/) -to add `OPENINT_API_KEY="My API Key"` to your `.env` file -so that your API Key is not stored in source control. - ## Async usage Simply import `AsyncOpenint` instead of `Openint` and use `await` with each API call: ```python -import os import asyncio from openint import AsyncOpenint -client = AsyncOpenint( - api_key=os.environ.get("OPENINT_API_KEY"), # This is the default and can be omitted -) +client = AsyncOpenint() async def main() -> None: diff --git a/src/openint/_client.py b/src/openint/_client.py index 71e4001..f7a90f1 100644 --- a/src/openint/_client.py +++ b/src/openint/_client.py @@ -128,14 +128,6 @@ def __init__( def qs(self) -> Querystring: return Querystring(array_format="comma") - @property - @override - def auth_headers(self) -> dict[str, str]: - api_key = self.api_key - if api_key is None: - return {} - return {"Authorization": f"Bearer {api_key}"} - @property @override def default_headers(self) -> dict[str, str | Omit]: @@ -145,17 +137,6 @@ def default_headers(self) -> dict[str, str | Omit]: **self._custom_headers, } - @override - def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: - if self.api_key and headers.get("Authorization"): - return - if isinstance(custom_headers.get("Authorization"), Omit): - return - - raise TypeError( - '"Could not resolve authentication method. Expected the api_key to be set. Or for the `Authorization` headers to be explicitly omitted"' - ) - def copy( self, *, @@ -246,7 +227,6 @@ def create_magic_link( self, *, customer_id: str, - email: str, connection_id: Optional[str] | NotGiven = NOT_GIVEN, connector_names: Optional[ Literal[ @@ -306,6 +286,7 @@ def create_magic_link( ] ] | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, redirect_url: Optional[str] | NotGiven = NOT_GIVEN, theme: Optional[Literal["light", "dark"]] | NotGiven = NOT_GIVEN, validity_in_seconds: float | NotGiven = NOT_GIVEN, @@ -321,10 +302,10 @@ def create_magic_link( Create a magic link for connecting integrations Args: - email: The email address of the customer - connector_names: Filter integrations by comma separated connector names + email: The email address of the customer + redirect_url: Where to send user to after connect / if they press back button theme: Magic Link display theme @@ -346,9 +327,9 @@ def create_magic_link( body=maybe_transform( { "customer_id": customer_id, - "email": email, "connection_id": connection_id, "connector_names": connector_names, + "email": email, "redirect_url": redirect_url, "theme": theme, "validity_in_seconds": validity_in_seconds, @@ -819,14 +800,6 @@ def __init__( def qs(self) -> Querystring: return Querystring(array_format="comma") - @property - @override - def auth_headers(self) -> dict[str, str]: - api_key = self.api_key - if api_key is None: - return {} - return {"Authorization": f"Bearer {api_key}"} - @property @override def default_headers(self) -> dict[str, str | Omit]: @@ -836,17 +809,6 @@ def default_headers(self) -> dict[str, str | Omit]: **self._custom_headers, } - @override - def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: - if self.api_key and headers.get("Authorization"): - return - if isinstance(custom_headers.get("Authorization"), Omit): - return - - raise TypeError( - '"Could not resolve authentication method. Expected the api_key to be set. Or for the `Authorization` headers to be explicitly omitted"' - ) - def copy( self, *, @@ -937,7 +899,6 @@ async def create_magic_link( self, *, customer_id: str, - email: str, connection_id: Optional[str] | NotGiven = NOT_GIVEN, connector_names: Optional[ Literal[ @@ -997,6 +958,7 @@ async def create_magic_link( ] ] | NotGiven = NOT_GIVEN, + email: str | NotGiven = NOT_GIVEN, redirect_url: Optional[str] | NotGiven = NOT_GIVEN, theme: Optional[Literal["light", "dark"]] | NotGiven = NOT_GIVEN, validity_in_seconds: float | NotGiven = NOT_GIVEN, @@ -1012,10 +974,10 @@ async def create_magic_link( Create a magic link for connecting integrations Args: - email: The email address of the customer - connector_names: Filter integrations by comma separated connector names + email: The email address of the customer + redirect_url: Where to send user to after connect / if they press back button theme: Magic Link display theme @@ -1037,9 +999,9 @@ async def create_magic_link( body=await async_maybe_transform( { "customer_id": customer_id, - "email": email, "connection_id": connection_id, "connector_names": connector_names, + "email": email, "redirect_url": redirect_url, "theme": theme, "validity_in_seconds": validity_in_seconds, diff --git a/src/openint/types/client_create_magic_link_params.py b/src/openint/types/client_create_magic_link_params.py index 9989433..735fe70 100644 --- a/src/openint/types/client_create_magic_link_params.py +++ b/src/openint/types/client_create_magic_link_params.py @@ -11,9 +11,6 @@ class ClientCreateMagicLinkParams(TypedDict, total=False): customer_id: Required[str] - email: Required[str] - """The email address of the customer""" - connection_id: Optional[str] connector_names: Optional[ @@ -75,6 +72,9 @@ class ClientCreateMagicLinkParams(TypedDict, total=False): ] """Filter integrations by comma separated connector names""" + email: str + """The email address of the customer""" + redirect_url: Optional[str] """Where to send user to after connect / if they press back button""" diff --git a/tests/api_resources/test_client.py b/tests/api_resources/test_client.py index 02e3154..3785ad7 100644 --- a/tests/api_resources/test_client.py +++ b/tests/api_resources/test_client.py @@ -72,7 +72,6 @@ def test_path_params_check_connection(self, client: Openint) -> None: def test_method_create_magic_link(self, client: Openint) -> None: client_ = client.create_magic_link( customer_id="x", - email="dev@stainless.com", ) assert_matches_type(CreateMagicLinkResponse, client_, path=["response"]) @@ -81,9 +80,9 @@ def test_method_create_magic_link(self, client: Openint) -> None: def test_method_create_magic_link_with_all_params(self, client: Openint) -> None: client_ = client.create_magic_link( customer_id="x", - email="dev@stainless.com", connection_id="connection_id", connector_names="aircall", + email="dev@stainless.com", redirect_url="redirect_url", theme="light", validity_in_seconds=0, @@ -96,7 +95,6 @@ def test_method_create_magic_link_with_all_params(self, client: Openint) -> None def test_raw_response_create_magic_link(self, client: Openint) -> None: response = client.with_raw_response.create_magic_link( customer_id="x", - email="dev@stainless.com", ) assert response.is_closed is True @@ -109,7 +107,6 @@ def test_raw_response_create_magic_link(self, client: Openint) -> None: def test_streaming_response_create_magic_link(self, client: Openint) -> None: with client.with_streaming_response.create_magic_link( customer_id="x", - email="dev@stainless.com", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -384,7 +381,6 @@ async def test_path_params_check_connection(self, async_client: AsyncOpenint) -> async def test_method_create_magic_link(self, async_client: AsyncOpenint) -> None: client = await async_client.create_magic_link( customer_id="x", - email="dev@stainless.com", ) assert_matches_type(CreateMagicLinkResponse, client, path=["response"]) @@ -393,9 +389,9 @@ async def test_method_create_magic_link(self, async_client: AsyncOpenint) -> Non async def test_method_create_magic_link_with_all_params(self, async_client: AsyncOpenint) -> None: client = await async_client.create_magic_link( customer_id="x", - email="dev@stainless.com", connection_id="connection_id", connector_names="aircall", + email="dev@stainless.com", redirect_url="redirect_url", theme="light", validity_in_seconds=0, @@ -408,7 +404,6 @@ async def test_method_create_magic_link_with_all_params(self, async_client: Asyn async def test_raw_response_create_magic_link(self, async_client: AsyncOpenint) -> None: response = await async_client.with_raw_response.create_magic_link( customer_id="x", - email="dev@stainless.com", ) assert response.is_closed is True @@ -421,7 +416,6 @@ async def test_raw_response_create_magic_link(self, async_client: AsyncOpenint) async def test_streaming_response_create_magic_link(self, async_client: AsyncOpenint) -> None: async with async_client.with_streaming_response.create_magic_link( customer_id="x", - email="dev@stainless.com", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/conftest.py b/tests/conftest.py index 7e0d354..0f9c67f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,9 +28,6 @@ def pytest_collection_modifyitems(items: list[pytest.Function]) -> None: base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" -customer_token = "GENERATED_CUSTOMER_TOKEN" - @pytest.fixture(scope="session") def client(request: FixtureRequest) -> Iterator[Openint]: @@ -38,9 +35,7 @@ def client(request: FixtureRequest) -> Iterator[Openint]: if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") - with Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=strict - ) as client: + with Openint(base_url=base_url, _strict_response_validation=strict) as client: yield client @@ -50,7 +45,5 @@ async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncOpenint]: if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") - async with AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=strict - ) as client: + async with AsyncOpenint(base_url=base_url, _strict_response_validation=strict) as client: yield client diff --git a/tests/test_client.py b/tests/test_client.py index 3400914..58576d1 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -36,8 +36,6 @@ from .utils import update_env base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -api_key = "My API Key" -customer_token = "GENERATED_CUSTOMER_TOKEN" def _get_params(client: BaseClient[Any, Any]) -> dict[str, str]: @@ -59,9 +57,7 @@ def _get_open_connections(client: Openint | AsyncOpenint) -> int: class TestOpenint: - client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = Openint(base_url=base_url, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) def test_raw_response(self, respx_mock: MockRouter) -> None: @@ -87,14 +83,6 @@ def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) - copied = self.client.copy(api_key="another My API Key") - assert copied.api_key == "another My API Key" - assert self.client.api_key == "My API Key" - - copied = self.client.copy(customer_token="another GENERATED_CUSTOMER_TOKEN") - assert copied.customer_token == "another GENERATED_CUSTOMER_TOKEN" - assert self.client.customer_token == "GENERATED_CUSTOMER_TOKEN" - def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) @@ -112,13 +100,7 @@ def test_copy_default_options(self) -> None: assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_headers={"X-Foo": "bar"}, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, default_headers={"X-Foo": "bar"}) assert client.default_headers["X-Foo"] == "bar" # does not override the already given value when not specified @@ -150,13 +132,7 @@ def test_copy_default_headers(self) -> None: client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"}) def test_copy_default_query(self) -> None: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_query={"foo": "bar"}, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, default_query={"foo": "bar"}) assert _get_params(client)["foo"] == "bar" # does not override the already given value when not specified @@ -279,13 +255,7 @@ def test_request_timeout(self) -> None: assert timeout == httpx.Timeout(100.0) def test_client_timeout_option(self) -> None: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - timeout=httpx.Timeout(0), - ) + client = Openint(base_url=base_url, _strict_response_validation=True, timeout=httpx.Timeout(0)) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -294,13 +264,7 @@ def test_client_timeout_option(self) -> None: def test_http_client_timeout_option(self) -> None: # custom timeout given to the httpx client should be used with httpx.Client(timeout=None) as http_client: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=http_client, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, http_client=http_client) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -308,13 +272,7 @@ def test_http_client_timeout_option(self) -> None: # no timeout given to the httpx client should not use the httpx default with httpx.Client() as http_client: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=http_client, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, http_client=http_client) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -322,13 +280,7 @@ def test_http_client_timeout_option(self) -> None: # explicitly passing the default timeout currently results in it being ignored with httpx.Client(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=http_client, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, http_client=http_client) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -337,30 +289,16 @@ def test_http_client_timeout_option(self) -> None: async def test_invalid_http_client(self) -> None: with pytest.raises(TypeError, match="Invalid `http_client` arg"): async with httpx.AsyncClient() as http_client: - Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=cast(Any, http_client), - ) + Openint(base_url=base_url, _strict_response_validation=True, http_client=cast(Any, http_client)) def test_default_headers_option(self) -> None: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_headers={"X-Foo": "bar"}, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, default_headers={"X-Foo": "bar"}) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("x-foo") == "bar" assert request.headers.get("x-stainless-lang") == "python" client2 = Openint( base_url=base_url, - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, default_headers={ "X-Foo": "stainless", @@ -371,37 +309,8 @@ def test_default_headers_option(self) -> None: assert request.headers.get("x-foo") == "stainless" assert request.headers.get("x-stainless-lang") == "my-overriding-header" - def test_validate_headers(self) -> None: - client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) - request = client._build_request(FinalRequestOptions(method="get", url="/foo")) - assert request.headers.get("Authorization") == f"Bearer {api_key}" - - with update_env(**{"OPENINT_API_KEY": Omit()}): - client2 = Openint( - base_url=base_url, api_key=None, customer_token=customer_token, _strict_response_validation=True - ) - - with pytest.raises( - TypeError, - match="Could not resolve authentication method. Expected the api_key to be set. Or for the `Authorization` headers to be explicitly omitted", - ): - client2._build_request(FinalRequestOptions(method="get", url="/foo")) - - request2 = client2._build_request( - FinalRequestOptions(method="get", url="/foo", headers={"Authorization": Omit()}) - ) - assert request2.headers.get("Authorization") is None - def test_default_query_option(self) -> None: - client = Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_query={"query_param": "bar"}, - ) + client = Openint(base_url=base_url, _strict_response_validation=True, default_query={"query_param": "bar"}) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) url = httpx.URL(request.url) assert dict(url.params) == {"query_param": "bar"} @@ -600,12 +509,7 @@ class Model(BaseModel): assert response.foo == 2 def test_base_url_setter(self) -> None: - client = Openint( - base_url="https://example.com/from_init", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ) + client = Openint(base_url="https://example.com/from_init", _strict_response_validation=True) assert client.base_url == "https://example.com/from_init/" client.base_url = "https://example.com/from_setter" # type: ignore[assignment] @@ -614,22 +518,15 @@ def test_base_url_setter(self) -> None: def test_base_url_env(self) -> None: with update_env(OPENINT_BASE_URL="http://localhost:5000/from/env"): - client = Openint(api_key=api_key, customer_token=customer_token, _strict_response_validation=True) + client = Openint(_strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" @pytest.mark.parametrize( "client", [ + Openint(base_url="http://localhost:5000/custom/path/", _strict_response_validation=True), Openint( base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ), - Openint( - base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, http_client=httpx.Client(), ), @@ -649,16 +546,9 @@ def test_base_url_trailing_slash(self, client: Openint) -> None: @pytest.mark.parametrize( "client", [ + Openint(base_url="http://localhost:5000/custom/path/", _strict_response_validation=True), Openint( base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ), - Openint( - base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, http_client=httpx.Client(), ), @@ -678,16 +568,9 @@ def test_base_url_no_trailing_slash(self, client: Openint) -> None: @pytest.mark.parametrize( "client", [ + Openint(base_url="http://localhost:5000/custom/path/", _strict_response_validation=True), Openint( base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ), - Openint( - base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, http_client=httpx.Client(), ), @@ -705,9 +588,7 @@ def test_absolute_request_url(self, client: Openint) -> None: assert request.url == "https://myapi.com/foo" def test_copied_client_does_not_close_http(self) -> None: - client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = Openint(base_url=base_url, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() @@ -718,9 +599,7 @@ def test_copied_client_does_not_close_http(self) -> None: assert not client.is_closed() def test_client_context_manager(self) -> None: - client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = Openint(base_url=base_url, _strict_response_validation=True) with client as c2: assert c2 is client assert not c2.is_closed() @@ -741,13 +620,7 @@ class Model(BaseModel): def test_client_max_retries_validation(self) -> None: with pytest.raises(TypeError, match=r"max_retries cannot be None"): - Openint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - max_retries=cast(Any, None), - ) + Openint(base_url=base_url, _strict_response_validation=True, max_retries=cast(Any, None)) @pytest.mark.respx(base_url=base_url) def test_received_text_for_expected_json(self, respx_mock: MockRouter) -> None: @@ -756,16 +629,12 @@ class Model(BaseModel): respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) - strict_client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + strict_client = Openint(base_url=base_url, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): strict_client.get("/foo", cast_to=Model) - client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=False - ) + client = Openint(base_url=base_url, _strict_response_validation=False) response = client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @@ -793,9 +662,7 @@ class Model(BaseModel): ) @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None: - client = Openint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = Openint(base_url=base_url, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) @@ -901,9 +768,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: class TestAsyncOpenint: - client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio @@ -931,14 +796,6 @@ def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) - copied = self.client.copy(api_key="another My API Key") - assert copied.api_key == "another My API Key" - assert self.client.api_key == "My API Key" - - copied = self.client.copy(customer_token="another GENERATED_CUSTOMER_TOKEN") - assert copied.customer_token == "another GENERATED_CUSTOMER_TOKEN" - assert self.client.customer_token == "GENERATED_CUSTOMER_TOKEN" - def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) @@ -956,13 +813,7 @@ def test_copy_default_options(self) -> None: assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_headers={"X-Foo": "bar"}, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, default_headers={"X-Foo": "bar"}) assert client.default_headers["X-Foo"] == "bar" # does not override the already given value when not specified @@ -994,13 +845,7 @@ def test_copy_default_headers(self) -> None: client.copy(set_default_headers={}, default_headers={"X-Foo": "Bar"}) def test_copy_default_query(self) -> None: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_query={"foo": "bar"}, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, default_query={"foo": "bar"}) assert _get_params(client)["foo"] == "bar" # does not override the already given value when not specified @@ -1123,13 +968,7 @@ async def test_request_timeout(self) -> None: assert timeout == httpx.Timeout(100.0) async def test_client_timeout_option(self) -> None: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - timeout=httpx.Timeout(0), - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, timeout=httpx.Timeout(0)) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -1138,13 +977,7 @@ async def test_client_timeout_option(self) -> None: async def test_http_client_timeout_option(self) -> None: # custom timeout given to the httpx client should be used async with httpx.AsyncClient(timeout=None) as http_client: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=http_client, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, http_client=http_client) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -1152,13 +985,7 @@ async def test_http_client_timeout_option(self) -> None: # no timeout given to the httpx client should not use the httpx default async with httpx.AsyncClient() as http_client: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=http_client, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, http_client=http_client) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -1166,13 +993,7 @@ async def test_http_client_timeout_option(self) -> None: # explicitly passing the default timeout currently results in it being ignored async with httpx.AsyncClient(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=http_client, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, http_client=http_client) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) timeout = httpx.Timeout(**request.extensions["timeout"]) # type: ignore @@ -1181,30 +1002,16 @@ async def test_http_client_timeout_option(self) -> None: def test_invalid_http_client(self) -> None: with pytest.raises(TypeError, match="Invalid `http_client` arg"): with httpx.Client() as http_client: - AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - http_client=cast(Any, http_client), - ) + AsyncOpenint(base_url=base_url, _strict_response_validation=True, http_client=cast(Any, http_client)) def test_default_headers_option(self) -> None: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_headers={"X-Foo": "bar"}, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, default_headers={"X-Foo": "bar"}) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("x-foo") == "bar" assert request.headers.get("x-stainless-lang") == "python" client2 = AsyncOpenint( base_url=base_url, - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, default_headers={ "X-Foo": "stainless", @@ -1215,37 +1022,8 @@ def test_default_headers_option(self) -> None: assert request.headers.get("x-foo") == "stainless" assert request.headers.get("x-stainless-lang") == "my-overriding-header" - def test_validate_headers(self) -> None: - client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) - request = client._build_request(FinalRequestOptions(method="get", url="/foo")) - assert request.headers.get("Authorization") == f"Bearer {api_key}" - - with update_env(**{"OPENINT_API_KEY": Omit()}): - client2 = AsyncOpenint( - base_url=base_url, api_key=None, customer_token=customer_token, _strict_response_validation=True - ) - - with pytest.raises( - TypeError, - match="Could not resolve authentication method. Expected the api_key to be set. Or for the `Authorization` headers to be explicitly omitted", - ): - client2._build_request(FinalRequestOptions(method="get", url="/foo")) - - request2 = client2._build_request( - FinalRequestOptions(method="get", url="/foo", headers={"Authorization": Omit()}) - ) - assert request2.headers.get("Authorization") is None - def test_default_query_option(self) -> None: - client = AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - default_query={"query_param": "bar"}, - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True, default_query={"query_param": "bar"}) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) url = httpx.URL(request.url) assert dict(url.params) == {"query_param": "bar"} @@ -1444,12 +1222,7 @@ class Model(BaseModel): assert response.foo == 2 def test_base_url_setter(self) -> None: - client = AsyncOpenint( - base_url="https://example.com/from_init", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ) + client = AsyncOpenint(base_url="https://example.com/from_init", _strict_response_validation=True) assert client.base_url == "https://example.com/from_init/" client.base_url = "https://example.com/from_setter" # type: ignore[assignment] @@ -1458,22 +1231,15 @@ def test_base_url_setter(self) -> None: def test_base_url_env(self) -> None: with update_env(OPENINT_BASE_URL="http://localhost:5000/from/env"): - client = AsyncOpenint(api_key=api_key, customer_token=customer_token, _strict_response_validation=True) + client = AsyncOpenint(_strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" @pytest.mark.parametrize( "client", [ + AsyncOpenint(base_url="http://localhost:5000/custom/path/", _strict_response_validation=True), AsyncOpenint( base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ), - AsyncOpenint( - base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), @@ -1493,16 +1259,9 @@ def test_base_url_trailing_slash(self, client: AsyncOpenint) -> None: @pytest.mark.parametrize( "client", [ + AsyncOpenint(base_url="http://localhost:5000/custom/path/", _strict_response_validation=True), AsyncOpenint( base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ), - AsyncOpenint( - base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), @@ -1522,16 +1281,9 @@ def test_base_url_no_trailing_slash(self, client: AsyncOpenint) -> None: @pytest.mark.parametrize( "client", [ + AsyncOpenint(base_url="http://localhost:5000/custom/path/", _strict_response_validation=True), AsyncOpenint( base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - ), - AsyncOpenint( - base_url="http://localhost:5000/custom/path/", - api_key=api_key, - customer_token=customer_token, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), @@ -1549,9 +1301,7 @@ def test_absolute_request_url(self, client: AsyncOpenint) -> None: assert request.url == "https://myapi.com/foo" async def test_copied_client_does_not_close_http(self) -> None: - client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() @@ -1563,9 +1313,7 @@ async def test_copied_client_does_not_close_http(self) -> None: assert not client.is_closed() async def test_client_context_manager(self) -> None: - client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True) async with client as c2: assert c2 is client assert not c2.is_closed() @@ -1587,13 +1335,7 @@ class Model(BaseModel): async def test_client_max_retries_validation(self) -> None: with pytest.raises(TypeError, match=r"max_retries cannot be None"): - AsyncOpenint( - base_url=base_url, - api_key=api_key, - customer_token=customer_token, - _strict_response_validation=True, - max_retries=cast(Any, None), - ) + AsyncOpenint(base_url=base_url, _strict_response_validation=True, max_retries=cast(Any, None)) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio @@ -1603,16 +1345,12 @@ class Model(BaseModel): respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) - strict_client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + strict_client = AsyncOpenint(base_url=base_url, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): await strict_client.get("/foo", cast_to=Model) - client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=False - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=False) response = await client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @@ -1641,9 +1379,7 @@ class Model(BaseModel): @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) @pytest.mark.asyncio async def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None: - client = AsyncOpenint( - base_url=base_url, api_key=api_key, customer_token=customer_token, _strict_response_validation=True - ) + client = AsyncOpenint(base_url=base_url, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3)