diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 000572ece..b0699969f 100755
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.13"
+ ".": "0.1.0-alpha.14"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index cd6612ae1..41b5ab409 100755
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 22
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-8c7e1b2377a7a76ebd891bda5df65c28f1574bae085e0460b8f614811bb193fe.yml
+configured_endpoints: 36
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-ea589851f2dbba35fea6c010ac4c577cad56aa44e1d5bd4e5b472c802b2f13c4.yml
diff --git a/README.md b/README.md
index c30cc313a..8dc4c7e51 100755
--- 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/api.md b/api.md
index 292241006..ba23ae8ae 100755
--- a/api.md
+++ b/api.md
@@ -43,15 +43,37 @@ Types:
from runloop_api_client.types import CodeMountParameters
```
+# Deployments
+
+Types:
+
+```python
+from runloop_api_client.types import (
+ DeploymentRetrieveResponse,
+ DeploymentGetResponse,
+ DeploymentLogsResponse,
+ DeploymentRedeployResponse,
+ DeploymentTailResponse,
+)
+```
+
+Methods:
+
+- client.deployments.retrieve(deployment_id) -> DeploymentRetrieveResponse
+- client.deployments.get(\*\*params) -> DeploymentGetResponse
+- client.deployments.logs(deployment_id) -> DeploymentLogsResponse
+- client.deployments.redeploy(deployment_id) -> DeploymentRedeployResponse
+- client.deployments.tail(deployment_id) -> DeploymentTailResponse
+
# Devboxes
Types:
```python
from runloop_api_client.types import (
- DevboxExecutionDetailView,
- DevboxListView,
DevboxView,
+ DevboxListResponse,
+ DevboxCreateSSHKeyResponse,
DevboxReadFileContentsResponse,
DevboxUploadFileResponse,
)
@@ -61,31 +83,49 @@ 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.list(\*\*params) -> DevboxListResponse
+- 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
+Methods:
+
+- client.devboxes.logs.list(id) -> DevboxLogsListView
+- client.devboxes.logs.tail(id) -> None
+
+## Executions
+
Types:
```python
-from runloop_api_client.types.devboxes import DevboxLogsListView
+from runloop_api_client.types.devboxes import (
+ DevboxAsyncExecutionDetailView,
+ DevboxExecutionDetailView,
+ DevboxLogsListView,
+)
```
Methods:
-- client.devboxes.logs.list(id) -> DevboxLogsListView
+- client.devboxes.executions.retrieve(exe_id, \*, id, \*\*params) -> DevboxAsyncExecutionDetailView
+- client.devboxes.executions.execute_async(id, \*\*params) -> DevboxAsyncExecutionDetailView
+- client.devboxes.executions.execute_sync(id, \*\*params) -> DevboxExecutionDetailView
+- client.devboxes.executions.kill(exe_id, \*, id) -> DevboxAsyncExecutionDetailView
+- client.devboxes.executions.logs(execution_id, \*, id) -> DevboxLogsListView
+- client.devboxes.executions.tail(execution_id, \*, id) -> None
# Functions
Types:
```python
-from runloop_api_client.types import FunctionListView
+from runloop_api_client.types import FunctionListView, FunctionListOpenAPIResponse
```
Methods:
@@ -93,13 +133,18 @@ Methods:
- client.functions.list() -> FunctionListView
- client.functions.invoke_async(function_name, \*, project_name, \*\*params) -> FunctionInvocationExecutionDetailView
- client.functions.invoke_sync(function_name, \*, project_name, \*\*params) -> FunctionInvocationExecutionDetailView
+- client.functions.list_openapi() -> object
## Invocations
Types:
```python
-from runloop_api_client.types.functions import FunctionInvocationListView, KillOperationResponse
+from runloop_api_client.types.functions import (
+ FunctionInvocationListView,
+ KillOperationResponse,
+ InvocationLogsResponse,
+)
```
Methods:
@@ -107,6 +152,7 @@ Methods:
- client.functions.invocations.retrieve(invocation_id) -> FunctionInvocationExecutionDetailView
- client.functions.invocations.list(\*\*params) -> FunctionInvocationListView
- client.functions.invocations.kill(invocation_id) -> object
+- client.functions.invocations.logs(invocation_id) -> InvocationLogsResponse
# Projects
diff --git a/pyproject.toml b/pyproject.toml
index cdeb9d124..22380a1af 100755
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "runloop_api_client"
-version = "0.1.0-alpha.13"
+version = "0.1.0-alpha.14"
description = "The official Python library for the runloop API"
dynamic = ["readme"]
license = "MIT"
diff --git a/src/runloop_api_client/_client.py b/src/runloop_api_client/_client.py
index 1609aebcc..f173ecd62 100755
--- a/src/runloop_api_client/_client.py
+++ b/src/runloop_api_client/_client.py
@@ -47,6 +47,7 @@
class Runloop(SyncAPIClient):
blueprints: resources.BlueprintsResource
+ deployments: resources.DeploymentsResource
devboxes: resources.DevboxesResource
functions: resources.FunctionsResource
projects: resources.ProjectsResource
@@ -108,6 +109,7 @@ def __init__(
)
self.blueprints = resources.BlueprintsResource(self)
+ self.deployments = resources.DeploymentsResource(self)
self.devboxes = resources.DevboxesResource(self)
self.functions = resources.FunctionsResource(self)
self.projects = resources.ProjectsResource(self)
@@ -221,6 +223,7 @@ def _make_status_error(
class AsyncRunloop(AsyncAPIClient):
blueprints: resources.AsyncBlueprintsResource
+ deployments: resources.AsyncDeploymentsResource
devboxes: resources.AsyncDevboxesResource
functions: resources.AsyncFunctionsResource
projects: resources.AsyncProjectsResource
@@ -282,6 +285,7 @@ def __init__(
)
self.blueprints = resources.AsyncBlueprintsResource(self)
+ self.deployments = resources.AsyncDeploymentsResource(self)
self.devboxes = resources.AsyncDevboxesResource(self)
self.functions = resources.AsyncFunctionsResource(self)
self.projects = resources.AsyncProjectsResource(self)
@@ -396,6 +400,7 @@ def _make_status_error(
class RunloopWithRawResponse:
def __init__(self, client: Runloop) -> None:
self.blueprints = resources.BlueprintsResourceWithRawResponse(client.blueprints)
+ self.deployments = resources.DeploymentsResourceWithRawResponse(client.deployments)
self.devboxes = resources.DevboxesResourceWithRawResponse(client.devboxes)
self.functions = resources.FunctionsResourceWithRawResponse(client.functions)
self.projects = resources.ProjectsResourceWithRawResponse(client.projects)
@@ -404,6 +409,7 @@ def __init__(self, client: Runloop) -> None:
class AsyncRunloopWithRawResponse:
def __init__(self, client: AsyncRunloop) -> None:
self.blueprints = resources.AsyncBlueprintsResourceWithRawResponse(client.blueprints)
+ self.deployments = resources.AsyncDeploymentsResourceWithRawResponse(client.deployments)
self.devboxes = resources.AsyncDevboxesResourceWithRawResponse(client.devboxes)
self.functions = resources.AsyncFunctionsResourceWithRawResponse(client.functions)
self.projects = resources.AsyncProjectsResourceWithRawResponse(client.projects)
@@ -412,6 +418,7 @@ def __init__(self, client: AsyncRunloop) -> None:
class RunloopWithStreamedResponse:
def __init__(self, client: Runloop) -> None:
self.blueprints = resources.BlueprintsResourceWithStreamingResponse(client.blueprints)
+ self.deployments = resources.DeploymentsResourceWithStreamingResponse(client.deployments)
self.devboxes = resources.DevboxesResourceWithStreamingResponse(client.devboxes)
self.functions = resources.FunctionsResourceWithStreamingResponse(client.functions)
self.projects = resources.ProjectsResourceWithStreamingResponse(client.projects)
@@ -420,6 +427,7 @@ def __init__(self, client: Runloop) -> None:
class AsyncRunloopWithStreamedResponse:
def __init__(self, client: AsyncRunloop) -> None:
self.blueprints = resources.AsyncBlueprintsResourceWithStreamingResponse(client.blueprints)
+ self.deployments = resources.AsyncDeploymentsResourceWithStreamingResponse(client.deployments)
self.devboxes = resources.AsyncDevboxesResourceWithStreamingResponse(client.devboxes)
self.functions = resources.AsyncFunctionsResourceWithStreamingResponse(client.functions)
self.projects = resources.AsyncProjectsResourceWithStreamingResponse(client.projects)
diff --git a/src/runloop_api_client/_constants.py b/src/runloop_api_client/_constants.py
index 8e36fea12..a2ac3b6f3 100755
--- 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/_version.py b/src/runloop_api_client/_version.py
index afe22f572..70a399d94 100755
--- 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.13" # x-release-please-version
+__version__ = "0.1.0-alpha.14" # x-release-please-version
diff --git a/src/runloop_api_client/resources/__init__.py b/src/runloop_api_client/resources/__init__.py
index f36499829..e26ff0410 100755
--- a/src/runloop_api_client/resources/__init__.py
+++ b/src/runloop_api_client/resources/__init__.py
@@ -32,6 +32,14 @@
BlueprintsResourceWithStreamingResponse,
AsyncBlueprintsResourceWithStreamingResponse,
)
+from .deployments import (
+ DeploymentsResource,
+ AsyncDeploymentsResource,
+ DeploymentsResourceWithRawResponse,
+ AsyncDeploymentsResourceWithRawResponse,
+ DeploymentsResourceWithStreamingResponse,
+ AsyncDeploymentsResourceWithStreamingResponse,
+)
__all__ = [
"BlueprintsResource",
@@ -40,6 +48,12 @@
"AsyncBlueprintsResourceWithRawResponse",
"BlueprintsResourceWithStreamingResponse",
"AsyncBlueprintsResourceWithStreamingResponse",
+ "DeploymentsResource",
+ "AsyncDeploymentsResource",
+ "DeploymentsResourceWithRawResponse",
+ "AsyncDeploymentsResourceWithRawResponse",
+ "DeploymentsResourceWithStreamingResponse",
+ "AsyncDeploymentsResourceWithStreamingResponse",
"DevboxesResource",
"AsyncDevboxesResource",
"DevboxesResourceWithRawResponse",
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
index 814a1ca00..ec7c746ac 100755
--- 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
index 7b1c0388d..4586a46b5 100755
--- a/src/runloop_api_client/resources/devboxes/devboxes.py
+++ b/src/runloop_api_client/resources/devboxes/devboxes.py
@@ -20,6 +20,7 @@
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
@@ -30,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,
@@ -39,8 +48,10 @@
)
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_list_response import DevboxListResponse
+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"]
@@ -50,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)
@@ -183,7 +198,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> DevboxListView:
+ ) -> DevboxListResponse:
"""List all devboxes or filter by status.
If no status is provided, all devboxes
@@ -220,7 +235,77 @@ def list(
devbox_list_params.DevboxListParams,
),
),
- cast_to=DevboxListView,
+ cast_to=DevboxListResponse,
+ )
+
+ 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,
+ *,
+ 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}, 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=DevboxAsyncExecutionDetailView,
)
def execute_sync(
@@ -434,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)
@@ -567,7 +656,7 @@ async def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> DevboxListView:
+ ) -> DevboxListResponse:
"""List all devboxes or filter by status.
If no status is provided, all devboxes
@@ -604,7 +693,79 @@ async def list(
devbox_list_params.DevboxListParams,
),
),
- cast_to=DevboxListView,
+ cast_to=DevboxListResponse,
+ )
+
+ 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,
+ *,
+ 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}, 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=DevboxAsyncExecutionDetailView,
)
async def execute_sync(
@@ -826,6 +987,12 @@ 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,
)
@@ -846,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:
@@ -860,6 +1031,12 @@ 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,
)
@@ -880,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:
@@ -894,6 +1075,12 @@ 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,
)
@@ -914,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:
@@ -928,6 +1119,12 @@ 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,
)
@@ -947,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..9b68a432f
--- /dev/null
+++ b/src/runloop_api_client/resources/devboxes/executions.py
@@ -0,0 +1,598 @@
+# 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, NoneType, 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_retrieve_params, execution_execute_sync_params, execution_execute_async_params
+from ...types.devboxes.devbox_logs_list_view import DevboxLogsListView
+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 retrieve(
+ self,
+ exe_id: str,
+ *,
+ 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:
+ """
+ Get status of an execution 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}")
+ if not exe_id:
+ raise ValueError(f"Expected a non-empty value for `exe_id` but received {exe_id!r}")
+ return self._post(
+ f"/v1/devboxes/{id}/executions/{exe_id}",
+ body=maybe_transform({"command": command}, execution_retrieve_params.ExecutionRetrieveParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxAsyncExecutionDetailView,
+ )
+
+ 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,
+ )
+
+ def kill(
+ self,
+ exe_id: str,
+ *,
+ 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,
+ ) -> DevboxAsyncExecutionDetailView:
+ """
+ Kill an asynchronous execution currently running on a devbox
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ if not exe_id:
+ raise ValueError(f"Expected a non-empty value for `exe_id` but received {exe_id!r}")
+ return self._post(
+ f"/v1/devboxes/{id}/executions/{exe_id}/kill",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxAsyncExecutionDetailView,
+ )
+
+ def logs(
+ self,
+ execution_id: str,
+ *,
+ 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,
+ ) -> DevboxLogsListView:
+ """
+ Get all logs from a Devbox execution 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}")
+ if not execution_id:
+ raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}")
+ return self._get(
+ f"/v1/devboxes/{id}/executions/{execution_id}/logs",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxLogsListView,
+ )
+
+ def tail(
+ self,
+ execution_id: str,
+ *,
+ 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,
+ ) -> None:
+ """Tail the logs for the given devbox async execution.
+
+ This will return past log
+ entries and continue from there. This is a streaming api and will continue to
+ stream logs until the connection is closed.
+
+ 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}")
+ if not execution_id:
+ raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ f"/v1/devboxes/{id}/executions/{execution_id}/logs/tail",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+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 retrieve(
+ self,
+ exe_id: str,
+ *,
+ 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:
+ """
+ Get status of an execution 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}")
+ if not exe_id:
+ raise ValueError(f"Expected a non-empty value for `exe_id` but received {exe_id!r}")
+ return await self._post(
+ f"/v1/devboxes/{id}/executions/{exe_id}",
+ body=await async_maybe_transform({"command": command}, execution_retrieve_params.ExecutionRetrieveParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxAsyncExecutionDetailView,
+ )
+
+ 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,
+ )
+
+ async def kill(
+ self,
+ exe_id: str,
+ *,
+ 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,
+ ) -> DevboxAsyncExecutionDetailView:
+ """
+ Kill an asynchronous execution currently running on a devbox
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ if not exe_id:
+ raise ValueError(f"Expected a non-empty value for `exe_id` but received {exe_id!r}")
+ return await self._post(
+ f"/v1/devboxes/{id}/executions/{exe_id}/kill",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxAsyncExecutionDetailView,
+ )
+
+ async def logs(
+ self,
+ execution_id: str,
+ *,
+ 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,
+ ) -> DevboxLogsListView:
+ """
+ Get all logs from a Devbox execution 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}")
+ if not execution_id:
+ raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}")
+ return await self._get(
+ f"/v1/devboxes/{id}/executions/{execution_id}/logs",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DevboxLogsListView,
+ )
+
+ async def tail(
+ self,
+ execution_id: str,
+ *,
+ 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,
+ ) -> None:
+ """Tail the logs for the given devbox async execution.
+
+ This will return past log
+ entries and continue from there. This is a streaming api and will continue to
+ stream logs until the connection is closed.
+
+ 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}")
+ if not execution_id:
+ raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ f"/v1/devboxes/{id}/executions/{execution_id}/logs/tail",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class ExecutionsResourceWithRawResponse:
+ def __init__(self, executions: ExecutionsResource) -> None:
+ self._executions = executions
+
+ self.retrieve = to_raw_response_wrapper(
+ executions.retrieve,
+ )
+ self.execute_async = to_raw_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = to_raw_response_wrapper(
+ executions.execute_sync,
+ )
+ self.kill = to_raw_response_wrapper(
+ executions.kill,
+ )
+ self.logs = to_raw_response_wrapper(
+ executions.logs,
+ )
+ self.tail = to_raw_response_wrapper(
+ executions.tail,
+ )
+
+
+class AsyncExecutionsResourceWithRawResponse:
+ def __init__(self, executions: AsyncExecutionsResource) -> None:
+ self._executions = executions
+
+ self.retrieve = async_to_raw_response_wrapper(
+ executions.retrieve,
+ )
+ self.execute_async = async_to_raw_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = async_to_raw_response_wrapper(
+ executions.execute_sync,
+ )
+ self.kill = async_to_raw_response_wrapper(
+ executions.kill,
+ )
+ self.logs = async_to_raw_response_wrapper(
+ executions.logs,
+ )
+ self.tail = async_to_raw_response_wrapper(
+ executions.tail,
+ )
+
+
+class ExecutionsResourceWithStreamingResponse:
+ def __init__(self, executions: ExecutionsResource) -> None:
+ self._executions = executions
+
+ self.retrieve = to_streamed_response_wrapper(
+ executions.retrieve,
+ )
+ self.execute_async = to_streamed_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = to_streamed_response_wrapper(
+ executions.execute_sync,
+ )
+ self.kill = to_streamed_response_wrapper(
+ executions.kill,
+ )
+ self.logs = to_streamed_response_wrapper(
+ executions.logs,
+ )
+ self.tail = to_streamed_response_wrapper(
+ executions.tail,
+ )
+
+
+class AsyncExecutionsResourceWithStreamingResponse:
+ def __init__(self, executions: AsyncExecutionsResource) -> None:
+ self._executions = executions
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ executions.retrieve,
+ )
+ self.execute_async = async_to_streamed_response_wrapper(
+ executions.execute_async,
+ )
+ self.execute_sync = async_to_streamed_response_wrapper(
+ executions.execute_sync,
+ )
+ self.kill = async_to_streamed_response_wrapper(
+ executions.kill,
+ )
+ self.logs = async_to_streamed_response_wrapper(
+ executions.logs,
+ )
+ self.tail = async_to_streamed_response_wrapper(
+ executions.tail,
+ )
diff --git a/src/runloop_api_client/resources/devboxes/logs.py b/src/runloop_api_client/resources/devboxes/logs.py
index cabe8f329..1f03fc023 100755
--- a/src/runloop_api_client/resources/devboxes/logs.py
+++ b/src/runloop_api_client/resources/devboxes/logs.py
@@ -4,7 +4,7 @@
import httpx
-from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -61,6 +61,43 @@ def list(
cast_to=DevboxLogsListView,
)
+ def tail(
+ 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,
+ ) -> None:
+ """Tail the logs for the given devbox.
+
+ This will return past log entries and
+ continue from there. This is a streaming api and will continue to stream logs
+ until the connection is closed.
+
+ 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}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._get(
+ f"/v1/devboxes/{id}/logs/tail",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class AsyncLogsResource(AsyncAPIResource):
@cached_property
@@ -104,6 +141,43 @@ async def list(
cast_to=DevboxLogsListView,
)
+ async def tail(
+ 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,
+ ) -> None:
+ """Tail the logs for the given devbox.
+
+ This will return past log entries and
+ continue from there. This is a streaming api and will continue to stream logs
+ until the connection is closed.
+
+ 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}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._get(
+ f"/v1/devboxes/{id}/logs/tail",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class LogsResourceWithRawResponse:
def __init__(self, logs: LogsResource) -> None:
@@ -112,6 +186,9 @@ def __init__(self, logs: LogsResource) -> None:
self.list = to_raw_response_wrapper(
logs.list,
)
+ self.tail = to_raw_response_wrapper(
+ logs.tail,
+ )
class AsyncLogsResourceWithRawResponse:
@@ -121,6 +198,9 @@ def __init__(self, logs: AsyncLogsResource) -> None:
self.list = async_to_raw_response_wrapper(
logs.list,
)
+ self.tail = async_to_raw_response_wrapper(
+ logs.tail,
+ )
class LogsResourceWithStreamingResponse:
@@ -130,6 +210,9 @@ def __init__(self, logs: LogsResource) -> None:
self.list = to_streamed_response_wrapper(
logs.list,
)
+ self.tail = to_streamed_response_wrapper(
+ logs.tail,
+ )
class AsyncLogsResourceWithStreamingResponse:
@@ -139,3 +222,6 @@ def __init__(self, logs: AsyncLogsResource) -> None:
self.list = async_to_streamed_response_wrapper(
logs.list,
)
+ self.tail = async_to_streamed_response_wrapper(
+ logs.tail,
+ )
diff --git a/src/runloop_api_client/resources/functions/functions.py b/src/runloop_api_client/resources/functions/functions.py
index 006a23817..8628eca96 100755
--- a/src/runloop_api_client/resources/functions/functions.py
+++ b/src/runloop_api_client/resources/functions/functions.py
@@ -164,6 +164,25 @@ def invoke_sync(
cast_to=FunctionInvocationExecutionDetailView,
)
+ def list_openapi(
+ self,
+ *,
+ # 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,
+ ) -> object:
+ """Get the OpenAPI Spec for this project."""
+ return self._get(
+ "/v1/functions/openapi",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=object,
+ )
+
class AsyncFunctionsResource(AsyncAPIResource):
@cached_property
@@ -296,6 +315,25 @@ async def invoke_sync(
cast_to=FunctionInvocationExecutionDetailView,
)
+ async def list_openapi(
+ self,
+ *,
+ # 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,
+ ) -> object:
+ """Get the OpenAPI Spec for this project."""
+ return await self._get(
+ "/v1/functions/openapi",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=object,
+ )
+
class FunctionsResourceWithRawResponse:
def __init__(self, functions: FunctionsResource) -> None:
@@ -310,6 +348,9 @@ def __init__(self, functions: FunctionsResource) -> None:
self.invoke_sync = to_raw_response_wrapper(
functions.invoke_sync,
)
+ self.list_openapi = to_raw_response_wrapper(
+ functions.list_openapi,
+ )
@cached_property
def invocations(self) -> InvocationsResourceWithRawResponse:
@@ -329,6 +370,9 @@ def __init__(self, functions: AsyncFunctionsResource) -> None:
self.invoke_sync = async_to_raw_response_wrapper(
functions.invoke_sync,
)
+ self.list_openapi = async_to_raw_response_wrapper(
+ functions.list_openapi,
+ )
@cached_property
def invocations(self) -> AsyncInvocationsResourceWithRawResponse:
@@ -348,6 +392,9 @@ def __init__(self, functions: FunctionsResource) -> None:
self.invoke_sync = to_streamed_response_wrapper(
functions.invoke_sync,
)
+ self.list_openapi = to_streamed_response_wrapper(
+ functions.list_openapi,
+ )
@cached_property
def invocations(self) -> InvocationsResourceWithStreamingResponse:
@@ -367,6 +414,9 @@ def __init__(self, functions: AsyncFunctionsResource) -> None:
self.invoke_sync = async_to_streamed_response_wrapper(
functions.invoke_sync,
)
+ self.list_openapi = async_to_streamed_response_wrapper(
+ functions.list_openapi,
+ )
@cached_property
def invocations(self) -> AsyncInvocationsResourceWithStreamingResponse:
diff --git a/src/runloop_api_client/resources/functions/invocations.py b/src/runloop_api_client/resources/functions/invocations.py
index 59491d1e7..5e9c2b046 100755
--- a/src/runloop_api_client/resources/functions/invocations.py
+++ b/src/runloop_api_client/resources/functions/invocations.py
@@ -19,6 +19,7 @@
)
from ..._base_client import make_request_options
from ...types.functions import invocation_list_params
+from ...types.functions.invocation_logs_response import InvocationLogsResponse
from ...types.functions.function_invocation_list_view import FunctionInvocationListView
from ...types.shared.function_invocation_execution_detail_view import FunctionInvocationExecutionDetailView
@@ -149,6 +150,39 @@ def kill(
cast_to=object,
)
+ def logs(
+ self,
+ invocation_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,
+ ) -> InvocationLogsResponse:
+ """
+ Get the logs for the given invocation.
+
+ 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 invocation_id:
+ raise ValueError(f"Expected a non-empty value for `invocation_id` but received {invocation_id!r}")
+ return self._get(
+ f"/v1/functions/invocations/{invocation_id}/logs",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InvocationLogsResponse,
+ )
+
class AsyncInvocationsResource(AsyncAPIResource):
@cached_property
@@ -274,6 +308,39 @@ async def kill(
cast_to=object,
)
+ async def logs(
+ self,
+ invocation_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,
+ ) -> InvocationLogsResponse:
+ """
+ Get the logs for the given invocation.
+
+ 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 invocation_id:
+ raise ValueError(f"Expected a non-empty value for `invocation_id` but received {invocation_id!r}")
+ return await self._get(
+ f"/v1/functions/invocations/{invocation_id}/logs",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InvocationLogsResponse,
+ )
+
class InvocationsResourceWithRawResponse:
def __init__(self, invocations: InvocationsResource) -> None:
@@ -288,6 +355,9 @@ def __init__(self, invocations: InvocationsResource) -> None:
self.kill = to_raw_response_wrapper(
invocations.kill,
)
+ self.logs = to_raw_response_wrapper(
+ invocations.logs,
+ )
class AsyncInvocationsResourceWithRawResponse:
@@ -303,6 +373,9 @@ def __init__(self, invocations: AsyncInvocationsResource) -> None:
self.kill = async_to_raw_response_wrapper(
invocations.kill,
)
+ self.logs = async_to_raw_response_wrapper(
+ invocations.logs,
+ )
class InvocationsResourceWithStreamingResponse:
@@ -318,6 +391,9 @@ def __init__(self, invocations: InvocationsResource) -> None:
self.kill = to_streamed_response_wrapper(
invocations.kill,
)
+ self.logs = to_streamed_response_wrapper(
+ invocations.logs,
+ )
class AsyncInvocationsResourceWithStreamingResponse:
@@ -333,3 +409,6 @@ def __init__(self, invocations: AsyncInvocationsResource) -> None:
self.kill = async_to_streamed_response_wrapper(
invocations.kill,
)
+ self.logs = async_to_streamed_response_wrapper(
+ invocations.logs,
+ )
diff --git a/src/runloop_api_client/types/__init__.py b/src/runloop_api_client/types/__init__.py
index 5817fab7d..e1b1ebff5 100755
--- a/src/runloop_api_client/types/__init__.py
+++ b/src/runloop_api_client/types/__init__.py
@@ -9,26 +9,33 @@
from .devbox_view import DevboxView as DevboxView
from .resource_size import ResourceSize as ResourceSize
from .blueprint_view import BlueprintView as BlueprintView
-from .devbox_list_view import DevboxListView as DevboxListView
from .project_list_view import ProjectListView as ProjectListView
from .devbox_list_params import DevboxListParams as DevboxListParams
from .function_list_view import FunctionListView as FunctionListView
from .blueprint_build_log import BlueprintBuildLog as BlueprintBuildLog
from .blueprint_list_view import BlueprintListView as BlueprintListView
from .devbox_create_params import DevboxCreateParams as DevboxCreateParams
+from .devbox_list_response import DevboxListResponse as DevboxListResponse
from .blueprint_list_params import BlueprintListParams as BlueprintListParams
from .code_mount_parameters import CodeMountParameters as CodeMountParameters
+from .deployment_get_params import DeploymentGetParams as DeploymentGetParams
from .blueprint_preview_view import BlueprintPreviewView as BlueprintPreviewView
from .blueprint_create_params import BlueprintCreateParams as BlueprintCreateParams
+from .deployment_get_response import DeploymentGetResponse as DeploymentGetResponse
from .blueprint_preview_params import BlueprintPreviewParams as BlueprintPreviewParams
+from .deployment_logs_response import DeploymentLogsResponse as DeploymentLogsResponse
+from .deployment_tail_response import DeploymentTailResponse as DeploymentTailResponse
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 .deployment_redeploy_response import DeploymentRedeployResponse as DeploymentRedeployResponse
+from .deployment_retrieve_response import DeploymentRetrieveResponse as DeploymentRetrieveResponse
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/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_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_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_view.py b/src/runloop_api_client/types/devbox_view.py
index 71eb25578..e2433cc10 100755
--- a/src/runloop_api_client/types/devbox_view.py
+++ b/src/runloop_api_client/types/devbox_view.py
@@ -21,6 +21,9 @@ 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."""
diff --git a/src/runloop_api_client/types/devboxes/__init__.py b/src/runloop_api_client/types/devboxes/__init__.py
index 7baebfdd7..90ed90bb5 100755
--- a/src/runloop_api_client/types/devboxes/__init__.py
+++ b/src/runloop_api_client/types/devboxes/__init__.py
@@ -3,3 +3,8 @@
from __future__ import annotations
from .devbox_logs_list_view import DevboxLogsListView as DevboxLogsListView
+from .execution_retrieve_params import ExecutionRetrieveParams as ExecutionRetrieveParams
+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/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/functions/__init__.py b/src/runloop_api_client/types/functions/__init__.py
index 65762ab89..da953f2d5 100755
--- a/src/runloop_api_client/types/functions/__init__.py
+++ b/src/runloop_api_client/types/functions/__init__.py
@@ -3,4 +3,5 @@
from __future__ import annotations
from .invocation_list_params import InvocationListParams as InvocationListParams
+from .invocation_logs_response import InvocationLogsResponse as InvocationLogsResponse
from .function_invocation_list_view import FunctionInvocationListView as FunctionInvocationListView
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/tests/api_resources/devboxes/test_executions.py b/tests/api_resources/devboxes/test_executions.py
new file mode 100755
index 000000000..665142572
--- /dev/null
+++ b/tests/api_resources/devboxes/test_executions.py
@@ -0,0 +1,612 @@
+# 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 (
+ DevboxLogsListView,
+ 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_retrieve(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.retrieve(
+ exe_id="exeId",
+ id="id",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_method_retrieve_with_all_params(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.retrieve(
+ exe_id="exeId",
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Runloop) -> None:
+ response = client.devboxes.executions.with_raw_response.retrieve(
+ exe_id="exeId",
+ 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_retrieve(self, client: Runloop) -> None:
+ with client.devboxes.executions.with_streaming_response.retrieve(
+ exe_id="exeId",
+ 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_retrieve(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.retrieve(
+ exe_id="exeId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `exe_id` but received ''"):
+ client.devboxes.executions.with_raw_response.retrieve(
+ exe_id="",
+ id="id",
+ )
+
+ @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="",
+ )
+
+ @parametrize
+ def test_method_kill(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.kill(
+ exe_id="exeId",
+ id="id",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ def test_raw_response_kill(self, client: Runloop) -> None:
+ response = client.devboxes.executions.with_raw_response.kill(
+ exe_id="exeId",
+ 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_kill(self, client: Runloop) -> None:
+ with client.devboxes.executions.with_streaming_response.kill(
+ exe_id="exeId",
+ 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_kill(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.kill(
+ exe_id="exeId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `exe_id` but received ''"):
+ client.devboxes.executions.with_raw_response.kill(
+ exe_id="",
+ id="id",
+ )
+
+ @parametrize
+ def test_method_logs(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.logs(
+ execution_id="execution_id",
+ id="id",
+ )
+ assert_matches_type(DevboxLogsListView, execution, path=["response"])
+
+ @parametrize
+ def test_raw_response_logs(self, client: Runloop) -> None:
+ response = client.devboxes.executions.with_raw_response.logs(
+ execution_id="execution_id",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = response.parse()
+ assert_matches_type(DevboxLogsListView, execution, path=["response"])
+
+ @parametrize
+ def test_streaming_response_logs(self, client: Runloop) -> None:
+ with client.devboxes.executions.with_streaming_response.logs(
+ execution_id="execution_id",
+ 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(DevboxLogsListView, execution, 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 `id` but received ''"):
+ client.devboxes.executions.with_raw_response.logs(
+ execution_id="execution_id",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
+ client.devboxes.executions.with_raw_response.logs(
+ execution_id="",
+ id="id",
+ )
+
+ @parametrize
+ def test_method_tail(self, client: Runloop) -> None:
+ execution = client.devboxes.executions.tail(
+ execution_id="execution_id",
+ id="id",
+ )
+ assert execution is None
+
+ @parametrize
+ def test_raw_response_tail(self, client: Runloop) -> None:
+ response = client.devboxes.executions.with_raw_response.tail(
+ execution_id="execution_id",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = response.parse()
+ assert execution is None
+
+ @parametrize
+ def test_streaming_response_tail(self, client: Runloop) -> None:
+ with client.devboxes.executions.with_streaming_response.tail(
+ execution_id="execution_id",
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ execution = response.parse()
+ assert execution is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_tail(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.tail(
+ execution_id="execution_id",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
+ client.devboxes.executions.with_raw_response.tail(
+ execution_id="",
+ id="id",
+ )
+
+
+class TestAsyncExecutions:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.retrieve(
+ exe_id="exeId",
+ id="id",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_method_retrieve_with_all_params(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.retrieve(
+ exe_id="exeId",
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.executions.with_raw_response.retrieve(
+ exe_id="exeId",
+ 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_retrieve(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.executions.with_streaming_response.retrieve(
+ exe_id="exeId",
+ 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_retrieve(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.retrieve(
+ exe_id="exeId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `exe_id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.retrieve(
+ exe_id="",
+ id="id",
+ )
+
+ @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="",
+ )
+
+ @parametrize
+ async def test_method_kill(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.kill(
+ exe_id="exeId",
+ id="id",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, execution, path=["response"])
+
+ @parametrize
+ async def test_raw_response_kill(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.executions.with_raw_response.kill(
+ exe_id="exeId",
+ 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_kill(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.executions.with_streaming_response.kill(
+ exe_id="exeId",
+ 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_kill(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.kill(
+ exe_id="exeId",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `exe_id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.kill(
+ exe_id="",
+ id="id",
+ )
+
+ @parametrize
+ async def test_method_logs(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.logs(
+ execution_id="execution_id",
+ id="id",
+ )
+ assert_matches_type(DevboxLogsListView, execution, path=["response"])
+
+ @parametrize
+ async def test_raw_response_logs(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.executions.with_raw_response.logs(
+ execution_id="execution_id",
+ 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(DevboxLogsListView, execution, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_logs(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.executions.with_streaming_response.logs(
+ execution_id="execution_id",
+ 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(DevboxLogsListView, execution, 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 `id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.logs(
+ execution_id="execution_id",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.logs(
+ execution_id="",
+ id="id",
+ )
+
+ @parametrize
+ async def test_method_tail(self, async_client: AsyncRunloop) -> None:
+ execution = await async_client.devboxes.executions.tail(
+ execution_id="execution_id",
+ id="id",
+ )
+ assert execution is None
+
+ @parametrize
+ async def test_raw_response_tail(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.executions.with_raw_response.tail(
+ execution_id="execution_id",
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ execution = await response.parse()
+ assert execution is None
+
+ @parametrize
+ async def test_streaming_response_tail(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.executions.with_streaming_response.tail(
+ execution_id="execution_id",
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ execution = await response.parse()
+ assert execution is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_tail(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.tail(
+ execution_id="execution_id",
+ id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
+ await async_client.devboxes.executions.with_raw_response.tail(
+ execution_id="",
+ id="id",
+ )
diff --git a/tests/api_resources/devboxes/test_logs.py b/tests/api_resources/devboxes/test_logs.py
index 85ea9be84..c0d8bdc24 100755
--- a/tests/api_resources/devboxes/test_logs.py
+++ b/tests/api_resources/devboxes/test_logs.py
@@ -55,6 +55,44 @@ def test_path_params_list(self, client: Runloop) -> None:
"",
)
+ @parametrize
+ def test_method_tail(self, client: Runloop) -> None:
+ log = client.devboxes.logs.tail(
+ "id",
+ )
+ assert log is None
+
+ @parametrize
+ def test_raw_response_tail(self, client: Runloop) -> None:
+ response = client.devboxes.logs.with_raw_response.tail(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ log = response.parse()
+ assert log is None
+
+ @parametrize
+ def test_streaming_response_tail(self, client: Runloop) -> None:
+ with client.devboxes.logs.with_streaming_response.tail(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ log = response.parse()
+ assert log is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_tail(self, client: Runloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.devboxes.logs.with_raw_response.tail(
+ "",
+ )
+
class TestAsyncLogs:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
@@ -96,3 +134,41 @@ async def test_path_params_list(self, async_client: AsyncRunloop) -> None:
await async_client.devboxes.logs.with_raw_response.list(
"",
)
+
+ @parametrize
+ async def test_method_tail(self, async_client: AsyncRunloop) -> None:
+ log = await async_client.devboxes.logs.tail(
+ "id",
+ )
+ assert log is None
+
+ @parametrize
+ async def test_raw_response_tail(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.devboxes.logs.with_raw_response.tail(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ log = await response.parse()
+ assert log is None
+
+ @parametrize
+ async def test_streaming_response_tail(self, async_client: AsyncRunloop) -> None:
+ async with async_client.devboxes.logs.with_streaming_response.tail(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ log = await response.parse()
+ assert log is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_tail(self, async_client: AsyncRunloop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.devboxes.logs.with_raw_response.tail(
+ "",
+ )
diff --git a/tests/api_resources/functions/test_invocations.py b/tests/api_resources/functions/test_invocations.py
index 726e5843c..38953c074 100755
--- a/tests/api_resources/functions/test_invocations.py
+++ b/tests/api_resources/functions/test_invocations.py
@@ -10,7 +10,10 @@
from tests.utils import assert_matches_type
from runloop_api_client import Runloop, AsyncRunloop
from runloop_api_client.types.shared import FunctionInvocationExecutionDetailView
-from runloop_api_client.types.functions import FunctionInvocationListView
+from runloop_api_client.types.functions import (
+ InvocationLogsResponse,
+ FunctionInvocationListView,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -127,6 +130,44 @@ def test_path_params_kill(self, client: Runloop) -> None:
"",
)
+ @parametrize
+ def test_method_logs(self, client: Runloop) -> None:
+ invocation = client.functions.invocations.logs(
+ "invocation_id",
+ )
+ assert_matches_type(InvocationLogsResponse, invocation, path=["response"])
+
+ @parametrize
+ def test_raw_response_logs(self, client: Runloop) -> None:
+ response = client.functions.invocations.with_raw_response.logs(
+ "invocation_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ invocation = response.parse()
+ assert_matches_type(InvocationLogsResponse, invocation, path=["response"])
+
+ @parametrize
+ def test_streaming_response_logs(self, client: Runloop) -> None:
+ with client.functions.invocations.with_streaming_response.logs(
+ "invocation_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ invocation = response.parse()
+ assert_matches_type(InvocationLogsResponse, invocation, 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 `invocation_id` but received ''"):
+ client.functions.invocations.with_raw_response.logs(
+ "",
+ )
+
class TestAsyncInvocations:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
@@ -239,3 +280,41 @@ async def test_path_params_kill(self, async_client: AsyncRunloop) -> None:
await async_client.functions.invocations.with_raw_response.kill(
"",
)
+
+ @parametrize
+ async def test_method_logs(self, async_client: AsyncRunloop) -> None:
+ invocation = await async_client.functions.invocations.logs(
+ "invocation_id",
+ )
+ assert_matches_type(InvocationLogsResponse, invocation, path=["response"])
+
+ @parametrize
+ async def test_raw_response_logs(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.functions.invocations.with_raw_response.logs(
+ "invocation_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ invocation = await response.parse()
+ assert_matches_type(InvocationLogsResponse, invocation, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_logs(self, async_client: AsyncRunloop) -> None:
+ async with async_client.functions.invocations.with_streaming_response.logs(
+ "invocation_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ invocation = await response.parse()
+ assert_matches_type(InvocationLogsResponse, invocation, 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 `invocation_id` but received ''"):
+ await async_client.functions.invocations.with_raw_response.logs(
+ "",
+ )
diff --git a/tests/api_resources/test_deployments.py b/tests/api_resources/test_deployments.py
new file mode 100755
index 000000000..5a83bef98
--- /dev/null
+++ b/tests/api_resources/test_deployments.py
@@ -0,0 +1,398 @@
+# 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(
+ "",
+ )
+
+ @parametrize
+ def test_method_tail(self, client: Runloop) -> None:
+ deployment = client.deployments.tail(
+ "deployment_id",
+ )
+ assert_matches_type(DeploymentTailResponse, deployment, path=["response"])
+
+ @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"])
+
+ @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
+
+ @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(
+ "",
+ )
+
+ @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"])
+
+ @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"])
+
+ @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
+
+ @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
index 1024eb26f..9b82bde44 100755
--- a/tests/api_resources/test_devboxes.py
+++ b/tests/api_resources/test_devboxes.py
@@ -11,9 +11,10 @@
from runloop_api_client import Runloop, AsyncRunloop
from runloop_api_client.types import (
DevboxView,
- DevboxListView,
- DevboxExecutionDetailView,
+ DevboxListResponse,
+ 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")
@@ -106,7 +107,7 @@ def test_path_params_retrieve(self, client: Runloop) -> None:
@parametrize
def test_method_list(self, client: Runloop) -> None:
devbox = client.devboxes.list()
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Runloop) -> None:
@@ -115,7 +116,7 @@ def test_method_list_with_all_params(self, client: Runloop) -> None:
starting_after="starting_after",
status="status",
)
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
@parametrize
def test_raw_response_list(self, client: Runloop) -> None:
@@ -124,7 +125,7 @@ def test_raw_response_list(self, client: Runloop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
devbox = response.parse()
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
@parametrize
def test_streaming_response_list(self, client: Runloop) -> None:
@@ -133,10 +134,94 @@ def test_streaming_response_list(self, client: Runloop) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
devbox = response.parse()
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
assert cast(Any, response.is_closed) is True
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, path=["response"])
+
+ @parametrize
+ def test_method_execute_async_with_all_params(self, client: Runloop) -> None:
+ devbox = client.devboxes.execute_async(
+ id="id",
+ command="command",
+ )
+ assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
+
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, path=["response"])
+
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, 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.with_raw_response.execute_async(
+ id="",
+ )
+
@parametrize
def test_method_execute_sync(self, client: Runloop) -> None:
devbox = client.devboxes.execute_sync(
@@ -450,7 +535,7 @@ async def test_path_params_retrieve(self, async_client: AsyncRunloop) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncRunloop) -> None:
devbox = await async_client.devboxes.list()
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncRunloop) -> None:
@@ -459,7 +544,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncRunloop) ->
starting_after="starting_after",
status="status",
)
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncRunloop) -> None:
@@ -468,7 +553,7 @@ async def test_raw_response_list(self, async_client: AsyncRunloop) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
devbox = await response.parse()
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
@parametrize
async def test_streaming_response_list(self, async_client: AsyncRunloop) -> None:
@@ -477,10 +562,94 @@ async def test_streaming_response_list(self, async_client: AsyncRunloop) -> None
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
devbox = await response.parse()
- assert_matches_type(DevboxListView, devbox, path=["response"])
+ assert_matches_type(DevboxListResponse, devbox, path=["response"])
assert cast(Any, response.is_closed) is True
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, path=["response"])
+
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, path=["response"])
+
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, path=["response"])
+
+ @parametrize
+ 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(DevboxAsyncExecutionDetailView, devbox, 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.with_raw_response.execute_async(
+ id="",
+ )
+
@parametrize
async def test_method_execute_sync(self, async_client: AsyncRunloop) -> None:
devbox = await async_client.devboxes.execute_sync(
diff --git a/tests/api_resources/test_functions.py b/tests/api_resources/test_functions.py
index e168b5de1..fa60f9801 100755
--- a/tests/api_resources/test_functions.py
+++ b/tests/api_resources/test_functions.py
@@ -169,6 +169,31 @@ def test_path_params_invoke_sync(self, client: Runloop) -> None:
request={},
)
+ @parametrize
+ def test_method_list_openapi(self, client: Runloop) -> None:
+ function = client.functions.list_openapi()
+ assert_matches_type(object, function, path=["response"])
+
+ @parametrize
+ def test_raw_response_list_openapi(self, client: Runloop) -> None:
+ response = client.functions.with_raw_response.list_openapi()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ function = response.parse()
+ assert_matches_type(object, function, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list_openapi(self, client: Runloop) -> None:
+ with client.functions.with_streaming_response.list_openapi() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ function = response.parse()
+ assert_matches_type(object, function, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
class TestAsyncFunctions:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
@@ -323,3 +348,28 @@ async def test_path_params_invoke_sync(self, async_client: AsyncRunloop) -> None
project_name="project_name",
request={},
)
+
+ @parametrize
+ async def test_method_list_openapi(self, async_client: AsyncRunloop) -> None:
+ function = await async_client.functions.list_openapi()
+ assert_matches_type(object, function, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list_openapi(self, async_client: AsyncRunloop) -> None:
+ response = await async_client.functions.with_raw_response.list_openapi()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ function = await response.parse()
+ assert_matches_type(object, function, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list_openapi(self, async_client: AsyncRunloop) -> None:
+ async with async_client.functions.with_streaming_response.list_openapi() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ function = await response.parse()
+ assert_matches_type(object, function, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/test_client.py b/tests/test_client.py
index a9738496a..ab10be034 100755
--- 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)