Skip to content

Commit

Permalink
feat: feat!: Update helper methods for client breaking changes (#78)
Browse files Browse the repository at this point in the history
* feat!: Update helper methods for client breaking changes

* Cleanup
  • Loading branch information
nbarbettini authored and stainless-app[bot] committed Jan 16, 2025
1 parent 968690b commit 13cae30
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 59 deletions.
27 changes: 7 additions & 20 deletions src/arcadepy/resources/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,7 @@ def status(
cast_to=AuthAuthorizationResponse,
)

def wait_for_completion(
self,
auth_response_or_id: AuthorizationResponse | str,
scopes: list[str] | None = None,
) -> AuthorizationResponse:
def wait_for_completion(self, auth_response_or_id: AuthorizationResponse | str) -> AuthorizationResponse:
"""
Waits for the authorization process to complete, for example:
Expand All @@ -178,23 +174,19 @@ def wait_for_completion(
```
"""
auth_id_val: str
scopes_val: str | NotGiven = NOT_GIVEN

if isinstance(auth_response_or_id, AuthorizationResponse):
if not auth_response_or_id.authorization_id:
if not auth_response_or_id.id:
raise ValueError("Authorization ID is required")
auth_id_val = auth_response_or_id.authorization_id
scopes_val = " ".join(auth_response_or_id.scopes) if auth_response_or_id.scopes else NOT_GIVEN
auth_id_val = auth_response_or_id.id
auth_response = auth_response_or_id
else:
auth_id_val = auth_response_or_id
scopes_val = " ".join(scopes) if scopes else NOT_GIVEN
auth_response = AuthorizationResponse()

while auth_response.status != "completed":
auth_response = self.status(
authorization_id=auth_id_val,
scopes=scopes_val,
id=auth_id_val,
wait=_DEFAULT_LONGPOLL_WAIT_TIME,
)
return auth_response
Expand Down Expand Up @@ -341,7 +333,6 @@ async def status(
async def wait_for_completion(
self,
auth_response_or_id: AuthorizationResponse | str,
scopes: list[str] | None = None,
) -> AuthorizationResponse:
"""
Waits for the authorization process to complete, for example:
Expand All @@ -352,23 +343,19 @@ async def wait_for_completion(
```
"""
auth_id_val: str
scopes_val: str | NotGiven = NOT_GIVEN

if isinstance(auth_response_or_id, AuthorizationResponse):
if not auth_response_or_id.authorization_id:
if not auth_response_or_id.id:
raise ValueError("Authorization ID is required")
auth_id_val = auth_response_or_id.authorization_id
scopes_val = " ".join(auth_response_or_id.scopes) if auth_response_or_id.scopes else NOT_GIVEN
auth_id_val = auth_response_or_id.id
auth_response = auth_response_or_id
else:
auth_id_val = auth_response_or_id
scopes_val = " ".join(scopes) if scopes else NOT_GIVEN
auth_response = AuthorizationResponse()

while auth_response.status != "completed":
auth_response = await self.status(
authorization_id=auth_id_val,
scopes=scopes_val,
id=auth_id_val,
wait=_DEFAULT_LONGPOLL_WAIT_TIME,
)
return auth_response
Expand Down
57 changes: 18 additions & 39 deletions tests/api_resources/test_auth_wait.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
from typing import List, Union, Optional
from unittest.mock import Mock, AsyncMock

import pytest

from arcadepy._types import NOT_GIVEN, NotGiven
from arcadepy._client import Arcade, AsyncArcade
from arcadepy.resources.auth import AuthResource, AsyncAuthResource
from arcadepy.types.shared.authorization_response import AuthorizationResponse

parametrize_scopes = pytest.mark.parametrize(
"scopes, expected_scopes",
[
(["scope1"], "scope1"),
(["scope1", "scope2"], "scope1 scope2"),
(None, NOT_GIVEN),
],
)


@pytest.fixture
def sync_auth_resource() -> AuthResource:
Expand All @@ -32,64 +21,57 @@ def async_auth_resource() -> AsyncAuthResource:
return auth


@parametrize_scopes
def test_wait_for_completion_calls_status_from_auth_response(
sync_auth_resource: AuthResource, scopes: Optional[List[str]], expected_scopes: Union[str, NotGiven]
) -> None:
def test_wait_for_completion_calls_status_from_auth_response(sync_auth_resource: AuthResource) -> None:
auth = sync_auth_resource
auth.status = Mock(return_value=AuthorizationResponse(status="completed")) # type: ignore

auth_response = AuthorizationResponse(status="pending", authorization_id="auth_id123", scopes=scopes)
auth_response = AuthorizationResponse(status="pending", id="auth_id123")

auth.wait_for_completion(auth_response)

auth.status.assert_called_with(
authorization_id="auth_id123",
scopes=expected_scopes,
id="auth_id123",
wait=45,
timeout=55.0,
)


def test_wait_for_completion_raises_value_error_for_empty_authorization_id(sync_auth_resource: AuthResource) -> None:
auth = sync_auth_resource
auth_response = AuthorizationResponse(status="pending", authorization_id="", scopes=["scope1"])
auth_response = AuthorizationResponse(status="pending", id="", scopes=["scope1"])

with pytest.raises(ValueError, match="Authorization ID is required"):
auth.wait_for_completion(auth_response)


@parametrize_scopes
def test_wait_for_completion_calls_status_with_auth_id(
sync_auth_resource: AuthResource, scopes: Optional[List[str]], expected_scopes: Union[str, NotGiven]
) -> None:
def test_wait_for_completion_calls_status_with_auth_id(sync_auth_resource: AuthResource) -> None:
auth = sync_auth_resource
auth.status = Mock(return_value=AuthorizationResponse(status="completed")) # type: ignore

auth.wait_for_completion("auth_id456", scopes)
auth.wait_for_completion("auth_id456")

auth.status.assert_called_with(
authorization_id="auth_id456",
scopes=expected_scopes,
id="auth_id456",
wait=45,
timeout=55.0,
)


@pytest.mark.asyncio
@parametrize_scopes
async def test_async_wait_for_completion_calls_status_from_auth_response(
async_auth_resource: AsyncAuthResource, scopes: Optional[List[str]], expected_scopes: Union[str, NotGiven]
async_auth_resource: AsyncAuthResource,
) -> None:
auth = async_auth_resource
auth.status = AsyncMock(return_value=AuthorizationResponse(status="completed")) # type: ignore

auth_response = AuthorizationResponse(status="pending", authorization_id="auth_id789", scopes=scopes)
auth_response = AuthorizationResponse(status="pending", id="auth_id789")

await auth.wait_for_completion(auth_response)

auth.status.assert_called_with(
authorization_id="auth_id789",
scopes=expected_scopes,
id="auth_id789",
wait=45,
timeout=55.0,
)


Expand All @@ -98,24 +80,21 @@ async def test_async_wait_for_completion_raises_value_error_for_empty_authorizat
async_auth_resource: AsyncAuthResource,
) -> None:
auth = async_auth_resource
auth_response = AuthorizationResponse(status="pending", authorization_id="", scopes=["scope1"])
auth_response = AuthorizationResponse(status="pending", id="", scopes=["scope1"])

with pytest.raises(ValueError, match="Authorization ID is required"):
await auth.wait_for_completion(auth_response)


@pytest.mark.asyncio
@parametrize_scopes
async def test_async_wait_for_completion_calls_status_with_auth_id(
async_auth_resource: AsyncAuthResource, scopes: Optional[List[str]], expected_scopes: Union[str, NotGiven]
) -> None:
async def test_async_wait_for_completion_calls_status_with_auth_id(async_auth_resource: AsyncAuthResource) -> None:
auth = async_auth_resource
auth.status = AsyncMock(return_value=AuthorizationResponse(status="completed")) # type: ignore

await auth.wait_for_completion("auth_id321", scopes)
await auth.wait_for_completion("auth_id321")

auth.status.assert_called_with(
authorization_id="auth_id321",
scopes=expected_scopes,
id="auth_id321",
wait=45,
timeout=55.0,
)

0 comments on commit 13cae30

Please sign in to comment.