From c56491e6fb6c5b8f0afb86658583a2bf8aa3cb63 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 18:42:29 +0000 Subject: [PATCH] feat(api): api update --- .stats.yml | 4 +- README.md | 2 +- api.md | 18 + src/runloop_api_client/_constants.py | 6 +- .../resources/devboxes/__init__.py | 14 + .../resources/devboxes/browsers.py | 78 ++++ .../resources/devboxes/computers.py | 78 ++++ .../resources/devboxes/devboxes.py | 153 +++++++ .../resources/devboxes/disk_snapshots.py | 421 ++++++++++++++++++ .../resources/scenarios/scorers.py | 24 +- src/runloop_api_client/types/__init__.py | 1 + .../types/devbox_update_params.py | 16 + .../types/devboxes/__init__.py | 3 + .../types/devboxes/browser_view.py | 4 +- .../devboxes/code_segment_info_response.py | 65 +-- .../types/devboxes/computer_view.py | 7 +- .../devboxes/disk_snapshot_list_params.py | 18 + .../devboxes/disk_snapshot_update_params.py | 16 + .../types/devboxes/document_symbol.py | 64 +++ .../types/scenarios/scorer_create_params.py | 4 +- .../types/scenarios/scorer_create_response.py | 4 +- .../types/scenarios/scorer_list_response.py | 4 +- .../scenarios/scorer_retrieve_response.py | 4 +- .../types/scenarios/scorer_update_params.py | 4 +- .../types/scenarios/scorer_update_response.py | 4 +- .../types/scoring_function.py | 9 + .../types/scoring_function_param.py | 9 + tests/api_resources/devboxes/test_browsers.py | 76 ++++ .../api_resources/devboxes/test_computers.py | 76 ++++ .../devboxes/test_disk_snapshots.py | 261 +++++++++++ tests/api_resources/scenarios/test_scorers.py | 28 +- tests/api_resources/test_devboxes.py | 94 ++++ tests/api_resources/test_scenarios.py | 10 + tests/test_client.py | 56 +-- 34 files changed, 1511 insertions(+), 124 deletions(-) create mode 100644 src/runloop_api_client/resources/devboxes/disk_snapshots.py create mode 100644 src/runloop_api_client/types/devbox_update_params.py create mode 100644 src/runloop_api_client/types/devboxes/disk_snapshot_list_params.py create mode 100644 src/runloop_api_client/types/devboxes/disk_snapshot_update_params.py create mode 100644 src/runloop_api_client/types/devboxes/document_symbol.py create mode 100644 tests/api_resources/devboxes/test_disk_snapshots.py diff --git a/.stats.yml b/.stats.yml index abd9dea8..fb43e6c6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 73 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-a6925284ea7678ed801dbaf6b5c60676b97ab7a16191c1b2ff8ef6a468e89f3b.yml +configured_endpoints: 77 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-a3d91c690527ff6a9040ade46943ba56916987f1f7d1fb45a9974546770ffe97.yml diff --git a/README.md b/README.md index 5954a957..f480d2d4 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ Error codes are as follows: ### Retries -Certain errors are automatically retried 2 times by default, with a short exponential backoff. +Certain errors are automatically retried 0 times by default, with a short exponential backoff. Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors are all retried by default. diff --git a/api.md b/api.md index 286bbffd..90c23734 100644 --- a/api.md +++ b/api.md @@ -83,6 +83,7 @@ Methods: - client.devboxes.create(\*\*params) -> DevboxView - client.devboxes.retrieve(id) -> DevboxView +- client.devboxes.update(id, \*\*params) -> DevboxView - client.devboxes.list(\*\*params) -> SyncDevboxesCursorIDPage[DevboxView] - client.devboxes.create_ssh_key(id) -> DevboxCreateSSHKeyResponse - client.devboxes.create_tunnel(id, \*\*params) -> DevboxTunnelView @@ -101,6 +102,20 @@ Methods: - client.devboxes.upload_file(id, \*\*params) -> object - client.devboxes.write_file_contents(id, \*\*params) -> DevboxExecutionDetailView +## DiskSnapshots + +Types: + +```python +from runloop_api_client.types.devboxes import DiskSnapshotDeleteResponse +``` + +Methods: + +- client.devboxes.disk_snapshots.update(id, \*\*params) -> DevboxSnapshotView +- client.devboxes.disk_snapshots.list(\*\*params) -> SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView] +- client.devboxes.disk_snapshots.delete(id) -> object + ## Browsers Types: @@ -112,6 +127,7 @@ from runloop_api_client.types.devboxes import BrowserView Methods: - client.devboxes.browsers.create(\*\*params) -> BrowserView +- client.devboxes.browsers.retrieve(id) -> BrowserView ## Computers @@ -129,6 +145,7 @@ from runloop_api_client.types.devboxes import ( Methods: - client.devboxes.computers.create(\*\*params) -> ComputerView +- client.devboxes.computers.retrieve(id) -> ComputerView - client.devboxes.computers.keyboard_interaction(id, \*\*params) -> ComputerKeyboardInteractionResponse - client.devboxes.computers.mouse_interaction(id, \*\*params) -> ComputerMouseInteractionResponse - client.devboxes.computers.screen_interaction(id, \*\*params) -> ComputerScreenInteractionResponse @@ -163,6 +180,7 @@ from runloop_api_client.types.devboxes import ( DiagnosticSeverity, DiagnosticsResponse, DiagnosticTag, + DocumentSymbol, DocumentSymbolResponse, DocumentUri, FileContentsResponse, diff --git a/src/runloop_api_client/_constants.py b/src/runloop_api_client/_constants.py index 6ddf2c71..6be0f5e0 100644 --- a/src/runloop_api_client/_constants.py +++ b/src/runloop_api_client/_constants.py @@ -7,8 +7,8 @@ # default timeout is 1 minute DEFAULT_TIMEOUT = httpx.Timeout(timeout=60, connect=5.0) -DEFAULT_MAX_RETRIES = 2 +DEFAULT_MAX_RETRIES = 0 DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20) -INITIAL_RETRY_DELAY = 0.5 -MAX_RETRY_DELAY = 8.0 +INITIAL_RETRY_DELAY = 1.0 +MAX_RETRY_DELAY = 10.0 diff --git a/src/runloop_api_client/resources/devboxes/__init__.py b/src/runloop_api_client/resources/devboxes/__init__.py index 1e09245d..acdd589f 100644 --- a/src/runloop_api_client/resources/devboxes/__init__.py +++ b/src/runloop_api_client/resources/devboxes/__init__.py @@ -48,8 +48,22 @@ ExecutionsResourceWithStreamingResponse, AsyncExecutionsResourceWithStreamingResponse, ) +from .disk_snapshots import ( + DiskSnapshotsResource, + AsyncDiskSnapshotsResource, + DiskSnapshotsResourceWithRawResponse, + AsyncDiskSnapshotsResourceWithRawResponse, + DiskSnapshotsResourceWithStreamingResponse, + AsyncDiskSnapshotsResourceWithStreamingResponse, +) __all__ = [ + "DiskSnapshotsResource", + "AsyncDiskSnapshotsResource", + "DiskSnapshotsResourceWithRawResponse", + "AsyncDiskSnapshotsResourceWithRawResponse", + "DiskSnapshotsResourceWithStreamingResponse", + "AsyncDiskSnapshotsResourceWithStreamingResponse", "BrowsersResource", "AsyncBrowsersResource", "BrowsersResourceWithRawResponse", diff --git a/src/runloop_api_client/resources/devboxes/browsers.py b/src/runloop_api_client/resources/devboxes/browsers.py index d59cbcd4..799b58ae 100644 --- a/src/runloop_api_client/resources/devboxes/browsers.py +++ b/src/runloop_api_client/resources/devboxes/browsers.py @@ -90,6 +90,39 @@ def create( cast_to=BrowserView, ) + def retrieve( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> BrowserView: + """ + Get Browser Details. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + f"/v1/devboxes/browsers/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BrowserView, + ) + class AsyncBrowsersResource(AsyncAPIResource): @cached_property @@ -155,6 +188,39 @@ async def create( cast_to=BrowserView, ) + async def retrieve( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> BrowserView: + """ + Get Browser Details. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + f"/v1/devboxes/browsers/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BrowserView, + ) + class BrowsersResourceWithRawResponse: def __init__(self, browsers: BrowsersResource) -> None: @@ -163,6 +229,9 @@ def __init__(self, browsers: BrowsersResource) -> None: self.create = to_raw_response_wrapper( browsers.create, ) + self.retrieve = to_raw_response_wrapper( + browsers.retrieve, + ) class AsyncBrowsersResourceWithRawResponse: @@ -172,6 +241,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None: self.create = async_to_raw_response_wrapper( browsers.create, ) + self.retrieve = async_to_raw_response_wrapper( + browsers.retrieve, + ) class BrowsersResourceWithStreamingResponse: @@ -181,6 +253,9 @@ def __init__(self, browsers: BrowsersResource) -> None: self.create = to_streamed_response_wrapper( browsers.create, ) + self.retrieve = to_streamed_response_wrapper( + browsers.retrieve, + ) class AsyncBrowsersResourceWithStreamingResponse: @@ -190,3 +265,6 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None: self.create = async_to_streamed_response_wrapper( browsers.create, ) + self.retrieve = async_to_streamed_response_wrapper( + browsers.retrieve, + ) diff --git a/src/runloop_api_client/resources/devboxes/computers.py b/src/runloop_api_client/resources/devboxes/computers.py index b3469739..fea63c39 100644 --- a/src/runloop_api_client/resources/devboxes/computers.py +++ b/src/runloop_api_client/resources/devboxes/computers.py @@ -110,6 +110,39 @@ def create( cast_to=ComputerView, ) + def retrieve( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> ComputerView: + """ + Get Computer Details. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + f"/v1/devboxes/computers/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ComputerView, + ) + def keyboard_interaction( self, id: str, @@ -343,6 +376,39 @@ async def create( cast_to=ComputerView, ) + async def retrieve( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> ComputerView: + """ + Get Computer Details. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + f"/v1/devboxes/computers/{id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ComputerView, + ) + async def keyboard_interaction( self, id: str, @@ -508,6 +574,9 @@ def __init__(self, computers: ComputersResource) -> None: self.create = to_raw_response_wrapper( computers.create, ) + self.retrieve = to_raw_response_wrapper( + computers.retrieve, + ) self.keyboard_interaction = to_raw_response_wrapper( computers.keyboard_interaction, ) @@ -526,6 +595,9 @@ def __init__(self, computers: AsyncComputersResource) -> None: self.create = async_to_raw_response_wrapper( computers.create, ) + self.retrieve = async_to_raw_response_wrapper( + computers.retrieve, + ) self.keyboard_interaction = async_to_raw_response_wrapper( computers.keyboard_interaction, ) @@ -544,6 +616,9 @@ def __init__(self, computers: ComputersResource) -> None: self.create = to_streamed_response_wrapper( computers.create, ) + self.retrieve = to_streamed_response_wrapper( + computers.retrieve, + ) self.keyboard_interaction = to_streamed_response_wrapper( computers.keyboard_interaction, ) @@ -562,6 +637,9 @@ def __init__(self, computers: AsyncComputersResource) -> None: self.create = async_to_streamed_response_wrapper( computers.create, ) + self.retrieve = async_to_streamed_response_wrapper( + computers.retrieve, + ) self.keyboard_interaction = async_to_streamed_response_wrapper( computers.keyboard_interaction, ) diff --git a/src/runloop_api_client/resources/devboxes/devboxes.py b/src/runloop_api_client/resources/devboxes/devboxes.py index f3be79cd..7c925310 100644 --- a/src/runloop_api_client/resources/devboxes/devboxes.py +++ b/src/runloop_api_client/resources/devboxes/devboxes.py @@ -26,6 +26,7 @@ from ...types import ( devbox_list_params, devbox_create_params, + devbox_update_params, devbox_upload_file_params, devbox_execute_sync_params, devbox_create_tunnel_params, @@ -91,6 +92,14 @@ AsyncDiskSnapshotsCursorIDPage, ) from ..._base_client import AsyncPaginator, make_request_options +from .disk_snapshots import ( + DiskSnapshotsResource, + AsyncDiskSnapshotsResource, + DiskSnapshotsResourceWithRawResponse, + AsyncDiskSnapshotsResourceWithRawResponse, + DiskSnapshotsResourceWithStreamingResponse, + AsyncDiskSnapshotsResourceWithStreamingResponse, +) from ...types.devbox_view import DevboxView from ...types.devbox_tunnel_view import DevboxTunnelView from ...types.devbox_snapshot_view import DevboxSnapshotView @@ -104,6 +113,10 @@ class DevboxesResource(SyncAPIResource): + @cached_property + def disk_snapshots(self) -> DiskSnapshotsResource: + return DiskSnapshotsResource(self._client) + @cached_property def browsers(self) -> BrowsersResource: return BrowsersResource(self._client) @@ -275,6 +288,60 @@ def retrieve( cast_to=DevboxView, ) + def update( + self, + id: str, + *, + metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + idempotency_key: str | None = None, + ) -> DevboxView: + """ + Updates a devbox by doing a complete update the existing name,metadata fields. + It does not patch partial values. + + Args: + metadata: User defined metadata to attach to the devbox for organization. + + name: (Optional) A user specified name to give the Devbox. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + f"/v1/devboxes/{id}", + body=maybe_transform( + { + "metadata": metadata, + "name": name, + }, + devbox_update_params.DevboxUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=DevboxView, + ) + def list( self, *, @@ -1109,6 +1176,10 @@ def write_file_contents( class AsyncDevboxesResource(AsyncAPIResource): + @cached_property + def disk_snapshots(self) -> AsyncDiskSnapshotsResource: + return AsyncDiskSnapshotsResource(self._client) + @cached_property def browsers(self) -> AsyncBrowsersResource: return AsyncBrowsersResource(self._client) @@ -1280,6 +1351,60 @@ async def retrieve( cast_to=DevboxView, ) + async def update( + self, + id: str, + *, + metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + idempotency_key: str | None = None, + ) -> DevboxView: + """ + Updates a devbox by doing a complete update the existing name,metadata fields. + It does not patch partial values. + + Args: + metadata: User defined metadata to attach to the devbox for organization. + + name: (Optional) A user specified name to give the Devbox. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + f"/v1/devboxes/{id}", + body=await async_maybe_transform( + { + "metadata": metadata, + "name": name, + }, + devbox_update_params.DevboxUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=DevboxView, + ) + def list( self, *, @@ -2123,6 +2248,9 @@ def __init__(self, devboxes: DevboxesResource) -> None: self.retrieve = to_raw_response_wrapper( devboxes.retrieve, ) + self.update = to_raw_response_wrapper( + devboxes.update, + ) self.list = to_raw_response_wrapper( devboxes.list, ) @@ -2176,6 +2304,10 @@ def __init__(self, devboxes: DevboxesResource) -> None: devboxes.write_file_contents, ) + @cached_property + def disk_snapshots(self) -> DiskSnapshotsResourceWithRawResponse: + return DiskSnapshotsResourceWithRawResponse(self._devboxes.disk_snapshots) + @cached_property def browsers(self) -> BrowsersResourceWithRawResponse: return BrowsersResourceWithRawResponse(self._devboxes.browsers) @@ -2207,6 +2339,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None: self.retrieve = async_to_raw_response_wrapper( devboxes.retrieve, ) + self.update = async_to_raw_response_wrapper( + devboxes.update, + ) self.list = async_to_raw_response_wrapper( devboxes.list, ) @@ -2260,6 +2395,10 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None: devboxes.write_file_contents, ) + @cached_property + def disk_snapshots(self) -> AsyncDiskSnapshotsResourceWithRawResponse: + return AsyncDiskSnapshotsResourceWithRawResponse(self._devboxes.disk_snapshots) + @cached_property def browsers(self) -> AsyncBrowsersResourceWithRawResponse: return AsyncBrowsersResourceWithRawResponse(self._devboxes.browsers) @@ -2291,6 +2430,9 @@ def __init__(self, devboxes: DevboxesResource) -> None: self.retrieve = to_streamed_response_wrapper( devboxes.retrieve, ) + self.update = to_streamed_response_wrapper( + devboxes.update, + ) self.list = to_streamed_response_wrapper( devboxes.list, ) @@ -2344,6 +2486,10 @@ def __init__(self, devboxes: DevboxesResource) -> None: devboxes.write_file_contents, ) + @cached_property + def disk_snapshots(self) -> DiskSnapshotsResourceWithStreamingResponse: + return DiskSnapshotsResourceWithStreamingResponse(self._devboxes.disk_snapshots) + @cached_property def browsers(self) -> BrowsersResourceWithStreamingResponse: return BrowsersResourceWithStreamingResponse(self._devboxes.browsers) @@ -2375,6 +2521,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None: self.retrieve = async_to_streamed_response_wrapper( devboxes.retrieve, ) + self.update = async_to_streamed_response_wrapper( + devboxes.update, + ) self.list = async_to_streamed_response_wrapper( devboxes.list, ) @@ -2428,6 +2577,10 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None: devboxes.write_file_contents, ) + @cached_property + def disk_snapshots(self) -> AsyncDiskSnapshotsResourceWithStreamingResponse: + return AsyncDiskSnapshotsResourceWithStreamingResponse(self._devboxes.disk_snapshots) + @cached_property def browsers(self) -> AsyncBrowsersResourceWithStreamingResponse: return AsyncBrowsersResourceWithStreamingResponse(self._devboxes.browsers) diff --git a/src/runloop_api_client/resources/devboxes/disk_snapshots.py b/src/runloop_api_client/resources/devboxes/disk_snapshots.py new file mode 100644 index 00000000..9d23416f --- /dev/null +++ b/src/runloop_api_client/resources/devboxes/disk_snapshots.py @@ -0,0 +1,421 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional + +import httpx + +from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ..._utils import ( + maybe_transform, + async_maybe_transform, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...pagination import SyncDiskSnapshotsCursorIDPage, AsyncDiskSnapshotsCursorIDPage +from ..._base_client import AsyncPaginator, make_request_options +from ...types.devboxes import disk_snapshot_list_params, disk_snapshot_update_params +from ...types.devbox_snapshot_view import DevboxSnapshotView + +__all__ = ["DiskSnapshotsResource", "AsyncDiskSnapshotsResource"] + + +class DiskSnapshotsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DiskSnapshotsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/runloopai/api-client-python#accessing-raw-response-data-eg-headers + """ + return DiskSnapshotsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DiskSnapshotsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/runloopai/api-client-python#with_streaming_response + """ + return DiskSnapshotsResourceWithStreamingResponse(self) + + def update( + self, + id: str, + *, + metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + idempotency_key: str | None = None, + ) -> DevboxSnapshotView: + """Updates disk snapshot metadata via update vs patch. + + The entire metadata will be + replaced. + + Args: + metadata: (Optional) Metadata used to describe the snapshot + + name: (Optional) A user specified name to give the snapshot + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + f"/v1/devboxes/disk_snapshots/{id}", + body=maybe_transform( + { + "metadata": metadata, + "name": name, + }, + disk_snapshot_update_params.DiskSnapshotUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=DevboxSnapshotView, + ) + + def list( + self, + *, + devbox_id: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + starting_after: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView]: + """ + List all snapshots of a Devbox while optionally filtering by Devbox ID. + + Args: + devbox_id: Devbox ID to filter by. + + limit: The limit of items to return. Default is 20. + + starting_after: Load the next page of data starting after the item with the given ID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/v1/devboxes/disk_snapshots", + page=SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "devbox_id": devbox_id, + "limit": limit, + "starting_after": starting_after, + }, + disk_snapshot_list_params.DiskSnapshotListParams, + ), + ), + model=DevboxSnapshotView, + ) + + def delete( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + idempotency_key: str | None = None, + ) -> object: + """ + Delete a previously taken disk snapshot of a Devbox. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + f"/v1/devboxes/disk_snapshots/{id}/delete", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=object, + ) + + +class AsyncDiskSnapshotsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDiskSnapshotsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/runloopai/api-client-python#accessing-raw-response-data-eg-headers + """ + return AsyncDiskSnapshotsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDiskSnapshotsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/runloopai/api-client-python#with_streaming_response + """ + return AsyncDiskSnapshotsResourceWithStreamingResponse(self) + + async def update( + self, + id: str, + *, + metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + idempotency_key: str | None = None, + ) -> DevboxSnapshotView: + """Updates disk snapshot metadata via update vs patch. + + The entire metadata will be + replaced. + + Args: + metadata: (Optional) Metadata used to describe the snapshot + + name: (Optional) A user specified name to give the snapshot + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + f"/v1/devboxes/disk_snapshots/{id}", + body=await async_maybe_transform( + { + "metadata": metadata, + "name": name, + }, + disk_snapshot_update_params.DiskSnapshotUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=DevboxSnapshotView, + ) + + def list( + self, + *, + devbox_id: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + starting_after: str | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[DevboxSnapshotView, AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView]]: + """ + List all snapshots of a Devbox while optionally filtering by Devbox ID. + + Args: + devbox_id: Devbox ID to filter by. + + limit: The limit of items to return. Default is 20. + + starting_after: Load the next page of data starting after the item with the given ID. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/v1/devboxes/disk_snapshots", + page=AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "devbox_id": devbox_id, + "limit": limit, + "starting_after": starting_after, + }, + disk_snapshot_list_params.DiskSnapshotListParams, + ), + ), + model=DevboxSnapshotView, + ) + + async def delete( + self, + id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + idempotency_key: str | None = None, + ) -> object: + """ + Delete a previously taken disk snapshot of a Devbox. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + f"/v1/devboxes/disk_snapshots/{id}/delete", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=object, + ) + + +class DiskSnapshotsResourceWithRawResponse: + def __init__(self, disk_snapshots: DiskSnapshotsResource) -> None: + self._disk_snapshots = disk_snapshots + + self.update = to_raw_response_wrapper( + disk_snapshots.update, + ) + self.list = to_raw_response_wrapper( + disk_snapshots.list, + ) + self.delete = to_raw_response_wrapper( + disk_snapshots.delete, + ) + + +class AsyncDiskSnapshotsResourceWithRawResponse: + def __init__(self, disk_snapshots: AsyncDiskSnapshotsResource) -> None: + self._disk_snapshots = disk_snapshots + + self.update = async_to_raw_response_wrapper( + disk_snapshots.update, + ) + self.list = async_to_raw_response_wrapper( + disk_snapshots.list, + ) + self.delete = async_to_raw_response_wrapper( + disk_snapshots.delete, + ) + + +class DiskSnapshotsResourceWithStreamingResponse: + def __init__(self, disk_snapshots: DiskSnapshotsResource) -> None: + self._disk_snapshots = disk_snapshots + + self.update = to_streamed_response_wrapper( + disk_snapshots.update, + ) + self.list = to_streamed_response_wrapper( + disk_snapshots.list, + ) + self.delete = to_streamed_response_wrapper( + disk_snapshots.delete, + ) + + +class AsyncDiskSnapshotsResourceWithStreamingResponse: + def __init__(self, disk_snapshots: AsyncDiskSnapshotsResource) -> None: + self._disk_snapshots = disk_snapshots + + self.update = async_to_streamed_response_wrapper( + disk_snapshots.update, + ) + self.list = async_to_streamed_response_wrapper( + disk_snapshots.list, + ) + self.delete = async_to_streamed_response_wrapper( + disk_snapshots.delete, + ) diff --git a/src/runloop_api_client/resources/scenarios/scorers.py b/src/runloop_api_client/resources/scenarios/scorers.py index 5d2ee5b5..77f9393d 100644 --- a/src/runloop_api_client/resources/scenarios/scorers.py +++ b/src/runloop_api_client/resources/scenarios/scorers.py @@ -54,7 +54,7 @@ def create( self, *, bash_script: str, - name: str, + type: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -70,7 +70,7 @@ def create( bash_script: Bash script for the custom scorer taking context as a json object $RL_TEST_CONTEXT. - name: Name of the custom scorer. + type: Name of the type of custom scorer. extra_headers: Send extra headers @@ -87,7 +87,7 @@ def create( body=maybe_transform( { "bash_script": bash_script, - "name": name, + "type": type, }, scorer_create_params.ScorerCreateParams, ), @@ -139,7 +139,7 @@ def update( id: str, *, bash_script: str, - name: str, + type: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -155,7 +155,7 @@ def update( bash_script: Bash script for the custom scorer taking context as a json object $RL_TEST_CONTEXT. - name: Name of the custom scorer. + type: Name of the type of custom scorer. extra_headers: Send extra headers @@ -174,7 +174,7 @@ def update( body=maybe_transform( { "bash_script": bash_script, - "name": name, + "type": type, }, scorer_update_params.ScorerUpdateParams, ), @@ -313,7 +313,7 @@ async def create( self, *, bash_script: str, - name: str, + type: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -329,7 +329,7 @@ async def create( bash_script: Bash script for the custom scorer taking context as a json object $RL_TEST_CONTEXT. - name: Name of the custom scorer. + type: Name of the type of custom scorer. extra_headers: Send extra headers @@ -346,7 +346,7 @@ async def create( body=await async_maybe_transform( { "bash_script": bash_script, - "name": name, + "type": type, }, scorer_create_params.ScorerCreateParams, ), @@ -398,7 +398,7 @@ async def update( id: str, *, bash_script: str, - name: str, + type: str, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -414,7 +414,7 @@ async def update( bash_script: Bash script for the custom scorer taking context as a json object $RL_TEST_CONTEXT. - name: Name of the custom scorer. + type: Name of the type of custom scorer. extra_headers: Send extra headers @@ -433,7 +433,7 @@ async def update( body=await async_maybe_transform( { "bash_script": bash_script, - "name": name, + "type": type, }, scorer_update_params.ScorerUpdateParams, ), diff --git a/src/runloop_api_client/types/__init__.py b/src/runloop_api_client/types/__init__.py index f8e0dbe8..62b6d30e 100644 --- a/src/runloop_api_client/types/__init__.py +++ b/src/runloop_api_client/types/__init__.py @@ -26,6 +26,7 @@ from .input_context_param import InputContextParam as InputContextParam from .devbox_create_params import DevboxCreateParams as DevboxCreateParams from .devbox_snapshot_view import DevboxSnapshotView as DevboxSnapshotView +from .devbox_update_params import DevboxUpdateParams as DevboxUpdateParams from .scenario_environment import ScenarioEnvironment as ScenarioEnvironment from .scenario_list_params import ScenarioListParams as ScenarioListParams from .benchmark_list_params import BenchmarkListParams as BenchmarkListParams diff --git a/src/runloop_api_client/types/devbox_update_params.py b/src/runloop_api_client/types/devbox_update_params.py new file mode 100644 index 00000000..2fbdae31 --- /dev/null +++ b/src/runloop_api_client/types/devbox_update_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import TypedDict + +__all__ = ["DevboxUpdateParams"] + + +class DevboxUpdateParams(TypedDict, total=False): + metadata: Optional[Dict[str, str]] + """User defined metadata to attach to the devbox for organization.""" + + name: Optional[str] + """(Optional) A user specified name to give the Devbox.""" diff --git a/src/runloop_api_client/types/devboxes/__init__.py b/src/runloop_api_client/types/devboxes/__init__.py index 66e9530e..ebfdc780 100644 --- a/src/runloop_api_client/types/devboxes/__init__.py +++ b/src/runloop_api_client/types/devboxes/__init__.py @@ -26,6 +26,7 @@ from .location_param import LocationParam as LocationParam from .position_param import PositionParam as PositionParam from .base_diagnostic import BaseDiagnostic as BaseDiagnostic +from .document_symbol import DocumentSymbol as DocumentSymbol from .log_list_params import LogListParams as LogListParams from .lsp_file_params import LspFileParams as LspFileParams from .text_edit_param import TextEditParam as TextEditParam @@ -60,10 +61,12 @@ from .file_definition_response import FileDefinitionResponse as FileDefinitionResponse from .base_workspace_edit_param import BaseWorkspaceEditParam as BaseWorkspaceEditParam from .code_action_context_param import CodeActionContextParam as CodeActionContextParam +from .disk_snapshot_list_params import DiskSnapshotListParams as DiskSnapshotListParams from .execution_retrieve_params import ExecutionRetrieveParams as ExecutionRetrieveParams from .base_parameter_information import BaseParameterInformation as BaseParameterInformation from .code_segment_info_response import CodeSegmentInfoResponse as CodeSegmentInfoResponse from .lsp_file_definition_params import LspFileDefinitionParams as LspFileDefinitionParams +from .disk_snapshot_update_params import DiskSnapshotUpdateParams as DiskSnapshotUpdateParams from .lsp_document_symbols_params import LspDocumentSymbolsParams as LspDocumentSymbolsParams from .lsp_apply_code_action_params import LspApplyCodeActionParams as LspApplyCodeActionParams from .execution_execute_sync_params import ExecutionExecuteSyncParams as ExecutionExecuteSyncParams diff --git a/src/runloop_api_client/types/devboxes/browser_view.py b/src/runloop_api_client/types/devboxes/browser_view.py index ef9303f0..84341e30 100644 --- a/src/runloop_api_client/types/devboxes/browser_view.py +++ b/src/runloop_api_client/types/devboxes/browser_view.py @@ -20,5 +20,7 @@ class BrowserView(BaseModel): live_view_url: str """ The url to view the browser window and enable user interactions via their own - browser. + browser. You can control the interactivity of the browser by adding or removing + 'view_only' query parameter. view_only=1 will allow interaction and view_only=0 + will disable interaction. """ diff --git a/src/runloop_api_client/types/devboxes/code_segment_info_response.py b/src/runloop_api_client/types/devboxes/code_segment_info_response.py index dbc01bdf..aa064187 100644 --- a/src/runloop_api_client/types/devboxes/code_segment_info_response.py +++ b/src/runloop_api_client/types/devboxes/code_segment_info_response.py @@ -1,64 +1,19 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import TYPE_CHECKING, List, Optional +from __future__ import annotations -from pydantic import Field as FieldInfo +from typing import List, Optional -from .range import Range from .file_uri import FileUri +from ..._compat import PYDANTIC_V2 from ..._models import BaseModel from .base_range import BaseRange -from .symbol_tag import SymbolTag -from .symbol_kind import SymbolKind from .base_location import BaseLocation from .base_diagnostic import BaseDiagnostic from .base_code_action import BaseCodeAction from .signature_help_response import SignatureHelpResponse -__all__ = ["CodeSegmentInfoResponse", "Symbol", "Hover"] - - -class Symbol(BaseModel): - kind: SymbolKind - """The kind of this symbol.""" - - name: str - """The name of this symbol. - - Will be displayed in the user interface and therefore must not be an empty - string or a string only consisting of white spaces. - """ - - range: Range - """ - The range enclosing this symbol not including leading/trailing whitespace but - everything else like comments. This information is typically used to determine - if the clients cursor is inside the symbol to reveal in the symbol in the UI. - """ - - selection_range: Range = FieldInfo(alias="selectionRange") - """ - The range that should be selected and revealed when this symbol is being picked, - e.g the name of a function. Must be contained by the `range`. - """ - - children: Optional[List[object]] = None - """Children of this symbol, e.g. properties of a class.""" - - deprecated: Optional[bool] = None - """Indicates if this symbol is deprecated.""" - - detail: Optional[str] = None - """More detail for this symbol, e.g the signature of a function.""" - - tags: Optional[List[SymbolTag]] = None - """Tags for this document symbol.""" - - if TYPE_CHECKING: - # Stub to indicate that arbitrary properties are accepted. - # To access properties that are not valid identifiers you can use `getattr`, e.g. - # `getattr(obj, '$type')` - def __getattr__(self, attr: str) -> object: ... +__all__ = ["CodeSegmentInfoResponse", "Hover"] class Hover(BaseModel): @@ -74,7 +29,7 @@ class CodeSegmentInfoResponse(BaseModel): references: List[BaseLocation] - symbol: Symbol + symbol: "DocumentSymbol" """ Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be hierarchical and they have two @@ -87,3 +42,13 @@ class CodeSegmentInfoResponse(BaseModel): hover: Optional[Hover] = None signature: Optional[SignatureHelpResponse] = None + + +from .document_symbol import DocumentSymbol + +if PYDANTIC_V2: + CodeSegmentInfoResponse.model_rebuild() + Hover.model_rebuild() +else: + CodeSegmentInfoResponse.update_forward_refs() # type: ignore + Hover.update_forward_refs() # type: ignore diff --git a/src/runloop_api_client/types/devboxes/computer_view.py b/src/runloop_api_client/types/devboxes/computer_view.py index 858aa27a..f401845c 100644 --- a/src/runloop_api_client/types/devboxes/computer_view.py +++ b/src/runloop_api_client/types/devboxes/computer_view.py @@ -12,4 +12,9 @@ class ComputerView(BaseModel): """The underlying devbox the computer setup is running on.""" live_screen_url: str - """The http tunnel to connect and view the live screen of the computer.""" + """The http tunnel to connect and view the live screen of the computer. + + You can control the interactivity of the browser by adding or removing + 'view_only' query parameter. view_only=1 will allow interaction and view_only=0 + will disable interaction. + """ diff --git a/src/runloop_api_client/types/devboxes/disk_snapshot_list_params.py b/src/runloop_api_client/types/devboxes/disk_snapshot_list_params.py new file mode 100644 index 00000000..82cd1273 --- /dev/null +++ b/src/runloop_api_client/types/devboxes/disk_snapshot_list_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["DiskSnapshotListParams"] + + +class DiskSnapshotListParams(TypedDict, total=False): + devbox_id: str + """Devbox ID to filter by.""" + + limit: int + """The limit of items to return. Default is 20.""" + + starting_after: str + """Load the next page of data starting after the item with the given ID.""" diff --git a/src/runloop_api_client/types/devboxes/disk_snapshot_update_params.py b/src/runloop_api_client/types/devboxes/disk_snapshot_update_params.py new file mode 100644 index 00000000..6b4d276c --- /dev/null +++ b/src/runloop_api_client/types/devboxes/disk_snapshot_update_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import TypedDict + +__all__ = ["DiskSnapshotUpdateParams"] + + +class DiskSnapshotUpdateParams(TypedDict, total=False): + metadata: Optional[Dict[str, str]] + """(Optional) Metadata used to describe the snapshot""" + + name: Optional[str] + """(Optional) A user specified name to give the snapshot""" diff --git a/src/runloop_api_client/types/devboxes/document_symbol.py b/src/runloop_api_client/types/devboxes/document_symbol.py new file mode 100644 index 00000000..30ca96d6 --- /dev/null +++ b/src/runloop_api_client/types/devboxes/document_symbol.py @@ -0,0 +1,64 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import TYPE_CHECKING, List, Optional + +from pydantic import Field as FieldInfo + +from .range import Range +from ..._compat import PYDANTIC_V2 +from ..._models import BaseModel +from .symbol_tag import SymbolTag +from .symbol_kind import SymbolKind + +__all__ = ["DocumentSymbol"] + + +class DocumentSymbol(BaseModel): + kind: SymbolKind + """The kind of this symbol.""" + + name: str + """The name of this symbol. + + Will be displayed in the user interface and therefore must not be an empty + string or a string only consisting of white spaces. + """ + + range: Range + """ + The range enclosing this symbol not including leading/trailing whitespace but + everything else like comments. This information is typically used to determine + if the clients cursor is inside the symbol to reveal in the symbol in the UI. + """ + + selection_range: Range = FieldInfo(alias="selectionRange") + """ + The range that should be selected and revealed when this symbol is being picked, + e.g the name of a function. Must be contained by the `range`. + """ + + children: Optional[List["DocumentSymbol"]] = None + """Children of this symbol, e.g. properties of a class.""" + + deprecated: Optional[bool] = None + """Indicates if this symbol is deprecated.""" + + detail: Optional[str] = None + """More detail for this symbol, e.g the signature of a function.""" + + tags: Optional[List[SymbolTag]] = None + """Tags for this document symbol.""" + + if TYPE_CHECKING: + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> object: ... + + +if PYDANTIC_V2: + DocumentSymbol.model_rebuild() +else: + DocumentSymbol.update_forward_refs() # type: ignore diff --git a/src/runloop_api_client/types/scenarios/scorer_create_params.py b/src/runloop_api_client/types/scenarios/scorer_create_params.py index 8261dff5..4ba0d6d4 100644 --- a/src/runloop_api_client/types/scenarios/scorer_create_params.py +++ b/src/runloop_api_client/types/scenarios/scorer_create_params.py @@ -14,5 +14,5 @@ class ScorerCreateParams(TypedDict, total=False): $RL_TEST_CONTEXT. """ - name: Required[str] - """Name of the custom scorer.""" + type: Required[str] + """Name of the type of custom scorer.""" diff --git a/src/runloop_api_client/types/scenarios/scorer_create_response.py b/src/runloop_api_client/types/scenarios/scorer_create_response.py index 8c9adf29..49b614e0 100644 --- a/src/runloop_api_client/types/scenarios/scorer_create_response.py +++ b/src/runloop_api_client/types/scenarios/scorer_create_response.py @@ -13,5 +13,5 @@ class ScorerCreateResponse(BaseModel): bash_script: str """Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.""" - name: str - """Name of the scenario scorer.""" + type: str + """Name of the type of scenario scorer.""" diff --git a/src/runloop_api_client/types/scenarios/scorer_list_response.py b/src/runloop_api_client/types/scenarios/scorer_list_response.py index 59f7adc4..d24bfd87 100644 --- a/src/runloop_api_client/types/scenarios/scorer_list_response.py +++ b/src/runloop_api_client/types/scenarios/scorer_list_response.py @@ -13,5 +13,5 @@ class ScorerListResponse(BaseModel): bash_script: str """Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.""" - name: str - """Name of the scenario scorer.""" + type: str + """Name of the type of scenario scorer.""" diff --git a/src/runloop_api_client/types/scenarios/scorer_retrieve_response.py b/src/runloop_api_client/types/scenarios/scorer_retrieve_response.py index 25ab5b1d..d72dd577 100644 --- a/src/runloop_api_client/types/scenarios/scorer_retrieve_response.py +++ b/src/runloop_api_client/types/scenarios/scorer_retrieve_response.py @@ -13,5 +13,5 @@ class ScorerRetrieveResponse(BaseModel): bash_script: str """Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.""" - name: str - """Name of the scenario scorer.""" + type: str + """Name of the type of scenario scorer.""" diff --git a/src/runloop_api_client/types/scenarios/scorer_update_params.py b/src/runloop_api_client/types/scenarios/scorer_update_params.py index bff2e81c..3637f4b0 100644 --- a/src/runloop_api_client/types/scenarios/scorer_update_params.py +++ b/src/runloop_api_client/types/scenarios/scorer_update_params.py @@ -14,5 +14,5 @@ class ScorerUpdateParams(TypedDict, total=False): $RL_TEST_CONTEXT. """ - name: Required[str] - """Name of the custom scorer.""" + type: Required[str] + """Name of the type of custom scorer.""" diff --git a/src/runloop_api_client/types/scenarios/scorer_update_response.py b/src/runloop_api_client/types/scenarios/scorer_update_response.py index 72c6dce7..ef77f37e 100644 --- a/src/runloop_api_client/types/scenarios/scorer_update_response.py +++ b/src/runloop_api_client/types/scenarios/scorer_update_response.py @@ -13,5 +13,5 @@ class ScorerUpdateResponse(BaseModel): bash_script: str """Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.""" - name: str - """Name of the scenario scorer.""" + type: str + """Name of the type of scenario scorer.""" diff --git a/src/runloop_api_client/types/scoring_function.py b/src/runloop_api_client/types/scoring_function.py index 2ed26f67..a5adc2b7 100644 --- a/src/runloop_api_client/types/scoring_function.py +++ b/src/runloop_api_client/types/scoring_function.py @@ -11,6 +11,9 @@ class ScoringFunction(BaseModel): name: str """Name of scoring function.""" + type: str + """Type of the scoring function. Defaults to bash script.""" + weight: float """Wight to apply to scoring function score. @@ -23,3 +26,9 @@ class ScoringFunction(BaseModel): score to standard out. Score should be an integer between 0 and 100, and look like "score=[0..100]. """ + + scorer_params: Optional[object] = None + """ + Additional JSON structured context to pass to the scoring function if using + custom scorer. + """ diff --git a/src/runloop_api_client/types/scoring_function_param.py b/src/runloop_api_client/types/scoring_function_param.py index ba42923c..1f101bad 100644 --- a/src/runloop_api_client/types/scoring_function_param.py +++ b/src/runloop_api_client/types/scoring_function_param.py @@ -12,6 +12,9 @@ class ScoringFunctionParam(TypedDict, total=False): name: Required[str] """Name of scoring function.""" + type: Required[str] + """Type of the scoring function. Defaults to bash script.""" + weight: Required[float] """Wight to apply to scoring function score. @@ -24,3 +27,9 @@ class ScoringFunctionParam(TypedDict, total=False): score to standard out. Score should be an integer between 0 and 100, and look like "score=[0..100]. """ + + scorer_params: Optional[object] + """ + Additional JSON structured context to pass to the scoring function if using + custom scorer. + """ diff --git a/tests/api_resources/devboxes/test_browsers.py b/tests/api_resources/devboxes/test_browsers.py index 2bdbd823..5fa04afc 100644 --- a/tests/api_resources/devboxes/test_browsers.py +++ b/tests/api_resources/devboxes/test_browsers.py @@ -49,6 +49,44 @@ def test_streaming_response_create(self, client: Runloop) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_retrieve(self, client: Runloop) -> None: + browser = client.devboxes.browsers.retrieve( + "id", + ) + assert_matches_type(BrowserView, browser, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: Runloop) -> None: + response = client.devboxes.browsers.with_raw_response.retrieve( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + browser = response.parse() + assert_matches_type(BrowserView, browser, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: Runloop) -> None: + with client.devboxes.browsers.with_streaming_response.retrieve( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + browser = response.parse() + assert_matches_type(BrowserView, browser, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: Runloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.devboxes.browsers.with_raw_response.retrieve( + "", + ) + class TestAsyncBrowsers: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @@ -84,3 +122,41 @@ async def test_streaming_response_create(self, async_client: AsyncRunloop) -> No assert_matches_type(BrowserView, browser, path=["response"]) assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_retrieve(self, async_client: AsyncRunloop) -> None: + browser = await async_client.devboxes.browsers.retrieve( + "id", + ) + assert_matches_type(BrowserView, browser, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncRunloop) -> None: + response = await async_client.devboxes.browsers.with_raw_response.retrieve( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + browser = await response.parse() + assert_matches_type(BrowserView, browser, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncRunloop) -> None: + async with async_client.devboxes.browsers.with_streaming_response.retrieve( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + browser = await response.parse() + assert_matches_type(BrowserView, browser, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncRunloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.devboxes.browsers.with_raw_response.retrieve( + "", + ) diff --git a/tests/api_resources/devboxes/test_computers.py b/tests/api_resources/devboxes/test_computers.py index a388926b..8671cf96 100644 --- a/tests/api_resources/devboxes/test_computers.py +++ b/tests/api_resources/devboxes/test_computers.py @@ -58,6 +58,44 @@ def test_streaming_response_create(self, client: Runloop) -> None: assert cast(Any, response.is_closed) is True + @parametrize + def test_method_retrieve(self, client: Runloop) -> None: + computer = client.devboxes.computers.retrieve( + "id", + ) + assert_matches_type(ComputerView, computer, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: Runloop) -> None: + response = client.devboxes.computers.with_raw_response.retrieve( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert_matches_type(ComputerView, computer, path=["response"]) + + @parametrize + def test_streaming_response_retrieve(self, client: Runloop) -> None: + with client.devboxes.computers.with_streaming_response.retrieve( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert_matches_type(ComputerView, computer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_retrieve(self, client: Runloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.devboxes.computers.with_raw_response.retrieve( + "", + ) + @parametrize def test_method_keyboard_interaction(self, client: Runloop) -> None: computer = client.devboxes.computers.keyboard_interaction( @@ -245,6 +283,44 @@ async def test_streaming_response_create(self, async_client: AsyncRunloop) -> No assert cast(Any, response.is_closed) is True + @parametrize + async def test_method_retrieve(self, async_client: AsyncRunloop) -> None: + computer = await async_client.devboxes.computers.retrieve( + "id", + ) + assert_matches_type(ComputerView, computer, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncRunloop) -> None: + response = await async_client.devboxes.computers.with_raw_response.retrieve( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert_matches_type(ComputerView, computer, path=["response"]) + + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncRunloop) -> None: + async with async_client.devboxes.computers.with_streaming_response.retrieve( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert_matches_type(ComputerView, computer, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncRunloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.devboxes.computers.with_raw_response.retrieve( + "", + ) + @parametrize async def test_method_keyboard_interaction(self, async_client: AsyncRunloop) -> None: computer = await async_client.devboxes.computers.keyboard_interaction( diff --git a/tests/api_resources/devboxes/test_disk_snapshots.py b/tests/api_resources/devboxes/test_disk_snapshots.py new file mode 100644 index 00000000..dbbefa07 --- /dev/null +++ b/tests/api_resources/devboxes/test_disk_snapshots.py @@ -0,0 +1,261 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from runloop_api_client import Runloop, AsyncRunloop +from runloop_api_client.types import DevboxSnapshotView +from runloop_api_client.pagination import SyncDiskSnapshotsCursorIDPage, AsyncDiskSnapshotsCursorIDPage + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDiskSnapshots: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_update(self, client: Runloop) -> None: + disk_snapshot = client.devboxes.disk_snapshots.update( + id="id", + ) + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Runloop) -> None: + disk_snapshot = client.devboxes.disk_snapshots.update( + id="id", + metadata={"foo": "string"}, + name="name", + ) + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Runloop) -> None: + response = client.devboxes.disk_snapshots.with_raw_response.update( + id="id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + disk_snapshot = response.parse() + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Runloop) -> None: + with client.devboxes.disk_snapshots.with_streaming_response.update( + id="id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + disk_snapshot = response.parse() + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Runloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.devboxes.disk_snapshots.with_raw_response.update( + id="", + ) + + @parametrize + def test_method_list(self, client: Runloop) -> None: + disk_snapshot = client.devboxes.disk_snapshots.list() + assert_matches_type(SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Runloop) -> None: + disk_snapshot = client.devboxes.disk_snapshots.list( + devbox_id="devbox_id", + limit=0, + starting_after="starting_after", + ) + assert_matches_type(SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Runloop) -> None: + response = client.devboxes.disk_snapshots.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + disk_snapshot = response.parse() + assert_matches_type(SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Runloop) -> None: + with client.devboxes.disk_snapshots.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + disk_snapshot = response.parse() + assert_matches_type(SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_delete(self, client: Runloop) -> None: + disk_snapshot = client.devboxes.disk_snapshots.delete( + "id", + ) + assert_matches_type(object, disk_snapshot, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Runloop) -> None: + response = client.devboxes.disk_snapshots.with_raw_response.delete( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + disk_snapshot = response.parse() + assert_matches_type(object, disk_snapshot, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Runloop) -> None: + with client.devboxes.disk_snapshots.with_streaming_response.delete( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + disk_snapshot = response.parse() + assert_matches_type(object, disk_snapshot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_delete(self, client: Runloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.devboxes.disk_snapshots.with_raw_response.delete( + "", + ) + + +class TestAsyncDiskSnapshots: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + async def test_method_update(self, async_client: AsyncRunloop) -> None: + disk_snapshot = await async_client.devboxes.disk_snapshots.update( + id="id", + ) + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncRunloop) -> None: + disk_snapshot = await async_client.devboxes.disk_snapshots.update( + id="id", + metadata={"foo": "string"}, + name="name", + ) + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncRunloop) -> None: + response = await async_client.devboxes.disk_snapshots.with_raw_response.update( + id="id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + disk_snapshot = await response.parse() + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncRunloop) -> None: + async with async_client.devboxes.disk_snapshots.with_streaming_response.update( + id="id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + disk_snapshot = await response.parse() + assert_matches_type(DevboxSnapshotView, disk_snapshot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncRunloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.devboxes.disk_snapshots.with_raw_response.update( + id="", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncRunloop) -> None: + disk_snapshot = await async_client.devboxes.disk_snapshots.list() + assert_matches_type(AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncRunloop) -> None: + disk_snapshot = await async_client.devboxes.disk_snapshots.list( + devbox_id="devbox_id", + limit=0, + starting_after="starting_after", + ) + assert_matches_type(AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncRunloop) -> None: + response = await async_client.devboxes.disk_snapshots.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + disk_snapshot = await response.parse() + assert_matches_type(AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncRunloop) -> None: + async with async_client.devboxes.disk_snapshots.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + disk_snapshot = await response.parse() + assert_matches_type(AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView], disk_snapshot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_delete(self, async_client: AsyncRunloop) -> None: + disk_snapshot = await async_client.devboxes.disk_snapshots.delete( + "id", + ) + assert_matches_type(object, disk_snapshot, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncRunloop) -> None: + response = await async_client.devboxes.disk_snapshots.with_raw_response.delete( + "id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + disk_snapshot = await response.parse() + assert_matches_type(object, disk_snapshot, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncRunloop) -> None: + async with async_client.devboxes.disk_snapshots.with_streaming_response.delete( + "id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + disk_snapshot = await response.parse() + assert_matches_type(object, disk_snapshot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_delete(self, async_client: AsyncRunloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.devboxes.disk_snapshots.with_raw_response.delete( + "", + ) diff --git a/tests/api_resources/scenarios/test_scorers.py b/tests/api_resources/scenarios/test_scorers.py index aa0d641e..f3cc6cb5 100644 --- a/tests/api_resources/scenarios/test_scorers.py +++ b/tests/api_resources/scenarios/test_scorers.py @@ -28,7 +28,7 @@ class TestScorers: def test_method_create(self, client: Runloop) -> None: scorer = client.scenarios.scorers.create( bash_script="bash_script", - name="name", + type="type", ) assert_matches_type(ScorerCreateResponse, scorer, path=["response"]) @@ -36,7 +36,7 @@ def test_method_create(self, client: Runloop) -> None: def test_raw_response_create(self, client: Runloop) -> None: response = client.scenarios.scorers.with_raw_response.create( bash_script="bash_script", - name="name", + type="type", ) assert response.is_closed is True @@ -48,7 +48,7 @@ def test_raw_response_create(self, client: Runloop) -> None: def test_streaming_response_create(self, client: Runloop) -> None: with client.scenarios.scorers.with_streaming_response.create( bash_script="bash_script", - name="name", + type="type", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -101,7 +101,7 @@ def test_method_update(self, client: Runloop) -> None: scorer = client.scenarios.scorers.update( id="id", bash_script="bash_script", - name="name", + type="type", ) assert_matches_type(ScorerUpdateResponse, scorer, path=["response"]) @@ -110,7 +110,7 @@ def test_raw_response_update(self, client: Runloop) -> None: response = client.scenarios.scorers.with_raw_response.update( id="id", bash_script="bash_script", - name="name", + type="type", ) assert response.is_closed is True @@ -123,7 +123,7 @@ def test_streaming_response_update(self, client: Runloop) -> None: with client.scenarios.scorers.with_streaming_response.update( id="id", bash_script="bash_script", - name="name", + type="type", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -139,7 +139,7 @@ def test_path_params_update(self, client: Runloop) -> None: client.scenarios.scorers.with_raw_response.update( id="", bash_script="bash_script", - name="name", + type="type", ) @parametrize @@ -238,7 +238,7 @@ class TestAsyncScorers: async def test_method_create(self, async_client: AsyncRunloop) -> None: scorer = await async_client.scenarios.scorers.create( bash_script="bash_script", - name="name", + type="type", ) assert_matches_type(ScorerCreateResponse, scorer, path=["response"]) @@ -246,7 +246,7 @@ async def test_method_create(self, async_client: AsyncRunloop) -> None: async def test_raw_response_create(self, async_client: AsyncRunloop) -> None: response = await async_client.scenarios.scorers.with_raw_response.create( bash_script="bash_script", - name="name", + type="type", ) assert response.is_closed is True @@ -258,7 +258,7 @@ async def test_raw_response_create(self, async_client: AsyncRunloop) -> None: async def test_streaming_response_create(self, async_client: AsyncRunloop) -> None: async with async_client.scenarios.scorers.with_streaming_response.create( bash_script="bash_script", - name="name", + type="type", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -311,7 +311,7 @@ async def test_method_update(self, async_client: AsyncRunloop) -> None: scorer = await async_client.scenarios.scorers.update( id="id", bash_script="bash_script", - name="name", + type="type", ) assert_matches_type(ScorerUpdateResponse, scorer, path=["response"]) @@ -320,7 +320,7 @@ async def test_raw_response_update(self, async_client: AsyncRunloop) -> None: response = await async_client.scenarios.scorers.with_raw_response.update( id="id", bash_script="bash_script", - name="name", + type="type", ) assert response.is_closed is True @@ -333,7 +333,7 @@ async def test_streaming_response_update(self, async_client: AsyncRunloop) -> No async with async_client.scenarios.scorers.with_streaming_response.update( id="id", bash_script="bash_script", - name="name", + type="type", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -349,7 +349,7 @@ async def test_path_params_update(self, async_client: AsyncRunloop) -> None: await async_client.scenarios.scorers.with_raw_response.update( id="", bash_script="bash_script", - name="name", + type="type", ) @parametrize diff --git a/tests/api_resources/test_devboxes.py b/tests/api_resources/test_devboxes.py index 843c1b21..e3faa298 100644 --- a/tests/api_resources/test_devboxes.py +++ b/tests/api_resources/test_devboxes.py @@ -134,6 +134,53 @@ def test_path_params_retrieve(self, client: Runloop) -> None: "", ) + @parametrize + def test_method_update(self, client: Runloop) -> None: + devbox = client.devboxes.update( + id="id", + ) + assert_matches_type(DevboxView, devbox, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Runloop) -> None: + devbox = client.devboxes.update( + id="id", + metadata={"foo": "string"}, + name="name", + ) + assert_matches_type(DevboxView, devbox, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Runloop) -> None: + response = client.devboxes.with_raw_response.update( + id="id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + devbox = response.parse() + assert_matches_type(DevboxView, devbox, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Runloop) -> None: + with client.devboxes.with_streaming_response.update( + id="id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + devbox = response.parse() + assert_matches_type(DevboxView, devbox, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Runloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.devboxes.with_raw_response.update( + id="", + ) + @parametrize def test_method_list(self, client: Runloop) -> None: devbox = client.devboxes.list() @@ -960,6 +1007,53 @@ async def test_path_params_retrieve(self, async_client: AsyncRunloop) -> None: "", ) + @parametrize + async def test_method_update(self, async_client: AsyncRunloop) -> None: + devbox = await async_client.devboxes.update( + id="id", + ) + assert_matches_type(DevboxView, devbox, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncRunloop) -> None: + devbox = await async_client.devboxes.update( + id="id", + metadata={"foo": "string"}, + name="name", + ) + assert_matches_type(DevboxView, devbox, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncRunloop) -> None: + response = await async_client.devboxes.with_raw_response.update( + id="id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + devbox = await response.parse() + assert_matches_type(DevboxView, devbox, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncRunloop) -> None: + async with async_client.devboxes.with_streaming_response.update( + id="id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + devbox = await response.parse() + assert_matches_type(DevboxView, devbox, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncRunloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.devboxes.with_raw_response.update( + id="", + ) + @parametrize async def test_method_list(self, async_client: AsyncRunloop) -> None: devbox = await async_client.devboxes.list() diff --git a/tests/api_resources/test_scenarios.py b/tests/api_resources/test_scenarios.py index 64ae41c9..78b3cebc 100644 --- a/tests/api_resources/test_scenarios.py +++ b/tests/api_resources/test_scenarios.py @@ -30,6 +30,7 @@ def test_method_create(self, client: Runloop) -> None: "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, } ] @@ -49,8 +50,10 @@ def test_method_create_with_all_params(self, client: Runloop) -> None: "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, "bash_script": "bash_script", + "scorer_params": {}, } ] }, @@ -71,6 +74,7 @@ def test_raw_response_create(self, client: Runloop) -> None: "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, } ] @@ -91,6 +95,7 @@ def test_streaming_response_create(self, client: Runloop) -> None: "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, } ] @@ -263,6 +268,7 @@ async def test_method_create(self, async_client: AsyncRunloop) -> None: "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, } ] @@ -282,8 +288,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) - "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, "bash_script": "bash_script", + "scorer_params": {}, } ] }, @@ -304,6 +312,7 @@ async def test_raw_response_create(self, async_client: AsyncRunloop) -> None: "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, } ] @@ -324,6 +333,7 @@ async def test_streaming_response_create(self, async_client: AsyncRunloop) -> No "scoring_function_parameters": [ { "name": "name", + "type": "type", "weight": 0, } ] diff --git a/tests/test_client.py b/tests/test_client.py index 81c247f7..4e2d14a3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -92,7 +92,7 @@ def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) assert copied.max_retries == 7 - assert self.client.max_retries == 2 + assert self.client.max_retries == 0 copied2 = copied.copy(max_retries=6) assert copied2.max_retries == 6 @@ -738,21 +738,21 @@ class Model(BaseModel): "remaining_retries,retry_after,timeout", [ [3, "20", 20], - [3, "0", 0.5], - [3, "-10", 0.5], + [3, "0", 1], + [3, "-10", 1], [3, "60", 60], - [3, "61", 0.5], + [3, "61", 1], [3, "Fri, 29 Sep 2023 16:26:57 GMT", 20], - [3, "Fri, 29 Sep 2023 16:26:37 GMT", 0.5], - [3, "Fri, 29 Sep 2023 16:26:27 GMT", 0.5], + [3, "Fri, 29 Sep 2023 16:26:37 GMT", 1], + [3, "Fri, 29 Sep 2023 16:26:27 GMT", 1], [3, "Fri, 29 Sep 2023 16:27:37 GMT", 60], - [3, "Fri, 29 Sep 2023 16:27:38 GMT", 0.5], - [3, "99999999999999999999999999999999999", 0.5], - [3, "Zun, 29 Sep 2023 16:26:27 GMT", 0.5], - [3, "", 0.5], - [2, "", 0.5 * 2.0], - [1, "", 0.5 * 4.0], - [-1100, "", 8], # test large number potentially overflowing + [3, "Fri, 29 Sep 2023 16:27:38 GMT", 1], + [3, "99999999999999999999999999999999999", 1], + [3, "Zun, 29 Sep 2023 16:26:27 GMT", 1], + [3, "", 1], + [2, "", 1 * 2.0], + [1, "", 1 * 4.0], + [-1100, "", 10], # test large number potentially overflowing ], ) @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) @@ -762,7 +762,7 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) calculated = client._calculate_retry_timeout(remaining_retries, options, headers) - assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType] + assert calculated == pytest.approx(timeout, 1 * 0.875) # pyright: ignore[reportUnknownMemberType] @mock.patch("runloop_api_client._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url) @@ -909,7 +909,7 @@ def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) assert copied.max_retries == 7 - assert self.client.max_retries == 2 + assert self.client.max_retries == 0 copied2 = copied.copy(max_retries=6) assert copied2.max_retries == 6 @@ -1558,21 +1558,21 @@ class Model(BaseModel): "remaining_retries,retry_after,timeout", [ [3, "20", 20], - [3, "0", 0.5], - [3, "-10", 0.5], + [3, "0", 1], + [3, "-10", 1], [3, "60", 60], - [3, "61", 0.5], + [3, "61", 1], [3, "Fri, 29 Sep 2023 16:26:57 GMT", 20], - [3, "Fri, 29 Sep 2023 16:26:37 GMT", 0.5], - [3, "Fri, 29 Sep 2023 16:26:27 GMT", 0.5], + [3, "Fri, 29 Sep 2023 16:26:37 GMT", 1], + [3, "Fri, 29 Sep 2023 16:26:27 GMT", 1], [3, "Fri, 29 Sep 2023 16:27:37 GMT", 60], - [3, "Fri, 29 Sep 2023 16:27:38 GMT", 0.5], - [3, "99999999999999999999999999999999999", 0.5], - [3, "Zun, 29 Sep 2023 16:26:27 GMT", 0.5], - [3, "", 0.5], - [2, "", 0.5 * 2.0], - [1, "", 0.5 * 4.0], - [-1100, "", 8], # test large number potentially overflowing + [3, "Fri, 29 Sep 2023 16:27:38 GMT", 1], + [3, "99999999999999999999999999999999999", 1], + [3, "Zun, 29 Sep 2023 16:26:27 GMT", 1], + [3, "", 1], + [2, "", 1 * 2.0], + [1, "", 1 * 4.0], + [-1100, "", 10], # test large number potentially overflowing ], ) @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) @@ -1583,7 +1583,7 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) calculated = client._calculate_retry_timeout(remaining_retries, options, headers) - assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType] + assert calculated == pytest.approx(timeout, 1 * 0.875) # pyright: ignore[reportUnknownMemberType] @mock.patch("runloop_api_client._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @pytest.mark.respx(base_url=base_url)