Skip to content

Commit 2081caf

Browse files
feat(api): api update
1 parent cd055fb commit 2081caf

7 files changed

Lines changed: 220 additions & 3 deletions

File tree

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 35
1+
configured_endpoints: 36
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-f62eb21825a70921af8d88fe8eea69e1de89be49cf6a1b0f4cb068eb95f774c5.yml
33
openapi_spec_hash: 535d95b67167cf38a0c5d9d08ed273bd
4-
config_hash: d62791c689042fb10adf838253a71a6e
4+
config_hash: e49b3f69d57d7ffa0420acf772d5c846

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ from steel.types import (
5656
Session,
5757
SessionContext,
5858
Sessionslist,
59+
SessionComputerResponse,
5960
SessionEventsResponse,
6061
SessionLiveDetailsResponse,
6162
SessionReleaseResponse,
@@ -68,6 +69,7 @@ Methods:
6869
- <code title="post /v1/sessions">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">create</a>(\*\*<a href="src/steel/types/session_create_params.py">params</a>) -> <a href="./src/steel/types/session.py">Session</a></code>
6970
- <code title="get /v1/sessions/{id}">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">retrieve</a>(id) -> <a href="./src/steel/types/session.py">Session</a></code>
7071
- <code title="get /v1/sessions">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">list</a>(\*\*<a href="src/steel/types/session_list_params.py">params</a>) -> SyncSessionsCursor[Session]</code>
72+
- <code title="post /v1/sessions/{sessionId}/computer">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">computer</a>(session_id, \*\*<a href="src/steel/types/session_computer_params.py">params</a>) -> <a href="./src/steel/types/session_computer_response.py">SessionComputerResponse</a></code>
7173
- <code title="get /v1/sessions/{id}/context">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">context</a>(id) -> <a href="./src/steel/types/session_context.py">SessionContext</a></code>
7274
- <code title="get /v1/sessions/{id}/events">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">events</a>(id) -> <a href="./src/steel/types/session_events_response.py">SessionEventsResponse</a></code>
7375
- <code title="get /v1/sessions/{id}/live-details">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">live_details</a>(id) -> <a href="./src/steel/types/session_live_details_response.py">SessionLiveDetailsResponse</a></code>

src/steel/resources/sessions/sessions.py

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
FilesResourceWithStreamingResponse,
1515
AsyncFilesResourceWithStreamingResponse,
1616
)
17-
from ...types import session_list_params, session_create_params
17+
from ...types import session_list_params, session_create_params, session_computer_params
1818
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
1919
from ..._utils import maybe_transform, async_maybe_transform
2020
from .captchas import (
@@ -40,6 +40,7 @@
4040
from ...types.session_context import SessionContext
4141
from ...types.session_events_response import SessionEventsResponse
4242
from ...types.session_release_response import SessionReleaseResponse
43+
from ...types.session_computer_response import SessionComputerResponse
4344
from ...types.session_release_all_response import SessionReleaseAllResponse
4445
from ...types.session_live_details_response import SessionLiveDetailsResponse
4546

@@ -286,6 +287,43 @@ def list(
286287
model=SessionslistSession,
287288
)
288289

290+
def computer(
291+
self,
292+
session_id: str,
293+
*,
294+
body: object | Omit = omit,
295+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
296+
# The extra values given here take precedence over values defined on the client or passed to this method.
297+
extra_headers: Headers | None = None,
298+
extra_query: Query | None = None,
299+
extra_body: Body | None = None,
300+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
301+
) -> SessionComputerResponse:
302+
"""
303+
Execute computer actions like mouse movements, clicks, keyboard input, and more
304+
305+
Args:
306+
body: Computer action to execute (validation done in controller)
307+
308+
extra_headers: Send extra headers
309+
310+
extra_query: Add additional query parameters to the request
311+
312+
extra_body: Add additional JSON properties to the request
313+
314+
timeout: Override the client-level default timeout for this request, in seconds
315+
"""
316+
if not session_id:
317+
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
318+
return self._post(
319+
f"/v1/sessions/{session_id}/computer",
320+
body=maybe_transform(body, session_computer_params.SessionComputerParams),
321+
options=make_request_options(
322+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
323+
),
324+
cast_to=SessionComputerResponse,
325+
)
326+
289327
def context(
290328
self,
291329
id: str,
@@ -678,6 +716,43 @@ def list(
678716
model=SessionslistSession,
679717
)
680718

719+
async def computer(
720+
self,
721+
session_id: str,
722+
*,
723+
body: object | Omit = omit,
724+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
725+
# The extra values given here take precedence over values defined on the client or passed to this method.
726+
extra_headers: Headers | None = None,
727+
extra_query: Query | None = None,
728+
extra_body: Body | None = None,
729+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
730+
) -> SessionComputerResponse:
731+
"""
732+
Execute computer actions like mouse movements, clicks, keyboard input, and more
733+
734+
Args:
735+
body: Computer action to execute (validation done in controller)
736+
737+
extra_headers: Send extra headers
738+
739+
extra_query: Add additional query parameters to the request
740+
741+
extra_body: Add additional JSON properties to the request
742+
743+
timeout: Override the client-level default timeout for this request, in seconds
744+
"""
745+
if not session_id:
746+
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
747+
return await self._post(
748+
f"/v1/sessions/{session_id}/computer",
749+
body=await async_maybe_transform(body, session_computer_params.SessionComputerParams),
750+
options=make_request_options(
751+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
752+
),
753+
cast_to=SessionComputerResponse,
754+
)
755+
681756
async def context(
682757
self,
683758
id: str,
@@ -843,6 +918,9 @@ def __init__(self, sessions: SessionsResource) -> None:
843918
self.list = to_raw_response_wrapper(
844919
sessions.list,
845920
)
921+
self.computer = to_raw_response_wrapper(
922+
sessions.computer,
923+
)
846924
self.context = to_raw_response_wrapper(
847925
sessions.context,
848926
)
@@ -881,6 +959,9 @@ def __init__(self, sessions: AsyncSessionsResource) -> None:
881959
self.list = async_to_raw_response_wrapper(
882960
sessions.list,
883961
)
962+
self.computer = async_to_raw_response_wrapper(
963+
sessions.computer,
964+
)
884965
self.context = async_to_raw_response_wrapper(
885966
sessions.context,
886967
)
@@ -919,6 +1000,9 @@ def __init__(self, sessions: SessionsResource) -> None:
9191000
self.list = to_streamed_response_wrapper(
9201001
sessions.list,
9211002
)
1003+
self.computer = to_streamed_response_wrapper(
1004+
sessions.computer,
1005+
)
9221006
self.context = to_streamed_response_wrapper(
9231007
sessions.context,
9241008
)
@@ -957,6 +1041,9 @@ def __init__(self, sessions: AsyncSessionsResource) -> None:
9571041
self.list = async_to_streamed_response_wrapper(
9581042
sessions.list,
9591043
)
1044+
self.computer = async_to_streamed_response_wrapper(
1045+
sessions.computer,
1046+
)
9601047
self.context = async_to_streamed_response_wrapper(
9611048
sessions.context,
9621049
)

src/steel/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from .extension_update_params import ExtensionUpdateParams as ExtensionUpdateParams
2323
from .extension_upload_params import ExtensionUploadParams as ExtensionUploadParams
2424
from .profile_create_response import ProfileCreateResponse as ProfileCreateResponse
25+
from .session_computer_params import SessionComputerParams as SessionComputerParams
2526
from .session_events_response import SessionEventsResponse as SessionEventsResponse
2627
from .client_screenshot_params import ClientScreenshotParams as ClientScreenshotParams
2728
from .credential_create_params import CredentialCreateParams as CredentialCreateParams
@@ -32,6 +33,7 @@
3233
from .extension_delete_response import ExtensionDeleteResponse as ExtensionDeleteResponse
3334
from .extension_update_response import ExtensionUpdateResponse as ExtensionUpdateResponse
3435
from .extension_upload_response import ExtensionUploadResponse as ExtensionUploadResponse
36+
from .session_computer_response import SessionComputerResponse as SessionComputerResponse
3537
from .credential_create_response import CredentialCreateResponse as CredentialCreateResponse
3638
from .credential_delete_response import CredentialDeleteResponse as CredentialDeleteResponse
3739
from .credential_update_response import CredentialUpdateResponse as CredentialUpdateResponse
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import TypedDict
6+
7+
__all__ = ["SessionComputerParams"]
8+
9+
10+
class SessionComputerParams(TypedDict, total=False):
11+
body: object
12+
"""Computer action to execute (validation done in controller)"""
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Optional
4+
5+
from .._models import BaseModel
6+
7+
__all__ = ["SessionComputerResponse"]
8+
9+
10+
class SessionComputerResponse(BaseModel):
11+
base64_image: Optional[str] = None
12+
"""Base64 encoded screenshot if requested"""
13+
14+
error: Optional[str] = None
15+
"""Error message if action failed"""
16+
17+
output: Optional[str] = None
18+
"""Output message from the action"""
19+
20+
system: Optional[str] = None
21+
"""System information"""

tests/api_resources/test_sessions.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
SessionContext,
1414
SessionEventsResponse,
1515
SessionReleaseResponse,
16+
SessionComputerResponse,
1617
SessionReleaseAllResponse,
1718
SessionLiveDetailsResponse,
1819
)
@@ -217,6 +218,52 @@ def test_streaming_response_list(self, client: Steel) -> None:
217218

218219
assert cast(Any, response.is_closed) is True
219220

221+
@parametrize
222+
def test_method_computer(self, client: Steel) -> None:
223+
session = client.sessions.computer(
224+
session_id="sessionId",
225+
)
226+
assert_matches_type(SessionComputerResponse, session, path=["response"])
227+
228+
@parametrize
229+
def test_method_computer_with_all_params(self, client: Steel) -> None:
230+
session = client.sessions.computer(
231+
session_id="sessionId",
232+
body={},
233+
)
234+
assert_matches_type(SessionComputerResponse, session, path=["response"])
235+
236+
@parametrize
237+
def test_raw_response_computer(self, client: Steel) -> None:
238+
response = client.sessions.with_raw_response.computer(
239+
session_id="sessionId",
240+
)
241+
242+
assert response.is_closed is True
243+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
244+
session = response.parse()
245+
assert_matches_type(SessionComputerResponse, session, path=["response"])
246+
247+
@parametrize
248+
def test_streaming_response_computer(self, client: Steel) -> None:
249+
with client.sessions.with_streaming_response.computer(
250+
session_id="sessionId",
251+
) as response:
252+
assert not response.is_closed
253+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
254+
255+
session = response.parse()
256+
assert_matches_type(SessionComputerResponse, session, path=["response"])
257+
258+
assert cast(Any, response.is_closed) is True
259+
260+
@parametrize
261+
def test_path_params_computer(self, client: Steel) -> None:
262+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
263+
client.sessions.with_raw_response.computer(
264+
session_id="",
265+
)
266+
220267
@parametrize
221268
def test_method_context(self, client: Steel) -> None:
222269
session = client.sessions.context(
@@ -590,6 +637,52 @@ async def test_streaming_response_list(self, async_client: AsyncSteel) -> None:
590637

591638
assert cast(Any, response.is_closed) is True
592639

640+
@parametrize
641+
async def test_method_computer(self, async_client: AsyncSteel) -> None:
642+
session = await async_client.sessions.computer(
643+
session_id="sessionId",
644+
)
645+
assert_matches_type(SessionComputerResponse, session, path=["response"])
646+
647+
@parametrize
648+
async def test_method_computer_with_all_params(self, async_client: AsyncSteel) -> None:
649+
session = await async_client.sessions.computer(
650+
session_id="sessionId",
651+
body={},
652+
)
653+
assert_matches_type(SessionComputerResponse, session, path=["response"])
654+
655+
@parametrize
656+
async def test_raw_response_computer(self, async_client: AsyncSteel) -> None:
657+
response = await async_client.sessions.with_raw_response.computer(
658+
session_id="sessionId",
659+
)
660+
661+
assert response.is_closed is True
662+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
663+
session = await response.parse()
664+
assert_matches_type(SessionComputerResponse, session, path=["response"])
665+
666+
@parametrize
667+
async def test_streaming_response_computer(self, async_client: AsyncSteel) -> None:
668+
async with async_client.sessions.with_streaming_response.computer(
669+
session_id="sessionId",
670+
) as response:
671+
assert not response.is_closed
672+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
673+
674+
session = await response.parse()
675+
assert_matches_type(SessionComputerResponse, session, path=["response"])
676+
677+
assert cast(Any, response.is_closed) is True
678+
679+
@parametrize
680+
async def test_path_params_computer(self, async_client: AsyncSteel) -> None:
681+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
682+
await async_client.sessions.with_raw_response.computer(
683+
session_id="",
684+
)
685+
593686
@parametrize
594687
async def test_method_context(self, async_client: AsyncSteel) -> None:
595688
session = await async_client.sessions.context(

0 commit comments

Comments
 (0)