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.1.0-alpha.6"
".": "0.1.0-alpha.7"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 3
configured_endpoints: 4
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-d168b58fcf39dbd0458d132091793d3e2d0930070b7dda2d5f7f1baff20dd31b.yml
openapi_spec_hash: b7e0fd7ee1656d7dbad57209d1584d92
config_hash: 9139d1eb064baf60fd2265aac382f097
config_hash: eab40627b734534462ae3b8ccd8b263b
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.1.0-alpha.7 (2025-05-11)

Full Changelog: [v0.1.0-alpha.6...v0.1.0-alpha.7](https://github.com/onkernel/kernel-python-sdk/compare/v0.1.0-alpha.6...v0.1.0-alpha.7)

### Features

* **api:** update via SDK Studio ([2810c5c](https://github.com/onkernel/kernel-python-sdk/commit/2810c5c0e0e0e89e03a00b27fb1d2ab355f3a8ff))

## 0.1.0-alpha.6 (2025-05-11)

Full Changelog: [v0.1.0-alpha.5...v0.1.0-alpha.6](https://github.com/onkernel/kernel-python-sdk/compare/v0.1.0-alpha.5...v0.1.0-alpha.6)
Expand Down
3 changes: 2 additions & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
Types:

```python
from kernel.types import AppDeployResponse, AppInvokeResponse
from kernel.types import AppDeployResponse, AppInvokeResponse, AppRetrieveInvocationResponse
```

Methods:

- <code title="post /apps/deploy">client.apps.<a href="./src/kernel/resources/apps.py">deploy</a>(\*\*<a href="src/kernel/types/app_deploy_params.py">params</a>) -> <a href="./src/kernel/types/app_deploy_response.py">AppDeployResponse</a></code>
- <code title="post /apps/invoke">client.apps.<a href="./src/kernel/resources/apps.py">invoke</a>(\*\*<a href="src/kernel/types/app_invoke_params.py">params</a>) -> <a href="./src/kernel/types/app_invoke_response.py">AppInvokeResponse</a></code>
- <code title="get /apps/invocations/{id}">client.apps.<a href="./src/kernel/resources/apps.py">retrieve_invocation</a>(id) -> <a href="./src/kernel/types/app_retrieve_invocation_response.py">AppRetrieveInvocationResponse</a></code>

# Browser

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.1.0-alpha.6"
version = "0.1.0-alpha.7"
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.1.0-alpha.6" # x-release-please-version
__version__ = "0.1.0-alpha.7" # x-release-please-version
13 changes: 6 additions & 7 deletions src/kernel/app_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class KernelAppJson:
class KernelJson:
"""JSON representation of Kernel manifest"""
apps: List[KernelAppJson]
entrypoint: str

# App class
class KernelApp:
Expand Down Expand Up @@ -127,14 +126,14 @@ def get_apps(self) -> List[KernelApp]:
def get_app_by_name(self, name: str) -> Optional[KernelApp]:
return self.apps.get(name)

def export(self, entrypoint_relpath: str) -> KernelJson:
def export(self) -> KernelJson:
"""Export the registry as a KernelJson object"""
apps = [app.to_dict() for app in self.get_apps()]
return KernelJson(apps=apps, entrypoint=entrypoint_relpath)
return KernelJson(apps=apps)

def export_json(self, entrypoint_relpath: str) -> str:
def export_json(self) -> str:
"""Export the registry as JSON"""
kernel_json = self.export(entrypoint_relpath)
kernel_json = self.export()
return json.dumps(kernel_json.__dict__, indent=2)


Expand All @@ -150,6 +149,6 @@ def App(name: str) -> KernelApp:
app_registry = _app_registry

# Function to export registry as JSON
def export_registry(entrypoint_relpath: str) -> str:
def export_registry() -> str:
"""Export the registry as JSON"""
return _app_registry.export_json(entrypoint_relpath)
return _app_registry.export_json()
79 changes: 79 additions & 0 deletions src/kernel/resources/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .._base_client import make_request_options
from ..types.app_deploy_response import AppDeployResponse
from ..types.app_invoke_response import AppInvokeResponse
from ..types.app_retrieve_invocation_response import AppRetrieveInvocationResponse

__all__ = ["AppsResource", "AsyncAppsResource"]

Expand Down Expand Up @@ -152,6 +153,39 @@ def invoke(
cast_to=AppInvokeResponse,
)

def retrieve_invocation(
self,
id: str,
*,
# 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,
) -> AppRetrieveInvocationResponse:
"""
Get an app invocation by id

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}")
return self._get(
f"/apps/invocations/{id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=AppRetrieveInvocationResponse,
)


class AsyncAppsResource(AsyncAPIResource):
@cached_property
Expand Down Expand Up @@ -281,6 +315,39 @@ async def invoke(
cast_to=AppInvokeResponse,
)

async def retrieve_invocation(
self,
id: str,
*,
# 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,
) -> AppRetrieveInvocationResponse:
"""
Get an app invocation by id

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}")
return await self._get(
f"/apps/invocations/{id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=AppRetrieveInvocationResponse,
)


class AppsResourceWithRawResponse:
def __init__(self, apps: AppsResource) -> None:
Expand All @@ -292,6 +359,9 @@ def __init__(self, apps: AppsResource) -> None:
self.invoke = to_raw_response_wrapper(
apps.invoke,
)
self.retrieve_invocation = to_raw_response_wrapper(
apps.retrieve_invocation,
)


class AsyncAppsResourceWithRawResponse:
Expand All @@ -304,6 +374,9 @@ def __init__(self, apps: AsyncAppsResource) -> None:
self.invoke = async_to_raw_response_wrapper(
apps.invoke,
)
self.retrieve_invocation = async_to_raw_response_wrapper(
apps.retrieve_invocation,
)


class AppsResourceWithStreamingResponse:
Expand All @@ -316,6 +389,9 @@ def __init__(self, apps: AppsResource) -> None:
self.invoke = to_streamed_response_wrapper(
apps.invoke,
)
self.retrieve_invocation = to_streamed_response_wrapper(
apps.retrieve_invocation,
)


class AsyncAppsResourceWithStreamingResponse:
Expand All @@ -328,3 +404,6 @@ def __init__(self, apps: AsyncAppsResource) -> None:
self.invoke = async_to_streamed_response_wrapper(
apps.invoke,
)
self.retrieve_invocation = async_to_streamed_response_wrapper(
apps.retrieve_invocation,
)
1 change: 1 addition & 0 deletions src/kernel/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
from .app_deploy_response import AppDeployResponse as AppDeployResponse
from .app_invoke_response import AppInvokeResponse as AppInvokeResponse
from .browser_create_session_response import BrowserCreateSessionResponse as BrowserCreateSessionResponse
from .app_retrieve_invocation_response import AppRetrieveInvocationResponse as AppRetrieveInvocationResponse
25 changes: 25 additions & 0 deletions src/kernel/types/app_retrieve_invocation_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Optional

from pydantic import Field as FieldInfo

from .._models import BaseModel

__all__ = ["AppRetrieveInvocationResponse"]


class AppRetrieveInvocationResponse(BaseModel):
id: str

app_name: str = FieldInfo(alias="appName")

finished_at: Optional[str] = FieldInfo(alias="finishedAt", default=None)

input: str

output: str

started_at: str = FieldInfo(alias="startedAt")

status: str
90 changes: 89 additions & 1 deletion tests/api_resources/test_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@

from kernel import Kernel, AsyncKernel
from tests.utils import assert_matches_type
from kernel.types import AppDeployResponse, AppInvokeResponse
from kernel.types import (
AppDeployResponse,
AppInvokeResponse,
AppRetrieveInvocationResponse,
)

base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")

Expand Down Expand Up @@ -111,6 +115,48 @@ def test_streaming_response_invoke(self, client: Kernel) -> None:

assert cast(Any, response.is_closed) is True

@pytest.mark.skip()
@parametrize
def test_method_retrieve_invocation(self, client: Kernel) -> None:
app = client.apps.retrieve_invocation(
"id",
)
assert_matches_type(AppRetrieveInvocationResponse, app, path=["response"])

@pytest.mark.skip()
@parametrize
def test_raw_response_retrieve_invocation(self, client: Kernel) -> None:
response = client.apps.with_raw_response.retrieve_invocation(
"id",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
app = response.parse()
assert_matches_type(AppRetrieveInvocationResponse, app, path=["response"])

@pytest.mark.skip()
@parametrize
def test_streaming_response_retrieve_invocation(self, client: Kernel) -> None:
with client.apps.with_streaming_response.retrieve_invocation(
"id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

app = response.parse()
assert_matches_type(AppRetrieveInvocationResponse, app, path=["response"])

assert cast(Any, response.is_closed) is True

@pytest.mark.skip()
@parametrize
def test_path_params_retrieve_invocation(self, client: Kernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.apps.with_raw_response.retrieve_invocation(
"",
)


class TestAsyncApps:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
Expand Down Expand Up @@ -208,3 +254,45 @@ async def test_streaming_response_invoke(self, async_client: AsyncKernel) -> Non
assert_matches_type(AppInvokeResponse, app, path=["response"])

assert cast(Any, response.is_closed) is True

@pytest.mark.skip()
@parametrize
async def test_method_retrieve_invocation(self, async_client: AsyncKernel) -> None:
app = await async_client.apps.retrieve_invocation(
"id",
)
assert_matches_type(AppRetrieveInvocationResponse, app, path=["response"])

@pytest.mark.skip()
@parametrize
async def test_raw_response_retrieve_invocation(self, async_client: AsyncKernel) -> None:
response = await async_client.apps.with_raw_response.retrieve_invocation(
"id",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
app = await response.parse()
assert_matches_type(AppRetrieveInvocationResponse, app, path=["response"])

@pytest.mark.skip()
@parametrize
async def test_streaming_response_retrieve_invocation(self, async_client: AsyncKernel) -> None:
async with async_client.apps.with_streaming_response.retrieve_invocation(
"id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

app = await response.parse()
assert_matches_type(AppRetrieveInvocationResponse, app, path=["response"])

assert cast(Any, response.is_closed) is True

@pytest.mark.skip()
@parametrize
async def test_path_params_retrieve_invocation(self, async_client: AsyncKernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.apps.with_raw_response.retrieve_invocation(
"",
)