From a7f41f69320704671b03835e06cdc16aa37b27e4 Mon Sep 17 00:00:00 2001 From: stainless-bot Date: Mon, 14 Oct 2024 00:52:57 +0000 Subject: [PATCH] feat(api): api update --- .github/workflows/publish-pypi.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- LICENSE | 2 +- README.md | 46 ++++--- SECURITY.md | 4 +- bin/check-release-environment | 2 +- pyproject.toml | 4 +- src/arcadepy/__init__.py | 22 +--- src/arcadepy/_client.py | 136 ++++++--------------- src/arcadepy/_exceptions.py | 4 +- src/arcadepy/_resource.py | 10 +- src/arcadepy/_response.py | 4 +- src/arcadepy/_streaming.py | 6 +- src/arcadepy/_utils/_logs.py | 2 +- tests/api_resources/test_auth.py | 34 +++--- tests/api_resources/test_chat.py | 18 +-- tests/api_resources/test_health.py | 14 +-- tests/api_resources/test_tools.py | 42 +++---- tests/conftest.py | 10 +- tests/test_client.py | 176 ++++++++++++--------------- tests/test_response.py | 26 ++-- tests/test_streaming.py | 30 ++--- 22 files changed, 250 insertions(+), 346 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 918b838c..e68c2875 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -28,4 +28,4 @@ jobs: run: | bash ./bin/publish-pypi env: - PYPI_TOKEN: ${{ secrets.ARCADE_AI_PYPI_TOKEN || secrets.PYPI_TOKEN }} + PYPI_TOKEN: ${{ secrets.ARCADE_PYPI_TOKEN || secrets.PYPI_TOKEN }} diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index a16324eb..d4ed5cf1 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -18,4 +18,4 @@ jobs: run: | bash ./bin/check-release-environment env: - PYPI_TOKEN: ${{ secrets.ARCADE_AI_PYPI_TOKEN || secrets.PYPI_TOKEN }} + PYPI_TOKEN: ${{ secrets.ARCADE_PYPI_TOKEN || secrets.PYPI_TOKEN }} diff --git a/LICENSE b/LICENSE index 334a3439..a47b4317 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Arcade AI + Copyright 2024 Arcade Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 92047a12..7dfe008a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Arcade AI Python API library +# Arcade Python API library [![PyPI version](https://img.shields.io/pypi/v/arcadepy.svg)](https://pypi.org/project/arcadepy/) -The Arcade AI Python library provides convenient access to the Arcade AI REST API from any Python 3.7+ +The Arcade Python library provides convenient access to the Arcade REST API from any Python 3.7+ application. The library includes type definitions for all request params and response fields, and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx). @@ -28,13 +28,11 @@ The full API of this library can be found in [api.md](api.md). ```python import os -from arcadepy import ArcadeAI +from arcadepy import Arcade -client = ArcadeAI( +client = Arcade( # This is the default and can be omitted api_key=os.environ.get("ARCADE_API_KEY"), - # defaults to "production". - environment="staging", ) tool_response = client.tools.execute( @@ -53,18 +51,16 @@ so that your API Key is not stored in source control. ## Async usage -Simply import `AsyncArcadeAI` instead of `ArcadeAI` and use `await` with each API call: +Simply import `AsyncArcade` instead of `Arcade` and use `await` with each API call: ```python import os import asyncio -from arcadepy import AsyncArcadeAI +from arcadepy import AsyncArcade -client = AsyncArcadeAI( +client = AsyncArcade( # This is the default and can be omitted api_key=os.environ.get("ARCADE_API_KEY"), - # defaults to "production". - environment="staging", ) @@ -103,9 +99,9 @@ All errors inherit from `arcadepy.APIError`. ```python import arcadepy -from arcadepy import ArcadeAI +from arcadepy import Arcade -client = ArcadeAI() +client = Arcade() try: client.chat.completions( @@ -149,10 +145,10 @@ Connection errors (for example, due to a network connectivity problem), 408 Requ You can use the `max_retries` option to configure or disable retry settings: ```python -from arcadepy import ArcadeAI +from arcadepy import Arcade # Configure the default for all requests: -client = ArcadeAI( +client = Arcade( # default is 2 max_retries=0, ) @@ -174,16 +170,16 @@ By default requests time out after 1 minute. You can configure this with a `time which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object: ```python -from arcadepy import ArcadeAI +from arcadepy import Arcade # Configure the default for all requests: -client = ArcadeAI( +client = Arcade( # 20 seconds (default is 1 minute) timeout=20.0, ) # More granular control: -client = ArcadeAI( +client = Arcade( timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0), ) @@ -208,10 +204,10 @@ Note that requests that time out are [retried twice by default](#retries). We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module. -You can enable logging by setting the environment variable `ARCADE_AI_LOG` to `debug`. +You can enable logging by setting the environment variable `ARCADE_LOG` to `debug`. ```shell -$ export ARCADE_AI_LOG=debug +$ export ARCADE_LOG=debug ``` ### How to tell whether `None` means `null` or missing @@ -231,9 +227,9 @@ if response.my_field is None: The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g., ```py -from arcadepy import ArcadeAI +from arcadepy import Arcade -client = ArcadeAI() +client = Arcade() response = client.chat.with_raw_response.completions( messages=[{ "role": "user", @@ -317,10 +313,10 @@ You can directly override the [httpx client](https://www.python-httpx.org/api/#c - Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality ```python -from arcadepy import ArcadeAI, DefaultHttpxClient +from arcadepy import Arcade, DefaultHttpxClient -client = ArcadeAI( - # Or use the `ARCADE_AI_BASE_URL` env var +client = Arcade( + # Or use the `ARCADE_BASE_URL` env var base_url="http://my.test.server.example.com:8083", http_client=DefaultHttpxClient( proxies="http://my.test.proxy.example.com", diff --git a/SECURITY.md b/SECURITY.md index 3ab81032..a5382b7d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,9 +16,9 @@ before making any information public. ## Reporting Non-SDK Related Security Issues If you encounter security issues that are not directly related to SDKs but pertain to the services -or products provided by Arcade AI please follow the respective company's security reporting guidelines. +or products provided by Arcade please follow the respective company's security reporting guidelines. -### Arcade AI Terms and Policies +### Arcade Terms and Policies Please contact contact@arcade-ai.com for any questions or concerns regarding security of our services. diff --git a/bin/check-release-environment b/bin/check-release-environment index b98a6fa0..adcf74b4 100644 --- a/bin/check-release-environment +++ b/bin/check-release-environment @@ -3,7 +3,7 @@ errors=() if [ -z "${PYPI_TOKEN}" ]; then - errors+=("The ARCADE_AI_PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.") + errors+=("The ARCADE_PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.") fi lenErrors=${#errors[@]} diff --git a/pyproject.toml b/pyproject.toml index 30cb15e0..352d8399 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,11 @@ [project] name = "arcadepy" version = "0.1.0-alpha.2" -description = "The official Python library for the Arcade AI API" +description = "The official Python library for the Arcade API" dynamic = ["readme"] license = "Apache-2.0" authors = [ -{ name = "Arcade AI", email = "contact@arcade-ai.com" }, +{ name = "Arcade", email = "contact@arcade-ai.com" }, ] dependencies = [ "httpx>=0.23.0, <1", diff --git a/src/arcadepy/__init__.py b/src/arcadepy/__init__.py index 855de195..8f72a207 100644 --- a/src/arcadepy/__init__.py +++ b/src/arcadepy/__init__.py @@ -3,25 +3,14 @@ from . import types from ._types import NOT_GIVEN, NoneType, NotGiven, Transport, ProxiesTypes from ._utils import file_from_path -from ._client import ( - ENVIRONMENTS, - Client, - Stream, - Timeout, - ArcadeAI, - Transport, - AsyncClient, - AsyncStream, - AsyncArcadeAI, - RequestOptions, -) +from ._client import Arcade, Client, Stream, Timeout, Transport, AsyncArcade, AsyncClient, AsyncStream, RequestOptions from ._models import BaseModel from ._version import __title__, __version__ from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse from ._constants import DEFAULT_TIMEOUT, DEFAULT_MAX_RETRIES, DEFAULT_CONNECTION_LIMITS from ._exceptions import ( APIError, - ArcadeAIError, + ArcadeError, ConflictError, NotFoundError, APIStatusError, @@ -47,7 +36,7 @@ "ProxiesTypes", "NotGiven", "NOT_GIVEN", - "ArcadeAIError", + "ArcadeError", "APIError", "APIStatusError", "APITimeoutError", @@ -67,9 +56,8 @@ "AsyncClient", "Stream", "AsyncStream", - "ArcadeAI", - "AsyncArcadeAI", - "ENVIRONMENTS", + "Arcade", + "AsyncArcade", "file_from_path", "BaseModel", "DEFAULT_TIMEOUT", diff --git a/src/arcadepy/_client.py b/src/arcadepy/_client.py index 41b0073b..2cf4cb44 100644 --- a/src/arcadepy/_client.py +++ b/src/arcadepy/_client.py @@ -3,8 +3,8 @@ from __future__ import annotations import os -from typing import Any, Dict, Union, Mapping, cast -from typing_extensions import Self, Literal, override +from typing import Any, Union, Mapping +from typing_extensions import Self, override import httpx @@ -25,7 +25,7 @@ ) from ._version import __version__ from ._streaming import Stream as Stream, AsyncStream as AsyncStream -from ._exceptions import ArcadeAIError, APIStatusError +from ._exceptions import ArcadeError, APIStatusError from ._base_client import ( DEFAULT_MAX_RETRIES, SyncAPIClient, @@ -33,43 +33,34 @@ ) __all__ = [ - "ENVIRONMENTS", "Timeout", "Transport", "ProxiesTypes", "RequestOptions", "resources", - "ArcadeAI", - "AsyncArcadeAI", + "Arcade", + "AsyncArcade", "Client", "AsyncClient", ] -ENVIRONMENTS: Dict[str, str] = { - "production": "https://api.arcade-ai.com", - "staging": "https://dev-api.arcade-ai.com", -} - -class ArcadeAI(SyncAPIClient): +class Arcade(SyncAPIClient): auth: resources.AuthResource chat: resources.ChatResource health: resources.HealthResource tools: resources.ToolsResource - with_raw_response: ArcadeAIWithRawResponse - with_streaming_response: ArcadeAIWithStreamedResponse + with_raw_response: ArcadeWithRawResponse + with_streaming_response: ArcadeWithStreamedResponse # client options api_key: str - _environment: Literal["production", "staging"] | NotGiven - def __init__( self, *, api_key: str | None = None, - environment: Literal["production", "staging"] | NotGiven = NOT_GIVEN, - base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN, + base_url: str | httpx.URL | None = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, @@ -88,43 +79,22 @@ def __init__( # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: - """Construct a new synchronous Arcade AI client instance. + """Construct a new synchronous Arcade client instance. This automatically infers the `api_key` argument from the `ARCADE_API_KEY` environment variable if it is not provided. """ if api_key is None: api_key = os.environ.get("ARCADE_API_KEY") if api_key is None: - raise ArcadeAIError( + raise ArcadeError( "The api_key client option must be set either by passing api_key to the client or by setting the ARCADE_API_KEY environment variable" ) self.api_key = api_key - self._environment = environment - - base_url_env = os.environ.get("ARCADE_AI_BASE_URL") - if is_given(base_url) and base_url is not None: - # cast required because mypy doesn't understand the type narrowing - base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast] - elif is_given(environment): - if base_url_env and base_url is not None: - raise ValueError( - "Ambiguous URL; The `ARCADE_AI_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None", - ) - - try: - base_url = ENVIRONMENTS[environment] - except KeyError as exc: - raise ValueError(f"Unknown environment: {environment}") from exc - elif base_url_env is not None: - base_url = base_url_env - else: - self._environment = environment = "production" - - try: - base_url = ENVIRONMENTS[environment] - except KeyError as exc: - raise ValueError(f"Unknown environment: {environment}") from exc + if base_url is None: + base_url = os.environ.get("ARCADE_BASE_URL") + if base_url is None: + base_url = f"https://api.arcade-ai.com" super().__init__( version=__version__, @@ -143,8 +113,8 @@ def __init__( self.chat = resources.ChatResource(self) self.health = resources.HealthResource(self) self.tools = resources.ToolsResource(self) - self.with_raw_response = ArcadeAIWithRawResponse(self) - self.with_streaming_response = ArcadeAIWithStreamedResponse(self) + self.with_raw_response = ArcadeWithRawResponse(self) + self.with_streaming_response = ArcadeWithStreamedResponse(self) @property @override @@ -170,7 +140,6 @@ def copy( self, *, api_key: str | None = None, - environment: Literal["production", "staging"] | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.Client | None = None, @@ -206,7 +175,6 @@ def copy( return self.__class__( api_key=api_key or self.api_key, base_url=base_url or self.base_url, - environment=environment or self._environment, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, @@ -253,25 +221,22 @@ def _make_status_error( return APIStatusError(err_msg, response=response, body=body) -class AsyncArcadeAI(AsyncAPIClient): +class AsyncArcade(AsyncAPIClient): auth: resources.AsyncAuthResource chat: resources.AsyncChatResource health: resources.AsyncHealthResource tools: resources.AsyncToolsResource - with_raw_response: AsyncArcadeAIWithRawResponse - with_streaming_response: AsyncArcadeAIWithStreamedResponse + with_raw_response: AsyncArcadeWithRawResponse + with_streaming_response: AsyncArcadeWithStreamedResponse # client options api_key: str - _environment: Literal["production", "staging"] | NotGiven - def __init__( self, *, api_key: str | None = None, - environment: Literal["production", "staging"] | NotGiven = NOT_GIVEN, - base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN, + base_url: str | httpx.URL | None = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, @@ -290,43 +255,22 @@ def __init__( # part of our public interface in the future. _strict_response_validation: bool = False, ) -> None: - """Construct a new async Arcade AI client instance. + """Construct a new async Arcade client instance. This automatically infers the `api_key` argument from the `ARCADE_API_KEY` environment variable if it is not provided. """ if api_key is None: api_key = os.environ.get("ARCADE_API_KEY") if api_key is None: - raise ArcadeAIError( + raise ArcadeError( "The api_key client option must be set either by passing api_key to the client or by setting the ARCADE_API_KEY environment variable" ) self.api_key = api_key - self._environment = environment - - base_url_env = os.environ.get("ARCADE_AI_BASE_URL") - if is_given(base_url) and base_url is not None: - # cast required because mypy doesn't understand the type narrowing - base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast] - elif is_given(environment): - if base_url_env and base_url is not None: - raise ValueError( - "Ambiguous URL; The `ARCADE_AI_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None", - ) - - try: - base_url = ENVIRONMENTS[environment] - except KeyError as exc: - raise ValueError(f"Unknown environment: {environment}") from exc - elif base_url_env is not None: - base_url = base_url_env - else: - self._environment = environment = "production" - - try: - base_url = ENVIRONMENTS[environment] - except KeyError as exc: - raise ValueError(f"Unknown environment: {environment}") from exc + if base_url is None: + base_url = os.environ.get("ARCADE_BASE_URL") + if base_url is None: + base_url = f"https://api.arcade-ai.com" super().__init__( version=__version__, @@ -345,8 +289,8 @@ def __init__( self.chat = resources.AsyncChatResource(self) self.health = resources.AsyncHealthResource(self) self.tools = resources.AsyncToolsResource(self) - self.with_raw_response = AsyncArcadeAIWithRawResponse(self) - self.with_streaming_response = AsyncArcadeAIWithStreamedResponse(self) + self.with_raw_response = AsyncArcadeWithRawResponse(self) + self.with_streaming_response = AsyncArcadeWithStreamedResponse(self) @property @override @@ -372,7 +316,6 @@ def copy( self, *, api_key: str | None = None, - environment: Literal["production", "staging"] | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.AsyncClient | None = None, @@ -408,7 +351,6 @@ def copy( return self.__class__( api_key=api_key or self.api_key, base_url=base_url or self.base_url, - environment=environment or self._environment, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, max_retries=max_retries if is_given(max_retries) else self.max_retries, @@ -455,38 +397,38 @@ def _make_status_error( return APIStatusError(err_msg, response=response, body=body) -class ArcadeAIWithRawResponse: - def __init__(self, client: ArcadeAI) -> None: +class ArcadeWithRawResponse: + def __init__(self, client: Arcade) -> None: self.auth = resources.AuthResourceWithRawResponse(client.auth) self.chat = resources.ChatResourceWithRawResponse(client.chat) self.health = resources.HealthResourceWithRawResponse(client.health) self.tools = resources.ToolsResourceWithRawResponse(client.tools) -class AsyncArcadeAIWithRawResponse: - def __init__(self, client: AsyncArcadeAI) -> None: +class AsyncArcadeWithRawResponse: + def __init__(self, client: AsyncArcade) -> None: self.auth = resources.AsyncAuthResourceWithRawResponse(client.auth) self.chat = resources.AsyncChatResourceWithRawResponse(client.chat) self.health = resources.AsyncHealthResourceWithRawResponse(client.health) self.tools = resources.AsyncToolsResourceWithRawResponse(client.tools) -class ArcadeAIWithStreamedResponse: - def __init__(self, client: ArcadeAI) -> None: +class ArcadeWithStreamedResponse: + def __init__(self, client: Arcade) -> None: self.auth = resources.AuthResourceWithStreamingResponse(client.auth) self.chat = resources.ChatResourceWithStreamingResponse(client.chat) self.health = resources.HealthResourceWithStreamingResponse(client.health) self.tools = resources.ToolsResourceWithStreamingResponse(client.tools) -class AsyncArcadeAIWithStreamedResponse: - def __init__(self, client: AsyncArcadeAI) -> None: +class AsyncArcadeWithStreamedResponse: + def __init__(self, client: AsyncArcade) -> None: self.auth = resources.AsyncAuthResourceWithStreamingResponse(client.auth) self.chat = resources.AsyncChatResourceWithStreamingResponse(client.chat) self.health = resources.AsyncHealthResourceWithStreamingResponse(client.health) self.tools = resources.AsyncToolsResourceWithStreamingResponse(client.tools) -Client = ArcadeAI +Client = Arcade -AsyncClient = AsyncArcadeAI +AsyncClient = AsyncArcade diff --git a/src/arcadepy/_exceptions.py b/src/arcadepy/_exceptions.py index 6744a4c3..fd0cb6d8 100644 --- a/src/arcadepy/_exceptions.py +++ b/src/arcadepy/_exceptions.py @@ -18,11 +18,11 @@ ] -class ArcadeAIError(Exception): +class ArcadeError(Exception): pass -class APIError(ArcadeAIError): +class APIError(ArcadeError): message: str request: httpx.Request diff --git a/src/arcadepy/_resource.py b/src/arcadepy/_resource.py index 9ad5da43..f5eb4486 100644 --- a/src/arcadepy/_resource.py +++ b/src/arcadepy/_resource.py @@ -8,13 +8,13 @@ import anyio if TYPE_CHECKING: - from ._client import ArcadeAI, AsyncArcadeAI + from ._client import Arcade, AsyncArcade class SyncAPIResource: - _client: ArcadeAI + _client: Arcade - def __init__(self, client: ArcadeAI) -> None: + def __init__(self, client: Arcade) -> None: self._client = client self._get = client.get self._post = client.post @@ -28,9 +28,9 @@ def _sleep(self, seconds: float) -> None: class AsyncAPIResource: - _client: AsyncArcadeAI + _client: AsyncArcade - def __init__(self, client: AsyncArcadeAI) -> None: + def __init__(self, client: AsyncArcade) -> None: self._client = client self._get = client.get self._post = client.post diff --git a/src/arcadepy/_response.py b/src/arcadepy/_response.py index c71a72f6..70461f92 100644 --- a/src/arcadepy/_response.py +++ b/src/arcadepy/_response.py @@ -29,7 +29,7 @@ from ._models import BaseModel, is_basemodel from ._constants import RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type -from ._exceptions import ArcadeAIError, APIResponseValidationError +from ._exceptions import ArcadeError, APIResponseValidationError if TYPE_CHECKING: from ._models import FinalRequestOptions @@ -554,7 +554,7 @@ def __init__(self) -> None: ) -class StreamAlreadyConsumed(ArcadeAIError): +class StreamAlreadyConsumed(ArcadeError): """ Attempted to read or stream content, but the content has already been streamed. diff --git a/src/arcadepy/_streaming.py b/src/arcadepy/_streaming.py index bca8270f..c3f35449 100644 --- a/src/arcadepy/_streaming.py +++ b/src/arcadepy/_streaming.py @@ -12,7 +12,7 @@ from ._utils import extract_type_var_from_base if TYPE_CHECKING: - from ._client import ArcadeAI, AsyncArcadeAI + from ._client import Arcade, AsyncArcade _T = TypeVar("_T") @@ -30,7 +30,7 @@ def __init__( *, cast_to: type[_T], response: httpx.Response, - client: ArcadeAI, + client: Arcade, ) -> None: self.response = response self._cast_to = cast_to @@ -93,7 +93,7 @@ def __init__( *, cast_to: type[_T], response: httpx.Response, - client: AsyncArcadeAI, + client: AsyncArcade, ) -> None: self.response = response self._cast_to = cast_to diff --git a/src/arcadepy/_utils/_logs.py b/src/arcadepy/_utils/_logs.py index ea2b4608..4d36ed2d 100644 --- a/src/arcadepy/_utils/_logs.py +++ b/src/arcadepy/_utils/_logs.py @@ -14,7 +14,7 @@ def _basic_config() -> None: def setup_logging() -> None: - env = os.environ.get("ARCADE_AI_LOG") + env = os.environ.get("ARCADE_LOG") if env == "debug": _basic_config() logger.setLevel(logging.DEBUG) diff --git a/tests/api_resources/test_auth.py b/tests/api_resources/test_auth.py index d4171b49..d0816c46 100644 --- a/tests/api_resources/test_auth.py +++ b/tests/api_resources/test_auth.py @@ -7,7 +7,7 @@ import pytest -from arcadepy import ArcadeAI, AsyncArcadeAI +from arcadepy import Arcade, AsyncArcade from tests.utils import assert_matches_type from arcadepy.types import AuthorizationResponse @@ -18,7 +18,7 @@ class TestAuth: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_authorize(self, client: ArcadeAI) -> None: + def test_method_authorize(self, client: Arcade) -> None: auth = client.auth.authorize( auth_requirement={"provider": "provider"}, user_id="user_id", @@ -26,7 +26,7 @@ def test_method_authorize(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - def test_method_authorize_with_all_params(self, client: ArcadeAI) -> None: + def test_method_authorize_with_all_params(self, client: Arcade) -> None: auth = client.auth.authorize( auth_requirement={ "provider": "provider", @@ -40,7 +40,7 @@ def test_method_authorize_with_all_params(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - def test_raw_response_authorize(self, client: ArcadeAI) -> None: + def test_raw_response_authorize(self, client: Arcade) -> None: response = client.auth.with_raw_response.authorize( auth_requirement={"provider": "provider"}, user_id="user_id", @@ -52,7 +52,7 @@ def test_raw_response_authorize(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - def test_streaming_response_authorize(self, client: ArcadeAI) -> None: + def test_streaming_response_authorize(self, client: Arcade) -> None: with client.auth.with_streaming_response.authorize( auth_requirement={"provider": "provider"}, user_id="user_id", @@ -66,14 +66,14 @@ def test_streaming_response_authorize(self, client: ArcadeAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - def test_method_status(self, client: ArcadeAI) -> None: + def test_method_status(self, client: Arcade) -> None: auth = client.auth.status( authorization_id="authorizationID", ) assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - def test_method_status_with_all_params(self, client: ArcadeAI) -> None: + def test_method_status_with_all_params(self, client: Arcade) -> None: auth = client.auth.status( authorization_id="authorizationID", scopes="scopes", @@ -81,7 +81,7 @@ def test_method_status_with_all_params(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - def test_raw_response_status(self, client: ArcadeAI) -> None: + def test_raw_response_status(self, client: Arcade) -> None: response = client.auth.with_raw_response.status( authorization_id="authorizationID", ) @@ -92,7 +92,7 @@ def test_raw_response_status(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - def test_streaming_response_status(self, client: ArcadeAI) -> None: + def test_streaming_response_status(self, client: Arcade) -> None: with client.auth.with_streaming_response.status( authorization_id="authorizationID", ) as response: @@ -109,7 +109,7 @@ class TestAsyncAuth: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_authorize(self, async_client: AsyncArcadeAI) -> None: + async def test_method_authorize(self, async_client: AsyncArcade) -> None: auth = await async_client.auth.authorize( auth_requirement={"provider": "provider"}, user_id="user_id", @@ -117,7 +117,7 @@ async def test_method_authorize(self, async_client: AsyncArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - async def test_method_authorize_with_all_params(self, async_client: AsyncArcadeAI) -> None: + async def test_method_authorize_with_all_params(self, async_client: AsyncArcade) -> None: auth = await async_client.auth.authorize( auth_requirement={ "provider": "provider", @@ -131,7 +131,7 @@ async def test_method_authorize_with_all_params(self, async_client: AsyncArcadeA assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - async def test_raw_response_authorize(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_authorize(self, async_client: AsyncArcade) -> None: response = await async_client.auth.with_raw_response.authorize( auth_requirement={"provider": "provider"}, user_id="user_id", @@ -143,7 +143,7 @@ async def test_raw_response_authorize(self, async_client: AsyncArcadeAI) -> None assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - async def test_streaming_response_authorize(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_authorize(self, async_client: AsyncArcade) -> None: async with async_client.auth.with_streaming_response.authorize( auth_requirement={"provider": "provider"}, user_id="user_id", @@ -157,14 +157,14 @@ async def test_streaming_response_authorize(self, async_client: AsyncArcadeAI) - assert cast(Any, response.is_closed) is True @parametrize - async def test_method_status(self, async_client: AsyncArcadeAI) -> None: + async def test_method_status(self, async_client: AsyncArcade) -> None: auth = await async_client.auth.status( authorization_id="authorizationID", ) assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - async def test_method_status_with_all_params(self, async_client: AsyncArcadeAI) -> None: + async def test_method_status_with_all_params(self, async_client: AsyncArcade) -> None: auth = await async_client.auth.status( authorization_id="authorizationID", scopes="scopes", @@ -172,7 +172,7 @@ async def test_method_status_with_all_params(self, async_client: AsyncArcadeAI) assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - async def test_raw_response_status(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_status(self, async_client: AsyncArcade) -> None: response = await async_client.auth.with_raw_response.status( authorization_id="authorizationID", ) @@ -183,7 +183,7 @@ async def test_raw_response_status(self, async_client: AsyncArcadeAI) -> None: assert_matches_type(AuthorizationResponse, auth, path=["response"]) @parametrize - async def test_streaming_response_status(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_status(self, async_client: AsyncArcade) -> None: async with async_client.auth.with_streaming_response.status( authorization_id="authorizationID", ) as response: diff --git a/tests/api_resources/test_chat.py b/tests/api_resources/test_chat.py index 455b858a..0b6b9658 100644 --- a/tests/api_resources/test_chat.py +++ b/tests/api_resources/test_chat.py @@ -7,7 +7,7 @@ import pytest -from arcadepy import ArcadeAI, AsyncArcadeAI +from arcadepy import Arcade, AsyncArcade from tests.utils import assert_matches_type from arcadepy.types import ChatResponse @@ -18,12 +18,12 @@ class TestChat: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_completions(self, client: ArcadeAI) -> None: + def test_method_completions(self, client: Arcade) -> None: chat = client.chat.completions() assert_matches_type(ChatResponse, chat, path=["response"]) @parametrize - def test_method_completions_with_all_params(self, client: ArcadeAI) -> None: + def test_method_completions_with_all_params(self, client: Arcade) -> None: chat = client.chat.completions( frequency_penalty=0, logit_bias={"foo": 0}, @@ -146,7 +146,7 @@ def test_method_completions_with_all_params(self, client: ArcadeAI) -> None: assert_matches_type(ChatResponse, chat, path=["response"]) @parametrize - def test_raw_response_completions(self, client: ArcadeAI) -> None: + def test_raw_response_completions(self, client: Arcade) -> None: response = client.chat.with_raw_response.completions() assert response.is_closed is True @@ -155,7 +155,7 @@ def test_raw_response_completions(self, client: ArcadeAI) -> None: assert_matches_type(ChatResponse, chat, path=["response"]) @parametrize - def test_streaming_response_completions(self, client: ArcadeAI) -> None: + def test_streaming_response_completions(self, client: Arcade) -> None: with client.chat.with_streaming_response.completions() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -170,12 +170,12 @@ class TestAsyncChat: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_completions(self, async_client: AsyncArcadeAI) -> None: + async def test_method_completions(self, async_client: AsyncArcade) -> None: chat = await async_client.chat.completions() assert_matches_type(ChatResponse, chat, path=["response"]) @parametrize - async def test_method_completions_with_all_params(self, async_client: AsyncArcadeAI) -> None: + async def test_method_completions_with_all_params(self, async_client: AsyncArcade) -> None: chat = await async_client.chat.completions( frequency_penalty=0, logit_bias={"foo": 0}, @@ -298,7 +298,7 @@ async def test_method_completions_with_all_params(self, async_client: AsyncArcad assert_matches_type(ChatResponse, chat, path=["response"]) @parametrize - async def test_raw_response_completions(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_completions(self, async_client: AsyncArcade) -> None: response = await async_client.chat.with_raw_response.completions() assert response.is_closed is True @@ -307,7 +307,7 @@ async def test_raw_response_completions(self, async_client: AsyncArcadeAI) -> No assert_matches_type(ChatResponse, chat, path=["response"]) @parametrize - async def test_streaming_response_completions(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_completions(self, async_client: AsyncArcade) -> None: async with async_client.chat.with_streaming_response.completions() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/api_resources/test_health.py b/tests/api_resources/test_health.py index ca3ffc14..910a6ac0 100644 --- a/tests/api_resources/test_health.py +++ b/tests/api_resources/test_health.py @@ -7,7 +7,7 @@ import pytest -from arcadepy import ArcadeAI, AsyncArcadeAI +from arcadepy import Arcade, AsyncArcade from tests.utils import assert_matches_type from arcadepy.types import HealthSchema @@ -18,12 +18,12 @@ class TestHealth: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_check(self, client: ArcadeAI) -> None: + def test_method_check(self, client: Arcade) -> None: health = client.health.check() assert_matches_type(HealthSchema, health, path=["response"]) @parametrize - def test_raw_response_check(self, client: ArcadeAI) -> None: + def test_raw_response_check(self, client: Arcade) -> None: response = client.health.with_raw_response.check() assert response.is_closed is True @@ -32,7 +32,7 @@ def test_raw_response_check(self, client: ArcadeAI) -> None: assert_matches_type(HealthSchema, health, path=["response"]) @parametrize - def test_streaming_response_check(self, client: ArcadeAI) -> None: + def test_streaming_response_check(self, client: Arcade) -> None: with client.health.with_streaming_response.check() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -47,12 +47,12 @@ class TestAsyncHealth: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_check(self, async_client: AsyncArcadeAI) -> None: + async def test_method_check(self, async_client: AsyncArcade) -> None: health = await async_client.health.check() assert_matches_type(HealthSchema, health, path=["response"]) @parametrize - async def test_raw_response_check(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_check(self, async_client: AsyncArcade) -> None: response = await async_client.health.with_raw_response.check() assert response.is_closed is True @@ -61,7 +61,7 @@ async def test_raw_response_check(self, async_client: AsyncArcadeAI) -> None: assert_matches_type(HealthSchema, health, path=["response"]) @parametrize - async def test_streaming_response_check(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_check(self, async_client: AsyncArcade) -> None: async with async_client.health.with_streaming_response.check() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/api_resources/test_tools.py b/tests/api_resources/test_tools.py index 6a0d501a..8fbcf4a6 100644 --- a/tests/api_resources/test_tools.py +++ b/tests/api_resources/test_tools.py @@ -7,7 +7,7 @@ import pytest -from arcadepy import ArcadeAI, AsyncArcadeAI +from arcadepy import Arcade, AsyncArcade from tests.utils import assert_matches_type from arcadepy.types import ( ToolResponse, @@ -22,7 +22,7 @@ class TestTools: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_authorize(self, client: ArcadeAI) -> None: + def test_method_authorize(self, client: Arcade) -> None: tool = client.tools.authorize( tool_name="tool_name", user_id="user_id", @@ -30,7 +30,7 @@ def test_method_authorize(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, tool, path=["response"]) @parametrize - def test_method_authorize_with_all_params(self, client: ArcadeAI) -> None: + def test_method_authorize_with_all_params(self, client: Arcade) -> None: tool = client.tools.authorize( tool_name="tool_name", user_id="user_id", @@ -39,7 +39,7 @@ def test_method_authorize_with_all_params(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, tool, path=["response"]) @parametrize - def test_raw_response_authorize(self, client: ArcadeAI) -> None: + def test_raw_response_authorize(self, client: Arcade) -> None: response = client.tools.with_raw_response.authorize( tool_name="tool_name", user_id="user_id", @@ -51,7 +51,7 @@ def test_raw_response_authorize(self, client: ArcadeAI) -> None: assert_matches_type(AuthorizationResponse, tool, path=["response"]) @parametrize - def test_streaming_response_authorize(self, client: ArcadeAI) -> None: + def test_streaming_response_authorize(self, client: Arcade) -> None: with client.tools.with_streaming_response.authorize( tool_name="tool_name", user_id="user_id", @@ -65,7 +65,7 @@ def test_streaming_response_authorize(self, client: ArcadeAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - def test_method_execute(self, client: ArcadeAI) -> None: + def test_method_execute(self, client: Arcade) -> None: tool = client.tools.execute( inputs="inputs", tool_name="tool_name", @@ -75,7 +75,7 @@ def test_method_execute(self, client: ArcadeAI) -> None: assert_matches_type(ToolResponse, tool, path=["response"]) @parametrize - def test_raw_response_execute(self, client: ArcadeAI) -> None: + def test_raw_response_execute(self, client: Arcade) -> None: response = client.tools.with_raw_response.execute( inputs="inputs", tool_name="tool_name", @@ -89,7 +89,7 @@ def test_raw_response_execute(self, client: ArcadeAI) -> None: assert_matches_type(ToolResponse, tool, path=["response"]) @parametrize - def test_streaming_response_execute(self, client: ArcadeAI) -> None: + def test_streaming_response_execute(self, client: Arcade) -> None: with client.tools.with_streaming_response.execute( inputs="inputs", tool_name="tool_name", @@ -105,7 +105,7 @@ def test_streaming_response_execute(self, client: ArcadeAI) -> None: assert cast(Any, response.is_closed) is True @parametrize - def test_method_retrieve_definition(self, client: ArcadeAI) -> None: + def test_method_retrieve_definition(self, client: Arcade) -> None: tool = client.tools.retrieve_definition( director_id="director_id", tool_id="tool_id", @@ -113,7 +113,7 @@ def test_method_retrieve_definition(self, client: ArcadeAI) -> None: assert_matches_type(ToolDefinition, tool, path=["response"]) @parametrize - def test_raw_response_retrieve_definition(self, client: ArcadeAI) -> None: + def test_raw_response_retrieve_definition(self, client: Arcade) -> None: response = client.tools.with_raw_response.retrieve_definition( director_id="director_id", tool_id="tool_id", @@ -125,7 +125,7 @@ def test_raw_response_retrieve_definition(self, client: ArcadeAI) -> None: assert_matches_type(ToolDefinition, tool, path=["response"]) @parametrize - def test_streaming_response_retrieve_definition(self, client: ArcadeAI) -> None: + def test_streaming_response_retrieve_definition(self, client: Arcade) -> None: with client.tools.with_streaming_response.retrieve_definition( director_id="director_id", tool_id="tool_id", @@ -143,7 +143,7 @@ class TestAsyncTools: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_authorize(self, async_client: AsyncArcadeAI) -> None: + async def test_method_authorize(self, async_client: AsyncArcade) -> None: tool = await async_client.tools.authorize( tool_name="tool_name", user_id="user_id", @@ -151,7 +151,7 @@ async def test_method_authorize(self, async_client: AsyncArcadeAI) -> None: assert_matches_type(AuthorizationResponse, tool, path=["response"]) @parametrize - async def test_method_authorize_with_all_params(self, async_client: AsyncArcadeAI) -> None: + async def test_method_authorize_with_all_params(self, async_client: AsyncArcade) -> None: tool = await async_client.tools.authorize( tool_name="tool_name", user_id="user_id", @@ -160,7 +160,7 @@ async def test_method_authorize_with_all_params(self, async_client: AsyncArcadeA assert_matches_type(AuthorizationResponse, tool, path=["response"]) @parametrize - async def test_raw_response_authorize(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_authorize(self, async_client: AsyncArcade) -> None: response = await async_client.tools.with_raw_response.authorize( tool_name="tool_name", user_id="user_id", @@ -172,7 +172,7 @@ async def test_raw_response_authorize(self, async_client: AsyncArcadeAI) -> None assert_matches_type(AuthorizationResponse, tool, path=["response"]) @parametrize - async def test_streaming_response_authorize(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_authorize(self, async_client: AsyncArcade) -> None: async with async_client.tools.with_streaming_response.authorize( tool_name="tool_name", user_id="user_id", @@ -186,7 +186,7 @@ async def test_streaming_response_authorize(self, async_client: AsyncArcadeAI) - assert cast(Any, response.is_closed) is True @parametrize - async def test_method_execute(self, async_client: AsyncArcadeAI) -> None: + async def test_method_execute(self, async_client: AsyncArcade) -> None: tool = await async_client.tools.execute( inputs="inputs", tool_name="tool_name", @@ -196,7 +196,7 @@ async def test_method_execute(self, async_client: AsyncArcadeAI) -> None: assert_matches_type(ToolResponse, tool, path=["response"]) @parametrize - async def test_raw_response_execute(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_execute(self, async_client: AsyncArcade) -> None: response = await async_client.tools.with_raw_response.execute( inputs="inputs", tool_name="tool_name", @@ -210,7 +210,7 @@ async def test_raw_response_execute(self, async_client: AsyncArcadeAI) -> None: assert_matches_type(ToolResponse, tool, path=["response"]) @parametrize - async def test_streaming_response_execute(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_execute(self, async_client: AsyncArcade) -> None: async with async_client.tools.with_streaming_response.execute( inputs="inputs", tool_name="tool_name", @@ -226,7 +226,7 @@ async def test_streaming_response_execute(self, async_client: AsyncArcadeAI) -> assert cast(Any, response.is_closed) is True @parametrize - async def test_method_retrieve_definition(self, async_client: AsyncArcadeAI) -> None: + async def test_method_retrieve_definition(self, async_client: AsyncArcade) -> None: tool = await async_client.tools.retrieve_definition( director_id="director_id", tool_id="tool_id", @@ -234,7 +234,7 @@ async def test_method_retrieve_definition(self, async_client: AsyncArcadeAI) -> assert_matches_type(ToolDefinition, tool, path=["response"]) @parametrize - async def test_raw_response_retrieve_definition(self, async_client: AsyncArcadeAI) -> None: + async def test_raw_response_retrieve_definition(self, async_client: AsyncArcade) -> None: response = await async_client.tools.with_raw_response.retrieve_definition( director_id="director_id", tool_id="tool_id", @@ -246,7 +246,7 @@ async def test_raw_response_retrieve_definition(self, async_client: AsyncArcadeA assert_matches_type(ToolDefinition, tool, path=["response"]) @parametrize - async def test_streaming_response_retrieve_definition(self, async_client: AsyncArcadeAI) -> None: + async def test_streaming_response_retrieve_definition(self, async_client: AsyncArcade) -> None: async with async_client.tools.with_streaming_response.retrieve_definition( director_id="director_id", tool_id="tool_id", diff --git a/tests/conftest.py b/tests/conftest.py index ba66b4aa..2206dddb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,7 +7,7 @@ import pytest -from arcadepy import ArcadeAI, AsyncArcadeAI +from arcadepy import Arcade, AsyncArcade if TYPE_CHECKING: from _pytest.fixtures import FixtureRequest @@ -30,20 +30,20 @@ def event_loop() -> Iterator[asyncio.AbstractEventLoop]: @pytest.fixture(scope="session") -def client(request: FixtureRequest) -> Iterator[ArcadeAI]: +def client(request: FixtureRequest) -> Iterator[Arcade]: strict = getattr(request, "param", True) if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") - with ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: + with Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: yield client @pytest.fixture(scope="session") -async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncArcadeAI]: +async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncArcade]: strict = getattr(request, "param", True) if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") - async with AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: + async with AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client: yield client diff --git a/tests/test_client.py b/tests/test_client.py index 534824d3..04929ebb 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -16,11 +16,11 @@ from respx import MockRouter from pydantic import ValidationError -from arcadepy import ArcadeAI, AsyncArcadeAI, APIResponseValidationError +from arcadepy import Arcade, AsyncArcade, APIResponseValidationError from arcadepy._types import Omit from arcadepy._models import BaseModel, FinalRequestOptions from arcadepy._constants import RAW_RESPONSE_HEADER -from arcadepy._exceptions import ArcadeAIError, APIStatusError, APITimeoutError, APIResponseValidationError +from arcadepy._exceptions import ArcadeError, APIStatusError, APITimeoutError, APIResponseValidationError from arcadepy._base_client import ( DEFAULT_TIMEOUT, HTTPX_DEFAULT_TIMEOUT, @@ -44,7 +44,7 @@ def _low_retry_timeout(*_args: Any, **_kwargs: Any) -> float: return 0.1 -def _get_open_connections(client: ArcadeAI | AsyncArcadeAI) -> int: +def _get_open_connections(client: Arcade | AsyncArcade) -> int: transport = client._client._transport assert isinstance(transport, httpx.HTTPTransport) or isinstance(transport, httpx.AsyncHTTPTransport) @@ -52,8 +52,8 @@ def _get_open_connections(client: ArcadeAI | AsyncArcadeAI) -> int: return len(pool._requests) -class TestArcadeAI: - client = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) +class TestArcade: + client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) def test_raw_response(self, respx_mock: MockRouter) -> None: @@ -100,7 +100,7 @@ def test_copy_default_options(self) -> None: assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: - client = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"} ) assert client.default_headers["X-Foo"] == "bar" @@ -134,7 +134,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 = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"foo": "bar"} ) assert _get_params(client)["foo"] == "bar" @@ -259,9 +259,7 @@ def test_request_timeout(self) -> None: assert timeout == httpx.Timeout(100.0) def test_client_timeout_option(self) -> None: - client = ArcadeAI( - base_url=base_url, api_key=api_key, _strict_response_validation=True, timeout=httpx.Timeout(0) - ) + client = Arcade(base_url=base_url, api_key=api_key, _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 @@ -270,7 +268,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 = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) @@ -280,7 +278,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 = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) @@ -290,7 +288,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 = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) @@ -301,7 +299,7 @@ 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: - ArcadeAI( + Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, @@ -309,14 +307,14 @@ async def test_invalid_http_client(self) -> None: ) def test_default_headers_option(self) -> None: - client = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _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 = ArcadeAI( + client2 = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, @@ -330,17 +328,17 @@ def test_default_headers_option(self) -> None: assert request.headers.get("x-stainless-lang") == "my-overriding-header" def test_validate_headers(self) -> None: - client = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("Authorization") == api_key - with pytest.raises(ArcadeAIError): + with pytest.raises(ArcadeError): with update_env(**{"ARCADE_API_KEY": Omit()}): - client2 = ArcadeAI(base_url=base_url, api_key=None, _strict_response_validation=True) + client2 = Arcade(base_url=base_url, api_key=None, _strict_response_validation=True) _ = client2 def test_default_query_option(self) -> None: - client = ArcadeAI( + client = Arcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"} ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -454,7 +452,7 @@ def test_request_extra_query(self) -> None: params = dict(request.url.params) assert params == {"foo": "2"} - def test_multipart_repeating_array(self, client: ArcadeAI) -> None: + def test_multipart_repeating_array(self, client: Arcade) -> None: request = client._build_request( FinalRequestOptions.construct( method="get", @@ -572,7 +570,7 @@ def test_idempotency_header_options(self, respx_mock: MockRouter) -> None: assert response.request.headers.get("Idempotency-Key") == "custom-key" def test_base_url_setter(self) -> None: - client = ArcadeAI(base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True) + client = Arcade(base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True) assert client.base_url == "https://example.com/from_init/" client.base_url = "https://example.com/from_setter" # type: ignore[assignment] @@ -580,25 +578,15 @@ def test_base_url_setter(self) -> None: assert client.base_url == "https://example.com/from_setter/" def test_base_url_env(self) -> None: - with update_env(ARCADE_AI_BASE_URL="http://localhost:5000/from/env"): - client = ArcadeAI(api_key=api_key, _strict_response_validation=True) + with update_env(ARCADE_BASE_URL="http://localhost:5000/from/env"): + client = Arcade(api_key=api_key, _strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" - # explicit environment arg requires explicitness - with update_env(ARCADE_AI_BASE_URL="http://localhost:5000/from/env"): - with pytest.raises(ValueError, match=r"you must pass base_url=None"): - ArcadeAI(api_key=api_key, _strict_response_validation=True, environment="production") - - client = ArcadeAI( - base_url=None, api_key=api_key, _strict_response_validation=True, environment="production" - ) - assert str(client.base_url).startswith("https://api.arcade-ai.com") - @pytest.mark.parametrize( "client", [ - ArcadeAI(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), - ArcadeAI( + Arcade(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), + Arcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, @@ -607,7 +595,7 @@ def test_base_url_env(self) -> None: ], ids=["standard", "custom http client"], ) - def test_base_url_trailing_slash(self, client: ArcadeAI) -> None: + def test_base_url_trailing_slash(self, client: Arcade) -> None: request = client._build_request( FinalRequestOptions( method="post", @@ -620,8 +608,8 @@ def test_base_url_trailing_slash(self, client: ArcadeAI) -> None: @pytest.mark.parametrize( "client", [ - ArcadeAI(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), - ArcadeAI( + Arcade(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), + Arcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, @@ -630,7 +618,7 @@ def test_base_url_trailing_slash(self, client: ArcadeAI) -> None: ], ids=["standard", "custom http client"], ) - def test_base_url_no_trailing_slash(self, client: ArcadeAI) -> None: + def test_base_url_no_trailing_slash(self, client: Arcade) -> None: request = client._build_request( FinalRequestOptions( method="post", @@ -643,8 +631,8 @@ def test_base_url_no_trailing_slash(self, client: ArcadeAI) -> None: @pytest.mark.parametrize( "client", [ - ArcadeAI(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), - ArcadeAI( + Arcade(base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True), + Arcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, @@ -653,7 +641,7 @@ def test_base_url_no_trailing_slash(self, client: ArcadeAI) -> None: ], ids=["standard", "custom http client"], ) - def test_absolute_request_url(self, client: ArcadeAI) -> None: + def test_absolute_request_url(self, client: Arcade) -> None: request = client._build_request( FinalRequestOptions( method="post", @@ -664,7 +652,7 @@ def test_absolute_request_url(self, client: ArcadeAI) -> None: assert request.url == "https://myapi.com/foo" def test_copied_client_does_not_close_http(self) -> None: - client = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() @@ -675,7 +663,7 @@ def test_copied_client_does_not_close_http(self) -> None: assert not client.is_closed() def test_client_context_manager(self) -> None: - client = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) with client as c2: assert c2 is client assert not c2.is_closed() @@ -696,7 +684,7 @@ class Model(BaseModel): def test_client_max_retries_validation(self) -> None: with pytest.raises(TypeError, match=r"max_retries cannot be None"): - ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True, max_retries=cast(Any, None)) + Arcade(base_url=base_url, api_key=api_key, _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: @@ -705,12 +693,12 @@ class Model(BaseModel): respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) - strict_client = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + strict_client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): strict_client.get("/foo", cast_to=Model) - client = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=False) response = client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @@ -738,7 +726,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 = ArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = Arcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) @@ -798,7 +786,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) -> Non @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("arcadepy._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) - def test_retries_taken(self, client: ArcadeAI, failures_before_success: int, respx_mock: MockRouter) -> None: + def test_retries_taken(self, client: Arcade, failures_before_success: int, respx_mock: MockRouter) -> None: client = client.with_options(max_retries=4) nb_retries = 0 @@ -821,7 +809,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: @mock.patch("arcadepy._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_omit_retry_count_header( - self, client: ArcadeAI, failures_before_success: int, respx_mock: MockRouter + self, client: Arcade, failures_before_success: int, respx_mock: MockRouter ) -> None: client = client.with_options(max_retries=4) @@ -844,7 +832,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: @mock.patch("arcadepy._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_overwrite_retry_count_header( - self, client: ArcadeAI, failures_before_success: int, respx_mock: MockRouter + self, client: Arcade, failures_before_success: int, respx_mock: MockRouter ) -> None: client = client.with_options(max_retries=4) @@ -864,8 +852,8 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: assert response.http_request.headers.get("x-stainless-retry-count") == "42" -class TestAsyncArcadeAI: - client = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) +class TestAsyncArcade: + client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio @@ -914,7 +902,7 @@ def test_copy_default_options(self) -> None: assert isinstance(self.client.timeout, httpx.Timeout) def test_copy_default_headers(self) -> None: - client = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_headers={"X-Foo": "bar"} ) assert client.default_headers["X-Foo"] == "bar" @@ -948,7 +936,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 = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"foo": "bar"} ) assert _get_params(client)["foo"] == "bar" @@ -1073,7 +1061,7 @@ async def test_request_timeout(self) -> None: assert timeout == httpx.Timeout(100.0) async def test_client_timeout_option(self) -> None: - client = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, timeout=httpx.Timeout(0) ) @@ -1084,7 +1072,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 = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) @@ -1094,7 +1082,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 = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) @@ -1104,7 +1092,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 = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, http_client=http_client ) @@ -1115,7 +1103,7 @@ 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: - AsyncArcadeAI( + AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, @@ -1123,14 +1111,14 @@ def test_invalid_http_client(self) -> None: ) def test_default_headers_option(self) -> None: - client = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _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 = AsyncArcadeAI( + client2 = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, @@ -1144,17 +1132,17 @@ def test_default_headers_option(self) -> None: assert request.headers.get("x-stainless-lang") == "my-overriding-header" def test_validate_headers(self) -> None: - client = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("Authorization") == api_key - with pytest.raises(ArcadeAIError): + with pytest.raises(ArcadeError): with update_env(**{"ARCADE_API_KEY": Omit()}): - client2 = AsyncArcadeAI(base_url=base_url, api_key=None, _strict_response_validation=True) + client2 = AsyncArcade(base_url=base_url, api_key=None, _strict_response_validation=True) _ = client2 def test_default_query_option(self) -> None: - client = AsyncArcadeAI( + client = AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"} ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -1268,7 +1256,7 @@ def test_request_extra_query(self) -> None: params = dict(request.url.params) assert params == {"foo": "2"} - def test_multipart_repeating_array(self, async_client: AsyncArcadeAI) -> None: + def test_multipart_repeating_array(self, async_client: AsyncArcade) -> None: request = async_client._build_request( FinalRequestOptions.construct( method="get", @@ -1386,7 +1374,7 @@ async def test_idempotency_header_options(self, respx_mock: MockRouter) -> None: assert response.request.headers.get("Idempotency-Key") == "custom-key" def test_base_url_setter(self) -> None: - client = AsyncArcadeAI( + client = AsyncArcade( base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True ) assert client.base_url == "https://example.com/from_init/" @@ -1396,27 +1384,17 @@ def test_base_url_setter(self) -> None: assert client.base_url == "https://example.com/from_setter/" def test_base_url_env(self) -> None: - with update_env(ARCADE_AI_BASE_URL="http://localhost:5000/from/env"): - client = AsyncArcadeAI(api_key=api_key, _strict_response_validation=True) + with update_env(ARCADE_BASE_URL="http://localhost:5000/from/env"): + client = AsyncArcade(api_key=api_key, _strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" - # explicit environment arg requires explicitness - with update_env(ARCADE_AI_BASE_URL="http://localhost:5000/from/env"): - with pytest.raises(ValueError, match=r"you must pass base_url=None"): - AsyncArcadeAI(api_key=api_key, _strict_response_validation=True, environment="production") - - client = AsyncArcadeAI( - base_url=None, api_key=api_key, _strict_response_validation=True, environment="production" - ) - assert str(client.base_url).startswith("https://api.arcade-ai.com") - @pytest.mark.parametrize( "client", [ - AsyncArcadeAI( + AsyncArcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True ), - AsyncArcadeAI( + AsyncArcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, @@ -1425,7 +1403,7 @@ def test_base_url_env(self) -> None: ], ids=["standard", "custom http client"], ) - def test_base_url_trailing_slash(self, client: AsyncArcadeAI) -> None: + def test_base_url_trailing_slash(self, client: AsyncArcade) -> None: request = client._build_request( FinalRequestOptions( method="post", @@ -1438,10 +1416,10 @@ def test_base_url_trailing_slash(self, client: AsyncArcadeAI) -> None: @pytest.mark.parametrize( "client", [ - AsyncArcadeAI( + AsyncArcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True ), - AsyncArcadeAI( + AsyncArcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, @@ -1450,7 +1428,7 @@ def test_base_url_trailing_slash(self, client: AsyncArcadeAI) -> None: ], ids=["standard", "custom http client"], ) - def test_base_url_no_trailing_slash(self, client: AsyncArcadeAI) -> None: + def test_base_url_no_trailing_slash(self, client: AsyncArcade) -> None: request = client._build_request( FinalRequestOptions( method="post", @@ -1463,10 +1441,10 @@ def test_base_url_no_trailing_slash(self, client: AsyncArcadeAI) -> None: @pytest.mark.parametrize( "client", [ - AsyncArcadeAI( + AsyncArcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True ), - AsyncArcadeAI( + AsyncArcade( base_url="http://localhost:5000/custom/path/", api_key=api_key, _strict_response_validation=True, @@ -1475,7 +1453,7 @@ def test_base_url_no_trailing_slash(self, client: AsyncArcadeAI) -> None: ], ids=["standard", "custom http client"], ) - def test_absolute_request_url(self, client: AsyncArcadeAI) -> None: + def test_absolute_request_url(self, client: AsyncArcade) -> None: request = client._build_request( FinalRequestOptions( method="post", @@ -1486,7 +1464,7 @@ def test_absolute_request_url(self, client: AsyncArcadeAI) -> None: assert request.url == "https://myapi.com/foo" async def test_copied_client_does_not_close_http(self) -> None: - client = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() @@ -1498,7 +1476,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 = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) async with client as c2: assert c2 is client assert not c2.is_closed() @@ -1520,7 +1498,7 @@ class Model(BaseModel): async def test_client_max_retries_validation(self) -> None: with pytest.raises(TypeError, match=r"max_retries cannot be None"): - AsyncArcadeAI( + AsyncArcade( base_url=base_url, api_key=api_key, _strict_response_validation=True, max_retries=cast(Any, None) ) @@ -1532,12 +1510,12 @@ class Model(BaseModel): respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) - strict_client = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + strict_client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): await strict_client.get("/foo", cast_to=Model) - client = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=False) response = await client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @@ -1566,7 +1544,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 = AsyncArcadeAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + client = AsyncArcade(base_url=base_url, api_key=api_key, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) @@ -1628,7 +1606,7 @@ async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_retries_taken( - self, async_client: AsyncArcadeAI, failures_before_success: int, respx_mock: MockRouter + self, async_client: AsyncArcade, failures_before_success: int, respx_mock: MockRouter ) -> None: client = async_client.with_options(max_retries=4) @@ -1653,7 +1631,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_omit_retry_count_header( - self, async_client: AsyncArcadeAI, failures_before_success: int, respx_mock: MockRouter + self, async_client: AsyncArcade, failures_before_success: int, respx_mock: MockRouter ) -> None: client = async_client.with_options(max_retries=4) @@ -1677,7 +1655,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio async def test_overwrite_retry_count_header( - self, async_client: AsyncArcadeAI, failures_before_success: int, respx_mock: MockRouter + self, async_client: AsyncArcade, failures_before_success: int, respx_mock: MockRouter ) -> None: client = async_client.with_options(max_retries=4) diff --git a/tests/test_response.py b/tests/test_response.py index 2551438b..11e31ec9 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -6,7 +6,7 @@ import pytest import pydantic -from arcadepy import ArcadeAI, BaseModel, AsyncArcadeAI +from arcadepy import Arcade, BaseModel, AsyncArcade from arcadepy._response import ( APIResponse, BaseAPIResponse, @@ -56,7 +56,7 @@ def test_extract_response_type_binary_response() -> None: class PydanticModel(pydantic.BaseModel): ... -def test_response_parse_mismatched_basemodel(client: ArcadeAI) -> None: +def test_response_parse_mismatched_basemodel(client: Arcade) -> None: response = APIResponse( raw=httpx.Response(200, content=b"foo"), client=client, @@ -74,7 +74,7 @@ def test_response_parse_mismatched_basemodel(client: ArcadeAI) -> None: @pytest.mark.asyncio -async def test_async_response_parse_mismatched_basemodel(async_client: AsyncArcadeAI) -> None: +async def test_async_response_parse_mismatched_basemodel(async_client: AsyncArcade) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=b"foo"), client=async_client, @@ -91,7 +91,7 @@ async def test_async_response_parse_mismatched_basemodel(async_client: AsyncArca await response.parse(to=PydanticModel) -def test_response_parse_custom_stream(client: ArcadeAI) -> None: +def test_response_parse_custom_stream(client: Arcade) -> None: response = APIResponse( raw=httpx.Response(200, content=b"foo"), client=client, @@ -106,7 +106,7 @@ def test_response_parse_custom_stream(client: ArcadeAI) -> None: @pytest.mark.asyncio -async def test_async_response_parse_custom_stream(async_client: AsyncArcadeAI) -> None: +async def test_async_response_parse_custom_stream(async_client: AsyncArcade) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=b"foo"), client=async_client, @@ -125,7 +125,7 @@ class CustomModel(BaseModel): bar: int -def test_response_parse_custom_model(client: ArcadeAI) -> None: +def test_response_parse_custom_model(client: Arcade) -> None: response = APIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=client, @@ -141,7 +141,7 @@ def test_response_parse_custom_model(client: ArcadeAI) -> None: @pytest.mark.asyncio -async def test_async_response_parse_custom_model(async_client: AsyncArcadeAI) -> None: +async def test_async_response_parse_custom_model(async_client: AsyncArcade) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=async_client, @@ -156,7 +156,7 @@ async def test_async_response_parse_custom_model(async_client: AsyncArcadeAI) -> assert obj.bar == 2 -def test_response_parse_annotated_type(client: ArcadeAI) -> None: +def test_response_parse_annotated_type(client: Arcade) -> None: response = APIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=client, @@ -173,7 +173,7 @@ def test_response_parse_annotated_type(client: ArcadeAI) -> None: assert obj.bar == 2 -async def test_async_response_parse_annotated_type(async_client: AsyncArcadeAI) -> None: +async def test_async_response_parse_annotated_type(async_client: AsyncArcade) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})), client=async_client, @@ -201,7 +201,7 @@ async def test_async_response_parse_annotated_type(async_client: AsyncArcadeAI) ("FalSe", False), ], ) -def test_response_parse_bool(client: ArcadeAI, content: str, expected: bool) -> None: +def test_response_parse_bool(client: Arcade, content: str, expected: bool) -> None: response = APIResponse( raw=httpx.Response(200, content=content), client=client, @@ -226,7 +226,7 @@ def test_response_parse_bool(client: ArcadeAI, content: str, expected: bool) -> ("FalSe", False), ], ) -async def test_async_response_parse_bool(client: AsyncArcadeAI, content: str, expected: bool) -> None: +async def test_async_response_parse_bool(client: AsyncArcade, content: str, expected: bool) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=content), client=client, @@ -245,7 +245,7 @@ class OtherModel(BaseModel): @pytest.mark.parametrize("client", [False], indirect=True) # loose validation -def test_response_parse_expect_model_union_non_json_content(client: ArcadeAI) -> None: +def test_response_parse_expect_model_union_non_json_content(client: Arcade) -> None: response = APIResponse( raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}), client=client, @@ -262,7 +262,7 @@ def test_response_parse_expect_model_union_non_json_content(client: ArcadeAI) -> @pytest.mark.asyncio @pytest.mark.parametrize("async_client", [False], indirect=True) # loose validation -async def test_async_response_parse_expect_model_union_non_json_content(async_client: AsyncArcadeAI) -> None: +async def test_async_response_parse_expect_model_union_non_json_content(async_client: AsyncArcade) -> None: response = AsyncAPIResponse( raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}), client=async_client, diff --git a/tests/test_streaming.py b/tests/test_streaming.py index 17da4ab0..65985b2c 100644 --- a/tests/test_streaming.py +++ b/tests/test_streaming.py @@ -5,13 +5,13 @@ import httpx import pytest -from arcadepy import ArcadeAI, AsyncArcadeAI +from arcadepy import Arcade, AsyncArcade from arcadepy._streaming import Stream, AsyncStream, ServerSentEvent @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_basic(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_basic(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: completion\n" yield b'data: {"foo":true}\n' @@ -28,7 +28,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_data_missing_event(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_data_missing_event(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b'data: {"foo":true}\n' yield b"\n" @@ -44,7 +44,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_event_missing_data(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_event_missing_data(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"\n" @@ -60,7 +60,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_multiple_events(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_multiple_events(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"\n" @@ -82,7 +82,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_multiple_events_with_data(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_multiple_events_with_data(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b'data: {"foo":true}\n' @@ -106,7 +106,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_multiple_data_lines_with_empty_line(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_multiple_data_lines_with_empty_line(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"data: {\n" @@ -128,7 +128,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_data_json_escaped_double_new_line(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_data_json_escaped_double_new_line(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b'data: {"foo": "my long\\n\\ncontent"}' @@ -145,7 +145,7 @@ def body() -> Iterator[bytes]: @pytest.mark.asyncio @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) -async def test_multiple_data_lines(sync: bool, client: ArcadeAI, async_client: AsyncArcadeAI) -> None: +async def test_multiple_data_lines(sync: bool, client: Arcade, async_client: AsyncArcade) -> None: def body() -> Iterator[bytes]: yield b"event: ping\n" yield b"data: {\n" @@ -165,8 +165,8 @@ def body() -> Iterator[bytes]: @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_special_new_line_character( sync: bool, - client: ArcadeAI, - async_client: AsyncArcadeAI, + client: Arcade, + async_client: AsyncArcade, ) -> None: def body() -> Iterator[bytes]: yield b'data: {"content":" culpa"}\n' @@ -196,8 +196,8 @@ def body() -> Iterator[bytes]: @pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"]) async def test_multi_byte_character_multiple_chunks( sync: bool, - client: ArcadeAI, - async_client: AsyncArcadeAI, + client: Arcade, + async_client: AsyncArcade, ) -> None: def body() -> Iterator[bytes]: yield b'data: {"content":"' @@ -237,8 +237,8 @@ def make_event_iterator( content: Iterator[bytes], *, sync: bool, - client: ArcadeAI, - async_client: AsyncArcadeAI, + client: Arcade, + async_client: AsyncArcade, ) -> Iterator[ServerSentEvent] | AsyncIterator[ServerSentEvent]: if sync: return Stream(cast_to=object, client=client, response=httpx.Response(200, content=content))._iter_events()