diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
old mode 100644
new mode 100755
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
old mode 100644
new mode 100755
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
old mode 100644
new mode 100755
diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml
old mode 100644
new mode 100755
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
old mode 100644
new mode 100755
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/.python-version b/.python-version
old mode 100644
new mode 100755
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
old mode 100644
new mode 100755
index b0699969f..08e82c45c
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.14"
+ ".": "0.1.0-alpha.15"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
old mode 100644
new mode 100755
index 0169fbd25..f0fee8e9b
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 23
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-ccdd2f1f86705a3cc4e40bc294ca94e0e761f22bc8487955fc2a663c046688b5.yml
+configured_endpoints: 24
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-2085d09cb7954db9bd300c0d93f1f08e25b69906011c0d65e899951880372ef1.yml
diff --git a/Brewfile b/Brewfile
old mode 100644
new mode 100755
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 143fd3ea8..94a00f222 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,28 @@
# Changelog
+## 0.1.0-alpha.15 (2024-08-23)
+
+Full Changelog: [v0.1.0-alpha.14...v0.1.0-alpha.15](https://github.com/runloopai/api-client-python/compare/v0.1.0-alpha.14...v0.1.0-alpha.15)
+
+### Features
+
+* **api:** manual updates ([#117](https://github.com/runloopai/api-client-python/issues/117)) ([5222c74](https://github.com/runloopai/api-client-python/commit/5222c7462dae22befa4cbfe000635660c0b72070))
+* **api:** manual updates ([#118](https://github.com/runloopai/api-client-python/issues/118)) ([2801d62](https://github.com/runloopai/api-client-python/commit/2801d62df46e79a9054a4c32453b46436362aa2c))
+* **api:** OpenAPI spec update via Stainless API ([#106](https://github.com/runloopai/api-client-python/issues/106)) ([977e845](https://github.com/runloopai/api-client-python/commit/977e845bb31245f85aa00e1c0bdd091ed81967df))
+* **api:** OpenAPI spec update via Stainless API ([#110](https://github.com/runloopai/api-client-python/issues/110)) ([dc0bc88](https://github.com/runloopai/api-client-python/commit/dc0bc888d147dce2619d0e0f38897bd1df4372e6))
+* **api:** OpenAPI spec update via Stainless API ([#111](https://github.com/runloopai/api-client-python/issues/111)) ([82a1581](https://github.com/runloopai/api-client-python/commit/82a158114880b0d416ae4e9660926151daf1a60f))
+* **api:** OpenAPI spec update via Stainless API ([#112](https://github.com/runloopai/api-client-python/issues/112)) ([cfddae4](https://github.com/runloopai/api-client-python/commit/cfddae44be11039af98c8d6f570990351c552d9d))
+* **api:** OpenAPI spec update via Stainless API ([#113](https://github.com/runloopai/api-client-python/issues/113)) ([23d90e8](https://github.com/runloopai/api-client-python/commit/23d90e8d22775abcaf90e44fa7b9dc112d6d36ad))
+* **api:** OpenAPI spec update via Stainless API ([#114](https://github.com/runloopai/api-client-python/issues/114)) ([f754530](https://github.com/runloopai/api-client-python/commit/f7545300ecc975f555178729c987fa506d8c0dde))
+* **api:** OpenAPI spec update via Stainless API ([#115](https://github.com/runloopai/api-client-python/issues/115)) ([b5200de](https://github.com/runloopai/api-client-python/commit/b5200dedec44c8785daf06cb1acfa3b6909d8361))
+* **api:** OpenAPI spec update via Stainless API ([#120](https://github.com/runloopai/api-client-python/issues/120)) ([e432b64](https://github.com/runloopai/api-client-python/commit/e432b64ee28bf061878cba1bf76285d847cd3ce7))
+
+
+### Chores
+
+* **ci:** also run pydantic v1 tests ([#109](https://github.com/runloopai/api-client-python/issues/109)) ([23009f0](https://github.com/runloopai/api-client-python/commit/23009f032c59a5ab216c7602cabfe63253dd33b5))
+* **client:** fix parsing union responses when non-json is returned ([#108](https://github.com/runloopai/api-client-python/issues/108)) ([9133e9b](https://github.com/runloopai/api-client-python/commit/9133e9b87be8d363742b08f2f829699657982a6e))
+
## 0.1.0-alpha.14 (2024-08-16)
Full Changelog: [v0.1.0-alpha.13...v0.1.0-alpha.14](https://github.com/runloopai/api-client-python/compare/v0.1.0-alpha.13...v0.1.0-alpha.14)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
old mode 100644
new mode 100755
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index c30cc313a..8dc4c7e51
--- a/README.md
+++ b/README.md
@@ -118,7 +118,7 @@ Error codes are as followed:
### Retries
-Certain errors are automatically retried 0 times by default, with a short exponential backoff.
+Certain errors are automatically retried 2 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/SECURITY.md b/SECURITY.md
old mode 100644
new mode 100755
diff --git a/api.md b/api.md
old mode 100644
new mode 100755
index 6f52516ae..6bae20322
--- a/api.md
+++ b/api.md
@@ -49,9 +49,11 @@ Types:
```python
from runloop_api_client.types import (
+ DevboxAsyncExecutionDetailView,
DevboxExecutionDetailView,
DevboxListView,
DevboxView,
+ DevboxCreateSSHKeyResponse,
DevboxReadFileContentsResponse,
DevboxUploadFileResponse,
)
@@ -62,12 +64,13 @@ Methods:
- client.devboxes.create(\*\*params) -> DevboxView
- client.devboxes.retrieve(id) -> DevboxView
- client.devboxes.list(\*\*params) -> DevboxListView
-- client.devboxes.execute_sync(id, \*\*params) -> DevboxExecutionDetailView
-- client.devboxes.read_file(id, \*\*params) -> DevboxExecutionDetailView
+- client.devboxes.create_ssh_key(id) -> DevboxCreateSSHKeyResponse
+- client.devboxes.execute_async(id, \*\*params) -> DevboxAsyncExecutionDetailView
+- client.devboxes.execute_sync(id, \*\*params) -> DevboxExecutionDetailView
- client.devboxes.read_file_contents(id, \*\*params) -> str
- client.devboxes.shutdown(id) -> DevboxView
- client.devboxes.upload_file(id, \*\*params) -> object
-- client.devboxes.write_file(id, \*\*params) -> DevboxExecutionDetailView
+- client.devboxes.write_file(id, \*\*params) -> DevboxExecutionDetailView
## Logs
@@ -81,6 +84,23 @@ Methods:
- client.devboxes.logs.list(id) -> DevboxLogsListView
+## Executions
+
+Types:
+
+```python
+from runloop_api_client.types.devboxes import (
+ DevboxAsyncExecutionDetailView,
+ DevboxExecutionDetailView,
+ DevboxLogsListView,
+)
+```
+
+Methods:
+
+- client.devboxes.executions.execute_async(id, \*\*params) -> DevboxAsyncExecutionDetailView
+- client.devboxes.executions.execute_sync(id, \*\*params) -> DevboxExecutionDetailView
+
# Functions
Types:
diff --git a/bin/check-release-environment b/bin/check-release-environment
old mode 100644
new mode 100755
diff --git a/examples/.keep b/examples/.keep
old mode 100644
new mode 100755
diff --git a/mypy.ini b/mypy.ini
old mode 100644
new mode 100755
diff --git a/noxfile.py b/noxfile.py
old mode 100644
new mode 100755
diff --git a/pyproject.toml b/pyproject.toml
old mode 100644
new mode 100755
index 22380a1af..a0b32864f
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "runloop_api_client"
-version = "0.1.0-alpha.14"
+version = "0.1.0-alpha.15"
description = "The official Python library for the runloop API"
dynamic = ["readme"]
license = "MIT"
diff --git a/release-please-config.json b/release-please-config.json
old mode 100644
new mode 100755
diff --git a/requirements-dev.lock b/requirements-dev.lock
old mode 100644
new mode 100755
diff --git a/requirements.lock b/requirements.lock
old mode 100644
new mode 100755
diff --git a/scripts/test b/scripts/test
index b3ace9013..4fa5698b8 100755
--- a/scripts/test
+++ b/scripts/test
@@ -54,3 +54,6 @@ fi
echo "==> Running tests"
rye run pytest "$@"
+
+echo "==> Running Pydantic v1 tests"
+rye run nox -s test-pydantic-v1 -- "$@"
diff --git a/scripts/utils/ruffen-docs.py b/scripts/utils/ruffen-docs.py
old mode 100644
new mode 100755
diff --git a/src/runloop/lib/.keep b/src/runloop/lib/.keep
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/__init__.py b/src/runloop_api_client/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_base_client.py b/src/runloop_api_client/_base_client.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_client.py b/src/runloop_api_client/_client.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_compat.py b/src/runloop_api_client/_compat.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_constants.py b/src/runloop_api_client/_constants.py
old mode 100644
new mode 100755
index 8e36fea12..a2ac3b6f3
--- 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.0, connect=5.0)
-DEFAULT_MAX_RETRIES = 0
+DEFAULT_MAX_RETRIES = 2
DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20)
-INITIAL_RETRY_DELAY = 1.0
-MAX_RETRY_DELAY = 5.0
+INITIAL_RETRY_DELAY = 0.5
+MAX_RETRY_DELAY = 8.0
diff --git a/src/runloop_api_client/_exceptions.py b/src/runloop_api_client/_exceptions.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_files.py b/src/runloop_api_client/_files.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_models.py b/src/runloop_api_client/_models.py
old mode 100644
new mode 100755
index 5148d5a7b..d386eaa3a
--- a/src/runloop_api_client/_models.py
+++ b/src/runloop_api_client/_models.py
@@ -380,6 +380,8 @@ def is_basemodel(type_: type) -> bool:
def is_basemodel_type(type_: type) -> TypeGuard[type[BaseModel] | type[GenericModel]]:
origin = get_origin(type_) or type_
+ if not inspect.isclass(origin):
+ return False
return issubclass(origin, BaseModel) or issubclass(origin, GenericModel)
diff --git a/src/runloop_api_client/_qs.py b/src/runloop_api_client/_qs.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_resource.py b/src/runloop_api_client/_resource.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_response.py b/src/runloop_api_client/_response.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_streaming.py b/src/runloop_api_client/_streaming.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_types.py b/src/runloop_api_client/_types.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/__init__.py b/src/runloop_api_client/_utils/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_logs.py b/src/runloop_api_client/_utils/_logs.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_proxy.py b/src/runloop_api_client/_utils/_proxy.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_reflection.py b/src/runloop_api_client/_utils/_reflection.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_streams.py b/src/runloop_api_client/_utils/_streams.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_sync.py b/src/runloop_api_client/_utils/_sync.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_transform.py b/src/runloop_api_client/_utils/_transform.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_typing.py b/src/runloop_api_client/_utils/_typing.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_utils/_utils.py b/src/runloop_api_client/_utils/_utils.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/_version.py b/src/runloop_api_client/_version.py
old mode 100644
new mode 100755
index 70a399d94..b1688be6c
--- a/src/runloop_api_client/_version.py
+++ b/src/runloop_api_client/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "runloop_api_client"
-__version__ = "0.1.0-alpha.14" # x-release-please-version
+__version__ = "0.1.0-alpha.15" # x-release-please-version
diff --git a/src/runloop_api_client/lib/.keep b/src/runloop_api_client/lib/.keep
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/py.typed b/src/runloop_api_client/py.typed
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/__init__.py b/src/runloop_api_client/resources/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/blueprints.py b/src/runloop_api_client/resources/blueprints.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/deployments.py b/src/runloop_api_client/resources/deployments.py
new file mode 100755
index 000000000..70abbe237
--- /dev/null
+++ b/src/runloop_api_client/resources/deployments.py
@@ -0,0 +1,488 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..types import deployment_get_params
+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 .._base_client import make_request_options
+from ..types.deployment_get_response import DeploymentGetResponse
+from ..types.deployment_logs_response import DeploymentLogsResponse
+from ..types.deployment_tail_response import DeploymentTailResponse
+from ..types.deployment_redeploy_response import DeploymentRedeployResponse
+from ..types.deployment_retrieve_response import DeploymentRetrieveResponse
+
+__all__ = ["DeploymentsResource", "AsyncDeploymentsResource"]
+
+
+class DeploymentsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> DeploymentsResourceWithRawResponse:
+ return DeploymentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DeploymentsResourceWithStreamingResponse:
+ return DeploymentsResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ deployment_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,
+ ) -> DeploymentRetrieveResponse:
+ """
+ Get details of a deployment
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return self._get(
+ f"/v1/deployments/{deployment_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentRetrieveResponse,
+ )
+
+ def get(
+ self,
+ *,
+ limit: str | 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,
+ ) -> DeploymentGetResponse:
+ """
+ Get list of all deployments for the authenticated user.
+
+ Args:
+ limit: Page Limit
+
+ starting_after: Load the next page starting after the given token.
+
+ 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(
+ "/v1/deployments",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "starting_after": starting_after,
+ },
+ deployment_get_params.DeploymentGetParams,
+ ),
+ ),
+ cast_to=DeploymentGetResponse,
+ )
+
+ def logs(
+ self,
+ deployment_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,
+ ) -> DeploymentLogsResponse:
+ """
+ Get list of all logs from a deployment.
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return self._get(
+ f"/v1/deployments/{deployment_id}/logs",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentLogsResponse,
+ )
+
+ def redeploy(
+ self,
+ deployment_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,
+ ) -> DeploymentRedeployResponse:
+ """
+ Creates a deployment for a previously deployed version.
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return self._post(
+ f"/v1/deployments/{deployment_id}/redeploy",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentRedeployResponse,
+ )
+
+ def tail(
+ self,
+ deployment_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,
+ ) -> DeploymentTailResponse:
+ """
+ Tails the logs for the given deployment with SSE streaming
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return self._get(
+ f"/v1/deployments/{deployment_id}/logs/tail",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentTailResponse,
+ )
+
+
+class AsyncDeploymentsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncDeploymentsResourceWithRawResponse:
+ return AsyncDeploymentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDeploymentsResourceWithStreamingResponse:
+ return AsyncDeploymentsResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ deployment_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,
+ ) -> DeploymentRetrieveResponse:
+ """
+ Get details of a deployment
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return await self._get(
+ f"/v1/deployments/{deployment_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentRetrieveResponse,
+ )
+
+ async def get(
+ self,
+ *,
+ limit: str | 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,
+ ) -> DeploymentGetResponse:
+ """
+ Get list of all deployments for the authenticated user.
+
+ Args:
+ limit: Page Limit
+
+ starting_after: Load the next page starting after the given token.
+
+ 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 await self._get(
+ "/v1/deployments",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "limit": limit,
+ "starting_after": starting_after,
+ },
+ deployment_get_params.DeploymentGetParams,
+ ),
+ ),
+ cast_to=DeploymentGetResponse,
+ )
+
+ async def logs(
+ self,
+ deployment_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,
+ ) -> DeploymentLogsResponse:
+ """
+ Get list of all logs from a deployment.
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return await self._get(
+ f"/v1/deployments/{deployment_id}/logs",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentLogsResponse,
+ )
+
+ async def redeploy(
+ self,
+ deployment_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,
+ ) -> DeploymentRedeployResponse:
+ """
+ Creates a deployment for a previously deployed version.
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return await self._post(
+ f"/v1/deployments/{deployment_id}/redeploy",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentRedeployResponse,
+ )
+
+ async def tail(
+ self,
+ deployment_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,
+ ) -> DeploymentTailResponse:
+ """
+ Tails the logs for the given deployment with SSE streaming
+
+ 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 deployment_id:
+ raise ValueError(f"Expected a non-empty value for `deployment_id` but received {deployment_id!r}")
+ return await self._get(
+ f"/v1/deployments/{deployment_id}/logs/tail",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DeploymentTailResponse,
+ )
+
+
+class DeploymentsResourceWithRawResponse:
+ def __init__(self, deployments: DeploymentsResource) -> None:
+ self._deployments = deployments
+
+ self.retrieve = to_raw_response_wrapper(
+ deployments.retrieve,
+ )
+ self.get = to_raw_response_wrapper(
+ deployments.get,
+ )
+ self.logs = to_raw_response_wrapper(
+ deployments.logs,
+ )
+ self.redeploy = to_raw_response_wrapper(
+ deployments.redeploy,
+ )
+ self.tail = to_raw_response_wrapper(
+ deployments.tail,
+ )
+
+
+class AsyncDeploymentsResourceWithRawResponse:
+ def __init__(self, deployments: AsyncDeploymentsResource) -> None:
+ self._deployments = deployments
+
+ self.retrieve = async_to_raw_response_wrapper(
+ deployments.retrieve,
+ )
+ self.get = async_to_raw_response_wrapper(
+ deployments.get,
+ )
+ self.logs = async_to_raw_response_wrapper(
+ deployments.logs,
+ )
+ self.redeploy = async_to_raw_response_wrapper(
+ deployments.redeploy,
+ )
+ self.tail = async_to_raw_response_wrapper(
+ deployments.tail,
+ )
+
+
+class DeploymentsResourceWithStreamingResponse:
+ def __init__(self, deployments: DeploymentsResource) -> None:
+ self._deployments = deployments
+
+ self.retrieve = to_streamed_response_wrapper(
+ deployments.retrieve,
+ )
+ self.get = to_streamed_response_wrapper(
+ deployments.get,
+ )
+ self.logs = to_streamed_response_wrapper(
+ deployments.logs,
+ )
+ self.redeploy = to_streamed_response_wrapper(
+ deployments.redeploy,
+ )
+ self.tail = to_streamed_response_wrapper(
+ deployments.tail,
+ )
+
+
+class AsyncDeploymentsResourceWithStreamingResponse:
+ def __init__(self, deployments: AsyncDeploymentsResource) -> None:
+ self._deployments = deployments
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ deployments.retrieve,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ deployments.get,
+ )
+ self.logs = async_to_streamed_response_wrapper(
+ deployments.logs,
+ )
+ self.redeploy = async_to_streamed_response_wrapper(
+ deployments.redeploy,
+ )
+ self.tail = async_to_streamed_response_wrapper(
+ deployments.tail,
+ )
diff --git a/src/runloop_api_client/resources/devboxes/__init__.py b/src/runloop_api_client/resources/devboxes/__init__.py
old mode 100644
new mode 100755
index 814a1ca00..ec7c746ac
--- a/src/runloop_api_client/resources/devboxes/__init__.py
+++ b/src/runloop_api_client/resources/devboxes/__init__.py
@@ -16,6 +16,14 @@
DevboxesResourceWithStreamingResponse,
AsyncDevboxesResourceWithStreamingResponse,
)
+from .executions import (
+ ExecutionsResource,
+ AsyncExecutionsResource,
+ ExecutionsResourceWithRawResponse,
+ AsyncExecutionsResourceWithRawResponse,
+ ExecutionsResourceWithStreamingResponse,
+ AsyncExecutionsResourceWithStreamingResponse,
+)
__all__ = [
"LogsResource",
@@ -24,6 +32,12 @@
"AsyncLogsResourceWithRawResponse",
"LogsResourceWithStreamingResponse",
"AsyncLogsResourceWithStreamingResponse",
+ "ExecutionsResource",
+ "AsyncExecutionsResource",
+ "ExecutionsResourceWithRawResponse",
+ "AsyncExecutionsResourceWithRawResponse",
+ "ExecutionsResourceWithStreamingResponse",
+ "AsyncExecutionsResourceWithStreamingResponse",
"DevboxesResource",
"AsyncDevboxesResource",
"DevboxesResourceWithRawResponse",
diff --git a/src/runloop_api_client/resources/devboxes/devboxes.py b/src/runloop_api_client/resources/devboxes/devboxes.py
old mode 100644
new mode 100755
index 9bdd4b784..a45032569
--- a/src/runloop_api_client/resources/devboxes/devboxes.py
+++ b/src/runloop_api_client/resources/devboxes/devboxes.py
@@ -17,10 +17,10 @@
from ...types import (
devbox_list_params,
devbox_create_params,
- devbox_read_file_params,
devbox_write_file_params,
devbox_upload_file_params,
devbox_execute_sync_params,
+ devbox_execute_async_params,
devbox_read_file_contents_params,
)
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven, FileTypes
@@ -31,6 +31,14 @@
async_maybe_transform,
)
from ..._compat import cached_property
+from .executions import (
+ ExecutionsResource,
+ AsyncExecutionsResource,
+ ExecutionsResourceWithRawResponse,
+ AsyncExecutionsResourceWithRawResponse,
+ ExecutionsResourceWithStreamingResponse,
+ AsyncExecutionsResourceWithStreamingResponse,
+)
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
to_raw_response_wrapper,
@@ -41,7 +49,9 @@
from ..._base_client import make_request_options
from ...types.devbox_view import DevboxView
from ...types.devbox_list_view import DevboxListView
-from ...types.devbox_execution_detail_view import DevboxExecutionDetailView
+from ...types.devbox_create_ssh_key_response import DevboxCreateSSHKeyResponse
+from ...types.devboxes.devbox_execution_detail_view import DevboxExecutionDetailView
+from ...types.devboxes.devbox_async_execution_detail_view import DevboxAsyncExecutionDetailView
__all__ = ["DevboxesResource", "AsyncDevboxesResource"]
@@ -51,6 +61,10 @@ class DevboxesResource(SyncAPIResource):
def logs(self) -> LogsResource:
return LogsResource(self._client)
+ @cached_property
+ def executions(self) -> ExecutionsResource:
+ return ExecutionsResource(self._client)
+
@cached_property
def with_raw_response(self) -> DevboxesResourceWithRawResponse:
return DevboxesResourceWithRawResponse(self)
@@ -68,6 +82,7 @@ def create(
environment_variables: Dict[str, str] | NotGiven = NOT_GIVEN,
file_mounts: Dict[str, str] | NotGiven = NOT_GIVEN,
launch_parameters: devbox_create_params.LaunchParameters | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, str] | NotGiven = NOT_GIVEN,
name: str | NotGiven = NOT_GIVEN,
setup_commands: List[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -99,6 +114,8 @@ def create(
launch_parameters: Parameters to configure the resources and launch time behavior of the Devbox.
+ metadata: User defined metadata to attach to the devbox for organization.
+
name: (Optional) A user specified name to give the Devbox.
setup_commands: (Optional) List of commands needed to set up your Devbox. Examples might include
@@ -123,6 +140,7 @@ def create(
"environment_variables": environment_variables,
"file_mounts": file_mounts,
"launch_parameters": launch_parameters,
+ "metadata": metadata,
"name": name,
"setup_commands": setup_commands,
},
@@ -220,7 +238,40 @@ def list(
cast_to=DevboxListView,
)
- def execute_sync(
+ def create_ssh_key(
+ 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,
+ ) -> DevboxCreateSSHKeyResponse:
+ """
+ Create an SSH key for a devbox by id.
+
+ 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._post(
+ f"/v1/devboxes/{id}/create_ssh_key",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxCreateSSHKeyResponse,
+ )
+
+ def execute_async(
self,
id: str,
*,
@@ -231,9 +282,9 @@ def execute_sync(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> DevboxExecutionDetailView:
+ ) -> DevboxAsyncExecutionDetailView:
"""
- Synchronously execute a command on a devbox
+ Asynchronously execute a command on a devbox
Args:
command: The command to execute on the Devbox.
@@ -249,19 +300,19 @@ def execute_sync(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/v1/devboxes/{id}/execute_sync",
- body=maybe_transform({"command": command}, devbox_execute_sync_params.DevboxExecuteSyncParams),
+ f"/v1/devboxes/{id}/executions/execute_async",
+ body=maybe_transform({"command": command}, devbox_execute_async_params.DevboxExecuteAsyncParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=DevboxExecutionDetailView,
+ cast_to=DevboxAsyncExecutionDetailView,
)
- def read_file(
+ def execute_sync(
self,
id: str,
*,
- file_path: str | NotGiven = NOT_GIVEN,
+ command: 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,
@@ -270,10 +321,10 @@ def read_file(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> DevboxExecutionDetailView:
"""
- Read file contents from a file on given Devbox.
+ Synchronously execute a command on a devbox
Args:
- file_path: The path of the file to read.
+ command: The command to execute on the Devbox.
extra_headers: Send extra headers
@@ -286,8 +337,8 @@ def read_file(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/v1/devboxes/{id}/read_file",
- body=maybe_transform({"file_path": file_path}, devbox_read_file_params.DevboxReadFileParams),
+ f"/v1/devboxes/{id}/execute_sync",
+ body=maybe_transform({"command": command}, devbox_execute_sync_params.DevboxExecuteSyncParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -468,6 +519,10 @@ class AsyncDevboxesResource(AsyncAPIResource):
def logs(self) -> AsyncLogsResource:
return AsyncLogsResource(self._client)
+ @cached_property
+ def executions(self) -> AsyncExecutionsResource:
+ return AsyncExecutionsResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncDevboxesResourceWithRawResponse:
return AsyncDevboxesResourceWithRawResponse(self)
@@ -485,6 +540,7 @@ async def create(
environment_variables: Dict[str, str] | NotGiven = NOT_GIVEN,
file_mounts: Dict[str, str] | NotGiven = NOT_GIVEN,
launch_parameters: devbox_create_params.LaunchParameters | NotGiven = NOT_GIVEN,
+ metadata: Dict[str, str] | NotGiven = NOT_GIVEN,
name: str | NotGiven = NOT_GIVEN,
setup_commands: List[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -516,6 +572,8 @@ async def create(
launch_parameters: Parameters to configure the resources and launch time behavior of the Devbox.
+ metadata: User defined metadata to attach to the devbox for organization.
+
name: (Optional) A user specified name to give the Devbox.
setup_commands: (Optional) List of commands needed to set up your Devbox. Examples might include
@@ -540,6 +598,7 @@ async def create(
"environment_variables": environment_variables,
"file_mounts": file_mounts,
"launch_parameters": launch_parameters,
+ "metadata": metadata,
"name": name,
"setup_commands": setup_commands,
},
@@ -637,7 +696,40 @@ async def list(
cast_to=DevboxListView,
)
- async def execute_sync(
+ async def create_ssh_key(
+ 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,
+ ) -> DevboxCreateSSHKeyResponse:
+ """
+ Create an SSH key for a devbox by id.
+
+ 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._post(
+ f"/v1/devboxes/{id}/create_ssh_key",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxCreateSSHKeyResponse,
+ )
+
+ async def execute_async(
self,
id: str,
*,
@@ -648,9 +740,9 @@ async def execute_sync(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> DevboxExecutionDetailView:
+ ) -> DevboxAsyncExecutionDetailView:
"""
- Synchronously execute a command on a devbox
+ Asynchronously execute a command on a devbox
Args:
command: The command to execute on the Devbox.
@@ -666,19 +758,21 @@ async def execute_sync(
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}/execute_sync",
- body=await async_maybe_transform({"command": command}, devbox_execute_sync_params.DevboxExecuteSyncParams),
+ f"/v1/devboxes/{id}/executions/execute_async",
+ body=await async_maybe_transform(
+ {"command": command}, devbox_execute_async_params.DevboxExecuteAsyncParams
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=DevboxExecutionDetailView,
+ cast_to=DevboxAsyncExecutionDetailView,
)
- async def read_file(
+ async def execute_sync(
self,
id: str,
*,
- file_path: str | NotGiven = NOT_GIVEN,
+ command: 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,
@@ -687,10 +781,10 @@ async def read_file(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> DevboxExecutionDetailView:
"""
- Read file contents from a file on given Devbox.
+ Synchronously execute a command on a devbox
Args:
- file_path: The path of the file to read.
+ command: The command to execute on the Devbox.
extra_headers: Send extra headers
@@ -703,8 +797,8 @@ async def read_file(
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}/read_file",
- body=await async_maybe_transform({"file_path": file_path}, devbox_read_file_params.DevboxReadFileParams),
+ f"/v1/devboxes/{id}/execute_sync",
+ body=await async_maybe_transform({"command": command}, devbox_execute_sync_params.DevboxExecuteSyncParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -893,12 +987,15 @@ def __init__(self, devboxes: DevboxesResource) -> None:
self.list = to_raw_response_wrapper(
devboxes.list,
)
+ self.create_ssh_key = to_raw_response_wrapper(
+ devboxes.create_ssh_key,
+ )
+ self.execute_async = to_raw_response_wrapper(
+ devboxes.execute_async,
+ )
self.execute_sync = to_raw_response_wrapper(
devboxes.execute_sync,
)
- self.read_file = to_raw_response_wrapper(
- devboxes.read_file,
- )
self.read_file_contents = to_raw_response_wrapper(
devboxes.read_file_contents,
)
@@ -916,6 +1013,10 @@ def __init__(self, devboxes: DevboxesResource) -> None:
def logs(self) -> LogsResourceWithRawResponse:
return LogsResourceWithRawResponse(self._devboxes.logs)
+ @cached_property
+ def executions(self) -> ExecutionsResourceWithRawResponse:
+ return ExecutionsResourceWithRawResponse(self._devboxes.executions)
+
class AsyncDevboxesResourceWithRawResponse:
def __init__(self, devboxes: AsyncDevboxesResource) -> None:
@@ -930,12 +1031,15 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
self.list = async_to_raw_response_wrapper(
devboxes.list,
)
+ self.create_ssh_key = async_to_raw_response_wrapper(
+ devboxes.create_ssh_key,
+ )
+ self.execute_async = async_to_raw_response_wrapper(
+ devboxes.execute_async,
+ )
self.execute_sync = async_to_raw_response_wrapper(
devboxes.execute_sync,
)
- self.read_file = async_to_raw_response_wrapper(
- devboxes.read_file,
- )
self.read_file_contents = async_to_raw_response_wrapper(
devboxes.read_file_contents,
)
@@ -953,6 +1057,10 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
def logs(self) -> AsyncLogsResourceWithRawResponse:
return AsyncLogsResourceWithRawResponse(self._devboxes.logs)
+ @cached_property
+ def executions(self) -> AsyncExecutionsResourceWithRawResponse:
+ return AsyncExecutionsResourceWithRawResponse(self._devboxes.executions)
+
class DevboxesResourceWithStreamingResponse:
def __init__(self, devboxes: DevboxesResource) -> None:
@@ -967,12 +1075,15 @@ def __init__(self, devboxes: DevboxesResource) -> None:
self.list = to_streamed_response_wrapper(
devboxes.list,
)
+ self.create_ssh_key = to_streamed_response_wrapper(
+ devboxes.create_ssh_key,
+ )
+ self.execute_async = to_streamed_response_wrapper(
+ devboxes.execute_async,
+ )
self.execute_sync = to_streamed_response_wrapper(
devboxes.execute_sync,
)
- self.read_file = to_streamed_response_wrapper(
- devboxes.read_file,
- )
self.read_file_contents = to_streamed_response_wrapper(
devboxes.read_file_contents,
)
@@ -990,6 +1101,10 @@ def __init__(self, devboxes: DevboxesResource) -> None:
def logs(self) -> LogsResourceWithStreamingResponse:
return LogsResourceWithStreamingResponse(self._devboxes.logs)
+ @cached_property
+ def executions(self) -> ExecutionsResourceWithStreamingResponse:
+ return ExecutionsResourceWithStreamingResponse(self._devboxes.executions)
+
class AsyncDevboxesResourceWithStreamingResponse:
def __init__(self, devboxes: AsyncDevboxesResource) -> None:
@@ -1004,12 +1119,15 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
self.list = async_to_streamed_response_wrapper(
devboxes.list,
)
+ self.create_ssh_key = async_to_streamed_response_wrapper(
+ devboxes.create_ssh_key,
+ )
+ self.execute_async = async_to_streamed_response_wrapper(
+ devboxes.execute_async,
+ )
self.execute_sync = async_to_streamed_response_wrapper(
devboxes.execute_sync,
)
- self.read_file = async_to_streamed_response_wrapper(
- devboxes.read_file,
- )
self.read_file_contents = async_to_streamed_response_wrapper(
devboxes.read_file_contents,
)
@@ -1026,3 +1144,7 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
@cached_property
def logs(self) -> AsyncLogsResourceWithStreamingResponse:
return AsyncLogsResourceWithStreamingResponse(self._devboxes.logs)
+
+ @cached_property
+ def executions(self) -> AsyncExecutionsResourceWithStreamingResponse:
+ return AsyncExecutionsResourceWithStreamingResponse(self._devboxes.executions)
diff --git a/src/runloop_api_client/resources/devboxes/executions.py b/src/runloop_api_client/resources/devboxes/executions.py
new file mode 100755
index 000000000..7886822a3
--- /dev/null
+++ b/src/runloop_api_client/resources/devboxes/executions.py
@@ -0,0 +1,245 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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 ..._base_client import make_request_options
+from ...types.devboxes import execution_execute_sync_params, execution_execute_async_params
+from ...types.devboxes.devbox_execution_detail_view import DevboxExecutionDetailView
+from ...types.devboxes.devbox_async_execution_detail_view import DevboxAsyncExecutionDetailView
+
+__all__ = ["ExecutionsResource", "AsyncExecutionsResource"]
+
+
+class ExecutionsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ExecutionsResourceWithRawResponse:
+ return ExecutionsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ExecutionsResourceWithStreamingResponse:
+ return ExecutionsResourceWithStreamingResponse(self)
+
+ def execute_async(
+ self,
+ id: str,
+ *,
+ command: 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,
+ ) -> DevboxAsyncExecutionDetailView:
+ """
+ Asynchronously execute a command on a devbox
+
+ Args:
+ command: The command to execute on 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
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ f"/v1/devboxes/{id}/executions/execute_async",
+ body=maybe_transform({"command": command}, execution_execute_async_params.ExecutionExecuteAsyncParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxAsyncExecutionDetailView,
+ )
+
+ def execute_sync(
+ self,
+ id: str,
+ *,
+ command: 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,
+ ) -> DevboxExecutionDetailView:
+ """
+ Synchronously execute a command on a devbox
+
+ Args:
+ command: The command to execute on 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
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ f"/v1/devboxes/{id}/execute_sync",
+ body=maybe_transform({"command": command}, execution_execute_sync_params.ExecutionExecuteSyncParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxExecutionDetailView,
+ )
+
+
+class AsyncExecutionsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncExecutionsResourceWithRawResponse:
+ return AsyncExecutionsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncExecutionsResourceWithStreamingResponse:
+ return AsyncExecutionsResourceWithStreamingResponse(self)
+
+ async def execute_async(
+ self,
+ id: str,
+ *,
+ command: 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,
+ ) -> DevboxAsyncExecutionDetailView:
+ """
+ Asynchronously execute a command on a devbox
+
+ Args:
+ command: The command to execute on 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
+ """
+ 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}/executions/execute_async",
+ body=await async_maybe_transform(
+ {"command": command}, execution_execute_async_params.ExecutionExecuteAsyncParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxAsyncExecutionDetailView,
+ )
+
+ async def execute_sync(
+ self,
+ id: str,
+ *,
+ command: 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,
+ ) -> DevboxExecutionDetailView:
+ """
+ Synchronously execute a command on a devbox
+
+ Args:
+ command: The command to execute on 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
+ """
+ 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}/execute_sync",
+ body=await async_maybe_transform(
+ {"command": command}, execution_execute_sync_params.ExecutionExecuteSyncParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxExecutionDetailView,
+ )
+
+
+class ExecutionsResourceWithRawResponse:
+ def __init__(self, executions: ExecutionsResource) -> None:
+ self._executions = executions
+
+ self.execute_async = to_raw_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = to_raw_response_wrapper(
+ executions.execute_sync,
+ )
+
+
+class AsyncExecutionsResourceWithRawResponse:
+ def __init__(self, executions: AsyncExecutionsResource) -> None:
+ self._executions = executions
+
+ self.execute_async = async_to_raw_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = async_to_raw_response_wrapper(
+ executions.execute_sync,
+ )
+
+
+class ExecutionsResourceWithStreamingResponse:
+ def __init__(self, executions: ExecutionsResource) -> None:
+ self._executions = executions
+
+ self.execute_async = to_streamed_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = to_streamed_response_wrapper(
+ executions.execute_sync,
+ )
+
+
+class AsyncExecutionsResourceWithStreamingResponse:
+ def __init__(self, executions: AsyncExecutionsResource) -> None:
+ self._executions = executions
+
+ self.execute_async = async_to_streamed_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = async_to_streamed_response_wrapper(
+ executions.execute_sync,
+ )
diff --git a/src/runloop_api_client/resources/devboxes/logs.py b/src/runloop_api_client/resources/devboxes/logs.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/functions/__init__.py b/src/runloop_api_client/resources/functions/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/functions/functions.py b/src/runloop_api_client/resources/functions/functions.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/functions/invocations.py b/src/runloop_api_client/resources/functions/invocations.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/projects/__init__.py b/src/runloop_api_client/resources/projects/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/projects/logs.py b/src/runloop_api_client/resources/projects/logs.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/resources/projects/projects.py b/src/runloop_api_client/resources/projects/projects.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/__init__.py b/src/runloop_api_client/types/__init__.py
old mode 100644
new mode 100755
index 616342b9e..c24af1bd1
--- a/src/runloop_api_client/types/__init__.py
+++ b/src/runloop_api_client/types/__init__.py
@@ -20,16 +20,16 @@
from .code_mount_parameters import CodeMountParameters as CodeMountParameters
from .blueprint_preview_view import BlueprintPreviewView as BlueprintPreviewView
from .blueprint_create_params import BlueprintCreateParams as BlueprintCreateParams
-from .devbox_read_file_params import DevboxReadFileParams as DevboxReadFileParams
from .blueprint_preview_params import BlueprintPreviewParams as BlueprintPreviewParams
from .devbox_write_file_params import DevboxWriteFileParams as DevboxWriteFileParams
from .devbox_upload_file_params import DevboxUploadFileParams as DevboxUploadFileParams
from .blueprint_build_parameters import BlueprintBuildParameters as BlueprintBuildParameters
from .devbox_execute_sync_params import DevboxExecuteSyncParams as DevboxExecuteSyncParams
from .code_mount_parameters_param import CodeMountParametersParam as CodeMountParametersParam
+from .devbox_execute_async_params import DevboxExecuteAsyncParams as DevboxExecuteAsyncParams
from .function_invoke_sync_params import FunctionInvokeSyncParams as FunctionInvokeSyncParams
-from .devbox_execution_detail_view import DevboxExecutionDetailView as DevboxExecutionDetailView
from .function_invoke_async_params import FunctionInvokeAsyncParams as FunctionInvokeAsyncParams
from .blueprint_build_logs_list_view import BlueprintBuildLogsListView as BlueprintBuildLogsListView
+from .devbox_create_ssh_key_response import DevboxCreateSSHKeyResponse as DevboxCreateSSHKeyResponse
from .devbox_read_file_contents_params import DevboxReadFileContentsParams as DevboxReadFileContentsParams
from .devbox_read_file_contents_response import DevboxReadFileContentsResponse as DevboxReadFileContentsResponse
diff --git a/src/runloop_api_client/types/blueprint_build_log.py b/src/runloop_api_client/types/blueprint_build_log.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_build_logs_list_view.py b/src/runloop_api_client/types/blueprint_build_logs_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_build_parameters.py b/src/runloop_api_client/types/blueprint_build_parameters.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_create_params.py b/src/runloop_api_client/types/blueprint_create_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_list_params.py b/src/runloop_api_client/types/blueprint_list_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_list_view.py b/src/runloop_api_client/types/blueprint_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_preview_params.py b/src/runloop_api_client/types/blueprint_preview_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_preview_view.py b/src/runloop_api_client/types/blueprint_preview_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/blueprint_view.py b/src/runloop_api_client/types/blueprint_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/code_mount_parameters.py b/src/runloop_api_client/types/code_mount_parameters.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/code_mount_parameters_param.py b/src/runloop_api_client/types/code_mount_parameters_param.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/deployment_get_params.py b/src/runloop_api_client/types/deployment_get_params.py
new file mode 100755
index 000000000..c4c564b6b
--- /dev/null
+++ b/src/runloop_api_client/types/deployment_get_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["DeploymentGetParams"]
+
+
+class DeploymentGetParams(TypedDict, total=False):
+ limit: str
+ """Page Limit"""
+
+ starting_after: str
+ """Load the next page starting after the given token."""
diff --git a/src/runloop_api_client/types/deployment_get_response.py b/src/runloop_api_client/types/deployment_get_response.py
new file mode 100755
index 000000000..e291ac77f
--- /dev/null
+++ b/src/runloop_api_client/types/deployment_get_response.py
@@ -0,0 +1,59 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DeploymentGetResponse", "Deployment"]
+
+
+class Deployment(BaseModel):
+ id: Optional[str] = None
+ """ID of the deployment."""
+
+ deploy_commit_message: Optional[str] = None
+ """Associated Commit Message"""
+
+ deploy_commit_sha: Optional[str] = None
+ """Associated Commit Sha"""
+
+ deploy_commit_time_ms: Optional[int] = None
+ """Associated Commit Time"""
+
+ deploy_end_time_ms: Optional[int] = None
+ """Time the Deploy completed (Unix timestamp milliseconds)."""
+
+ deploy_start_time_ms: Optional[int] = None
+ """Time the Deploy was started (Unix timestamp milliseconds)."""
+
+ deployed_functions: Optional[List[str]] = None
+ """The list of deployed functions."""
+
+ failure_code: Optional[str] = None
+ """
+ Failure code (generic_failure | git_clone_failure | not_runloop_repo |
+ secrets_failure | provision_failure | runtime_failure). Only set on
+ deploy_failed.
+ """
+
+ failure_message: Optional[str] = None
+ """Failure message"""
+
+ project_name: Optional[str] = None
+ """Project name associated with the deployment."""
+
+ redeploy_of: Optional[str] = None
+ """ID of original deployment this is redeployment for."""
+
+ status: Optional[Literal["scheduled", "skipped", "in_progress", "failed", "deployed"]] = None
+ """Status of the deploy."""
+
+
+class DeploymentGetResponse(BaseModel):
+ deployments: Optional[List[Deployment]] = None
+ """List of projects matching given query."""
+
+ has_more: Optional[bool] = None
+
+ total_count: Optional[int] = None
diff --git a/src/runloop_api_client/types/deployment_logs_response.py b/src/runloop_api_client/types/deployment_logs_response.py
new file mode 100755
index 000000000..ccd2ec3da
--- /dev/null
+++ b/src/runloop_api_client/types/deployment_logs_response.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+
+__all__ = ["DeploymentLogsResponse", "Log"]
+
+
+class Log(BaseModel):
+ level: Optional[str] = None
+ """Log line severity level."""
+
+ message: Optional[str] = None
+ """Log line message."""
+
+ timestamp_ms: Optional[int] = None
+ """Time of log (Unix timestamp milliseconds)."""
+
+
+class DeploymentLogsResponse(BaseModel):
+ deployment_id: Optional[str] = None
+ """ID of the given deployment."""
+
+ logs: Optional[List[Log]] = None
+ """List of logs for the given deployment."""
diff --git a/src/runloop_api_client/types/deployment_redeploy_response.py b/src/runloop_api_client/types/deployment_redeploy_response.py
new file mode 100755
index 000000000..679938a26
--- /dev/null
+++ b/src/runloop_api_client/types/deployment_redeploy_response.py
@@ -0,0 +1,50 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DeploymentRedeployResponse"]
+
+
+class DeploymentRedeployResponse(BaseModel):
+ id: Optional[str] = None
+ """ID of the deployment."""
+
+ deploy_commit_message: Optional[str] = None
+ """Associated Commit Message"""
+
+ deploy_commit_sha: Optional[str] = None
+ """Associated Commit Sha"""
+
+ deploy_commit_time_ms: Optional[int] = None
+ """Associated Commit Time"""
+
+ deploy_end_time_ms: Optional[int] = None
+ """Time the Deploy completed (Unix timestamp milliseconds)."""
+
+ deploy_start_time_ms: Optional[int] = None
+ """Time the Deploy was started (Unix timestamp milliseconds)."""
+
+ deployed_functions: Optional[List[str]] = None
+ """The list of deployed functions."""
+
+ failure_code: Optional[str] = None
+ """
+ Failure code (generic_failure | git_clone_failure | not_runloop_repo |
+ secrets_failure | provision_failure | runtime_failure). Only set on
+ deploy_failed.
+ """
+
+ failure_message: Optional[str] = None
+ """Failure message"""
+
+ project_name: Optional[str] = None
+ """Project name associated with the deployment."""
+
+ redeploy_of: Optional[str] = None
+ """ID of original deployment this is redeployment for."""
+
+ status: Optional[Literal["scheduled", "skipped", "in_progress", "failed", "deployed"]] = None
+ """Status of the deploy."""
diff --git a/src/runloop_api_client/types/deployment_retrieve_response.py b/src/runloop_api_client/types/deployment_retrieve_response.py
new file mode 100755
index 000000000..a2fa1bf41
--- /dev/null
+++ b/src/runloop_api_client/types/deployment_retrieve_response.py
@@ -0,0 +1,50 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DeploymentRetrieveResponse"]
+
+
+class DeploymentRetrieveResponse(BaseModel):
+ id: Optional[str] = None
+ """ID of the deployment."""
+
+ deploy_commit_message: Optional[str] = None
+ """Associated Commit Message"""
+
+ deploy_commit_sha: Optional[str] = None
+ """Associated Commit Sha"""
+
+ deploy_commit_time_ms: Optional[int] = None
+ """Associated Commit Time"""
+
+ deploy_end_time_ms: Optional[int] = None
+ """Time the Deploy completed (Unix timestamp milliseconds)."""
+
+ deploy_start_time_ms: Optional[int] = None
+ """Time the Deploy was started (Unix timestamp milliseconds)."""
+
+ deployed_functions: Optional[List[str]] = None
+ """The list of deployed functions."""
+
+ failure_code: Optional[str] = None
+ """
+ Failure code (generic_failure | git_clone_failure | not_runloop_repo |
+ secrets_failure | provision_failure | runtime_failure). Only set on
+ deploy_failed.
+ """
+
+ failure_message: Optional[str] = None
+ """Failure message"""
+
+ project_name: Optional[str] = None
+ """Project name associated with the deployment."""
+
+ redeploy_of: Optional[str] = None
+ """ID of original deployment this is redeployment for."""
+
+ status: Optional[Literal["scheduled", "skipped", "in_progress", "failed", "deployed"]] = None
+ """Status of the deploy."""
diff --git a/src/runloop_api_client/types/deployment_tail_response.py b/src/runloop_api_client/types/deployment_tail_response.py
new file mode 100755
index 000000000..afd26fc86
--- /dev/null
+++ b/src/runloop_api_client/types/deployment_tail_response.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+
+__all__ = ["DeploymentTailResponse", "Log"]
+
+
+class Log(BaseModel):
+ level: Optional[str] = None
+ """Log line severity level."""
+
+ message: Optional[str] = None
+ """Log line message."""
+
+ timestamp_ms: Optional[int] = None
+ """Time of log (Unix timestamp milliseconds)."""
+
+
+class DeploymentTailResponse(BaseModel):
+ deployment_id: Optional[str] = None
+ """ID of the given deployment."""
+
+ logs: Optional[List[Log]] = None
+ """List of logs for the given deployment."""
diff --git a/src/runloop_api_client/types/devbox_create_params.py b/src/runloop_api_client/types/devbox_create_params.py
old mode 100644
new mode 100755
index 80cd31ef3..61bb1453a
--- a/src/runloop_api_client/types/devbox_create_params.py
+++ b/src/runloop_api_client/types/devbox_create_params.py
@@ -40,6 +40,9 @@ class DevboxCreateParams(TypedDict, total=False):
launch_parameters: LaunchParameters
"""Parameters to configure the resources and launch time behavior of the Devbox."""
+ metadata: Dict[str, str]
+ """User defined metadata to attach to the devbox for organization."""
+
name: str
"""(Optional) A user specified name to give the Devbox."""
diff --git a/src/runloop_api_client/types/devbox_create_ssh_key_response.py b/src/runloop_api_client/types/devbox_create_ssh_key_response.py
new file mode 100755
index 000000000..3f8c7c366
--- /dev/null
+++ b/src/runloop_api_client/types/devbox_create_ssh_key_response.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+
+__all__ = ["DevboxCreateSSHKeyResponse"]
+
+
+class DevboxCreateSSHKeyResponse(BaseModel):
+ id: Optional[str] = None
+ """The id of the Devbox."""
+
+ ssh_private_key: Optional[str] = None
+ """The ssh private key, in PEM format."""
+
+ url: Optional[str] = None
+ """The url of the Devbox."""
diff --git a/src/runloop_api_client/types/devbox_execute_async_params.py b/src/runloop_api_client/types/devbox_execute_async_params.py
new file mode 100755
index 000000000..9f5a7a8f4
--- /dev/null
+++ b/src/runloop_api_client/types/devbox_execute_async_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["DevboxExecuteAsyncParams"]
+
+
+class DevboxExecuteAsyncParams(TypedDict, total=False):
+ command: str
+ """The command to execute on the Devbox."""
diff --git a/src/runloop_api_client/types/devbox_execute_sync_params.py b/src/runloop_api_client/types/devbox_execute_sync_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_execution_detail_view.py b/src/runloop_api_client/types/devbox_execution_detail_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_list_params.py b/src/runloop_api_client/types/devbox_list_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_list_response.py b/src/runloop_api_client/types/devbox_list_response.py
new file mode 100755
index 000000000..d56c67f9f
--- /dev/null
+++ b/src/runloop_api_client/types/devbox_list_response.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+from .devbox_view import DevboxView
+
+__all__ = ["DevboxListResponse"]
+
+
+class DevboxListResponse(BaseModel):
+ devboxes: Optional[List[DevboxView]] = None
+ """List of devboxes matching filter."""
+
+ has_more: Optional[bool] = None
+
+ total_count: Optional[int] = None
diff --git a/src/runloop_api_client/types/devbox_list_view.py b/src/runloop_api_client/types/devbox_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_read_file_contents_params.py b/src/runloop_api_client/types/devbox_read_file_contents_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_read_file_contents_response.py b/src/runloop_api_client/types/devbox_read_file_contents_response.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_read_file_params.py b/src/runloop_api_client/types/devbox_read_file_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_upload_file_params.py b/src/runloop_api_client/types/devbox_upload_file_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devbox_view.py b/src/runloop_api_client/types/devbox_view.py
old mode 100644
new mode 100755
index 724ce3372..e2433cc10
--- a/src/runloop_api_client/types/devbox_view.py
+++ b/src/runloop_api_client/types/devbox_view.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import Dict, Optional
from typing_extensions import Literal
from .._models import BaseModel
@@ -21,12 +21,18 @@ class DevboxView(BaseModel):
end_time_ms: Optional[int] = None
"""The time the Devbox finished execution (Unix timestamp milliseconds)."""
+ failure_reason: Optional[Literal["out_of_memory", "out_of_disk", "execution_failed"]] = None
+ """The failure reason if the Devbox failed, if any."""
+
initiator_id: Optional[str] = None
"""The initiator ID of the devbox."""
initiator_type: Optional[Literal["unknown", "api", "invocation"]] = None
"""The initiator of the devbox."""
+ metadata: Optional[Dict[str, str]] = None
+ """The user defined Devbox metadata."""
+
name: Optional[str] = None
"""The name of the Devbox."""
diff --git a/src/runloop_api_client/types/devbox_write_file_params.py b/src/runloop_api_client/types/devbox_write_file_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devboxes/__init__.py b/src/runloop_api_client/types/devboxes/__init__.py
old mode 100644
new mode 100755
index 7baebfdd7..cdfd4886e
--- a/src/runloop_api_client/types/devboxes/__init__.py
+++ b/src/runloop_api_client/types/devboxes/__init__.py
@@ -3,3 +3,7 @@
from __future__ import annotations
from .devbox_logs_list_view import DevboxLogsListView as DevboxLogsListView
+from .devbox_execution_detail_view import DevboxExecutionDetailView as DevboxExecutionDetailView
+from .execution_execute_sync_params import ExecutionExecuteSyncParams as ExecutionExecuteSyncParams
+from .execution_execute_async_params import ExecutionExecuteAsyncParams as ExecutionExecuteAsyncParams
+from .devbox_async_execution_detail_view import DevboxAsyncExecutionDetailView as DevboxAsyncExecutionDetailView
diff --git a/src/runloop_api_client/types/devboxes/devbox_async_execution_detail_view.py b/src/runloop_api_client/types/devboxes/devbox_async_execution_detail_view.py
new file mode 100755
index 000000000..ea60ca7f0
--- /dev/null
+++ b/src/runloop_api_client/types/devboxes/devbox_async_execution_detail_view.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["DevboxAsyncExecutionDetailView"]
+
+
+class DevboxAsyncExecutionDetailView(BaseModel):
+ devbox_id: Optional[str] = None
+ """Devbox id where command was executed."""
+
+ execution_id: Optional[str] = None
+ """Ephemeral id of the execution in progress."""
+
+ exit_status: Optional[int] = None
+ """Exit code of command execution.
+
+ This field will remain unset until the execution has completed.
+ """
+
+ status: Optional[Literal["running", "success", "failure", "canceled"]] = None
+ """Current status of the execution."""
+
+ stderr: Optional[str] = None
+ """Standard error generated by command.
+
+ This field will remain unset until the execution has completed.
+ """
+
+ stdout: Optional[str] = None
+ """Standard out generated by command.
+
+ This field will remain unset until the execution has completed.
+ """
diff --git a/src/runloop_api_client/types/devboxes/devbox_execution_detail_view.py b/src/runloop_api_client/types/devboxes/devbox_execution_detail_view.py
new file mode 100755
index 000000000..eadd60b1d
--- /dev/null
+++ b/src/runloop_api_client/types/devboxes/devbox_execution_detail_view.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["DevboxExecutionDetailView"]
+
+
+class DevboxExecutionDetailView(BaseModel):
+ devbox_id: Optional[str] = None
+ """Devbox id where command was executed."""
+
+ exit_status: Optional[int] = None
+ """Exit status of command execution."""
+
+ stderr: Optional[str] = None
+ """Standard error generated by command."""
+
+ stdout: Optional[str] = None
+ """Standard out generated by command."""
diff --git a/src/runloop_api_client/types/devboxes/devbox_logs_list_view.py b/src/runloop_api_client/types/devboxes/devbox_logs_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/devboxes/execution_execute_async_params.py b/src/runloop_api_client/types/devboxes/execution_execute_async_params.py
new file mode 100755
index 000000000..7878309c5
--- /dev/null
+++ b/src/runloop_api_client/types/devboxes/execution_execute_async_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ExecutionExecuteAsyncParams"]
+
+
+class ExecutionExecuteAsyncParams(TypedDict, total=False):
+ command: str
+ """The command to execute on the Devbox."""
diff --git a/src/runloop_api_client/types/devboxes/execution_execute_sync_params.py b/src/runloop_api_client/types/devboxes/execution_execute_sync_params.py
new file mode 100755
index 000000000..392794ac9
--- /dev/null
+++ b/src/runloop_api_client/types/devboxes/execution_execute_sync_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["ExecutionExecuteSyncParams"]
+
+
+class ExecutionExecuteSyncParams(TypedDict, total=False):
+ command: str
+ """The command to execute on the Devbox."""
diff --git a/src/runloop_api_client/types/devboxes/execution_retrieve_params.py b/src/runloop_api_client/types/devboxes/execution_retrieve_params.py
new file mode 100755
index 000000000..3cafe88fe
--- /dev/null
+++ b/src/runloop_api_client/types/devboxes/execution_retrieve_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ExecutionRetrieveParams"]
+
+
+class ExecutionRetrieveParams(TypedDict, total=False):
+ id: Required[str]
+
+ command: str
+ """The command to execute on the Devbox."""
diff --git a/src/runloop_api_client/types/function_invoke_async_params.py b/src/runloop_api_client/types/function_invoke_async_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/function_invoke_sync_params.py b/src/runloop_api_client/types/function_invoke_sync_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/function_list_view.py b/src/runloop_api_client/types/function_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/functions/__init__.py b/src/runloop_api_client/types/functions/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/functions/function_invocation_list_view.py b/src/runloop_api_client/types/functions/function_invocation_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/functions/invocation_list_params.py b/src/runloop_api_client/types/functions/invocation_list_params.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/functions/invocation_logs_response.py b/src/runloop_api_client/types/functions/invocation_logs_response.py
new file mode 100755
index 000000000..240b32c4a
--- /dev/null
+++ b/src/runloop_api_client/types/functions/invocation_logs_response.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ..._models import BaseModel
+
+__all__ = ["InvocationLogsResponse", "Log"]
+
+
+class Log(BaseModel):
+ level: Optional[str] = None
+ """Log line severity level."""
+
+ message: Optional[str] = None
+ """Log line message."""
+
+ timestamp_ms: Optional[int] = None
+ """Time of log (Unix timestamp milliseconds)."""
+
+
+class InvocationLogsResponse(BaseModel):
+ invocation_id: Optional[str] = None
+ """ID of the invocation."""
+
+ logs: Optional[List[Log]] = None
+ """List of logs for the given invocation."""
diff --git a/src/runloop_api_client/types/project_list_view.py b/src/runloop_api_client/types/project_list_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/projects/__init__.py b/src/runloop_api_client/types/projects/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/resource_size.py b/src/runloop_api_client/types/resource_size.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/shared/__init__.py b/src/runloop_api_client/types/shared/__init__.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/shared/function_invocation_execution_detail_view.py b/src/runloop_api_client/types/shared/function_invocation_execution_detail_view.py
old mode 100644
new mode 100755
diff --git a/src/runloop_api_client/types/shared/project_logs_view.py b/src/runloop_api_client/types/shared/project_logs_view.py
old mode 100644
new mode 100755
diff --git a/tests/__init__.py b/tests/__init__.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/__init__.py b/tests/api_resources/__init__.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/devboxes/__init__.py b/tests/api_resources/devboxes/__init__.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/devboxes/test_executions.py b/tests/api_resources/devboxes/test_executions.py
new file mode 100755
index 000000000..540e32771
--- /dev/null
+++ b/tests/api_resources/devboxes/test_executions.py
@@ -0,0 +1,209 @@
+# 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.devboxes import (
+ DevboxExecutionDetailView,
+ DevboxAsyncExecutionDetailView,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestExecutions:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_execute_async(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.execute_async(
+ id="id",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_method_execute_async_with_all_params(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.execute_async(
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_raw_response_execute_async(self, client: Runloop) -> None:
+ response = client.devboxes.executions.with_raw_response.execute_async(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = response.parse()
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_streaming_response_execute_async(self, client: Runloop) -> None:
+ with client.devboxes.executions.with_streaming_response.execute_async(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ execution = response.parse()
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_execute_async(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.devboxes.executions.with_raw_response.execute_async(
+ id="",
+ )
+
+ @parametrize
+ def test_method_execute_sync(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.execute_sync(
+ id="id",
+ )
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_method_execute_sync_with_all_params(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.execute_sync(
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_raw_response_execute_sync(self, client: Runloop) -> None:
+ response = client.devboxes.executions.with_raw_response.execute_sync(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = response.parse()
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_streaming_response_execute_sync(self, client: Runloop) -> None:
+ with client.devboxes.executions.with_streaming_response.execute_sync(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ execution = response.parse()
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_execute_sync(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.devboxes.executions.with_raw_response.execute_sync(
+ id="",
+ )
+
+
+class TestAsyncExecutions:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_execute_async(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.execute_async(
+ id="id",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_method_execute_async_with_all_params(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.execute_async(
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_raw_response_execute_async(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.executions.with_raw_response.execute_async(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = await response.parse()
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_execute_async(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.executions.with_streaming_response.execute_async(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ execution = await response.parse()
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_execute_async(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.execute_async(
+ id="",
+ )
+
+ @parametrize
+ async def test_method_execute_sync(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.execute_sync(
+ id="id",
+ )
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_method_execute_sync_with_all_params(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.execute_sync(
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_raw_response_execute_sync(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.executions.with_raw_response.execute_sync(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = await response.parse()
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_execute_sync(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.executions.with_streaming_response.execute_sync(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ execution = await response.parse()
+ assert_matches_type(DevboxExecutionDetailView, execution, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_execute_sync(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.execute_sync(
+ id="",
+ )
diff --git a/tests/api_resources/devboxes/test_logs.py b/tests/api_resources/devboxes/test_logs.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/functions/__init__.py b/tests/api_resources/functions/__init__.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/functions/test_invocations.py b/tests/api_resources/functions/test_invocations.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/projects/__init__.py b/tests/api_resources/projects/__init__.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/projects/test_logs.py b/tests/api_resources/projects/test_logs.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/test_blueprints.py b/tests/api_resources/test_blueprints.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/test_deployments.py b/tests/api_resources/test_deployments.py
new file mode 100755
index 000000000..1c1c11f74
--- /dev/null
+++ b/tests/api_resources/test_deployments.py
@@ -0,0 +1,406 @@
+# 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 (
+ DeploymentGetResponse,
+ DeploymentLogsResponse,
+ DeploymentTailResponse,
+ DeploymentRedeployResponse,
+ DeploymentRetrieveResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestDeployments:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_retrieve(self, client: Runloop) -> None:
+ deployment = client.deployments.retrieve(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Runloop) -> None:
+ response = client.deployments.with_raw_response.retrieve(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = response.parse()
+ assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Runloop) -> None:
+ with client.deployments.with_streaming_response.retrieve(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = response.parse()
+ assert_matches_type(DeploymentRetrieveResponse, deployment, 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 `deployment_id` but received ''"):
+ client.deployments.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Runloop) -> None:
+ deployment = client.deployments.get()
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_method_get_with_all_params(self, client: Runloop) -> None:
+ deployment = client.deployments.get(
+ limit="limit",
+ starting_after="starting_after",
+ )
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Runloop) -> None:
+ response = client.deployments.with_raw_response.get()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = response.parse()
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Runloop) -> None:
+ with client.deployments.with_streaming_response.get() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = response.parse()
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_method_logs(self, client: Runloop) -> None:
+ deployment = client.deployments.logs(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentLogsResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_raw_response_logs(self, client: Runloop) -> None:
+ response = client.deployments.with_raw_response.logs(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = response.parse()
+ assert_matches_type(DeploymentLogsResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_streaming_response_logs(self, client: Runloop) -> None:
+ with client.deployments.with_streaming_response.logs(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = response.parse()
+ assert_matches_type(DeploymentLogsResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_logs(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"):
+ client.deployments.with_raw_response.logs(
+ "",
+ )
+
+ @parametrize
+ def test_method_redeploy(self, client: Runloop) -> None:
+ deployment = client.deployments.redeploy(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentRedeployResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_raw_response_redeploy(self, client: Runloop) -> None:
+ response = client.deployments.with_raw_response.redeploy(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = response.parse()
+ assert_matches_type(DeploymentRedeployResponse, deployment, path=["response"])
+
+ @parametrize
+ def test_streaming_response_redeploy(self, client: Runloop) -> None:
+ with client.deployments.with_streaming_response.redeploy(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = response.parse()
+ assert_matches_type(DeploymentRedeployResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_redeploy(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"):
+ client.deployments.with_raw_response.redeploy(
+ "",
+ )
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ def test_method_tail(self, client: Runloop) -> None:
+ deployment = client.deployments.tail(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ def test_raw_response_tail(self, client: Runloop) -> None:
+ response = client.deployments.with_raw_response.tail(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = response.parse()
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ def test_streaming_response_tail(self, client: Runloop) -> None:
+ with client.deployments.with_streaming_response.tail(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = response.parse()
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ def test_path_params_tail(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"):
+ client.deployments.with_raw_response.tail(
+ "",
+ )
+
+
+class TestAsyncDeployments:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncRunloop) -> None:
+ deployment = await async_client.deployments.retrieve(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.deployments.with_raw_response.retrieve(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = await response.parse()
+ assert_matches_type(DeploymentRetrieveResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncRunloop) -> None:
+ async with async_client.deployments.with_streaming_response.retrieve(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = await response.parse()
+ assert_matches_type(DeploymentRetrieveResponse, deployment, 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 `deployment_id` but received ''"):
+ await async_client.deployments.with_raw_response.retrieve(
+ "",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncRunloop) -> None:
+ deployment = await async_client.deployments.get()
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_method_get_with_all_params(self, async_client: AsyncRunloop) -> None:
+ deployment = await async_client.deployments.get(
+ limit="limit",
+ starting_after="starting_after",
+ )
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.deployments.with_raw_response.get()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = await response.parse()
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncRunloop) -> None:
+ async with async_client.deployments.with_streaming_response.get() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = await response.parse()
+ assert_matches_type(DeploymentGetResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_method_logs(self, async_client: AsyncRunloop) -> None:
+ deployment = await async_client.deployments.logs(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentLogsResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_raw_response_logs(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.deployments.with_raw_response.logs(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = await response.parse()
+ assert_matches_type(DeploymentLogsResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_logs(self, async_client: AsyncRunloop) -> None:
+ async with async_client.deployments.with_streaming_response.logs(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = await response.parse()
+ assert_matches_type(DeploymentLogsResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_logs(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"):
+ await async_client.deployments.with_raw_response.logs(
+ "",
+ )
+
+ @parametrize
+ async def test_method_redeploy(self, async_client: AsyncRunloop) -> None:
+ deployment = await async_client.deployments.redeploy(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentRedeployResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_raw_response_redeploy(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.deployments.with_raw_response.redeploy(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = await response.parse()
+ assert_matches_type(DeploymentRedeployResponse, deployment, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_redeploy(self, async_client: AsyncRunloop) -> None:
+ async with async_client.deployments.with_streaming_response.redeploy(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = await response.parse()
+ assert_matches_type(DeploymentRedeployResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_redeploy(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"):
+ await async_client.deployments.with_raw_response.redeploy(
+ "",
+ )
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ async def test_method_tail(self, async_client: AsyncRunloop) -> None:
+ deployment = await async_client.deployments.tail(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ async def test_raw_response_tail(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.deployments.with_raw_response.tail(
+ "deployment_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ deployment = await response.parse()
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ async def test_streaming_response_tail(self, async_client: AsyncRunloop) -> None:
+ async with async_client.deployments.with_streaming_response.tail(
+ "deployment_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ deployment = await response.parse()
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="cannot test text/event-stream")
+ @parametrize
+ async def test_path_params_tail(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `deployment_id` but received ''"):
+ await async_client.deployments.with_raw_response.tail(
+ "",
+ )
diff --git a/tests/api_resources/test_devboxes.py b/tests/api_resources/test_devboxes.py
old mode 100644
new mode 100755
index 5edb2c25e..80fce2549
--- a/tests/api_resources/test_devboxes.py
+++ b/tests/api_resources/test_devboxes.py
@@ -12,8 +12,9 @@
from runloop_api_client.types import (
DevboxView,
DevboxListView,
- DevboxExecutionDetailView,
+ DevboxCreateSSHKeyResponse,
)
+from runloop_api_client.types.devboxes import DevboxExecutionDetailView, DevboxAsyncExecutionDetailView
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -39,6 +40,7 @@ def test_method_create_with_all_params(self, client: Runloop) -> None:
"launch_commands": ["string", "string", "string"],
"resource_size_request": "MINI",
},
+ metadata={"foo": "string"},
name="name",
setup_commands=["string", "string", "string"],
)
@@ -137,69 +139,107 @@ def test_streaming_response_list(self, client: Runloop) -> None:
assert cast(Any, response.is_closed) is True
@parametrize
- def test_method_execute_sync(self, client: Runloop) -> None:
- devbox = client.devboxes.execute_sync(
+ def test_method_create_ssh_key(self, client: Runloop) -> None:
+ devbox = client.devboxes.create_ssh_key(
+ "id",
+ )
+ assert_matches_type(DevboxCreateSSHKeyResponse, devbox, path=["response"])
+
+ @parametrize
+ def test_raw_response_create_ssh_key(self, client: Runloop) -> None:
+ response = client.devboxes.with_raw_response.create_ssh_key(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ devbox = response.parse()
+ assert_matches_type(DevboxCreateSSHKeyResponse, devbox, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create_ssh_key(self, client: Runloop) -> None:
+ with client.devboxes.with_streaming_response.create_ssh_key(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ devbox = response.parse()
+ assert_matches_type(DevboxCreateSSHKeyResponse, devbox, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_create_ssh_key(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.devboxes.with_raw_response.create_ssh_key(
+ "",
+ )
+
+ @parametrize
+ def test_method_execute_async(self, client: Runloop) -> None:
+ devbox = client.devboxes.execute_async(
id="id",
)
- assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
@parametrize
- def test_method_execute_sync_with_all_params(self, client: Runloop) -> None:
- devbox = client.devboxes.execute_sync(
+ def test_method_execute_async_with_all_params(self, client: Runloop) -> None:
+ devbox = client.devboxes.execute_async(
id="id",
command="command",
)
- assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
@parametrize
- def test_raw_response_execute_sync(self, client: Runloop) -> None:
- response = client.devboxes.with_raw_response.execute_sync(
+ def test_raw_response_execute_async(self, client: Runloop) -> None:
+ response = client.devboxes.with_raw_response.execute_async(
id="id",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
devbox = response.parse()
- assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
@parametrize
- def test_streaming_response_execute_sync(self, client: Runloop) -> None:
- with client.devboxes.with_streaming_response.execute_sync(
+ def test_streaming_response_execute_async(self, client: Runloop) -> None:
+ with client.devboxes.with_streaming_response.execute_async(
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(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_execute_sync(self, client: Runloop) -> None:
+ def test_path_params_execute_async(self, client: Runloop) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.devboxes.with_raw_response.execute_sync(
+ client.devboxes.with_raw_response.execute_async(
id="",
)
@parametrize
- def test_method_read_file(self, client: Runloop) -> None:
- devbox = client.devboxes.read_file(
+ def test_method_execute_sync(self, client: Runloop) -> None:
+ devbox = client.devboxes.execute_sync(
id="id",
)
assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
@parametrize
- def test_method_read_file_with_all_params(self, client: Runloop) -> None:
- devbox = client.devboxes.read_file(
+ def test_method_execute_sync_with_all_params(self, client: Runloop) -> None:
+ devbox = client.devboxes.execute_sync(
id="id",
- file_path="file_path",
+ command="command",
)
assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
@parametrize
- def test_raw_response_read_file(self, client: Runloop) -> None:
- response = client.devboxes.with_raw_response.read_file(
+ def test_raw_response_execute_sync(self, client: Runloop) -> None:
+ response = client.devboxes.with_raw_response.execute_sync(
id="id",
)
@@ -209,8 +249,8 @@ def test_raw_response_read_file(self, client: Runloop) -> None:
assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
@parametrize
- def test_streaming_response_read_file(self, client: Runloop) -> None:
- with client.devboxes.with_streaming_response.read_file(
+ def test_streaming_response_execute_sync(self, client: Runloop) -> None:
+ with client.devboxes.with_streaming_response.execute_sync(
id="id",
) as response:
assert not response.is_closed
@@ -222,9 +262,9 @@ def test_streaming_response_read_file(self, client: Runloop) -> None:
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_read_file(self, client: Runloop) -> None:
+ def test_path_params_execute_sync(self, client: Runloop) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
- client.devboxes.with_raw_response.read_file(
+ client.devboxes.with_raw_response.execute_sync(
id="",
)
@@ -428,6 +468,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncRunloop) -
"launch_commands": ["string", "string", "string"],
"resource_size_request": "MINI",
},
+ metadata={"foo": "string"},
name="name",
setup_commands=["string", "string", "string"],
)
@@ -526,69 +567,107 @@ async def test_streaming_response_list(self, async_client: AsyncRunloop) -> None
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_method_execute_sync(self, async_client: AsyncRunloop) -> None:
- devbox = await async_client.devboxes.execute_sync(
+ async def test_method_create_ssh_key(self, async_client: AsyncRunloop) -> None:
+ devbox = await async_client.devboxes.create_ssh_key(
+ "id",
+ )
+ assert_matches_type(DevboxCreateSSHKeyResponse, devbox, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create_ssh_key(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.with_raw_response.create_ssh_key(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ devbox = await response.parse()
+ assert_matches_type(DevboxCreateSSHKeyResponse, devbox, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create_ssh_key(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.with_streaming_response.create_ssh_key(
+ "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(DevboxCreateSSHKeyResponse, devbox, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_create_ssh_key(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.create_ssh_key(
+ "",
+ )
+
+ @parametrize
+ async def test_method_execute_async(self, async_client: AsyncRunloop) -> None:
+ devbox = await async_client.devboxes.execute_async(
id="id",
)
- assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
@parametrize
- async def test_method_execute_sync_with_all_params(self, async_client: AsyncRunloop) -> None:
- devbox = await async_client.devboxes.execute_sync(
+ async def test_method_execute_async_with_all_params(self, async_client: AsyncRunloop) -> None:
+ devbox = await async_client.devboxes.execute_async(
id="id",
command="command",
)
- assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
@parametrize
- async def test_raw_response_execute_sync(self, async_client: AsyncRunloop) -> None:
- response = await async_client.devboxes.with_raw_response.execute_sync(
+ async def test_raw_response_execute_async(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.with_raw_response.execute_async(
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(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
@parametrize
- async def test_streaming_response_execute_sync(self, async_client: AsyncRunloop) -> None:
- async with async_client.devboxes.with_streaming_response.execute_sync(
+ async def test_streaming_response_execute_async(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.with_streaming_response.execute_async(
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(DevboxExecutionDetailView, devbox, path=["response"])
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_execute_sync(self, async_client: AsyncRunloop) -> None:
+ async def test_path_params_execute_async(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.execute_sync(
+ await async_client.devboxes.with_raw_response.execute_async(
id="",
)
@parametrize
- async def test_method_read_file(self, async_client: AsyncRunloop) -> None:
- devbox = await async_client.devboxes.read_file(
+ async def test_method_execute_sync(self, async_client: AsyncRunloop) -> None:
+ devbox = await async_client.devboxes.execute_sync(
id="id",
)
assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
@parametrize
- async def test_method_read_file_with_all_params(self, async_client: AsyncRunloop) -> None:
- devbox = await async_client.devboxes.read_file(
+ async def test_method_execute_sync_with_all_params(self, async_client: AsyncRunloop) -> None:
+ devbox = await async_client.devboxes.execute_sync(
id="id",
- file_path="file_path",
+ command="command",
)
assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
@parametrize
- async def test_raw_response_read_file(self, async_client: AsyncRunloop) -> None:
- response = await async_client.devboxes.with_raw_response.read_file(
+ async def test_raw_response_execute_sync(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.with_raw_response.execute_sync(
id="id",
)
@@ -598,8 +677,8 @@ async def test_raw_response_read_file(self, async_client: AsyncRunloop) -> None:
assert_matches_type(DevboxExecutionDetailView, devbox, path=["response"])
@parametrize
- async def test_streaming_response_read_file(self, async_client: AsyncRunloop) -> None:
- async with async_client.devboxes.with_streaming_response.read_file(
+ async def test_streaming_response_execute_sync(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.with_streaming_response.execute_sync(
id="id",
) as response:
assert not response.is_closed
@@ -611,9 +690,9 @@ async def test_streaming_response_read_file(self, async_client: AsyncRunloop) ->
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_read_file(self, async_client: AsyncRunloop) -> None:
+ async def test_path_params_execute_sync(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.read_file(
+ await async_client.devboxes.with_raw_response.execute_sync(
id="",
)
diff --git a/tests/api_resources/test_functions.py b/tests/api_resources/test_functions.py
old mode 100644
new mode 100755
diff --git a/tests/api_resources/test_projects.py b/tests/api_resources/test_projects.py
old mode 100644
new mode 100755
diff --git a/tests/conftest.py b/tests/conftest.py
old mode 100644
new mode 100755
diff --git a/tests/sample_file.txt b/tests/sample_file.txt
old mode 100644
new mode 100755
diff --git a/tests/test_client.py b/tests/test_client.py
old mode 100644
new mode 100755
index a9738496a..ab10be034
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -87,7 +87,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 == 0
+ assert self.client.max_retries == 2
copied2 = copied.copy(max_retries=6)
assert copied2.max_retries == 6
@@ -706,20 +706,20 @@ class Model(BaseModel):
"remaining_retries,retry_after,timeout",
[
[3, "20", 20],
- [3, "0", 1],
- [3, "-10", 1],
+ [3, "0", 0.5],
+ [3, "-10", 0.5],
[3, "60", 60],
- [3, "61", 1],
+ [3, "61", 0.5],
[3, "Fri, 29 Sep 2023 16:26:57 GMT", 20],
- [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:26:37 GMT", 0.5],
+ [3, "Fri, 29 Sep 2023 16:26:27 GMT", 0.5],
[3, "Fri, 29 Sep 2023 16:27:37 GMT", 60],
- [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],
+ [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],
],
)
@mock.patch("time.time", mock.MagicMock(return_value=1696004797))
@@ -729,7 +729,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, 1 * 0.875) # pyright: ignore[reportUnknownMemberType]
+ assert calculated == pytest.approx(timeout, 0.5 * 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)
@@ -820,7 +820,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 == 0
+ assert self.client.max_retries == 2
copied2 = copied.copy(max_retries=6)
assert copied2.max_retries == 6
@@ -1442,20 +1442,20 @@ class Model(BaseModel):
"remaining_retries,retry_after,timeout",
[
[3, "20", 20],
- [3, "0", 1],
- [3, "-10", 1],
+ [3, "0", 0.5],
+ [3, "-10", 0.5],
[3, "60", 60],
- [3, "61", 1],
+ [3, "61", 0.5],
[3, "Fri, 29 Sep 2023 16:26:57 GMT", 20],
- [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:26:37 GMT", 0.5],
+ [3, "Fri, 29 Sep 2023 16:26:27 GMT", 0.5],
[3, "Fri, 29 Sep 2023 16:27:37 GMT", 60],
- [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],
+ [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],
],
)
@mock.patch("time.time", mock.MagicMock(return_value=1696004797))
@@ -1466,7 +1466,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, 1 * 0.875) # pyright: ignore[reportUnknownMemberType]
+ assert calculated == pytest.approx(timeout, 0.5 * 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)
diff --git a/tests/test_deepcopy.py b/tests/test_deepcopy.py
old mode 100644
new mode 100755
diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py
old mode 100644
new mode 100755
diff --git a/tests/test_files.py b/tests/test_files.py
old mode 100644
new mode 100755
diff --git a/tests/test_models.py b/tests/test_models.py
old mode 100644
new mode 100755
diff --git a/tests/test_qs.py b/tests/test_qs.py
old mode 100644
new mode 100755
diff --git a/tests/test_required_args.py b/tests/test_required_args.py
old mode 100644
new mode 100755
diff --git a/tests/test_response.py b/tests/test_response.py
old mode 100644
new mode 100755
index d24372998..849a519e5
--- a/tests/test_response.py
+++ b/tests/test_response.py
@@ -1,5 +1,5 @@
import json
-from typing import List, cast
+from typing import Any, List, Union, cast
from typing_extensions import Annotated
import httpx
@@ -188,3 +188,40 @@ async def test_async_response_parse_annotated_type(async_client: AsyncRunloop) -
)
assert obj.foo == "hello!"
assert obj.bar == 2
+
+
+class OtherModel(BaseModel):
+ a: str
+
+
+@pytest.mark.parametrize("client", [False], indirect=True) # loose validation
+def test_response_parse_expect_model_union_non_json_content(client: Runloop) -> None:
+ response = APIResponse(
+ raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}),
+ client=client,
+ stream=False,
+ stream_cls=None,
+ cast_to=str,
+ options=FinalRequestOptions.construct(method="get", url="/foo"),
+ )
+
+ obj = response.parse(to=cast(Any, Union[CustomModel, OtherModel]))
+ assert isinstance(obj, str)
+ assert obj == "foo"
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("async_client", [False], indirect=True) # loose validation
+async def test_async_response_parse_expect_model_union_non_json_content(async_client: AsyncRunloop) -> None:
+ response = AsyncAPIResponse(
+ raw=httpx.Response(200, content=b"foo", headers={"Content-Type": "application/text"}),
+ client=async_client,
+ stream=False,
+ stream_cls=None,
+ cast_to=str,
+ options=FinalRequestOptions.construct(method="get", url="/foo"),
+ )
+
+ obj = await response.parse(to=cast(Any, Union[CustomModel, OtherModel]))
+ assert isinstance(obj, str)
+ assert obj == "foo"
diff --git a/tests/test_streaming.py b/tests/test_streaming.py
old mode 100644
new mode 100755
diff --git a/tests/test_transform.py b/tests/test_transform.py
old mode 100644
new mode 100755
diff --git a/tests/test_utils/test_proxy.py b/tests/test_utils/test_proxy.py
old mode 100644
new mode 100755
diff --git a/tests/test_utils/test_typing.py b/tests/test_utils/test_typing.py
old mode 100644
new mode 100755
diff --git a/tests/utils.py b/tests/utils.py
old mode 100644
new mode 100755