From 7cbec18f41508a8766a0aa9725f178d1e6950404 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 17 Jan 2026 21:34:40 +0000 Subject: [PATCH 1/4] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2857ba8..8e09c0a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 91 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-fc2c80b398a8dd511010ae7cda5e21c353e388ee130aa288974b47af4208b5b8.yml -openapi_spec_hash: 5e06586dbbb9fce12b907f4e32497006 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-1e490dbef30dfa53ccba72524fcba4079f244f2530a4f770c00f8fee707eaa72.yml +openapi_spec_hash: 1fd15429610959f19aed6d3cb170ab9e config_hash: cc7fdd701d995d4b3456d77041c604cf From 9d81781970ed6230844d479bc27893453b34a05e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 18 Jan 2026 22:56:59 +0000 Subject: [PATCH 2/4] feat(dashboard): add browser replays support for past browsers --- .stats.yml | 4 +- api.md | 2 +- src/kernel/resources/browsers/browsers.py | 50 ++++++++++++++++----- src/kernel/types/__init__.py | 1 + src/kernel/types/browser_list_params.py | 12 ++++- src/kernel/types/browser_retrieve_params.py | 12 +++++ tests/api_resources/test_browsers.py | 36 +++++++++++---- 7 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 src/kernel/types/browser_retrieve_params.py diff --git a/.stats.yml b/.stats.yml index 8e09c0a..37fa5b7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 91 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-1e490dbef30dfa53ccba72524fcba4079f244f2530a4f770c00f8fee707eaa72.yml -openapi_spec_hash: 1fd15429610959f19aed6d3cb170ab9e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-68729f2ff40476377ead9019c18ea140fc4efbc2e68d7c4fc323bd61ae81f768.yml +openapi_spec_hash: 9eec61481f9059b5fedc13abc3e39338 config_hash: cc7fdd701d995d4b3456d77041c604cf diff --git a/api.md b/api.md index 51f8cdb..a665bc2 100644 --- a/api.md +++ b/api.md @@ -89,7 +89,7 @@ from kernel.types import ( Methods: - client.browsers.create(\*\*params) -> BrowserCreateResponse -- client.browsers.retrieve(id) -> BrowserRetrieveResponse +- client.browsers.retrieve(id, \*\*params) -> BrowserRetrieveResponse - client.browsers.update(id, \*\*params) -> BrowserUpdateResponse - client.browsers.list(\*\*params) -> SyncOffsetPagination[BrowserListResponse] - client.browsers.delete(\*\*params) -> None diff --git a/src/kernel/resources/browsers/browsers.py b/src/kernel/resources/browsers/browsers.py index ab57854..d835f7a 100644 --- a/src/kernel/resources/browsers/browsers.py +++ b/src/kernel/resources/browsers/browsers.py @@ -4,6 +4,7 @@ import typing_extensions from typing import Mapping, Iterable, Optional, cast +from typing_extensions import Literal import httpx @@ -28,6 +29,7 @@ browser_create_params, browser_delete_params, browser_update_params, + browser_retrieve_params, browser_load_extensions_params, ) from .process import ( @@ -226,6 +228,7 @@ def retrieve( self, id: str, *, + include_deleted: bool | 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, @@ -237,6 +240,8 @@ def retrieve( Get information about a browser session. Args: + include_deleted: When true, includes soft-deleted browser sessions in the lookup. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -250,7 +255,13 @@ def retrieve( return self._get( f"/browsers/{id}", options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + {"include_deleted": include_deleted}, browser_retrieve_params.BrowserRetrieveParams + ), ), cast_to=BrowserRetrieveResponse, ) @@ -300,6 +311,7 @@ def list( include_deleted: bool | Omit = omit, limit: int | Omit = omit, offset: int | Omit = omit, + status: Literal["active", "deleted", "all"] | 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, @@ -309,17 +321,20 @@ def list( ) -> SyncOffsetPagination[BrowserListResponse]: """List all browser sessions with pagination support. - Use include_deleted=true to - include soft-deleted sessions in the results. + Use status parameter to + filter by session state. Args: - include_deleted: When true, includes soft-deleted browser sessions in the results alongside - active sessions. + include_deleted: Deprecated: Use status=all instead. When true, includes soft-deleted browser + sessions in the results alongside active sessions. limit: Maximum number of results to return. Defaults to 20, maximum 100. offset: Number of results to skip. Defaults to 0. + status: Filter sessions by status. "active" returns only active sessions (default), + "deleted" returns only soft-deleted sessions, "all" returns both. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -341,6 +356,7 @@ def list( "include_deleted": include_deleted, "limit": limit, "offset": offset, + "status": status, }, browser_list_params.BrowserListParams, ), @@ -610,6 +626,7 @@ async def retrieve( self, id: str, *, + include_deleted: bool | 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, @@ -621,6 +638,8 @@ async def retrieve( Get information about a browser session. Args: + include_deleted: When true, includes soft-deleted browser sessions in the lookup. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -634,7 +653,13 @@ async def retrieve( return await self._get( f"/browsers/{id}", options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + {"include_deleted": include_deleted}, browser_retrieve_params.BrowserRetrieveParams + ), ), cast_to=BrowserRetrieveResponse, ) @@ -684,6 +709,7 @@ def list( include_deleted: bool | Omit = omit, limit: int | Omit = omit, offset: int | Omit = omit, + status: Literal["active", "deleted", "all"] | 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, @@ -693,17 +719,20 @@ def list( ) -> AsyncPaginator[BrowserListResponse, AsyncOffsetPagination[BrowserListResponse]]: """List all browser sessions with pagination support. - Use include_deleted=true to - include soft-deleted sessions in the results. + Use status parameter to + filter by session state. Args: - include_deleted: When true, includes soft-deleted browser sessions in the results alongside - active sessions. + include_deleted: Deprecated: Use status=all instead. When true, includes soft-deleted browser + sessions in the results alongside active sessions. limit: Maximum number of results to return. Defaults to 20, maximum 100. offset: Number of results to skip. Defaults to 0. + status: Filter sessions by status. "active" returns only active sessions (default), + "deleted" returns only soft-deleted sessions, "all" returns both. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -725,6 +754,7 @@ def list( "include_deleted": include_deleted, "limit": limit, "offset": offset, + "status": status, }, browser_list_params.BrowserListParams, ), diff --git a/src/kernel/types/__init__.py b/src/kernel/types/__init__.py index d037578..016e17c 100644 --- a/src/kernel/types/__init__.py +++ b/src/kernel/types/__init__.py @@ -36,6 +36,7 @@ from .invocation_list_params import InvocationListParams as InvocationListParams from .invocation_state_event import InvocationStateEvent as InvocationStateEvent from .browser_create_response import BrowserCreateResponse as BrowserCreateResponse +from .browser_retrieve_params import BrowserRetrieveParams as BrowserRetrieveParams from .browser_update_response import BrowserUpdateResponse as BrowserUpdateResponse from .extension_list_response import ExtensionListResponse as ExtensionListResponse from .extension_upload_params import ExtensionUploadParams as ExtensionUploadParams diff --git a/src/kernel/types/browser_list_params.py b/src/kernel/types/browser_list_params.py index 20837be..02aa97a 100644 --- a/src/kernel/types/browser_list_params.py +++ b/src/kernel/types/browser_list_params.py @@ -2,14 +2,15 @@ from __future__ import annotations -from typing_extensions import TypedDict +from typing_extensions import Literal, TypedDict __all__ = ["BrowserListParams"] class BrowserListParams(TypedDict, total=False): include_deleted: bool - """ + """Deprecated: Use status=all instead. + When true, includes soft-deleted browser sessions in the results alongside active sessions. """ @@ -19,3 +20,10 @@ class BrowserListParams(TypedDict, total=False): offset: int """Number of results to skip. Defaults to 0.""" + + status: Literal["active", "deleted", "all"] + """Filter sessions by status. + + "active" returns only active sessions (default), "deleted" returns only + soft-deleted sessions, "all" returns both. + """ diff --git a/src/kernel/types/browser_retrieve_params.py b/src/kernel/types/browser_retrieve_params.py new file mode 100644 index 0000000..ec5e8aa --- /dev/null +++ b/src/kernel/types/browser_retrieve_params.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["BrowserRetrieveParams"] + + +class BrowserRetrieveParams(TypedDict, total=False): + include_deleted: bool + """When true, includes soft-deleted browser sessions in the lookup.""" diff --git a/tests/api_resources/test_browsers.py b/tests/api_resources/test_browsers.py index 5eec9de..139cf14 100644 --- a/tests/api_resources/test_browsers.py +++ b/tests/api_resources/test_browsers.py @@ -87,7 +87,16 @@ def test_streaming_response_create(self, client: Kernel) -> None: @parametrize def test_method_retrieve(self, client: Kernel) -> None: browser = client.browsers.retrieve( - "htzv5orfit78e1m2biiifpbv", + id="htzv5orfit78e1m2biiifpbv", + ) + assert_matches_type(BrowserRetrieveResponse, browser, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + def test_method_retrieve_with_all_params(self, client: Kernel) -> None: + browser = client.browsers.retrieve( + id="htzv5orfit78e1m2biiifpbv", + include_deleted=True, ) assert_matches_type(BrowserRetrieveResponse, browser, path=["response"]) @@ -95,7 +104,7 @@ def test_method_retrieve(self, client: Kernel) -> None: @parametrize def test_raw_response_retrieve(self, client: Kernel) -> None: response = client.browsers.with_raw_response.retrieve( - "htzv5orfit78e1m2biiifpbv", + id="htzv5orfit78e1m2biiifpbv", ) assert response.is_closed is True @@ -107,7 +116,7 @@ def test_raw_response_retrieve(self, client: Kernel) -> None: @parametrize def test_streaming_response_retrieve(self, client: Kernel) -> None: with client.browsers.with_streaming_response.retrieve( - "htzv5orfit78e1m2biiifpbv", + id="htzv5orfit78e1m2biiifpbv", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -122,7 +131,7 @@ def test_streaming_response_retrieve(self, client: Kernel) -> None: def test_path_params_retrieve(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): client.browsers.with_raw_response.retrieve( - "", + id="", ) @pytest.mark.skip(reason="Prism tests are disabled") @@ -189,6 +198,7 @@ def test_method_list_with_all_params(self, client: Kernel) -> None: include_deleted=True, limit=1, offset=0, + status="active", ) assert_matches_type(SyncOffsetPagination[BrowserListResponse], browser, path=["response"]) @@ -428,7 +438,16 @@ async def test_streaming_response_create(self, async_client: AsyncKernel) -> Non @parametrize async def test_method_retrieve(self, async_client: AsyncKernel) -> None: browser = await async_client.browsers.retrieve( - "htzv5orfit78e1m2biiifpbv", + id="htzv5orfit78e1m2biiifpbv", + ) + assert_matches_type(BrowserRetrieveResponse, browser, path=["response"]) + + @pytest.mark.skip(reason="Prism tests are disabled") + @parametrize + async def test_method_retrieve_with_all_params(self, async_client: AsyncKernel) -> None: + browser = await async_client.browsers.retrieve( + id="htzv5orfit78e1m2biiifpbv", + include_deleted=True, ) assert_matches_type(BrowserRetrieveResponse, browser, path=["response"]) @@ -436,7 +455,7 @@ async def test_method_retrieve(self, async_client: AsyncKernel) -> None: @parametrize async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None: response = await async_client.browsers.with_raw_response.retrieve( - "htzv5orfit78e1m2biiifpbv", + id="htzv5orfit78e1m2biiifpbv", ) assert response.is_closed is True @@ -448,7 +467,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None: @parametrize async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> None: async with async_client.browsers.with_streaming_response.retrieve( - "htzv5orfit78e1m2biiifpbv", + id="htzv5orfit78e1m2biiifpbv", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -463,7 +482,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> N async def test_path_params_retrieve(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): await async_client.browsers.with_raw_response.retrieve( - "", + id="", ) @pytest.mark.skip(reason="Prism tests are disabled") @@ -530,6 +549,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncKernel) -> N include_deleted=True, limit=1, offset=0, + status="active", ) assert_matches_type(AsyncOffsetPagination[BrowserListResponse], browser, path=["response"]) From f854b633f47b683762f6d5dfe02bb11ba8f93868 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:47:35 +0000 Subject: [PATCH 3/4] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 37fa5b7..9ec6fcc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 91 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-68729f2ff40476377ead9019c18ea140fc4efbc2e68d7c4fc323bd61ae81f768.yml -openapi_spec_hash: 9eec61481f9059b5fedc13abc3e39338 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-59d2925a3cb93809cc762a3ac350691b365898e284f2c66a5999b9a6a37a35e5.yml +openapi_spec_hash: dfcb0a49e657426d0c0f44cfa3e89430 config_hash: cc7fdd701d995d4b3456d77041c604cf From 8c7946cac695a3c6c5ce957c25a78acdd42cbdae Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:47:55 +0000 Subject: [PATCH 4/4] release: 0.27.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/kernel/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index caf5ca3..59acac4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.26.0" + ".": "0.27.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a63d3..2fc4eb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.27.0 (2026-01-19) + +Full Changelog: [v0.26.0...v0.27.0](https://github.com/kernel/kernel-python-sdk/compare/v0.26.0...v0.27.0) + +### Features + +* **dashboard:** add browser replays support for past browsers ([9d81781](https://github.com/kernel/kernel-python-sdk/commit/9d81781970ed6230844d479bc27893453b34a05e)) + ## 0.26.0 (2026-01-17) Full Changelog: [v0.25.0...v0.26.0](https://github.com/kernel/kernel-python-sdk/compare/v0.25.0...v0.26.0) diff --git a/pyproject.toml b/pyproject.toml index cad7dd2..7ac03dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.26.0" +version = "0.27.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 0c46e78..b962ca5 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.26.0" # x-release-please-version +__version__ = "0.27.0" # x-release-please-version