Skip to content
Merged
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
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.141.0"
".": "0.142.0"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
configured_endpoints: 176
configured_endpoints: 178
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.142.0](https://github.com/kernel/kernel-python-sdk/compare/v0.141.0...v0.142.0) (2026-11-06)


### Features

* Let reserved orgs list, pin and move ISP proxy IPs ([cfda76a](https://github.com/kernel/kernel-python-sdk/commit/cfda76aba98f670654ecb40853a33e8bfaeeb82e))

## [0.141.0](https://github.com/kernel/kernel-python-sdk/compare/v0.140.0...v0.141.0) (2026-11-05)


Expand Down
13 changes: 13 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,19 @@ Methods:
- <code title="delete /proxies/{id_or_name}">client.proxies.<a href="./src/kernel/resources/proxies.py">delete</a>(id_or_name) -> None</code>
- <code title="post /proxies/{id_or_name}/check">client.proxies.<a href="./src/kernel/resources/proxies.py">check</a>(id_or_name, \*\*<a href="src/kernel/types/proxy_check_params.py">params</a>) -> <a href="./src/kernel/types/proxy_check_response.py">ProxyCheckResponse</a></code>

# ProxyIPs

Types:

```python
from kernel.types import ProxyIP, ProxyIPDetail
```

Methods:

- <code title="get /proxy_ips/{ip_address}">client.proxy_ips.<a href="./src/kernel/resources/proxy_ips.py">retrieve</a>(ip_address) -> <a href="./src/kernel/types/proxy_ip_detail.py">ProxyIPDetail</a></code>
- <code title="get /proxy_ips">client.proxy_ips.<a href="./src/kernel/resources/proxy_ips.py">list</a>(\*\*<a href="src/kernel/types/proxy_ip_list_params.py">params</a>) -> <a href="./src/kernel/types/proxy_ip.py">SyncOffsetPagination[ProxyIP]</a></code>

# Extensions

Types:
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.141.0"
version = "0.142.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
44 changes: 44 additions & 0 deletions src/kernel/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
browsers,
profiles,
projects,
proxy_ips,
telemetry,
audit_logs,
extensions,
Expand All @@ -81,6 +82,7 @@
from .resources.api_keys import APIKeysResource, AsyncAPIKeysResource
from .resources.profiles import ProfilesResource, AsyncProfilesResource
from .resources.auth.auth import AuthResource, AsyncAuthResource
from .resources.proxy_ips import ProxyIPsResource, AsyncProxyIPsResource
from .resources.extensions import ExtensionsResource, AsyncExtensionsResource
from .resources.credentials import CredentialsResource, AsyncCredentialsResource
from .resources.deployments import DeploymentsResource, AsyncDeploymentsResource
Expand Down Expand Up @@ -281,6 +283,13 @@ def proxies(self) -> ProxiesResource:

return ProxiesResource(self)

@cached_property
def proxy_ips(self) -> ProxyIPsResource:
"""Create and manage proxy configurations for routing browser traffic."""
from .resources.proxy_ips import ProxyIPsResource

return ProxyIPsResource(self)

@cached_property
def extensions(self) -> ExtensionsResource:
"""Create, list, retrieve, and delete browser extensions."""
Expand Down Expand Up @@ -690,6 +699,13 @@ def proxies(self) -> AsyncProxiesResource:

return AsyncProxiesResource(self)

@cached_property
def proxy_ips(self) -> AsyncProxyIPsResource:
"""Create and manage proxy configurations for routing browser traffic."""
from .resources.proxy_ips import AsyncProxyIPsResource

return AsyncProxyIPsResource(self)

@cached_property
def extensions(self) -> AsyncExtensionsResource:
"""Create, list, retrieve, and delete browser extensions."""
Expand Down Expand Up @@ -999,6 +1015,13 @@ def proxies(self) -> proxies.ProxiesResourceWithRawResponse:

return ProxiesResourceWithRawResponse(self._client.proxies)

@cached_property
def proxy_ips(self) -> proxy_ips.ProxyIPsResourceWithRawResponse:
"""Create and manage proxy configurations for routing browser traffic."""
from .resources.proxy_ips import ProxyIPsResourceWithRawResponse

return ProxyIPsResourceWithRawResponse(self._client.proxy_ips)

@cached_property
def extensions(self) -> extensions.ExtensionsResourceWithRawResponse:
"""Create, list, retrieve, and delete browser extensions."""
Expand Down Expand Up @@ -1140,6 +1163,13 @@ def proxies(self) -> proxies.AsyncProxiesResourceWithRawResponse:

return AsyncProxiesResourceWithRawResponse(self._client.proxies)

@cached_property
def proxy_ips(self) -> proxy_ips.AsyncProxyIPsResourceWithRawResponse:
"""Create and manage proxy configurations for routing browser traffic."""
from .resources.proxy_ips import AsyncProxyIPsResourceWithRawResponse

return AsyncProxyIPsResourceWithRawResponse(self._client.proxy_ips)

@cached_property
def extensions(self) -> extensions.AsyncExtensionsResourceWithRawResponse:
"""Create, list, retrieve, and delete browser extensions."""
Expand Down Expand Up @@ -1281,6 +1311,13 @@ def proxies(self) -> proxies.ProxiesResourceWithStreamingResponse:

return ProxiesResourceWithStreamingResponse(self._client.proxies)

@cached_property
def proxy_ips(self) -> proxy_ips.ProxyIPsResourceWithStreamingResponse:
"""Create and manage proxy configurations for routing browser traffic."""
from .resources.proxy_ips import ProxyIPsResourceWithStreamingResponse

return ProxyIPsResourceWithStreamingResponse(self._client.proxy_ips)

@cached_property
def extensions(self) -> extensions.ExtensionsResourceWithStreamingResponse:
"""Create, list, retrieve, and delete browser extensions."""
Expand Down Expand Up @@ -1422,6 +1459,13 @@ def proxies(self) -> proxies.AsyncProxiesResourceWithStreamingResponse:

return AsyncProxiesResourceWithStreamingResponse(self._client.proxies)

@cached_property
def proxy_ips(self) -> proxy_ips.AsyncProxyIPsResourceWithStreamingResponse:
"""Create and manage proxy configurations for routing browser traffic."""
from .resources.proxy_ips import AsyncProxyIPsResourceWithStreamingResponse

return AsyncProxyIPsResourceWithStreamingResponse(self._client.proxy_ips)

@cached_property
def extensions(self) -> extensions.AsyncExtensionsResourceWithStreamingResponse:
"""Create, list, retrieve, and delete browser extensions."""
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.141.0" # x-release-please-version
__version__ = "0.142.0" # x-release-please-version
14 changes: 14 additions & 0 deletions src/kernel/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@
ProjectsResourceWithStreamingResponse,
AsyncProjectsResourceWithStreamingResponse,
)
from .proxy_ips import (
ProxyIPsResource,
AsyncProxyIPsResource,
ProxyIPsResourceWithRawResponse,
AsyncProxyIPsResourceWithRawResponse,
ProxyIPsResourceWithStreamingResponse,
AsyncProxyIPsResourceWithStreamingResponse,
)
from .telemetry import (
TelemetryResource,
AsyncTelemetryResource,
Expand Down Expand Up @@ -216,6 +224,12 @@
"AsyncProxiesResourceWithRawResponse",
"ProxiesResourceWithStreamingResponse",
"AsyncProxiesResourceWithStreamingResponse",
"ProxyIPsResource",
"AsyncProxyIPsResource",
"ProxyIPsResourceWithRawResponse",
"AsyncProxyIPsResourceWithRawResponse",
"ProxyIPsResourceWithStreamingResponse",
"AsyncProxyIPsResourceWithStreamingResponse",
"ExtensionsResource",
"AsyncExtensionsResource",
"ExtensionsResourceWithRawResponse",
Expand Down
60 changes: 50 additions & 10 deletions src/kernel/resources/proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ def update(
self,
id_or_name: str,
*,
name: str,
config: proxy_update_params.Config | Omit = omit,
name: 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,
Expand All @@ -159,12 +160,19 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> ProxyUpdateResponse:
"""Update a proxy's name.
"""Update a proxy's name, or move an ISP proxy to another reserved exit IP.
Proxy names are not unique and duplicate names are
allowed.
Proxy
names are not unique and duplicate names are allowed. Moving requires a reserved
ISP allocation and is accepted only for proxies of type isp: the new endpoint is
probed first and nothing changes if the probe fails. An IP outside the
allocation is a 400 with code ip_not_reserved. A 409 means the IP cannot
currently be assigned or the proxy was changed concurrently; read it back and
retry.
Args:
config: Changes to an ISP proxy's exit IP. Accepted only for proxies of type `isp`.
name: New proxy name. Proxy names are trimmed and length-checked only; duplicates are
allowed because proxies are updated by ID, not by name.
Expand All @@ -182,7 +190,13 @@ def update(
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
return self._patch(
path_template("/proxies/{id_or_name}", id_or_name=id_or_name),
body=maybe_transform({"name": name}, proxy_update_params.ProxyUpdateParams),
body=maybe_transform(
{
"config": config,
"name": name,
},
proxy_update_params.ProxyUpdateParams,
),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
Expand All @@ -196,6 +210,7 @@ def update(
def list(
self,
*,
ip_address: str | Omit = omit,
limit: int | Omit = omit,
name: str | Omit = omit,
offset: int | Omit = omit,
Expand All @@ -211,6 +226,10 @@ def list(
List proxies in the resolved project.
Args:
ip_address: Exact match on the primary exit IP of ISP proxies. Must be an IPv4 address. Only
ISP proxies are matched: the ip_address shown on other proxy types is a one-time
observation, not a stable identity.
limit: Limit the number of proxies to return.
name: Exact-match filter on proxy name using the database collation. In production,
Expand Down Expand Up @@ -240,6 +259,7 @@ def list(
timeout=timeout,
query=maybe_transform(
{
"ip_address": ip_address,
"limit": limit,
"name": name,
"offset": offset,
Expand Down Expand Up @@ -480,7 +500,8 @@ async def update(
self,
id_or_name: str,
*,
name: str,
config: proxy_update_params.Config | Omit = omit,
name: 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,
Expand All @@ -489,12 +510,19 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> ProxyUpdateResponse:
"""Update a proxy's name.
"""Update a proxy's name, or move an ISP proxy to another reserved exit IP.
Proxy names are not unique and duplicate names are
allowed.
Proxy
names are not unique and duplicate names are allowed. Moving requires a reserved
ISP allocation and is accepted only for proxies of type isp: the new endpoint is
probed first and nothing changes if the probe fails. An IP outside the
allocation is a 400 with code ip_not_reserved. A 409 means the IP cannot
currently be assigned or the proxy was changed concurrently; read it back and
retry.
Args:
config: Changes to an ISP proxy's exit IP. Accepted only for proxies of type `isp`.
name: New proxy name. Proxy names are trimmed and length-checked only; duplicates are
allowed because proxies are updated by ID, not by name.
Expand All @@ -512,7 +540,13 @@ async def update(
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
return await self._patch(
path_template("/proxies/{id_or_name}", id_or_name=id_or_name),
body=await async_maybe_transform({"name": name}, proxy_update_params.ProxyUpdateParams),
body=await async_maybe_transform(
{
"config": config,
"name": name,
},
proxy_update_params.ProxyUpdateParams,
),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
Expand All @@ -526,6 +560,7 @@ async def update(
def list(
self,
*,
ip_address: str | Omit = omit,
limit: int | Omit = omit,
name: str | Omit = omit,
offset: int | Omit = omit,
Expand All @@ -541,6 +576,10 @@ def list(
List proxies in the resolved project.
Args:
ip_address: Exact match on the primary exit IP of ISP proxies. Must be an IPv4 address. Only
ISP proxies are matched: the ip_address shown on other proxy types is a one-time
observation, not a stable identity.
limit: Limit the number of proxies to return.
name: Exact-match filter on proxy name using the database collation. In production,
Expand Down Expand Up @@ -570,6 +609,7 @@ def list(
timeout=timeout,
query=maybe_transform(
{
"ip_address": ip_address,
"limit": limit,
"name": name,
"offset": offset,
Expand Down
Loading
Loading