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.11.2"
".": "0.11.3"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 50
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-d3a597bbbb25c131e2c06eb9b47d70932d14a97a6f916677a195a128e196f4db.yml
openapi_spec_hash: c967b384624017eed0abff1b53a74530
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-5ee2116982adf46664acf84b8ba4b56ba65780983506c63d9b005dab49def757.yml
openapi_spec_hash: 42a3a519301d0e2bb2b5a71018915b55
config_hash: 0d150b61cae2dc57d3648ceae7784966
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.11.3 (2025-09-24)

Full Changelog: [v0.11.2...v0.11.3](https://github.com/onkernel/kernel-python-sdk/compare/v0.11.2...v0.11.3)

### Features

* Per Invocation Logs ([8c116b6](https://github.com/onkernel/kernel-python-sdk/commit/8c116b6e8590709dab14961b7e9c038229f5ace5))

## 0.11.2 (2025-09-24)

Full Changelog: [v0.11.1...v0.11.2](https://github.com/onkernel/kernel-python-sdk/compare/v0.11.1...v0.11.2)
Expand Down
2 changes: 1 addition & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Methods:
- <code title="get /invocations/{id}">client.invocations.<a href="./src/kernel/resources/invocations.py">retrieve</a>(id) -> <a href="./src/kernel/types/invocation_retrieve_response.py">InvocationRetrieveResponse</a></code>
- <code title="patch /invocations/{id}">client.invocations.<a href="./src/kernel/resources/invocations.py">update</a>(id, \*\*<a href="src/kernel/types/invocation_update_params.py">params</a>) -> <a href="./src/kernel/types/invocation_update_response.py">InvocationUpdateResponse</a></code>
- <code title="delete /invocations/{id}/browsers">client.invocations.<a href="./src/kernel/resources/invocations.py">delete_browsers</a>(id) -> None</code>
- <code title="get /invocations/{id}/events">client.invocations.<a href="./src/kernel/resources/invocations.py">follow</a>(id) -> <a href="./src/kernel/types/invocation_follow_response.py">InvocationFollowResponse</a></code>
- <code title="get /invocations/{id}/events">client.invocations.<a href="./src/kernel/resources/invocations.py">follow</a>(id, \*\*<a href="src/kernel/types/invocation_follow_params.py">params</a>) -> <a href="./src/kernel/types/invocation_follow_response.py">InvocationFollowResponse</a></code>

# Browsers

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.11.2"
version = "0.11.3"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
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.11.2" # x-release-please-version
__version__ = "0.11.3" # x-release-please-version
20 changes: 17 additions & 3 deletions src/kernel/resources/invocations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import httpx

from ..types import invocation_create_params, invocation_update_params
from ..types import invocation_create_params, invocation_follow_params, invocation_update_params
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
Expand Down Expand Up @@ -223,6 +223,7 @@ def follow(
self,
id: str,
*,
since: 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 @@ -236,6 +237,8 @@ def follow(
invocation reaches a terminal state.

Args:
since: Show logs since the given time (RFC timestamps or durations like 5m).

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -250,7 +253,11 @@ def follow(
return self._get(
f"/invocations/{id}/events",
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({"since": since}, invocation_follow_params.InvocationFollowParams),
),
cast_to=cast(
Any, InvocationFollowResponse
Expand Down Expand Up @@ -455,6 +462,7 @@ async def follow(
self,
id: str,
*,
since: 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 @@ -468,6 +476,8 @@ async def follow(
invocation reaches a terminal state.

Args:
since: Show logs since the given time (RFC timestamps or durations like 5m).

extra_headers: Send extra headers

extra_query: Add additional query parameters to the request
Expand All @@ -482,7 +492,11 @@ async def follow(
return await self._get(
f"/invocations/{id}/events",
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({"since": since}, invocation_follow_params.InvocationFollowParams),
),
cast_to=cast(
Any, InvocationFollowResponse
Expand Down
1 change: 1 addition & 0 deletions src/kernel/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from .deployment_follow_params import DeploymentFollowParams as DeploymentFollowParams
from .deployment_list_response import DeploymentListResponse as DeploymentListResponse
from .invocation_create_params import InvocationCreateParams as InvocationCreateParams
from .invocation_follow_params import InvocationFollowParams as InvocationFollowParams
from .invocation_update_params import InvocationUpdateParams as InvocationUpdateParams
from .browser_persistence_param import BrowserPersistenceParam as BrowserPersistenceParam
from .browser_retrieve_response import BrowserRetrieveResponse as BrowserRetrieveResponse
Expand Down
12 changes: 12 additions & 0 deletions src/kernel/types/invocation_follow_params.py
Original file line number Diff line number Diff line change
@@ -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__ = ["InvocationFollowParams"]


class InvocationFollowParams(TypedDict, total=False):
since: str
"""Show logs since the given time (RFC timestamps or durations like 5m)."""
34 changes: 26 additions & 8 deletions tests/api_resources/test_invocations.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,24 @@ def test_path_params_delete_browsers(self, client: Kernel) -> None:
@parametrize
def test_method_follow(self, client: Kernel) -> None:
invocation_stream = client.invocations.follow(
"id",
id="id",
)
invocation_stream.response.close()

@pytest.mark.skip(reason="Prism doesn't support text/event-stream responses")
@parametrize
def test_method_follow_with_all_params(self, client: Kernel) -> None:
invocation_stream = client.invocations.follow(
id="id",
since="2025-06-20T12:00:00Z",
)
invocation_stream.response.close()

@pytest.mark.skip(reason="Prism doesn't support text/event-stream responses")
@parametrize
def test_raw_response_follow(self, client: Kernel) -> None:
response = client.invocations.with_raw_response.follow(
"id",
id="id",
)

assert response.http_request.headers.get("X-Stainless-Lang") == "python"
Expand All @@ -236,7 +245,7 @@ def test_raw_response_follow(self, client: Kernel) -> None:
@parametrize
def test_streaming_response_follow(self, client: Kernel) -> None:
with client.invocations.with_streaming_response.follow(
"id",
id="id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
Expand All @@ -251,7 +260,7 @@ def test_streaming_response_follow(self, client: Kernel) -> None:
def test_path_params_follow(self, client: Kernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.invocations.with_raw_response.follow(
"",
id="",
)


Expand Down Expand Up @@ -456,15 +465,24 @@ async def test_path_params_delete_browsers(self, async_client: AsyncKernel) -> N
@parametrize
async def test_method_follow(self, async_client: AsyncKernel) -> None:
invocation_stream = await async_client.invocations.follow(
"id",
id="id",
)
await invocation_stream.response.aclose()

@pytest.mark.skip(reason="Prism doesn't support text/event-stream responses")
@parametrize
async def test_method_follow_with_all_params(self, async_client: AsyncKernel) -> None:
invocation_stream = await async_client.invocations.follow(
id="id",
since="2025-06-20T12:00:00Z",
)
await invocation_stream.response.aclose()

@pytest.mark.skip(reason="Prism doesn't support text/event-stream responses")
@parametrize
async def test_raw_response_follow(self, async_client: AsyncKernel) -> None:
response = await async_client.invocations.with_raw_response.follow(
"id",
id="id",
)

assert response.http_request.headers.get("X-Stainless-Lang") == "python"
Expand All @@ -475,7 +493,7 @@ async def test_raw_response_follow(self, async_client: AsyncKernel) -> None:
@parametrize
async def test_streaming_response_follow(self, async_client: AsyncKernel) -> None:
async with async_client.invocations.with_streaming_response.follow(
"id",
id="id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
Expand All @@ -490,5 +508,5 @@ async def test_streaming_response_follow(self, async_client: AsyncKernel) -> Non
async def test_path_params_follow(self, async_client: AsyncKernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.invocations.with_raw_response.follow(
"",
id="",
)