diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3d26904f..8f3e0a49 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.14.2" + ".": "0.15.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 6bb4af83..b4dc6064 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 57 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-6c765f1c4ce1c4dd4ceb371f56bf047aa79af36031ba43cbd68fa16a5fdb9bb3.yml -openapi_spec_hash: e9086f69281360f4e0895c9274a59531 -config_hash: deadfc4d2b0a947673bcf559b5db6e1b +configured_endpoints: 64 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-e21f0324774a1762bc2bba0da3a8a6b0d0e74720d7a1c83dec813f9e027fcf58.yml +openapi_spec_hash: f1b636abfd6cb8e7c2ba7ffb8e53b9ba +config_hash: 09a2df23048cb16689c9a390d9e5bc47 diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e1ed7b..e9fc2228 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.15.0 (2025-10-17) + +Full Changelog: [v0.14.2...v0.15.0](https://github.com/onkernel/kernel-python-sdk/compare/v0.14.2...v0.15.0) + +### Features + +* click mouse, move mouse, screenshot ([b63f7ad](https://github.com/onkernel/kernel-python-sdk/commit/b63f7adc7cf0da614a4fc3a9eed491f71f7ec742)) +* Phani/deploy with GitHub url ([eb86c27](https://github.com/onkernel/kernel-python-sdk/commit/eb86c27107781172bf740e0af3833eee86b7cb60)) + ## 0.14.2 (2025-10-16) Full Changelog: [v0.14.1...v0.14.2](https://github.com/onkernel/kernel-python-sdk/compare/v0.14.1...v0.14.2) diff --git a/README.md b/README.md index beec3f01..ae0066ec 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,6 @@ from kernel import Kernel client = Kernel() client.deployments.create( - entrypoint_rel_path="src/app.py", file=Path("/path/to/file"), ) ``` diff --git a/api.md b/api.md index 6059a78d..858dbfd8 100644 --- a/api.md +++ b/api.md @@ -166,6 +166,18 @@ Methods: - client.browsers.logs.stream(id, \*\*params) -> LogEvent +## Computer + +Methods: + +- client.browsers.computer.capture_screenshot(id, \*\*params) -> BinaryAPIResponse +- client.browsers.computer.click_mouse(id, \*\*params) -> None +- client.browsers.computer.drag_mouse(id, \*\*params) -> None +- client.browsers.computer.move_mouse(id, \*\*params) -> None +- client.browsers.computer.press_key(id, \*\*params) -> None +- client.browsers.computer.scroll(id, \*\*params) -> None +- client.browsers.computer.type_text(id, \*\*params) -> None + # Profiles Types: diff --git a/pyproject.toml b/pyproject.toml index c2e14c5d..0f8cb140 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.14.2" +version = "0.15.0" description = "The official Python library for the kernel API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/kernel/_version.py b/src/kernel/_version.py index dfcce591..e65ca7f2 100644 --- a/src/kernel/_version.py +++ b/src/kernel/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "kernel" -__version__ = "0.14.2" # x-release-please-version +__version__ = "0.15.0" # x-release-please-version diff --git a/src/kernel/resources/browsers/__init__.py b/src/kernel/resources/browsers/__init__.py index 97c987e4..abcc8f78 100644 --- a/src/kernel/resources/browsers/__init__.py +++ b/src/kernel/resources/browsers/__init__.py @@ -40,6 +40,14 @@ BrowsersResourceWithStreamingResponse, AsyncBrowsersResourceWithStreamingResponse, ) +from .computer import ( + ComputerResource, + AsyncComputerResource, + ComputerResourceWithRawResponse, + AsyncComputerResourceWithRawResponse, + ComputerResourceWithStreamingResponse, + AsyncComputerResourceWithStreamingResponse, +) __all__ = [ "ReplaysResource", @@ -66,6 +74,12 @@ "AsyncLogsResourceWithRawResponse", "LogsResourceWithStreamingResponse", "AsyncLogsResourceWithStreamingResponse", + "ComputerResource", + "AsyncComputerResource", + "ComputerResourceWithRawResponse", + "AsyncComputerResourceWithRawResponse", + "ComputerResourceWithStreamingResponse", + "AsyncComputerResourceWithStreamingResponse", "BrowsersResource", "AsyncBrowsersResource", "BrowsersResourceWithRawResponse", diff --git a/src/kernel/resources/browsers/browsers.py b/src/kernel/resources/browsers/browsers.py index 1d444214..c65a738a 100644 --- a/src/kernel/resources/browsers/browsers.py +++ b/src/kernel/resources/browsers/browsers.py @@ -41,6 +41,14 @@ ) from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given from ..._utils import extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform +from .computer import ( + ComputerResource, + AsyncComputerResource, + ComputerResourceWithRawResponse, + AsyncComputerResourceWithRawResponse, + ComputerResourceWithStreamingResponse, + AsyncComputerResourceWithStreamingResponse, +) from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -75,6 +83,10 @@ def process(self) -> ProcessResource: def logs(self) -> LogsResource: return LogsResource(self._client) + @cached_property + def computer(self) -> ComputerResource: + return ComputerResource(self._client) + @cached_property def with_raw_response(self) -> BrowsersResourceWithRawResponse: """ @@ -375,6 +387,10 @@ def process(self) -> AsyncProcessResource: def logs(self) -> AsyncLogsResource: return AsyncLogsResource(self._client) + @cached_property + def computer(self) -> AsyncComputerResource: + return AsyncComputerResource(self._client) + @cached_property def with_raw_response(self) -> AsyncBrowsersResourceWithRawResponse: """ @@ -699,6 +715,10 @@ def process(self) -> ProcessResourceWithRawResponse: def logs(self) -> LogsResourceWithRawResponse: return LogsResourceWithRawResponse(self._browsers.logs) + @cached_property + def computer(self) -> ComputerResourceWithRawResponse: + return ComputerResourceWithRawResponse(self._browsers.computer) + class AsyncBrowsersResourceWithRawResponse: def __init__(self, browsers: AsyncBrowsersResource) -> None: @@ -739,6 +759,10 @@ def process(self) -> AsyncProcessResourceWithRawResponse: def logs(self) -> AsyncLogsResourceWithRawResponse: return AsyncLogsResourceWithRawResponse(self._browsers.logs) + @cached_property + def computer(self) -> AsyncComputerResourceWithRawResponse: + return AsyncComputerResourceWithRawResponse(self._browsers.computer) + class BrowsersResourceWithStreamingResponse: def __init__(self, browsers: BrowsersResource) -> None: @@ -779,6 +803,10 @@ def process(self) -> ProcessResourceWithStreamingResponse: def logs(self) -> LogsResourceWithStreamingResponse: return LogsResourceWithStreamingResponse(self._browsers.logs) + @cached_property + def computer(self) -> ComputerResourceWithStreamingResponse: + return ComputerResourceWithStreamingResponse(self._browsers.computer) + class AsyncBrowsersResourceWithStreamingResponse: def __init__(self, browsers: AsyncBrowsersResource) -> None: @@ -818,3 +846,7 @@ def process(self) -> AsyncProcessResourceWithStreamingResponse: @cached_property def logs(self) -> AsyncLogsResourceWithStreamingResponse: return AsyncLogsResourceWithStreamingResponse(self._browsers.logs) + + @cached_property + def computer(self) -> AsyncComputerResourceWithStreamingResponse: + return AsyncComputerResourceWithStreamingResponse(self._browsers.computer) diff --git a/src/kernel/resources/browsers/computer.py b/src/kernel/resources/browsers/computer.py new file mode 100644 index 00000000..68cee420 --- /dev/null +++ b/src/kernel/resources/browsers/computer.py @@ -0,0 +1,949 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given +from ..._utils import maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + BinaryAPIResponse, + AsyncBinaryAPIResponse, + StreamedBinaryAPIResponse, + AsyncStreamedBinaryAPIResponse, + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + to_custom_raw_response_wrapper, + async_to_streamed_response_wrapper, + to_custom_streamed_response_wrapper, + async_to_custom_raw_response_wrapper, + async_to_custom_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.browsers import ( + computer_scroll_params, + computer_press_key_params, + computer_type_text_params, + computer_drag_mouse_params, + computer_move_mouse_params, + computer_click_mouse_params, + computer_capture_screenshot_params, +) + +__all__ = ["ComputerResource", "AsyncComputerResource"] + + +class ComputerResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ComputerResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/onkernel/kernel-python-sdk#accessing-raw-response-data-eg-headers + """ + return ComputerResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ComputerResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/onkernel/kernel-python-sdk#with_streaming_response + """ + return ComputerResourceWithStreamingResponse(self) + + def capture_screenshot( + self, + id: str, + *, + region: computer_capture_screenshot_params.Region | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BinaryAPIResponse: + """ + Capture a screenshot of the browser instance + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "image/png", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/screenshot", + body=maybe_transform( + {"region": region}, computer_capture_screenshot_params.ComputerCaptureScreenshotParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BinaryAPIResponse, + ) + + def click_mouse( + self, + id: str, + *, + x: int, + y: int, + button: Literal["left", "right", "middle", "back", "forward"] | Omit = omit, + click_type: Literal["down", "up", "click"] | Omit = omit, + hold_keys: SequenceNotStr[str] | Omit = omit, + num_clicks: int | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Simulate a mouse click action on the browser instance + + Args: + x: X coordinate of the click position + + y: Y coordinate of the click position + + button: Mouse button to interact with + + click_type: Type of click action + + hold_keys: Modifier keys to hold during the click + + num_clicks: Number of times to repeat the click + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/click_mouse", + body=maybe_transform( + { + "x": x, + "y": y, + "button": button, + "click_type": click_type, + "hold_keys": hold_keys, + "num_clicks": num_clicks, + }, + computer_click_mouse_params.ComputerClickMouseParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def drag_mouse( + self, + id: str, + *, + path: Iterable[Iterable[int]], + button: Literal["left", "middle", "right"] | Omit = omit, + delay: int | Omit = omit, + hold_keys: SequenceNotStr[str] | Omit = omit, + step_delay_ms: int | Omit = omit, + steps_per_segment: int | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Drag the mouse along a path + + Args: + path: Ordered list of [x, y] coordinate pairs to move through while dragging. Must + contain at least 2 points. + + button: Mouse button to drag with + + delay: Delay in milliseconds between button down and starting to move along the path. + + hold_keys: Modifier keys to hold during the drag + + step_delay_ms: Delay in milliseconds between relative steps while dragging (not the initial + delay). + + steps_per_segment: Number of relative move steps per segment in the path. Minimum 1. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/drag_mouse", + body=maybe_transform( + { + "path": path, + "button": button, + "delay": delay, + "hold_keys": hold_keys, + "step_delay_ms": step_delay_ms, + "steps_per_segment": steps_per_segment, + }, + computer_drag_mouse_params.ComputerDragMouseParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def move_mouse( + self, + id: str, + *, + x: int, + y: int, + hold_keys: SequenceNotStr[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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Move the mouse cursor to the specified coordinates on the browser instance + + Args: + x: X coordinate to move the cursor to + + y: Y coordinate to move the cursor to + + hold_keys: Modifier keys to hold during the move + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/move_mouse", + body=maybe_transform( + { + "x": x, + "y": y, + "hold_keys": hold_keys, + }, + computer_move_mouse_params.ComputerMoveMouseParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def press_key( + self, + id: str, + *, + keys: SequenceNotStr[str], + duration: int | Omit = omit, + hold_keys: SequenceNotStr[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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Press one or more keys on the host computer + + Args: + keys: List of key symbols to press. Each item should be a key symbol supported by + xdotool (see X11 keysym definitions). Examples include "Return", "Shift", + "Ctrl", "Alt", "F5". Items in this list could also be combinations, e.g. + "Ctrl+t" or "Ctrl+Shift+Tab". + + duration: Duration to hold the keys down in milliseconds. If omitted or 0, keys are + tapped. + + hold_keys: Optional modifier keys to hold during the key press sequence. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/press_key", + body=maybe_transform( + { + "keys": keys, + "duration": duration, + "hold_keys": hold_keys, + }, + computer_press_key_params.ComputerPressKeyParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def scroll( + self, + id: str, + *, + x: int, + y: int, + delta_x: int | Omit = omit, + delta_y: int | Omit = omit, + hold_keys: SequenceNotStr[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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Scroll the mouse wheel at a position on the host computer + + Args: + x: X coordinate at which to perform the scroll + + y: Y coordinate at which to perform the scroll + + delta_x: Horizontal scroll amount. Positive scrolls right, negative scrolls left. + + delta_y: Vertical scroll amount. Positive scrolls down, negative scrolls up. + + hold_keys: Modifier keys to hold during the scroll + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/scroll", + body=maybe_transform( + { + "x": x, + "y": y, + "delta_x": delta_x, + "delta_y": delta_y, + "hold_keys": hold_keys, + }, + computer_scroll_params.ComputerScrollParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def type_text( + self, + id: str, + *, + text: str, + delay: int | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Type text on the browser instance + + Args: + text: Text to type on the browser instance + + delay: Delay in milliseconds between keystrokes + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + f"/browsers/{id}/computer/type", + body=maybe_transform( + { + "text": text, + "delay": delay, + }, + computer_type_text_params.ComputerTypeTextParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + +class AsyncComputerResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncComputerResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/onkernel/kernel-python-sdk#accessing-raw-response-data-eg-headers + """ + return AsyncComputerResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncComputerResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/onkernel/kernel-python-sdk#with_streaming_response + """ + return AsyncComputerResourceWithStreamingResponse(self) + + async def capture_screenshot( + self, + id: str, + *, + region: computer_capture_screenshot_params.Region | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncBinaryAPIResponse: + """ + Capture a screenshot of the browser instance + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "image/png", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/screenshot", + body=await async_maybe_transform( + {"region": region}, computer_capture_screenshot_params.ComputerCaptureScreenshotParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AsyncBinaryAPIResponse, + ) + + async def click_mouse( + self, + id: str, + *, + x: int, + y: int, + button: Literal["left", "right", "middle", "back", "forward"] | Omit = omit, + click_type: Literal["down", "up", "click"] | Omit = omit, + hold_keys: SequenceNotStr[str] | Omit = omit, + num_clicks: int | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Simulate a mouse click action on the browser instance + + Args: + x: X coordinate of the click position + + y: Y coordinate of the click position + + button: Mouse button to interact with + + click_type: Type of click action + + hold_keys: Modifier keys to hold during the click + + num_clicks: Number of times to repeat the click + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/click_mouse", + body=await async_maybe_transform( + { + "x": x, + "y": y, + "button": button, + "click_type": click_type, + "hold_keys": hold_keys, + "num_clicks": num_clicks, + }, + computer_click_mouse_params.ComputerClickMouseParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def drag_mouse( + self, + id: str, + *, + path: Iterable[Iterable[int]], + button: Literal["left", "middle", "right"] | Omit = omit, + delay: int | Omit = omit, + hold_keys: SequenceNotStr[str] | Omit = omit, + step_delay_ms: int | Omit = omit, + steps_per_segment: int | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Drag the mouse along a path + + Args: + path: Ordered list of [x, y] coordinate pairs to move through while dragging. Must + contain at least 2 points. + + button: Mouse button to drag with + + delay: Delay in milliseconds between button down and starting to move along the path. + + hold_keys: Modifier keys to hold during the drag + + step_delay_ms: Delay in milliseconds between relative steps while dragging (not the initial + delay). + + steps_per_segment: Number of relative move steps per segment in the path. Minimum 1. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/drag_mouse", + body=await async_maybe_transform( + { + "path": path, + "button": button, + "delay": delay, + "hold_keys": hold_keys, + "step_delay_ms": step_delay_ms, + "steps_per_segment": steps_per_segment, + }, + computer_drag_mouse_params.ComputerDragMouseParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def move_mouse( + self, + id: str, + *, + x: int, + y: int, + hold_keys: SequenceNotStr[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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Move the mouse cursor to the specified coordinates on the browser instance + + Args: + x: X coordinate to move the cursor to + + y: Y coordinate to move the cursor to + + hold_keys: Modifier keys to hold during the move + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/move_mouse", + body=await async_maybe_transform( + { + "x": x, + "y": y, + "hold_keys": hold_keys, + }, + computer_move_mouse_params.ComputerMoveMouseParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def press_key( + self, + id: str, + *, + keys: SequenceNotStr[str], + duration: int | Omit = omit, + hold_keys: SequenceNotStr[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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Press one or more keys on the host computer + + Args: + keys: List of key symbols to press. Each item should be a key symbol supported by + xdotool (see X11 keysym definitions). Examples include "Return", "Shift", + "Ctrl", "Alt", "F5". Items in this list could also be combinations, e.g. + "Ctrl+t" or "Ctrl+Shift+Tab". + + duration: Duration to hold the keys down in milliseconds. If omitted or 0, keys are + tapped. + + hold_keys: Optional modifier keys to hold during the key press sequence. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/press_key", + body=await async_maybe_transform( + { + "keys": keys, + "duration": duration, + "hold_keys": hold_keys, + }, + computer_press_key_params.ComputerPressKeyParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def scroll( + self, + id: str, + *, + x: int, + y: int, + delta_x: int | Omit = omit, + delta_y: int | Omit = omit, + hold_keys: SequenceNotStr[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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Scroll the mouse wheel at a position on the host computer + + Args: + x: X coordinate at which to perform the scroll + + y: Y coordinate at which to perform the scroll + + delta_x: Horizontal scroll amount. Positive scrolls right, negative scrolls left. + + delta_y: Vertical scroll amount. Positive scrolls down, negative scrolls up. + + hold_keys: Modifier keys to hold during the scroll + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/scroll", + body=await async_maybe_transform( + { + "x": x, + "y": y, + "delta_x": delta_x, + "delta_y": delta_y, + "hold_keys": hold_keys, + }, + computer_scroll_params.ComputerScrollParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def type_text( + self, + id: str, + *, + text: str, + delay: int | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> None: + """ + Type text on the browser instance + + Args: + text: Text to type on the browser instance + + delay: Delay in milliseconds between keystrokes + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + f"/browsers/{id}/computer/type", + body=await async_maybe_transform( + { + "text": text, + "delay": delay, + }, + computer_type_text_params.ComputerTypeTextParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + +class ComputerResourceWithRawResponse: + def __init__(self, computer: ComputerResource) -> None: + self._computer = computer + + self.capture_screenshot = to_custom_raw_response_wrapper( + computer.capture_screenshot, + BinaryAPIResponse, + ) + self.click_mouse = to_raw_response_wrapper( + computer.click_mouse, + ) + self.drag_mouse = to_raw_response_wrapper( + computer.drag_mouse, + ) + self.move_mouse = to_raw_response_wrapper( + computer.move_mouse, + ) + self.press_key = to_raw_response_wrapper( + computer.press_key, + ) + self.scroll = to_raw_response_wrapper( + computer.scroll, + ) + self.type_text = to_raw_response_wrapper( + computer.type_text, + ) + + +class AsyncComputerResourceWithRawResponse: + def __init__(self, computer: AsyncComputerResource) -> None: + self._computer = computer + + self.capture_screenshot = async_to_custom_raw_response_wrapper( + computer.capture_screenshot, + AsyncBinaryAPIResponse, + ) + self.click_mouse = async_to_raw_response_wrapper( + computer.click_mouse, + ) + self.drag_mouse = async_to_raw_response_wrapper( + computer.drag_mouse, + ) + self.move_mouse = async_to_raw_response_wrapper( + computer.move_mouse, + ) + self.press_key = async_to_raw_response_wrapper( + computer.press_key, + ) + self.scroll = async_to_raw_response_wrapper( + computer.scroll, + ) + self.type_text = async_to_raw_response_wrapper( + computer.type_text, + ) + + +class ComputerResourceWithStreamingResponse: + def __init__(self, computer: ComputerResource) -> None: + self._computer = computer + + self.capture_screenshot = to_custom_streamed_response_wrapper( + computer.capture_screenshot, + StreamedBinaryAPIResponse, + ) + self.click_mouse = to_streamed_response_wrapper( + computer.click_mouse, + ) + self.drag_mouse = to_streamed_response_wrapper( + computer.drag_mouse, + ) + self.move_mouse = to_streamed_response_wrapper( + computer.move_mouse, + ) + self.press_key = to_streamed_response_wrapper( + computer.press_key, + ) + self.scroll = to_streamed_response_wrapper( + computer.scroll, + ) + self.type_text = to_streamed_response_wrapper( + computer.type_text, + ) + + +class AsyncComputerResourceWithStreamingResponse: + def __init__(self, computer: AsyncComputerResource) -> None: + self._computer = computer + + self.capture_screenshot = async_to_custom_streamed_response_wrapper( + computer.capture_screenshot, + AsyncStreamedBinaryAPIResponse, + ) + self.click_mouse = async_to_streamed_response_wrapper( + computer.click_mouse, + ) + self.drag_mouse = async_to_streamed_response_wrapper( + computer.drag_mouse, + ) + self.move_mouse = async_to_streamed_response_wrapper( + computer.move_mouse, + ) + self.press_key = async_to_streamed_response_wrapper( + computer.press_key, + ) + self.scroll = async_to_streamed_response_wrapper( + computer.scroll, + ) + self.type_text = async_to_streamed_response_wrapper( + computer.type_text, + ) diff --git a/src/kernel/resources/deployments.py b/src/kernel/resources/deployments.py index 15812440..bdc200f1 100644 --- a/src/kernel/resources/deployments.py +++ b/src/kernel/resources/deployments.py @@ -52,11 +52,12 @@ def with_streaming_response(self) -> DeploymentsResourceWithStreamingResponse: def create( self, *, - entrypoint_rel_path: str, - file: FileTypes, + entrypoint_rel_path: str | Omit = omit, env_vars: Dict[str, str] | Omit = omit, + file: FileTypes | Omit = omit, force: bool | Omit = omit, region: Literal["aws.us-east-1a"] | Omit = omit, + source: deployment_create_params.Source | Omit = omit, version: 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. @@ -71,15 +72,17 @@ def create( Args: entrypoint_rel_path: Relative path to the entrypoint of the application - file: ZIP file containing the application source directory - env_vars: Map of environment variables to set for the deployed application. Each key-value pair represents an environment variable. + file: ZIP file containing the application source directory + force: Allow overwriting an existing app version region: Region for deployment. Currently we only support "aws.us-east-1a" + source: Source from which to fetch application code. + version: Version of the application. Can be any string. extra_headers: Send extra headers @@ -93,10 +96,11 @@ def create( body = deepcopy_minimal( { "entrypoint_rel_path": entrypoint_rel_path, - "file": file, "env_vars": env_vars, + "file": file, "force": force, "region": region, + "source": source, "version": version, } ) @@ -271,11 +275,12 @@ def with_streaming_response(self) -> AsyncDeploymentsResourceWithStreamingRespon async def create( self, *, - entrypoint_rel_path: str, - file: FileTypes, + entrypoint_rel_path: str | Omit = omit, env_vars: Dict[str, str] | Omit = omit, + file: FileTypes | Omit = omit, force: bool | Omit = omit, region: Literal["aws.us-east-1a"] | Omit = omit, + source: deployment_create_params.Source | Omit = omit, version: 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. @@ -290,15 +295,17 @@ async def create( Args: entrypoint_rel_path: Relative path to the entrypoint of the application - file: ZIP file containing the application source directory - env_vars: Map of environment variables to set for the deployed application. Each key-value pair represents an environment variable. + file: ZIP file containing the application source directory + force: Allow overwriting an existing app version region: Region for deployment. Currently we only support "aws.us-east-1a" + source: Source from which to fetch application code. + version: Version of the application. Can be any string. extra_headers: Send extra headers @@ -312,10 +319,11 @@ async def create( body = deepcopy_minimal( { "entrypoint_rel_path": entrypoint_rel_path, - "file": file, "env_vars": env_vars, + "file": file, "force": force, "region": region, + "source": source, "version": version, } ) diff --git a/src/kernel/types/browsers/__init__.py b/src/kernel/types/browsers/__init__.py index d0b6b383..9b0ed53a 100644 --- a/src/kernel/types/browsers/__init__.py +++ b/src/kernel/types/browsers/__init__.py @@ -22,11 +22,18 @@ from .process_exec_response import ProcessExecResponse as ProcessExecResponse from .process_kill_response import ProcessKillResponse as ProcessKillResponse from .replay_start_response import ReplayStartResponse as ReplayStartResponse +from .computer_scroll_params import ComputerScrollParams as ComputerScrollParams from .process_spawn_response import ProcessSpawnResponse as ProcessSpawnResponse from .process_stdin_response import ProcessStdinResponse as ProcessStdinResponse from .process_status_response import ProcessStatusResponse as ProcessStatusResponse +from .computer_press_key_params import ComputerPressKeyParams as ComputerPressKeyParams +from .computer_type_text_params import ComputerTypeTextParams as ComputerTypeTextParams from .f_create_directory_params import FCreateDirectoryParams as FCreateDirectoryParams from .f_delete_directory_params import FDeleteDirectoryParams as FDeleteDirectoryParams from .f_download_dir_zip_params import FDownloadDirZipParams as FDownloadDirZipParams +from .computer_drag_mouse_params import ComputerDragMouseParams as ComputerDragMouseParams +from .computer_move_mouse_params import ComputerMoveMouseParams as ComputerMoveMouseParams +from .computer_click_mouse_params import ComputerClickMouseParams as ComputerClickMouseParams from .f_set_file_permissions_params import FSetFilePermissionsParams as FSetFilePermissionsParams from .process_stdout_stream_response import ProcessStdoutStreamResponse as ProcessStdoutStreamResponse +from .computer_capture_screenshot_params import ComputerCaptureScreenshotParams as ComputerCaptureScreenshotParams diff --git a/src/kernel/types/browsers/computer_capture_screenshot_params.py b/src/kernel/types/browsers/computer_capture_screenshot_params.py new file mode 100644 index 00000000..942cef30 --- /dev/null +++ b/src/kernel/types/browsers/computer_capture_screenshot_params.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["ComputerCaptureScreenshotParams", "Region"] + + +class ComputerCaptureScreenshotParams(TypedDict, total=False): + region: Region + + +class Region(TypedDict, total=False): + height: Required[int] + """Height of the region in pixels""" + + width: Required[int] + """Width of the region in pixels""" + + x: Required[int] + """X coordinate of the region's top-left corner""" + + y: Required[int] + """Y coordinate of the region's top-left corner""" diff --git a/src/kernel/types/browsers/computer_click_mouse_params.py b/src/kernel/types/browsers/computer_click_mouse_params.py new file mode 100644 index 00000000..9bde2e6a --- /dev/null +++ b/src/kernel/types/browsers/computer_click_mouse_params.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["ComputerClickMouseParams"] + + +class ComputerClickMouseParams(TypedDict, total=False): + x: Required[int] + """X coordinate of the click position""" + + y: Required[int] + """Y coordinate of the click position""" + + button: Literal["left", "right", "middle", "back", "forward"] + """Mouse button to interact with""" + + click_type: Literal["down", "up", "click"] + """Type of click action""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the click""" + + num_clicks: int + """Number of times to repeat the click""" diff --git a/src/kernel/types/browsers/computer_drag_mouse_params.py b/src/kernel/types/browsers/computer_drag_mouse_params.py new file mode 100644 index 00000000..fb03b4be --- /dev/null +++ b/src/kernel/types/browsers/computer_drag_mouse_params.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["ComputerDragMouseParams"] + + +class ComputerDragMouseParams(TypedDict, total=False): + path: Required[Iterable[Iterable[int]]] + """Ordered list of [x, y] coordinate pairs to move through while dragging. + + Must contain at least 2 points. + """ + + button: Literal["left", "middle", "right"] + """Mouse button to drag with""" + + delay: int + """Delay in milliseconds between button down and starting to move along the path.""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the drag""" + + step_delay_ms: int + """ + Delay in milliseconds between relative steps while dragging (not the initial + delay). + """ + + steps_per_segment: int + """Number of relative move steps per segment in the path. Minimum 1.""" diff --git a/src/kernel/types/browsers/computer_move_mouse_params.py b/src/kernel/types/browsers/computer_move_mouse_params.py new file mode 100644 index 00000000..1769e074 --- /dev/null +++ b/src/kernel/types/browsers/computer_move_mouse_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["ComputerMoveMouseParams"] + + +class ComputerMoveMouseParams(TypedDict, total=False): + x: Required[int] + """X coordinate to move the cursor to""" + + y: Required[int] + """Y coordinate to move the cursor to""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the move""" diff --git a/src/kernel/types/browsers/computer_press_key_params.py b/src/kernel/types/browsers/computer_press_key_params.py new file mode 100644 index 00000000..ea2c9b45 --- /dev/null +++ b/src/kernel/types/browsers/computer_press_key_params.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["ComputerPressKeyParams"] + + +class ComputerPressKeyParams(TypedDict, total=False): + keys: Required[SequenceNotStr[str]] + """List of key symbols to press. + + Each item should be a key symbol supported by xdotool (see X11 keysym + definitions). Examples include "Return", "Shift", "Ctrl", "Alt", "F5". Items in + this list could also be combinations, e.g. "Ctrl+t" or "Ctrl+Shift+Tab". + """ + + duration: int + """Duration to hold the keys down in milliseconds. + + If omitted or 0, keys are tapped. + """ + + hold_keys: SequenceNotStr[str] + """Optional modifier keys to hold during the key press sequence.""" diff --git a/src/kernel/types/browsers/computer_scroll_params.py b/src/kernel/types/browsers/computer_scroll_params.py new file mode 100644 index 00000000..110cb302 --- /dev/null +++ b/src/kernel/types/browsers/computer_scroll_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from ..._types import SequenceNotStr + +__all__ = ["ComputerScrollParams"] + + +class ComputerScrollParams(TypedDict, total=False): + x: Required[int] + """X coordinate at which to perform the scroll""" + + y: Required[int] + """Y coordinate at which to perform the scroll""" + + delta_x: int + """Horizontal scroll amount. Positive scrolls right, negative scrolls left.""" + + delta_y: int + """Vertical scroll amount. Positive scrolls down, negative scrolls up.""" + + hold_keys: SequenceNotStr[str] + """Modifier keys to hold during the scroll""" diff --git a/src/kernel/types/browsers/computer_type_text_params.py b/src/kernel/types/browsers/computer_type_text_params.py new file mode 100644 index 00000000..3a2c5133 --- /dev/null +++ b/src/kernel/types/browsers/computer_type_text_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["ComputerTypeTextParams"] + + +class ComputerTypeTextParams(TypedDict, total=False): + text: Required[str] + """Text to type on the browser instance""" + + delay: int + """Delay in milliseconds between keystrokes""" diff --git a/src/kernel/types/deployment_create_params.py b/src/kernel/types/deployment_create_params.py index 6701c0a8..16eb5702 100644 --- a/src/kernel/types/deployment_create_params.py +++ b/src/kernel/types/deployment_create_params.py @@ -7,27 +7,58 @@ from .._types import FileTypes -__all__ = ["DeploymentCreateParams"] +__all__ = ["DeploymentCreateParams", "Source", "SourceAuth"] class DeploymentCreateParams(TypedDict, total=False): - entrypoint_rel_path: Required[str] + entrypoint_rel_path: str """Relative path to the entrypoint of the application""" - file: Required[FileTypes] - """ZIP file containing the application source directory""" - env_vars: Dict[str, str] """Map of environment variables to set for the deployed application. Each key-value pair represents an environment variable. """ + file: FileTypes + """ZIP file containing the application source directory""" + force: bool """Allow overwriting an existing app version""" region: Literal["aws.us-east-1a"] """Region for deployment. Currently we only support "aws.us-east-1a" """ + source: Source + """Source from which to fetch application code.""" + version: str """Version of the application. Can be any string.""" + + +class SourceAuth(TypedDict, total=False): + token: Required[str] + """GitHub PAT or installation access token""" + + method: Required[Literal["github_token"]] + """Auth method""" + + +class Source(TypedDict, total=False): + entrypoint: Required[str] + """Relative path to the application entrypoint within the selected path.""" + + ref: Required[str] + """Git ref (branch, tag, or commit SHA) to fetch.""" + + type: Required[Literal["github"]] + """Source type identifier.""" + + url: Required[str] + """Base repository URL (without blob/tree suffixes).""" + + auth: SourceAuth + """Authentication for private repositories.""" + + path: str + """Path within the repo to deploy (omit to use repo root).""" diff --git a/tests/api_resources/browsers/test_computer.py b/tests/api_resources/browsers/test_computer.py new file mode 100644 index 00000000..9e245481 --- /dev/null +++ b/tests/api_resources/browsers/test_computer.py @@ -0,0 +1,892 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import httpx +import pytest +from respx import MockRouter + +from kernel import Kernel, AsyncKernel +from kernel._response import ( + BinaryAPIResponse, + AsyncBinaryAPIResponse, + StreamedBinaryAPIResponse, + AsyncStreamedBinaryAPIResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestComputer: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_method_capture_screenshot(self, client: Kernel, respx_mock: MockRouter) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + computer = client.browsers.computer.capture_screenshot( + id="id", + ) + assert computer.is_closed + assert computer.json() == {"foo": "bar"} + assert cast(Any, computer.is_closed) is True + assert isinstance(computer, BinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_method_capture_screenshot_with_all_params(self, client: Kernel, respx_mock: MockRouter) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + computer = client.browsers.computer.capture_screenshot( + id="id", + region={ + "height": 0, + "width": 0, + "x": 0, + "y": 0, + }, + ) + assert computer.is_closed + assert computer.json() == {"foo": "bar"} + assert cast(Any, computer.is_closed) is True + assert isinstance(computer, BinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_raw_response_capture_screenshot(self, client: Kernel, respx_mock: MockRouter) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + + computer = client.browsers.computer.with_raw_response.capture_screenshot( + id="id", + ) + + assert computer.is_closed is True + assert computer.http_request.headers.get("X-Stainless-Lang") == "python" + assert computer.json() == {"foo": "bar"} + assert isinstance(computer, BinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_streaming_response_capture_screenshot(self, client: Kernel, respx_mock: MockRouter) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + with client.browsers.computer.with_streaming_response.capture_screenshot( + id="id", + ) as computer: + assert not computer.is_closed + assert computer.http_request.headers.get("X-Stainless-Lang") == "python" + + assert computer.json() == {"foo": "bar"} + assert cast(Any, computer.is_closed) is True + assert isinstance(computer, StreamedBinaryAPIResponse) + + assert cast(Any, computer.is_closed) is True + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_path_params_capture_screenshot(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.capture_screenshot( + id="", + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_click_mouse(self, client: Kernel) -> None: + computer = client.browsers.computer.click_mouse( + id="id", + x=0, + y=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_click_mouse_with_all_params(self, client: Kernel) -> None: + computer = client.browsers.computer.click_mouse( + id="id", + x=0, + y=0, + button="left", + click_type="down", + hold_keys=["string"], + num_clicks=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_click_mouse(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.click_mouse( + id="id", + x=0, + y=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_click_mouse(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.click_mouse( + id="id", + x=0, + y=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_click_mouse(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.click_mouse( + id="", + x=0, + y=0, + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_drag_mouse(self, client: Kernel) -> None: + computer = client.browsers.computer.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_drag_mouse_with_all_params(self, client: Kernel) -> None: + computer = client.browsers.computer.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + button="left", + delay=0, + hold_keys=["string"], + step_delay_ms=0, + steps_per_segment=1, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_drag_mouse(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_drag_mouse(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_drag_mouse(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.drag_mouse( + id="", + path=[[0, 0], [0, 0]], + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_move_mouse(self, client: Kernel) -> None: + computer = client.browsers.computer.move_mouse( + id="id", + x=0, + y=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_move_mouse_with_all_params(self, client: Kernel) -> None: + computer = client.browsers.computer.move_mouse( + id="id", + x=0, + y=0, + hold_keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_move_mouse(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.move_mouse( + id="id", + x=0, + y=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_move_mouse(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.move_mouse( + id="id", + x=0, + y=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_move_mouse(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.move_mouse( + id="", + x=0, + y=0, + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_press_key(self, client: Kernel) -> None: + computer = client.browsers.computer.press_key( + id="id", + keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_press_key_with_all_params(self, client: Kernel) -> None: + computer = client.browsers.computer.press_key( + id="id", + keys=["string"], + duration=0, + hold_keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_press_key(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.press_key( + id="id", + keys=["string"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_press_key(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.press_key( + id="id", + keys=["string"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_press_key(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.press_key( + id="", + keys=["string"], + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_scroll(self, client: Kernel) -> None: + computer = client.browsers.computer.scroll( + id="id", + x=0, + y=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_scroll_with_all_params(self, client: Kernel) -> None: + computer = client.browsers.computer.scroll( + id="id", + x=0, + y=0, + delta_x=0, + delta_y=0, + hold_keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_scroll(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.scroll( + id="id", + x=0, + y=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_scroll(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.scroll( + id="id", + x=0, + y=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_scroll(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.scroll( + id="", + x=0, + y=0, + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_type_text(self, client: Kernel) -> None: + computer = client.browsers.computer.type_text( + id="id", + text="text", + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_type_text_with_all_params(self, client: Kernel) -> None: + computer = client.browsers.computer.type_text( + id="id", + text="text", + delay=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_raw_response_type_text(self, client: Kernel) -> None: + response = client.browsers.computer.with_raw_response.type_text( + id="id", + text="text", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_streaming_response_type_text(self, client: Kernel) -> None: + with client.browsers.computer.with_streaming_response.type_text( + id="id", + text="text", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_path_params_type_text(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.browsers.computer.with_raw_response.type_text( + id="", + text="text", + ) + + +class TestAsyncComputer: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_method_capture_screenshot(self, async_client: AsyncKernel, respx_mock: MockRouter) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + computer = await async_client.browsers.computer.capture_screenshot( + id="id", + ) + assert computer.is_closed + assert await computer.json() == {"foo": "bar"} + assert cast(Any, computer.is_closed) is True + assert isinstance(computer, AsyncBinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_method_capture_screenshot_with_all_params( + self, async_client: AsyncKernel, respx_mock: MockRouter + ) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + computer = await async_client.browsers.computer.capture_screenshot( + id="id", + region={ + "height": 0, + "width": 0, + "x": 0, + "y": 0, + }, + ) + assert computer.is_closed + assert await computer.json() == {"foo": "bar"} + assert cast(Any, computer.is_closed) is True + assert isinstance(computer, AsyncBinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_raw_response_capture_screenshot(self, async_client: AsyncKernel, respx_mock: MockRouter) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + + computer = await async_client.browsers.computer.with_raw_response.capture_screenshot( + id="id", + ) + + assert computer.is_closed is True + assert computer.http_request.headers.get("X-Stainless-Lang") == "python" + assert await computer.json() == {"foo": "bar"} + assert isinstance(computer, AsyncBinaryAPIResponse) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_streaming_response_capture_screenshot( + self, async_client: AsyncKernel, respx_mock: MockRouter + ) -> None: + respx_mock.post("/browsers/id/computer/screenshot").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + async with async_client.browsers.computer.with_streaming_response.capture_screenshot( + id="id", + ) as computer: + assert not computer.is_closed + assert computer.http_request.headers.get("X-Stainless-Lang") == "python" + + assert await computer.json() == {"foo": "bar"} + assert cast(Any, computer.is_closed) is True + assert isinstance(computer, AsyncStreamedBinaryAPIResponse) + + assert cast(Any, computer.is_closed) is True + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_path_params_capture_screenshot(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.capture_screenshot( + id="", + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_click_mouse(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.click_mouse( + id="id", + x=0, + y=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_click_mouse_with_all_params(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.click_mouse( + id="id", + x=0, + y=0, + button="left", + click_type="down", + hold_keys=["string"], + num_clicks=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_click_mouse(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.click_mouse( + id="id", + x=0, + y=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_click_mouse(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.click_mouse( + id="id", + x=0, + y=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_click_mouse(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.click_mouse( + id="", + x=0, + y=0, + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_drag_mouse(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_drag_mouse_with_all_params(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + button="left", + delay=0, + hold_keys=["string"], + step_delay_ms=0, + steps_per_segment=1, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_drag_mouse(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_drag_mouse(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.drag_mouse( + id="id", + path=[[0, 0], [0, 0]], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_drag_mouse(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.drag_mouse( + id="", + path=[[0, 0], [0, 0]], + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_move_mouse(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.move_mouse( + id="id", + x=0, + y=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_move_mouse_with_all_params(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.move_mouse( + id="id", + x=0, + y=0, + hold_keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_move_mouse(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.move_mouse( + id="id", + x=0, + y=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_move_mouse(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.move_mouse( + id="id", + x=0, + y=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_move_mouse(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.move_mouse( + id="", + x=0, + y=0, + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_press_key(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.press_key( + id="id", + keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_press_key_with_all_params(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.press_key( + id="id", + keys=["string"], + duration=0, + hold_keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_press_key(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.press_key( + id="id", + keys=["string"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_press_key(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.press_key( + id="id", + keys=["string"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_press_key(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.press_key( + id="", + keys=["string"], + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_scroll(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.scroll( + id="id", + x=0, + y=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_scroll_with_all_params(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.scroll( + id="id", + x=0, + y=0, + delta_x=0, + delta_y=0, + hold_keys=["string"], + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_scroll(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.scroll( + id="id", + x=0, + y=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_scroll(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.scroll( + id="id", + x=0, + y=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_scroll(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.scroll( + id="", + x=0, + y=0, + ) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_type_text(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.type_text( + id="id", + text="text", + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_type_text_with_all_params(self, async_client: AsyncKernel) -> None: + computer = await async_client.browsers.computer.type_text( + id="id", + text="text", + delay=0, + ) + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_raw_response_type_text(self, async_client: AsyncKernel) -> None: + response = await async_client.browsers.computer.with_raw_response.type_text( + id="id", + text="text", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + computer = await response.parse() + assert computer is None + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_streaming_response_type_text(self, async_client: AsyncKernel) -> None: + async with async_client.browsers.computer.with_streaming_response.type_text( + id="id", + text="text", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + computer = await response.parse() + assert computer is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_path_params_type_text(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.browsers.computer.with_raw_response.type_text( + id="", + text="text", + ) diff --git a/tests/api_resources/test_deployments.py b/tests/api_resources/test_deployments.py index fc5d2991..6c3354ef 100644 --- a/tests/api_resources/test_deployments.py +++ b/tests/api_resources/test_deployments.py @@ -25,10 +25,7 @@ class TestDeployments: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_create(self, client: Kernel) -> None: - deployment = client.deployments.create( - entrypoint_rel_path="src/app.py", - file=b"raw file contents", - ) + deployment = client.deployments.create() assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) @pytest.mark.skip(reason="Prism tests are disabled") @@ -36,10 +33,21 @@ def test_method_create(self, client: Kernel) -> None: def test_method_create_with_all_params(self, client: Kernel) -> None: deployment = client.deployments.create( entrypoint_rel_path="src/app.py", + env_vars={"FOO": "bar"}, file=b"raw file contents", - env_vars={"foo": "string"}, force=False, region="aws.us-east-1a", + source={ + "entrypoint": "src/index.ts", + "ref": "main", + "type": "github", + "url": "https://github.com/org/repo", + "auth": { + "token": "ghs_***", + "method": "github_token", + }, + "path": "apps/api", + }, version="1.0.0", ) assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) @@ -47,10 +55,7 @@ def test_method_create_with_all_params(self, client: Kernel) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_raw_response_create(self, client: Kernel) -> None: - response = client.deployments.with_raw_response.create( - entrypoint_rel_path="src/app.py", - file=b"raw file contents", - ) + response = client.deployments.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -60,10 +65,7 @@ def test_raw_response_create(self, client: Kernel) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_streaming_response_create(self, client: Kernel) -> None: - with client.deployments.with_streaming_response.create( - entrypoint_rel_path="src/app.py", - file=b"raw file contents", - ) as response: + with client.deployments.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -211,10 +213,7 @@ class TestAsyncDeployments: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_create(self, async_client: AsyncKernel) -> None: - deployment = await async_client.deployments.create( - entrypoint_rel_path="src/app.py", - file=b"raw file contents", - ) + deployment = await async_client.deployments.create() assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) @pytest.mark.skip(reason="Prism tests are disabled") @@ -222,10 +221,21 @@ async def test_method_create(self, async_client: AsyncKernel) -> None: async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> None: deployment = await async_client.deployments.create( entrypoint_rel_path="src/app.py", + env_vars={"FOO": "bar"}, file=b"raw file contents", - env_vars={"foo": "string"}, force=False, region="aws.us-east-1a", + source={ + "entrypoint": "src/index.ts", + "ref": "main", + "type": "github", + "url": "https://github.com/org/repo", + "auth": { + "token": "ghs_***", + "method": "github_token", + }, + "path": "apps/api", + }, version="1.0.0", ) assert_matches_type(DeploymentCreateResponse, deployment, path=["response"]) @@ -233,10 +243,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_raw_response_create(self, async_client: AsyncKernel) -> None: - response = await async_client.deployments.with_raw_response.create( - entrypoint_rel_path="src/app.py", - file=b"raw file contents", - ) + response = await async_client.deployments.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -246,10 +253,7 @@ async def test_raw_response_create(self, async_client: AsyncKernel) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_streaming_response_create(self, async_client: AsyncKernel) -> None: - async with async_client.deployments.with_streaming_response.create( - entrypoint_rel_path="src/app.py", - file=b"raw file contents", - ) as response: + async with async_client.deployments.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python"