Skip to content

Commit 2bf5311

Browse files
committed
pr changes
1 parent 5ff16ec commit 2bf5311

18 files changed

Lines changed: 1562 additions & 3 deletions

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ dependencies = [
1616
"distro>=1.7.0, <2",
1717
"sniffio",
1818
"uuid-utils>=0.11.0",
19+
"websocket-client>=1.8.0, <2",
20+
"websockets>=13.0, <16",
1921
]
2022

2123
requires-python = ">= 3.9"

requirements-dev.lock

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ certifi==2026.1.4
1515
# httpx
1616
colorama==0.4.6 ; sys_platform == 'win32'
1717
# via pytest
18+
coverage==7.10.7 ; python_full_version < '3.10'
19+
# via pytest-cov
20+
coverage==7.13.4 ; python_full_version >= '3.10'
21+
# via pytest-cov
1822
dirty-equals==0.11
1923
distro==1.9.0
2024
# via runloop-api-client
@@ -26,12 +30,18 @@ execnet==2.1.2
2630
# via pytest-xdist
2731
h11==0.16.0
2832
# via httpcore
33+
h2==4.3.0
34+
# via httpx
35+
hpack==4.1.0
36+
# via h2
2937
httpcore==1.0.9
3038
# via httpx
3139
httpx==0.28.1
3240
# via
3341
# respx
3442
# runloop-api-client
43+
hyperframe==6.1.0
44+
# via h2
3545
idna==3.11
3646
# via
3747
# anyio
@@ -57,7 +67,9 @@ packaging==25.0
5767
pathspec==1.0.3
5868
# via mypy
5969
pluggy==1.6.0
60-
# via pytest
70+
# via
71+
# pytest
72+
# pytest-cov
6173
pydantic==2.12.5
6274
# via runloop-api-client
6375
pydantic-core==2.41.5
@@ -70,16 +82,25 @@ pyright==1.1.399
7082
pytest==8.4.2 ; python_full_version < '3.10'
7183
# via
7284
# pytest-asyncio
85+
# pytest-cov
86+
# pytest-timeout
7387
# pytest-xdist
7488
pytest==9.0.2 ; python_full_version >= '3.10'
7589
# via
7690
# pytest-asyncio
91+
# pytest-cov
92+
# pytest-timeout
7793
# pytest-xdist
7894
pytest-asyncio==1.2.0 ; python_full_version < '3.10'
7995
pytest-asyncio==1.3.0 ; python_full_version >= '3.10'
96+
pytest-cov==7.0.0
97+
pytest-timeout==2.4.0
8098
pytest-xdist==3.8.0
8199
python-dateutil==2.9.0.post0 ; python_full_version < '3.10'
82100
# via time-machine
101+
python-frontmatter==1.1.0
102+
pyyaml==6.0.3
103+
# via python-frontmatter
83104
respx==0.22.0
84105
rich==14.2.0
85106
ruff==0.14.13
@@ -89,8 +110,9 @@ sniffio==1.3.1
89110
# via runloop-api-client
90111
time-machine==2.19.0 ; python_full_version < '3.10'
91112
time-machine==3.2.0 ; python_full_version >= '3.10'
92-
tomli==2.4.0 ; python_full_version < '3.11'
113+
tomli==2.4.0 ; python_full_version <= '3.11'
93114
# via
115+
# coverage
94116
# mypy
95117
# pytest
96118
typing-extensions==4.15.0
@@ -106,5 +128,11 @@ typing-extensions==4.15.0
106128
# typing-inspection
107129
typing-inspection==0.4.2
108130
# via pydantic
131+
uuid-utils==0.14.1
132+
# via runloop-api-client
133+
websocket-client==1.9.0
134+
# via runloop-api-client
135+
websockets==15.0.1
136+
# via runloop-api-client
109137
zipp==3.23.0
110138
# via importlib-metadata

src/runloop_api_client/_client.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
if TYPE_CHECKING:
3838
from .resources import (
39+
pty,
3940
axons,
4041
agents,
4142
apikeys,
@@ -52,6 +53,7 @@
5253
restricted_keys,
5354
network_policies,
5455
)
56+
from .resources.pty import PtyResource, AsyncPtyResource
5557
from .resources.agents import AgentsResource, AsyncAgentsResource
5658
from .resources.apikeys import ApikeysResource, AsyncApikeysResource
5759
from .resources.objects import ObjectsResource, AsyncObjectsResource
@@ -184,6 +186,12 @@ def devboxes(self) -> DevboxesResource:
184186

185187
return DevboxesResource(self)
186188

189+
@cached_property
190+
def pty(self) -> PtyResource:
191+
from .resources.pty import PtyResource
192+
193+
return PtyResource(self)
194+
187195
@cached_property
188196
def scenarios(self) -> ScenariosResource:
189197
from .resources.scenarios import ScenariosResource
@@ -466,6 +474,12 @@ def devboxes(self) -> AsyncDevboxesResource:
466474

467475
return AsyncDevboxesResource(self)
468476

477+
@cached_property
478+
def pty(self) -> AsyncPtyResource:
479+
from .resources.pty import AsyncPtyResource
480+
481+
return AsyncPtyResource(self)
482+
469483
@cached_property
470484
def scenarios(self) -> AsyncScenariosResource:
471485
from .resources.scenarios import AsyncScenariosResource
@@ -683,6 +697,12 @@ def devboxes(self) -> devboxes.DevboxesResourceWithRawResponse:
683697

684698
return DevboxesResourceWithRawResponse(self._client.devboxes)
685699

700+
@cached_property
701+
def pty(self) -> pty.PtyResourceWithRawResponse:
702+
from .resources.pty import PtyResourceWithRawResponse
703+
704+
return PtyResourceWithRawResponse(self._client.pty)
705+
686706
@cached_property
687707
def scenarios(self) -> scenarios.ScenariosResourceWithRawResponse:
688708
from .resources.scenarios import ScenariosResourceWithRawResponse
@@ -780,6 +800,12 @@ def devboxes(self) -> devboxes.AsyncDevboxesResourceWithRawResponse:
780800

781801
return AsyncDevboxesResourceWithRawResponse(self._client.devboxes)
782802

803+
@cached_property
804+
def pty(self) -> pty.AsyncPtyResourceWithRawResponse:
805+
from .resources.pty import AsyncPtyResourceWithRawResponse
806+
807+
return AsyncPtyResourceWithRawResponse(self._client.pty)
808+
783809
@cached_property
784810
def scenarios(self) -> scenarios.AsyncScenariosResourceWithRawResponse:
785811
from .resources.scenarios import AsyncScenariosResourceWithRawResponse
@@ -877,6 +903,12 @@ def devboxes(self) -> devboxes.DevboxesResourceWithStreamingResponse:
877903

878904
return DevboxesResourceWithStreamingResponse(self._client.devboxes)
879905

906+
@cached_property
907+
def pty(self) -> pty.PtyResourceWithStreamingResponse:
908+
from .resources.pty import PtyResourceWithStreamingResponse
909+
910+
return PtyResourceWithStreamingResponse(self._client.pty)
911+
880912
@cached_property
881913
def scenarios(self) -> scenarios.ScenariosResourceWithStreamingResponse:
882914
from .resources.scenarios import ScenariosResourceWithStreamingResponse
@@ -974,6 +1006,12 @@ def devboxes(self) -> devboxes.AsyncDevboxesResourceWithStreamingResponse:
9741006

9751007
return AsyncDevboxesResourceWithStreamingResponse(self._client.devboxes)
9761008

1009+
@cached_property
1010+
def pty(self) -> pty.AsyncPtyResourceWithStreamingResponse:
1011+
from .resources.pty import AsyncPtyResourceWithStreamingResponse
1012+
1013+
return AsyncPtyResourceWithStreamingResponse(self._client.pty)
1014+
9771015
@cached_property
9781016
def scenarios(self) -> scenarios.AsyncScenariosResourceWithStreamingResponse:
9791017
from .resources.scenarios import AsyncScenariosResourceWithStreamingResponse

src/runloop_api_client/resources/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424
ApikeysResourceWithStreamingResponse,
2525
AsyncApikeysResourceWithStreamingResponse,
2626
)
27+
from .pty import (
28+
PtyResource,
29+
AsyncPtyResource,
30+
PtyResourceWithRawResponse,
31+
AsyncPtyResourceWithRawResponse,
32+
PtyResourceWithStreamingResponse,
33+
AsyncPtyResourceWithStreamingResponse,
34+
)
2735
from .objects import (
2836
ObjectsResource,
2937
AsyncObjectsResource,
@@ -206,6 +214,12 @@
206214
"AsyncApikeysResourceWithRawResponse",
207215
"ApikeysResourceWithStreamingResponse",
208216
"AsyncApikeysResourceWithStreamingResponse",
217+
"PtyResource",
218+
"AsyncPtyResource",
219+
"PtyResourceWithRawResponse",
220+
"AsyncPtyResourceWithRawResponse",
221+
"PtyResourceWithStreamingResponse",
222+
"AsyncPtyResourceWithStreamingResponse",
209223
"RestrictedKeysResource",
210224
"AsyncRestrictedKeysResource",
211225
"RestrictedKeysResourceWithRawResponse",

src/runloop_api_client/resources/devboxes/devboxes.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,31 @@ def enable_tunnel(
777777
cast_to=TunnelView,
778778
)
779779

780+
def create_pty_tunnel(
781+
self,
782+
id: str,
783+
*,
784+
extra_headers: Headers | None = None,
785+
extra_query: Query | None = None,
786+
extra_body: Body | None = None,
787+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
788+
idempotency_key: str | None = None,
789+
) -> TunnelView:
790+
"""Create an authenticated tunnel for high-level PTY access."""
791+
if not id:
792+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
793+
return self._post(
794+
path_template("/v1/devboxes/{id}/create_pty_tunnel", id=id),
795+
options=make_request_options(
796+
extra_headers=extra_headers,
797+
extra_query=extra_query,
798+
extra_body=extra_body,
799+
timeout=timeout,
800+
idempotency_key=idempotency_key,
801+
),
802+
cast_to=TunnelView,
803+
)
804+
780805
def execute(
781806
self,
782807
id: str,
@@ -2395,6 +2420,31 @@ async def enable_tunnel(
23952420
cast_to=TunnelView,
23962421
)
23972422

2423+
async def create_pty_tunnel(
2424+
self,
2425+
id: str,
2426+
*,
2427+
extra_headers: Headers | None = None,
2428+
extra_query: Query | None = None,
2429+
extra_body: Body | None = None,
2430+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
2431+
idempotency_key: str | None = None,
2432+
) -> TunnelView:
2433+
"""Create an authenticated tunnel for high-level PTY access."""
2434+
if not id:
2435+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2436+
return await self._post(
2437+
path_template("/v1/devboxes/{id}/create_pty_tunnel", id=id),
2438+
options=make_request_options(
2439+
extra_headers=extra_headers,
2440+
extra_query=extra_query,
2441+
extra_body=extra_body,
2442+
timeout=timeout,
2443+
idempotency_key=idempotency_key,
2444+
),
2445+
cast_to=TunnelView,
2446+
)
2447+
23982448
async def execute(
23992449
self,
24002450
id: str,
@@ -3388,6 +3438,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
33883438
self.enable_tunnel = to_raw_response_wrapper(
33893439
devboxes.enable_tunnel,
33903440
)
3441+
self.create_pty_tunnel = to_raw_response_wrapper(
3442+
devboxes.create_pty_tunnel,
3443+
)
33913444
self.execute = to_raw_response_wrapper(
33923445
devboxes.execute,
33933446
)
@@ -3481,6 +3534,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
34813534
self.enable_tunnel = async_to_raw_response_wrapper(
34823535
devboxes.enable_tunnel,
34833536
)
3537+
self.create_pty_tunnel = async_to_raw_response_wrapper(
3538+
devboxes.create_pty_tunnel,
3539+
)
34843540
self.execute = async_to_raw_response_wrapper(
34853541
devboxes.execute,
34863542
)
@@ -3574,6 +3630,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
35743630
self.enable_tunnel = to_streamed_response_wrapper(
35753631
devboxes.enable_tunnel,
35763632
)
3633+
self.create_pty_tunnel = to_streamed_response_wrapper(
3634+
devboxes.create_pty_tunnel,
3635+
)
35773636
self.execute = to_streamed_response_wrapper(
35783637
devboxes.execute,
35793638
)
@@ -3667,6 +3726,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
36673726
self.enable_tunnel = async_to_streamed_response_wrapper(
36683727
devboxes.enable_tunnel,
36693728
)
3729+
self.create_pty_tunnel = async_to_streamed_response_wrapper(
3730+
devboxes.create_pty_tunnel,
3731+
)
36703732
self.execute = async_to_streamed_response_wrapper(
36713733
devboxes.execute,
36723734
)

0 commit comments

Comments
 (0)