Skip to content

Commit c3bebb5

Browse files
release: 1.5.1 (#730)
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> Co-authored-by: Albert Li <albert@runloop.ai>
1 parent 08c5bd7 commit c3bebb5

12 files changed

Lines changed: 170 additions & 9 deletions

File tree

.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.5.0"
2+
".": "1.5.1"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 112
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-84e997ca5716b9378a58a1bdf3d6616cf3be80156a6aaed1bed469fe93ba2c95.yml
3-
openapi_spec_hash: b44a4ba1c2c3cb775c14545f2bab05a8
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-b493cadf2e3b9658163a6bcf8f51e088dda169f12d68469c4441d17e889f5556.yml
3+
openapi_spec_hash: b27ec3822d88d10efa268f1681fddff3
44
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.1 (2026-01-30)
4+
5+
Full Changelog: [v1.5.0...v1.5.1](https://github.com/runloopai/api-client-python/compare/v1.5.0...v1.5.1)
6+
7+
### Chores
8+
9+
* **devbox:** rename tunnel auth enum ([#7239](https://github.com/runloopai/api-client-python/issues/7239)) ([7a9b7a4](https://github.com/runloopai/api-client-python/commit/7a9b7a449ce648ad4f220af83b35f800727ea28d))
10+
311
## 1.5.0 (2026-01-30)
412

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

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.5.0"
3+
version = "1.5.1"
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.5.0" # x-release-please-version
4+
__version__ = "1.5.1" # x-release-please-version

src/runloop_api_client/sdk/_types.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
NetworkPolicyListParams,
2323
DevboxCreateTunnelParams,
2424
DevboxDownloadFileParams,
25+
DevboxEnableTunnelParams,
2526
DevboxRemoveTunnelParams,
2627
DevboxSnapshotDiskParams,
2728
NetworkPolicyCreateParams,
@@ -121,6 +122,10 @@ class SDKDevboxCreateTunnelParams(DevboxCreateTunnelParams, LongRequestOptions):
121122
pass
122123

123124

125+
class SDKDevboxEnableTunnelParams(DevboxEnableTunnelParams, LongRequestOptions):
126+
pass
127+
128+
124129
class SDKDevboxRemoveTunnelParams(DevboxRemoveTunnelParams, LongRequestOptions):
125130
pass
126131

src/runloop_api_client/sdk/async_devbox.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from ..types import (
1212
DevboxView,
13+
TunnelView,
1314
DevboxTunnelView,
1415
DevboxExecutionDetailView,
1516
DevboxCreateSSHKeyResponse,
@@ -24,6 +25,7 @@
2425
SDKDevboxUploadFileParams,
2526
SDKDevboxCreateTunnelParams,
2627
SDKDevboxDownloadFileParams,
28+
SDKDevboxEnableTunnelParams,
2729
SDKDevboxExecuteAsyncParams,
2830
SDKDevboxRemoveTunnelParams,
2931
SDKDevboxSnapshotDiskParams,
@@ -731,7 +733,9 @@ async def create_tunnel(
731733
self,
732734
**params: Unpack[SDKDevboxCreateTunnelParams],
733735
) -> DevboxTunnelView:
734-
"""Create a network tunnel to expose a devbox port publicly.
736+
"""[Deprecated] Create a legacy tunnel to expose a devbox port publicly.
737+
738+
Use :meth:`enable_tunnel` instead for the V2 tunnel API.
735739
736740
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKDevboxCreateTunnelParams` for available parameters
737741
:return: Details about the public endpoint
@@ -748,6 +752,30 @@ async def create_tunnel(
748752
**params,
749753
)
750754

755+
async def enable_tunnel(
756+
self,
757+
**params: Unpack[SDKDevboxEnableTunnelParams],
758+
) -> TunnelView:
759+
"""Enable a V2 tunnel for secure HTTP access to the devbox.
760+
761+
V2 tunnels provide encrypted URL-based access without exposing internal IDs.
762+
Each devbox can have one tunnel. The tunnel URL format is:
763+
``https://{port}-{tunnel_key}.tunnel.runloop.ai``
764+
765+
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKDevboxEnableTunnelParams` for available parameters
766+
:return: Tunnel details including the tunnel key for constructing URLs
767+
:rtype: TunnelView
768+
769+
Example:
770+
>>> tunnel = await devbox.net.enable_tunnel(auth_mode="open")
771+
>>> print(f"Tunnel key: {tunnel.tunnel_key}")
772+
>>> # Access via: https://8080-{tunnel.tunnel_key}.tunnel.runloop.ai
773+
"""
774+
return await self._devbox._client.devboxes.enable_tunnel(
775+
self._devbox.id,
776+
**params,
777+
)
778+
751779
async def remove_tunnel(
752780
self,
753781
**params: Unpack[SDKDevboxRemoveTunnelParams],

src/runloop_api_client/sdk/devbox.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from ..types import (
1212
DevboxView,
13+
TunnelView,
1314
DevboxTunnelView,
1415
DevboxExecutionDetailView,
1516
DevboxCreateSSHKeyResponse,
@@ -25,6 +26,7 @@
2526
SDKDevboxUploadFileParams,
2627
SDKDevboxCreateTunnelParams,
2728
SDKDevboxDownloadFileParams,
29+
SDKDevboxEnableTunnelParams,
2830
SDKDevboxExecuteAsyncParams,
2931
SDKDevboxRemoveTunnelParams,
3032
SDKDevboxSnapshotDiskParams,
@@ -734,7 +736,9 @@ def create_tunnel(
734736
self,
735737
**params: Unpack[SDKDevboxCreateTunnelParams],
736738
) -> DevboxTunnelView:
737-
"""Create a network tunnel to expose a devbox port publicly.
739+
"""[Deprecated] Create a legacy tunnel to expose a devbox port publicly.
740+
741+
Use :meth:`enable_tunnel` instead for the V2 tunnel API.
738742
739743
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKDevboxCreateTunnelParams` for available parameters
740744
:return: Details about the public endpoint
@@ -751,6 +755,30 @@ def create_tunnel(
751755
**params,
752756
)
753757

758+
def enable_tunnel(
759+
self,
760+
**params: Unpack[SDKDevboxEnableTunnelParams],
761+
) -> TunnelView:
762+
"""Enable a V2 tunnel for secure HTTP access to the devbox.
763+
764+
V2 tunnels provide encrypted URL-based access without exposing internal IDs.
765+
Each devbox can have one tunnel. The tunnel URL format is:
766+
``https://{port}-{tunnel_key}.tunnel.runloop.ai``
767+
768+
:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKDevboxEnableTunnelParams` for available parameters
769+
:return: Tunnel details including the tunnel key for constructing URLs
770+
:rtype: :class:`~runloop_api_client.types.tunnel_view.TunnelView`
771+
772+
Example:
773+
>>> tunnel = devbox.net.enable_tunnel(auth_mode="open")
774+
>>> print(f"Tunnel key: {tunnel.tunnel_key}")
775+
>>> # Access via: https://8080-{tunnel.tunnel_key}.tunnel.runloop.ai
776+
"""
777+
return self._devbox._client.devboxes.enable_tunnel(
778+
self._devbox.id,
779+
**params,
780+
)
781+
754782
def remove_tunnel(
755783
self,
756784
**params: Unpack[SDKDevboxRemoveTunnelParams],

src/runloop_api_client/types/tunnel_view.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class TunnelView(BaseModel):
1515
Usage: https://{port}-{tunnel_key}.tunnel.runloop.ai
1616
"""
1717

18-
auth_mode: Literal["public_", "authenticated"]
18+
auth_mode: Literal["open", "authenticated"]
1919
"""The authentication mode for the tunnel."""
2020

2121
create_time_ms: int

tests/smoketests/sdk/test_async_devbox.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,53 @@ async def test_create_and_remove_tunnel(self, async_sdk_client: AsyncRunloopSDK)
458458
finally:
459459
await devbox.shutdown()
460460

461+
@pytest.mark.timeout(TWO_MINUTE_TIMEOUT)
462+
async def test_create_with_tunnel_param(self, async_sdk_client: AsyncRunloopSDK) -> None:
463+
"""Test creating a devbox with tunnel configuration in create params."""
464+
devbox = await async_sdk_client.devbox.create(
465+
name=unique_name("sdk-async-devbox-tunnel-param"),
466+
launch_parameters={"resource_size_request": "SMALL", "keep_alive_time_seconds": 60 * 5},
467+
tunnel={"auth_mode": "open"},
468+
)
469+
470+
try:
471+
# Verify devbox is running
472+
info = await devbox.get_info()
473+
assert info.status == "running"
474+
475+
# Verify tunnel was created at launch
476+
assert info.tunnel is not None
477+
assert info.tunnel.tunnel_key is not None
478+
assert info.tunnel.auth_mode is not None
479+
finally:
480+
await devbox.shutdown()
481+
482+
@pytest.mark.timeout(TWO_MINUTE_TIMEOUT)
483+
async def test_enable_tunnel(self, async_sdk_client: AsyncRunloopSDK) -> None:
484+
"""Test enabling a V2 tunnel on an existing devbox."""
485+
devbox = await async_sdk_client.devbox.create(
486+
name=unique_name("sdk-async-devbox-enable-tunnel"),
487+
launch_parameters={"resource_size_request": "SMALL", "keep_alive_time_seconds": 60 * 5},
488+
)
489+
490+
try:
491+
# Verify no tunnel exists initially
492+
info = await devbox.get_info()
493+
assert info.tunnel is None
494+
495+
# Enable tunnel using the V2 API via SDK
496+
tunnel = await devbox.net.enable_tunnel(auth_mode="open")
497+
assert tunnel is not None
498+
assert tunnel.tunnel_key is not None
499+
assert tunnel.auth_mode is not None
500+
501+
# Verify tunnel is now present in devbox info
502+
info = await devbox.get_info()
503+
assert info.tunnel is not None
504+
assert info.tunnel.tunnel_key == tunnel.tunnel_key
505+
finally:
506+
await devbox.shutdown()
507+
461508

462509
class TestAsyncDevboxCreationMethods:
463510
"""Test various async devbox creation methods."""

0 commit comments

Comments
 (0)