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)