Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/kernel-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6

Expand All @@ -38,7 +38,7 @@ jobs:
run: ./scripts/lint

build:
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
timeout-minutes: 10
name: build
permissions:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.prism.log
.stdy.log
_dev

__pycache__
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.44.0"
".": "0.45.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 104
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-bb2ac8e0d3a1c08e8afcbcbad7cb733d0f84bd22a8d233c1ec3100a01ee078ae.yml
openapi_spec_hash: a83f7d1c422c85d6dc6158af7afe1d09
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-aeb5ea5c2632fe7fd905d509bc6cbb06999d17c458ec44ffd713935ba5b848f9.yml
openapi_spec_hash: fef45a8569f1d3de04c86e95b1112665
config_hash: 16e4457a0bb26e98a335a1c2a572290a
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 0.45.0 (2026-03-27)

Full Changelog: [v0.44.0...v0.45.0](https://github.com/kernel/kernel-python-sdk/compare/v0.44.0...v0.45.0)

### Features

* [kernel-1008] browser pools add custom policy ([09f8520](https://github.com/kernel/kernel-python-sdk/commit/09f85209bc3c646d8a2a1231ed3925cad830f3dc))
* **internal:** implement indices array format for query and form serialization ([c798c39](https://github.com/kernel/kernel-python-sdk/commit/c798c39251def1447d61215c187f0e285f225f3d))


### Chores

* **ci:** skip lint on metadata-only changes ([f0815a8](https://github.com/kernel/kernel-python-sdk/commit/f0815a8d36799444220552cb599a19b79c9b5e12))
* **internal:** update gitignore ([34b47ab](https://github.com/kernel/kernel-python-sdk/commit/34b47ab40aeb12ad9f78e923493caaca88a554b4))

## 0.44.0 (2026-03-20)

Full Changelog: [v0.43.0...v0.44.0](https://github.com/kernel/kernel-python-sdk/compare/v0.43.0...v0.44.0)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "kernel"
version = "0.44.0"
version = "0.45.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
5 changes: 4 additions & 1 deletion src/kernel/_qs.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ def _stringify_item(
items.extend(self._stringify_item(key, item, opts))
return items
elif array_format == "indices":
raise NotImplementedError("The array indices format is not supported yet")
items = []
for i, item in enumerate(value):
items.extend(self._stringify_item(f"{key}[{i}]", item, opts))
return items
elif array_format == "brackets":
items = []
key = key + "[]"
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "kernel"
__version__ = "0.44.0" # x-release-please-version
__version__ = "0.45.0" # x-release-please-version
30 changes: 29 additions & 1 deletion src/kernel/resources/browser_pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Iterable
from typing import Dict, Iterable

import httpx

Expand Down Expand Up @@ -60,6 +60,7 @@ def create(
self,
*,
size: int,
chrome_policy: Dict[str, object] | Omit = omit,
extensions: Iterable[BrowserExtension] | Omit = omit,
fill_rate_per_minute: int | Omit = omit,
headless: bool | Omit = omit,
Expand All @@ -85,6 +86,11 @@ def create(
your organization's pooled sessions limit (the sum of all pool sizes cannot
exceed your limit).

chrome_policy: Custom Chrome enterprise policy overrides applied to all browsers in this pool.
Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/

extensions: List of browser extensions to load into the session. Provide each by id or name.

fill_rate_per_minute: Percentage of the pool to fill per minute. Defaults to 10%.
Expand Down Expand Up @@ -135,6 +141,7 @@ def create(
body=maybe_transform(
{
"size": size,
"chrome_policy": chrome_policy,
"extensions": extensions,
"fill_rate_per_minute": fill_rate_per_minute,
"headless": headless,
Expand Down Expand Up @@ -192,6 +199,7 @@ def update(
id_or_name: str,
*,
size: int,
chrome_policy: Dict[str, object] | Omit = omit,
discard_all_idle: bool | Omit = omit,
extensions: Iterable[BrowserExtension] | Omit = omit,
fill_rate_per_minute: int | Omit = omit,
Expand All @@ -218,6 +226,11 @@ def update(
your organization's pooled sessions limit (the sum of all pool sizes cannot
exceed your limit).

chrome_policy: Custom Chrome enterprise policy overrides applied to all browsers in this pool.
Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/

discard_all_idle: Whether to discard all idle browsers and rebuild the pool immediately. Defaults
to false.

Expand Down Expand Up @@ -273,6 +286,7 @@ def update(
body=maybe_transform(
{
"size": size,
"chrome_policy": chrome_policy,
"discard_all_idle": discard_all_idle,
"extensions": extensions,
"fill_rate_per_minute": fill_rate_per_minute,
Expand Down Expand Up @@ -508,6 +522,7 @@ async def create(
self,
*,
size: int,
chrome_policy: Dict[str, object] | Omit = omit,
extensions: Iterable[BrowserExtension] | Omit = omit,
fill_rate_per_minute: int | Omit = omit,
headless: bool | Omit = omit,
Expand All @@ -533,6 +548,11 @@ async def create(
your organization's pooled sessions limit (the sum of all pool sizes cannot
exceed your limit).

chrome_policy: Custom Chrome enterprise policy overrides applied to all browsers in this pool.
Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/

extensions: List of browser extensions to load into the session. Provide each by id or name.

fill_rate_per_minute: Percentage of the pool to fill per minute. Defaults to 10%.
Expand Down Expand Up @@ -583,6 +603,7 @@ async def create(
body=await async_maybe_transform(
{
"size": size,
"chrome_policy": chrome_policy,
"extensions": extensions,
"fill_rate_per_minute": fill_rate_per_minute,
"headless": headless,
Expand Down Expand Up @@ -640,6 +661,7 @@ async def update(
id_or_name: str,
*,
size: int,
chrome_policy: Dict[str, object] | Omit = omit,
discard_all_idle: bool | Omit = omit,
extensions: Iterable[BrowserExtension] | Omit = omit,
fill_rate_per_minute: int | Omit = omit,
Expand All @@ -666,6 +688,11 @@ async def update(
your organization's pooled sessions limit (the sum of all pool sizes cannot
exceed your limit).

chrome_policy: Custom Chrome enterprise policy overrides applied to all browsers in this pool.
Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/

discard_all_idle: Whether to discard all idle browsers and rebuild the pool immediately. Defaults
to false.

Expand Down Expand Up @@ -721,6 +748,7 @@ async def update(
body=await async_maybe_transform(
{
"size": size,
"chrome_policy": chrome_policy,
"discard_all_idle": discard_all_idle,
"extensions": extensions,
"fill_rate_per_minute": fill_rate_per_minute,
Expand Down
10 changes: 9 additions & 1 deletion src/kernel/types/browser_pool.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import List, Optional
from typing import Dict, List, Optional
from datetime import datetime

from .._models import BaseModel
Expand All @@ -21,6 +21,14 @@ class BrowserPoolConfig(BaseModel):
sum of all pool sizes cannot exceed your limit).
"""

chrome_policy: Optional[Dict[str, object]] = None
"""Custom Chrome enterprise policy overrides applied to all browsers in this pool.

Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/
"""

extensions: Optional[List[BrowserExtension]] = None
"""List of browser extensions to load into the session.

Expand Down
10 changes: 9 additions & 1 deletion src/kernel/types/browser_pool_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Iterable
from typing import Dict, Iterable
from typing_extensions import Required, TypedDict

from .shared_params.browser_profile import BrowserProfile
Expand All @@ -20,6 +20,14 @@ class BrowserPoolCreateParams(TypedDict, total=False):
sum of all pool sizes cannot exceed your limit).
"""

chrome_policy: Dict[str, object]
"""Custom Chrome enterprise policy overrides applied to all browsers in this pool.

Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/
"""

extensions: Iterable[BrowserExtension]
"""List of browser extensions to load into the session.

Expand Down
10 changes: 9 additions & 1 deletion src/kernel/types/browser_pool_update_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Iterable
from typing import Dict, Iterable
from typing_extensions import Required, TypedDict

from .shared_params.browser_profile import BrowserProfile
Expand All @@ -20,6 +20,14 @@ class BrowserPoolUpdateParams(TypedDict, total=False):
sum of all pool sizes cannot exceed your limit).
"""

chrome_policy: Dict[str, object]
"""Custom Chrome enterprise policy overrides applied to all browsers in this pool.

Keys are Chrome enterprise policy names; values must match their expected types.
Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
https://chromeenterprise.google/policies/
"""

discard_all_idle: bool
"""Whether to discard all idle browsers and rebuild the pool immediately.

Expand Down
4 changes: 4 additions & 0 deletions tests/api_resources/test_browser_pools.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def test_method_create(self, client: Kernel) -> None:
def test_method_create_with_all_params(self, client: Kernel) -> None:
browser_pool = client.browser_pools.create(
size=10,
chrome_policy={"foo": "bar"},
extensions=[
{
"id": "id",
Expand Down Expand Up @@ -143,6 +144,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None:
browser_pool = client.browser_pools.update(
id_or_name="id_or_name",
size=10,
chrome_policy={"foo": "bar"},
discard_all_idle=False,
extensions=[
{
Expand Down Expand Up @@ -454,6 +456,7 @@ async def test_method_create(self, async_client: AsyncKernel) -> None:
async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> None:
browser_pool = await async_client.browser_pools.create(
size=10,
chrome_policy={"foo": "bar"},
extensions=[
{
"id": "id",
Expand Down Expand Up @@ -563,6 +566,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) ->
browser_pool = await async_client.browser_pools.update(
id_or_name="id_or_name",
size=10,
chrome_policy={"foo": "bar"},
discard_all_idle=False,
extensions=[
{
Expand Down