Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.8.0"
".": "1.9.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 117
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-c8d61a0c8b88fa30666ba021d1239eb0d549902354513c4741e9216bcbfa8e6d.yml
openapi_spec_hash: 433e6fb4ce076012b696f69ae7596c67
config_hash: eb28692edd68a6ae95cf92af931c9976
configured_endpoints: 118
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-dd0f43e15cb67179deaf86f83ae04c6fae4ff858ee33e82a3b89231566cdc5bb.yml
openapi_spec_hash: 569176c1c4f48efd25a44fa526fad9d1
config_hash: cbda3692cb48ab8582a0df1674b9e5c8
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Changelog

## 1.9.0 (2026-02-25)

Full Changelog: [v1.8.0...v1.9.0](https://github.com/runloopai/api-client-python/compare/v1.8.0...v1.9.0)

### Features

* Add AI gateway and MCP gateway flags to network policy create ([#7638](https://github.com/runloopai/api-client-python/issues/7638)) ([85f2146](https://github.com/runloopai/api-client-python/commit/85f2146d2f25085d19d5bf34096066b0ba18cb5d))


### Chores

* Add archive method to stainless ([#7537](https://github.com/runloopai/api-client-python/issues/7537)) ([836f18d](https://github.com/runloopai/api-client-python/commit/836f18d52c20b4b43f9135a52571f8c7e87a0477))
* **benchmarks:** removed scorer ([#740](https://github.com/runloopai/api-client-python/issues/740)) ([1033264](https://github.com/runloopai/api-client-python/commit/1033264b0ed34cc47e2e16cac3ae5986f2a4e381))
* format all `api.md` files ([ee5d577](https://github.com/runloopai/api-client-python/commit/ee5d5773d408ac8e61101fd0187ec071709bebab))
* **internal:** add request options to SSE classes ([e636aca](https://github.com/runloopai/api-client-python/commit/e636aca4eedb81b35d80bd6f5229cc71153ec545))
* **internal:** make `test_proxy_environment_variables` more resilient ([564cd57](https://github.com/runloopai/api-client-python/commit/564cd5730fbf94b7014390ee71d7595cb7d6e71a))
* **internal:** make `test_proxy_environment_variables` more resilient to env ([21d4ce8](https://github.com/runloopai/api-client-python/commit/21d4ce865094d9272841871eefde3cf15c183d19))
* **scenarios:** make scenario status enum instead of string ([#7552](https://github.com/runloopai/api-client-python/issues/7552)) ([e6e5208](https://github.com/runloopai/api-client-python/commit/e6e5208c19360f24f10b3c0da84119f7eb356bb1))
* update mock server docs ([273fb5e](https://github.com/runloopai/api-client-python/commit/273fb5ec761bcc5948571d9757780d86b6f0f50d))


### Refactors

* deprecate and make Nullable total_count and remaining_count of ListViews ([#7533](https://github.com/runloopai/api-client-python/issues/7533)) ([8b16ebe](https://github.com/runloopai/api-client-python/commit/8b16ebe7aba9f96592f03ed2844211209b35d9e6))

## 1.8.0 (2026-02-12)

Full Changelog: [v1.7.0...v1.8.0](https://github.com/runloopai/api-client-python/compare/v1.7.0...v1.8.0)
Expand Down
3 changes: 1 addition & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ $ pip install ./path-to-wheel-file.whl
Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.

```sh
# you will need npm installed
npx prism mock path/to/your/openapi.yml
$ ./scripts/mock
```

```sh
Expand Down
3 changes: 2 additions & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Methods:
- <code title="post /v1/devboxes/{id}/remove_tunnel">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">remove_tunnel</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_remove_tunnel_params.py">params</a>) -> object</code>
- <code title="post /v1/devboxes/{id}/resume">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">resume</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
- <code title="get /v1/devboxes/{id}/usage">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">retrieve_resource_usage</a>(id) -> <a href="./src/runloop_api_client/types/devbox_resource_usage_view.py">DevboxResourceUsageView</a></code>
- <code title="post /v1/devboxes/{id}/shutdown">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">shutdown</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
- <code title="post /v1/devboxes/{id}/shutdown">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">shutdown</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_shutdown_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
- <code title="post /v1/devboxes/{id}/snapshot_disk">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">snapshot_disk</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_snapshot_disk_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_snapshot_view.py">DevboxSnapshotView</a></code>
- <code title="post /v1/devboxes/{id}/snapshot_disk_async">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">snapshot_disk_async</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_snapshot_disk_async_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_snapshot_view.py">DevboxSnapshotView</a></code>
- <code title="post /v1/devboxes/{id}/suspend">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">suspend</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
Expand Down Expand Up @@ -277,6 +277,7 @@ Methods:
- <code title="get /v1/scenarios/{id}">client.scenarios.<a href="./src/runloop_api_client/resources/scenarios/scenarios.py">retrieve</a>(id) -> <a href="./src/runloop_api_client/types/scenario_view.py">ScenarioView</a></code>
- <code title="post /v1/scenarios/{id}">client.scenarios.<a href="./src/runloop_api_client/resources/scenarios/scenarios.py">update</a>(id, \*\*<a href="src/runloop_api_client/types/scenario_update_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenario_view.py">ScenarioView</a></code>
- <code title="get /v1/scenarios">client.scenarios.<a href="./src/runloop_api_client/resources/scenarios/scenarios.py">list</a>(\*\*<a href="src/runloop_api_client/types/scenario_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenario_view.py">SyncScenariosCursorIDPage[ScenarioView]</a></code>
- <code title="post /v1/scenarios/{id}/archive">client.scenarios.<a href="./src/runloop_api_client/resources/scenarios/scenarios.py">archive</a>(id) -> <a href="./src/runloop_api_client/types/scenario_view.py">ScenarioView</a></code>
- <code title="get /v1/scenarios/list_public">client.scenarios.<a href="./src/runloop_api_client/resources/scenarios/scenarios.py">list_public</a>(\*\*<a href="src/runloop_api_client/types/scenario_list_public_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenario_view.py">SyncScenariosCursorIDPage[ScenarioView]</a></code>
- <code title="post /v1/scenarios/start_run">client.scenarios.<a href="./src/runloop_api_client/resources/scenarios/scenarios.py">start_run</a>(\*\*<a href="src/runloop_api_client/types/scenario_start_run_params.py">params</a>) -> <a href="./src/runloop_api_client/types/scenario_run_view.py">ScenarioRunView</a></code>

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "runloop_api_client"
version = "1.8.0"
version = "1.9.0"
description = "The official Python library for the runloop API"
dynamic = ["readme"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion scripts/format
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ uv run ruff check --fix .
uv run ruff format

echo "==> Formatting docs"
uv run python scripts/utils/ruffen-docs.py README.md api.md README-SDK.md
uv run python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md)
3 changes: 3 additions & 0 deletions src/runloop_api_client/_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
),
response=self.http_response,
client=cast(Any, self._client),
options=self._options,
),
)

Expand All @@ -162,6 +163,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=extract_stream_chunk_type(self._stream_cls),
response=self.http_response,
client=cast(Any, self._client),
options=self._options,
),
)

Expand All @@ -175,6 +177,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
options=self._options,
),
)

Expand Down
9 changes: 7 additions & 2 deletions src/runloop_api_client/_streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

if TYPE_CHECKING:
from ._client import Runloop, AsyncRunloop
from ._models import FinalRequestOptions


_T = TypeVar("_T")
Expand All @@ -41,7 +42,7 @@ class Stream(Generic[_T]):
"""Provides the core interface to iterate over a synchronous stream response."""

response: httpx.Response

_options: Optional[FinalRequestOptions] = None
_decoder: SSEBytesDecoder

def __init__(
Expand All @@ -50,10 +51,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: Runloop,
options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()

Expand Down Expand Up @@ -114,7 +117,7 @@ class AsyncStream(Generic[_T]):
"""Provides the core interface to iterate over an asynchronous stream response."""

response: httpx.Response

_options: Optional[FinalRequestOptions] = None
_decoder: SSEDecoder | SSEBytesDecoder

def __init__(
Expand All @@ -123,10 +126,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: AsyncRunloop,
options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()

Expand Down
2 changes: 1 addition & 1 deletion src/runloop_api_client/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "runloop_api_client"
__version__ = "1.8.0" # x-release-please-version
__version__ = "1.9.0" # x-release-please-version
39 changes: 35 additions & 4 deletions src/runloop_api_client/resources/devboxes/devboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
devbox_create_params,
devbox_update_params,
devbox_execute_params,
devbox_shutdown_params,
devbox_upload_file_params,
devbox_execute_sync_params,
devbox_create_tunnel_params,
Expand Down Expand Up @@ -806,6 +807,7 @@ def enable_tunnel(
id: str,
*,
auth_mode: Optional[Literal["open", "authenticated"]] | Omit = omit,
http_keep_alive: Optional[bool] | Omit = omit,
# 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,
Expand All @@ -825,6 +827,9 @@ def enable_tunnel(
Args:
auth_mode: Authentication mode for the tunnel. Defaults to 'public' if not specified.

http_keep_alive: When true, HTTP traffic through the tunnel counts as activity for idle lifecycle
policies, resetting the idle timer. Defaults to true if not specified.

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -839,7 +844,13 @@ def enable_tunnel(
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
f"/v1/devboxes/{id}/enable_tunnel",
body=maybe_transform({"auth_mode": auth_mode}, devbox_enable_tunnel_params.DevboxEnableTunnelParams),
body=maybe_transform(
{
"auth_mode": auth_mode,
"http_keep_alive": http_keep_alive,
},
devbox_enable_tunnel_params.DevboxEnableTunnelParams,
),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
Expand Down Expand Up @@ -1415,6 +1426,7 @@ def shutdown(
self,
id: str,
*,
force: str | Omit = omit,
# 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,
Expand All @@ -1427,9 +1439,13 @@ def shutdown(

This will permanently stop the Devbox. If you want to
save the state of the Devbox, you should take a snapshot before shutting down or
should suspend the Devbox instead of shutting down.
should suspend the Devbox instead of shutting down. If the Devbox has any
in-progress snapshots, the shutdown will be rejected with a 409 Conflict unless
force=true is specified.

Args:
force: If true, force shutdown even if snapshots are in progress. Defaults to false.

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -1450,6 +1466,7 @@ def shutdown(
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
query=maybe_transform({"force": force}, devbox_shutdown_params.DevboxShutdownParams),
),
cast_to=DevboxView,
)
Expand Down Expand Up @@ -2465,6 +2482,7 @@ async def enable_tunnel(
id: str,
*,
auth_mode: Optional[Literal["open", "authenticated"]] | Omit = omit,
http_keep_alive: Optional[bool] | Omit = omit,
# 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,
Expand All @@ -2484,6 +2502,9 @@ async def enable_tunnel(
Args:
auth_mode: Authentication mode for the tunnel. Defaults to 'public' if not specified.

http_keep_alive: When true, HTTP traffic through the tunnel counts as activity for idle lifecycle
policies, resetting the idle timer. Defaults to true if not specified.

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -2499,7 +2520,11 @@ async def enable_tunnel(
return await self._post(
f"/v1/devboxes/{id}/enable_tunnel",
body=await async_maybe_transform(
{"auth_mode": auth_mode}, devbox_enable_tunnel_params.DevboxEnableTunnelParams
{
"auth_mode": auth_mode,
"http_keep_alive": http_keep_alive,
},
devbox_enable_tunnel_params.DevboxEnableTunnelParams,
),
options=make_request_options(
extra_headers=extra_headers,
Expand Down Expand Up @@ -3077,6 +3102,7 @@ async def shutdown(
self,
id: str,
*,
force: str | Omit = omit,
# 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,
Expand All @@ -3089,9 +3115,13 @@ async def shutdown(

This will permanently stop the Devbox. If you want to
save the state of the Devbox, you should take a snapshot before shutting down or
should suspend the Devbox instead of shutting down.
should suspend the Devbox instead of shutting down. If the Devbox has any
in-progress snapshots, the shutdown will be rejected with a 409 Conflict unless
force=true is specified.

Args:
force: If true, force shutdown even if snapshots are in progress. Defaults to false.

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -3112,6 +3142,7 @@ async def shutdown(
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
query=await async_maybe_transform({"force": force}, devbox_shutdown_params.DevboxShutdownParams),
),
cast_to=DevboxView,
)
Expand Down
Loading