Skip to content

Commit 08c5bd7

Browse files
release: 1.5.0 (#729)
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 016bb0e commit 08c5bd7

File tree

12 files changed

+274
-31
lines changed

12 files changed

+274
-31
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.4.0"
2+
".": "1.5.0"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 111
1+
configured_endpoints: 112
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-84e997ca5716b9378a58a1bdf3d6616cf3be80156a6aaed1bed469fe93ba2c95.yml
33
openapi_spec_hash: b44a4ba1c2c3cb775c14545f2bab05a8
4-
config_hash: 22f65246be4646c23dde9f69f51252e7
4+
config_hash: 6c26299fd9ef01fb4713612a9a2ad17c

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 1.5.0 (2026-01-30)
4+
5+
Full Changelog: [v1.4.0...v1.5.0](https://github.com/runloopai/api-client-python/compare/v1.4.0...v1.5.0)
6+
7+
### Features
8+
9+
* **devbox:** add enable_tunnel API ([#7236](https://github.com/runloopai/api-client-python/issues/7236)) ([bb58bfc](https://github.com/runloopai/api-client-python/commit/bb58bfc40c93c5832634ddb82c255ada7214c7f4))
10+
311
## 1.4.0 (2026-01-30)
412

513
Full Changelog: [v1.3.2...v1.4.0](https://github.com/runloopai/api-client-python/compare/v1.3.2...v1.4.0)

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ from runloop_api_client.types import (
132132
DevboxSnapshotView,
133133
DevboxTunnelView,
134134
DevboxView,
135+
TunnelView,
135136
DevboxCreateSSHKeyResponse,
136137
DevboxReadFileContentsResponse,
137138
)
@@ -148,6 +149,7 @@ Methods:
148149
- <code title="post /v1/devboxes/{id}/create_tunnel">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">create_tunnel</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_create_tunnel_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_tunnel_view.py">DevboxTunnelView</a></code>
149150
- <code title="post /v1/devboxes/disk_snapshots/{id}/delete">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">delete_disk_snapshot</a>(id) -> object</code>
150151
- <code title="post /v1/devboxes/{id}/download_file">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">download_file</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_download_file_params.py">params</a>) -> BinaryAPIResponse</code>
152+
- <code title="post /v1/devboxes/{id}/enable_tunnel">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">enable_tunnel</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_enable_tunnel_params.py">params</a>) -> <a href="./src/runloop_api_client/types/tunnel_view.py">TunnelView</a></code>
151153
- <code title="post /v1/devboxes/{id}/execute">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">execute</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_execute_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_async_execution_detail_view.py">DevboxAsyncExecutionDetailView</a></code>
152154
- <code title="post /v1/devboxes/{id}/execute_async">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">execute_async</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_execute_async_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_async_execution_detail_view.py">DevboxAsyncExecutionDetailView</a></code>
153155
- <code title="post /v1/devboxes/{id}/execute_sync">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">execute_sync</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_execute_sync_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_execution_detail_view.py">DevboxExecutionDetailView</a></code>

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "runloop_api_client"
3-
version = "1.4.0"
3+
version = "1.5.0"
44
description = "The official Python library for the runloop API"
55
dynamic = ["readme"]
66
license = "MIT"

src/runloop_api_client/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "runloop_api_client"
4-
__version__ = "1.4.0" # x-release-please-version
4+
__version__ = "1.5.0" # x-release-please-version

src/runloop_api_client/resources/devboxes/devboxes.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
devbox_execute_sync_params,
2929
devbox_create_tunnel_params,
3030
devbox_download_file_params,
31+
devbox_enable_tunnel_params,
3132
devbox_execute_async_params,
3233
devbox_remove_tunnel_params,
3334
devbox_snapshot_disk_params,
@@ -99,6 +100,7 @@
99100
)
100101
from ...lib.polling_async import async_poll_until
101102
from ...types.devbox_view import DevboxView
103+
from ...types.tunnel_view import TunnelView
102104
from ...types.devbox_tunnel_view import DevboxTunnelView
103105
from ...types.shared_params.mount import Mount
104106
from ...types.devbox_snapshot_view import DevboxSnapshotView
@@ -787,6 +789,55 @@ def download_file(
787789
cast_to=BinaryAPIResponse,
788790
)
789791

792+
def enable_tunnel(
793+
self,
794+
id: str,
795+
*,
796+
auth_mode: Optional[Literal["open", "authenticated"]] | Omit = omit,
797+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
798+
# The extra values given here take precedence over values defined on the client or passed to this method.
799+
extra_headers: Headers | None = None,
800+
extra_query: Query | None = None,
801+
extra_body: Body | None = None,
802+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
803+
idempotency_key: str | None = None,
804+
) -> TunnelView:
805+
"""Create a V2 tunnel for an existing running Devbox.
806+
807+
Tunnels provide encrypted
808+
URL-based access to the Devbox without exposing internal IDs. The tunnel URL
809+
format is: https://{port}-{tunnel_key}.tunnel.runloop.ai
810+
811+
Each Devbox can have one tunnel.
812+
813+
Args:
814+
auth_mode: Authentication mode for the tunnel. Defaults to 'public' if not specified.
815+
816+
extra_headers: Send extra headers
817+
818+
extra_query: Add additional query parameters to the request
819+
820+
extra_body: Add additional JSON properties to the request
821+
822+
timeout: Override the client-level default timeout for this request, in seconds
823+
824+
idempotency_key: Specify a custom idempotency key for this request
825+
"""
826+
if not id:
827+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
828+
return self._post(
829+
f"/v1/devboxes/{id}/enable_tunnel",
830+
body=maybe_transform({"auth_mode": auth_mode}, devbox_enable_tunnel_params.DevboxEnableTunnelParams),
831+
options=make_request_options(
832+
extra_headers=extra_headers,
833+
extra_query=extra_query,
834+
extra_body=extra_body,
835+
timeout=timeout,
836+
idempotency_key=idempotency_key,
837+
),
838+
cast_to=TunnelView,
839+
)
840+
790841
def execute(
791842
self,
792843
id: str,
@@ -2347,6 +2398,57 @@ async def download_file(
23472398
cast_to=AsyncBinaryAPIResponse,
23482399
)
23492400

2401+
async def enable_tunnel(
2402+
self,
2403+
id: str,
2404+
*,
2405+
auth_mode: Optional[Literal["open", "authenticated"]] | Omit = omit,
2406+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2407+
# The extra values given here take precedence over values defined on the client or passed to this method.
2408+
extra_headers: Headers | None = None,
2409+
extra_query: Query | None = None,
2410+
extra_body: Body | None = None,
2411+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
2412+
idempotency_key: str | None = None,
2413+
) -> TunnelView:
2414+
"""Create a V2 tunnel for an existing running Devbox.
2415+
2416+
Tunnels provide encrypted
2417+
URL-based access to the Devbox without exposing internal IDs. The tunnel URL
2418+
format is: https://{port}-{tunnel_key}.tunnel.runloop.ai
2419+
2420+
Each Devbox can have one tunnel.
2421+
2422+
Args:
2423+
auth_mode: Authentication mode for the tunnel. Defaults to 'public' if not specified.
2424+
2425+
extra_headers: Send extra headers
2426+
2427+
extra_query: Add additional query parameters to the request
2428+
2429+
extra_body: Add additional JSON properties to the request
2430+
2431+
timeout: Override the client-level default timeout for this request, in seconds
2432+
2433+
idempotency_key: Specify a custom idempotency key for this request
2434+
"""
2435+
if not id:
2436+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2437+
return await self._post(
2438+
f"/v1/devboxes/{id}/enable_tunnel",
2439+
body=await async_maybe_transform(
2440+
{"auth_mode": auth_mode}, devbox_enable_tunnel_params.DevboxEnableTunnelParams
2441+
),
2442+
options=make_request_options(
2443+
extra_headers=extra_headers,
2444+
extra_query=extra_query,
2445+
extra_body=extra_body,
2446+
timeout=timeout,
2447+
idempotency_key=idempotency_key,
2448+
),
2449+
cast_to=TunnelView,
2450+
)
2451+
23502452
async def execute(
23512453
self,
23522454
id: str,
@@ -3293,6 +3395,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
32933395
devboxes.download_file,
32943396
BinaryAPIResponse,
32953397
)
3398+
self.enable_tunnel = to_raw_response_wrapper(
3399+
devboxes.enable_tunnel,
3400+
)
32963401
self.execute = to_raw_response_wrapper(
32973402
devboxes.execute,
32983403
)
@@ -3395,6 +3500,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
33953500
devboxes.download_file,
33963501
AsyncBinaryAPIResponse,
33973502
)
3503+
self.enable_tunnel = async_to_raw_response_wrapper(
3504+
devboxes.enable_tunnel,
3505+
)
33983506
self.execute = async_to_raw_response_wrapper(
33993507
devboxes.execute,
34003508
)
@@ -3497,6 +3605,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
34973605
devboxes.download_file,
34983606
StreamedBinaryAPIResponse,
34993607
)
3608+
self.enable_tunnel = to_streamed_response_wrapper(
3609+
devboxes.enable_tunnel,
3610+
)
35003611
self.execute = to_streamed_response_wrapper(
35013612
devboxes.execute,
35023613
)
@@ -3599,6 +3710,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
35993710
devboxes.download_file,
36003711
AsyncStreamedBinaryAPIResponse,
36013712
)
3713+
self.enable_tunnel = async_to_streamed_response_wrapper(
3714+
devboxes.enable_tunnel,
3715+
)
36023716
self.execute = async_to_streamed_response_wrapper(
36033717
devboxes.execute,
36043718
)

src/runloop_api_client/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from .devbox_view import DevboxView as DevboxView
1717
from .object_view import ObjectView as ObjectView
1818
from .secret_view import SecretView as SecretView
19+
from .tunnel_view import TunnelView as TunnelView
1920
from .input_context import InputContext as InputContext
2021
from .scenario_view import ScenarioView as ScenarioView
2122
from .benchmark_view import BenchmarkView as BenchmarkView
@@ -91,6 +92,7 @@
9192
from .benchmark_job_create_params import BenchmarkJobCreateParams as BenchmarkJobCreateParams
9293
from .devbox_create_tunnel_params import DevboxCreateTunnelParams as DevboxCreateTunnelParams
9394
from .devbox_download_file_params import DevboxDownloadFileParams as DevboxDownloadFileParams
95+
from .devbox_enable_tunnel_params import DevboxEnableTunnelParams as DevboxEnableTunnelParams
9496
from .devbox_execute_async_params import DevboxExecuteAsyncParams as DevboxExecuteAsyncParams
9597
from .devbox_remove_tunnel_params import DevboxRemoveTunnelParams as DevboxRemoveTunnelParams
9698
from .devbox_snapshot_disk_params import DevboxSnapshotDiskParams as DevboxSnapshotDiskParams
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing import Optional
6+
from typing_extensions import Literal, TypedDict
7+
8+
__all__ = ["DevboxEnableTunnelParams"]
9+
10+
11+
class DevboxEnableTunnelParams(TypedDict, total=False):
12+
auth_mode: Optional[Literal["open", "authenticated"]]
13+
"""Authentication mode for the tunnel. Defaults to 'public' if not specified."""

src/runloop_api_client/types/devbox_view.py

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from typing_extensions import Literal
55

66
from .._models import BaseModel
7+
from .tunnel_view import TunnelView
78
from .shared.launch_parameters import LaunchParameters
89

9-
__all__ = ["DevboxView", "StateTransition", "GatewaySpecs", "Tunnel"]
10+
__all__ = ["DevboxView", "StateTransition", "GatewaySpecs"]
1011

1112

1213
class StateTransition(BaseModel):
@@ -38,30 +39,6 @@ class GatewaySpecs(BaseModel):
3839
"""The ID of the secret containing the credential."""
3940

4041

41-
class Tunnel(BaseModel):
42-
"""
43-
V2 tunnel information if a tunnel was created at launch time or via the createTunnel API.
44-
"""
45-
46-
auth_mode: Literal["public_", "authenticated"]
47-
"""The authentication mode for the tunnel."""
48-
49-
create_time_ms: int
50-
"""Creation time of the tunnel (Unix timestamp milliseconds)."""
51-
52-
tunnel_key: str
53-
"""The encrypted tunnel key used to construct the tunnel URL.
54-
55-
URL format: https://{port}-{tunnel_key}.tunnel.runloop.{domain}
56-
"""
57-
58-
auth_token: Optional[str] = None
59-
"""Bearer token for tunnel authentication.
60-
61-
Only present when auth_mode is 'authenticated'.
62-
"""
63-
64-
6542
class DevboxView(BaseModel):
6643
"""A Devbox represents a virtual development environment.
6744
@@ -137,7 +114,7 @@ class DevboxView(BaseModel):
137114
Snapshot.
138115
"""
139116

140-
tunnel: Optional[Tunnel] = None
117+
tunnel: Optional[TunnelView] = None
141118
"""
142119
V2 tunnel information if a tunnel was created at launch time or via the
143120
createTunnel API.

0 commit comments

Comments
 (0)