From fc9900cd74c6e76976bbdf03b31002f2bbe8706a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 22:58:20 +0000 Subject: [PATCH] feat(api): update via SDK Studio --- README.md | 26 ++++++++++++++------------ src/oxp/_client.py | 16 ++++++++-------- tests/test_client.py | 44 ++++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 09c2fd8..67ed50d 100644 --- a/README.md +++ b/README.md @@ -28,15 +28,16 @@ import os from oxp import Oxp client = Oxp( - bearer_token=os.environ.get("OXP_BEARER_TOKEN"), # This is the default and can be omitted + bearer_token=os.environ.get("OXP_API_KEY"), # This is the default and can be omitted ) -client.health.check() +tool = client.tools.list() +print(tool.items) ``` While you can provide a `bearer_token` keyword argument, we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/) -to add `OXP_BEARER_TOKEN="My Bearer Token"` to your `.env` file +to add `OXP_API_KEY="My Bearer Token"` to your `.env` file so that your Bearer Token is not stored in source control. ## Async usage @@ -49,12 +50,13 @@ import asyncio from oxp import AsyncOxp client = AsyncOxp( - bearer_token=os.environ.get("OXP_BEARER_TOKEN"), # This is the default and can be omitted + bearer_token=os.environ.get("OXP_API_KEY"), # This is the default and can be omitted ) async def main() -> None: - await client.health.check() + tool = await client.tools.list() + print(tool.items) asyncio.run(main()) @@ -122,7 +124,7 @@ from oxp import Oxp client = Oxp() try: - client.health.check() + client.tools.list() except oxp.APIConnectionError as e: print("The server could not be reached") print(e.__cause__) # an underlying Exception, likely raised within httpx. @@ -165,7 +167,7 @@ client = Oxp( ) # Or, configure per-request: -client.with_options(max_retries=5).health.check() +client.with_options(max_retries=5).tools.list() ``` ### Timeouts @@ -188,7 +190,7 @@ client = Oxp( ) # Override per-request: -client.with_options(timeout=5.0).health.check() +client.with_options(timeout=5.0).tools.list() ``` On timeout, an `APITimeoutError` is thrown. @@ -229,11 +231,11 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to from oxp import Oxp client = Oxp() -response = client.health.with_raw_response.check() +response = client.tools.with_raw_response.list() print(response.headers.get('X-My-Header')) -health = response.parse() # get the object that `health.check()` would have returned -print(health) +tool = response.parse() # get the object that `tools.list()` would have returned +print(tool.items) ``` These methods return an [`APIResponse`](https://github.com/OpenExecProtocol/oxp-python/tree/main/src/oxp/_response.py) object. @@ -247,7 +249,7 @@ The above interface eagerly reads the full response body when you make the reque To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods. ```python -with client.health.with_streaming_response.check() as response: +with client.tools.with_streaming_response.list() as response: print(response.headers.get("X-My-Header")) for line in response.iter_lines(): diff --git a/src/oxp/_client.py b/src/oxp/_client.py index 1267e0e..c9dff3a 100644 --- a/src/oxp/_client.py +++ b/src/oxp/_client.py @@ -70,20 +70,20 @@ def __init__( ) -> None: """Construct a new synchronous Oxp client instance. - This automatically infers the `bearer_token` argument from the `OXP_BEARER_TOKEN` environment variable if it is not provided. + This automatically infers the `bearer_token` argument from the `OXP_API_KEY` environment variable if it is not provided. """ if bearer_token is None: - bearer_token = os.environ.get("OXP_BEARER_TOKEN") + bearer_token = os.environ.get("OXP_API_KEY") if bearer_token is None: raise OxpError( - "The bearer_token client option must be set either by passing bearer_token to the client or by setting the OXP_BEARER_TOKEN environment variable" + "The bearer_token client option must be set either by passing bearer_token to the client or by setting the OXP_API_KEY environment variable" ) self.bearer_token = bearer_token if base_url is None: base_url = os.environ.get("OXP_BASE_URL") if base_url is None: - base_url = f"https://api.example.com" + base_url = f"https://api.arcade.dev" super().__init__( version=__version__, @@ -240,20 +240,20 @@ def __init__( ) -> None: """Construct a new async AsyncOxp client instance. - This automatically infers the `bearer_token` argument from the `OXP_BEARER_TOKEN` environment variable if it is not provided. + This automatically infers the `bearer_token` argument from the `OXP_API_KEY` environment variable if it is not provided. """ if bearer_token is None: - bearer_token = os.environ.get("OXP_BEARER_TOKEN") + bearer_token = os.environ.get("OXP_API_KEY") if bearer_token is None: raise OxpError( - "The bearer_token client option must be set either by passing bearer_token to the client or by setting the OXP_BEARER_TOKEN environment variable" + "The bearer_token client option must be set either by passing bearer_token to the client or by setting the OXP_API_KEY environment variable" ) self.bearer_token = bearer_token if base_url is None: base_url = os.environ.get("OXP_BASE_URL") if base_url is None: - base_url = f"https://api.example.com" + base_url = f"https://api.arcade.dev" super().__init__( version=__version__, diff --git a/tests/test_client.py b/tests/test_client.py index 660bbf8..5d34911 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -341,7 +341,7 @@ def test_validate_headers(self) -> None: assert request.headers.get("Authorization") == f"Bearer {bearer_token}" with pytest.raises(OxpError): - with update_env(**{"OXP_BEARER_TOKEN": Omit()}): + with update_env(**{"OXP_API_KEY": Omit()}): client2 = Oxp(base_url=base_url, bearer_token=None, _strict_response_validation=True) _ = client2 @@ -735,20 +735,20 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str @mock.patch("oxp._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> None: - respx_mock.get("/health").mock(side_effect=httpx.TimeoutException("Test timeout error")) + respx_mock.get("/tools").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - self.client.get("/health", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}}) + self.client.get("/tools", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}}) assert _get_open_connections(self.client) == 0 @mock.patch("oxp._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) -> None: - respx_mock.get("/health").mock(return_value=httpx.Response(500)) + respx_mock.get("/tools").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - self.client.get("/health", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}}) + self.client.get("/tools", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}}) assert _get_open_connections(self.client) == 0 @@ -776,9 +776,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.get("/health").mock(side_effect=retry_handler) + respx_mock.get("/tools").mock(side_effect=retry_handler) - response = client.health.with_raw_response.check() + response = client.tools.with_raw_response.list() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -798,9 +798,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.get("/health").mock(side_effect=retry_handler) + respx_mock.get("/tools").mock(side_effect=retry_handler) - response = client.health.with_raw_response.check(extra_headers={"x-stainless-retry-count": Omit()}) + response = client.tools.with_raw_response.list(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -821,9 +821,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.get("/health").mock(side_effect=retry_handler) + respx_mock.get("/tools").mock(side_effect=retry_handler) - response = client.health.with_raw_response.check(extra_headers={"x-stainless-retry-count": "42"}) + response = client.tools.with_raw_response.list(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @@ -1119,7 +1119,7 @@ def test_validate_headers(self) -> None: assert request.headers.get("Authorization") == f"Bearer {bearer_token}" with pytest.raises(OxpError): - with update_env(**{"OXP_BEARER_TOKEN": Omit()}): + with update_env(**{"OXP_API_KEY": Omit()}): client2 = AsyncOxp(base_url=base_url, bearer_token=None, _strict_response_validation=True) _ = client2 @@ -1517,11 +1517,11 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte @mock.patch("oxp._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> None: - respx_mock.get("/health").mock(side_effect=httpx.TimeoutException("Test timeout error")) + respx_mock.get("/tools").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): await self.client.get( - "/health", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}} + "/tools", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}} ) assert _get_open_connections(self.client) == 0 @@ -1529,11 +1529,11 @@ async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) @mock.patch("oxp._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) -> None: - respx_mock.get("/health").mock(return_value=httpx.Response(500)) + respx_mock.get("/tools").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): await self.client.get( - "/health", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}} + "/tools", cast_to=httpx.Response, options={"headers": {RAW_RESPONSE_HEADER: "stream"}} ) assert _get_open_connections(self.client) == 0 @@ -1563,9 +1563,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.get("/health").mock(side_effect=retry_handler) + respx_mock.get("/tools").mock(side_effect=retry_handler) - response = await client.health.with_raw_response.check() + response = await client.tools.with_raw_response.list() assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -1588,9 +1588,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.get("/health").mock(side_effect=retry_handler) + respx_mock.get("/tools").mock(side_effect=retry_handler) - response = await client.health.with_raw_response.check(extra_headers={"x-stainless-retry-count": Omit()}) + response = await client.tools.with_raw_response.list(extra_headers={"x-stainless-retry-count": Omit()}) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -1612,9 +1612,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: return httpx.Response(500) return httpx.Response(200) - respx_mock.get("/health").mock(side_effect=retry_handler) + respx_mock.get("/tools").mock(side_effect=retry_handler) - response = await client.health.with_raw_response.check(extra_headers={"x-stainless-retry-count": "42"}) + response = await client.tools.with_raw_response.list(extra_headers={"x-stainless-retry-count": "42"}) assert response.http_request.headers.get("x-stainless-retry-count") == "42"