Skip to content

Commit 816aea5

Browse files
authored
Merge pull request #6 from onkernel/release-please--branches--main--changes--next
release: 0.1.0-alpha.5
2 parents a59386b + 83bb471 commit 816aea5

File tree

9 files changed

+127
-18
lines changed

9 files changed

+127
-18
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.1.0-alpha.4"
2+
".": "0.1.0-alpha.5"
33
}

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 4
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-d168b58fcf39dbd0458d132091793d3e2d0930070b7dda2d5f7f1baff20dd31b.yml
33
openapi_spec_hash: b7e0fd7ee1656d7dbad57209d1584d92
4-
config_hash: c2bc5253d8afd6d67e031f73353c9b22
4+
config_hash: 2d282609080a6011e3f6222451f72237

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 0.1.0-alpha.5 (2025-05-10)
4+
5+
Full Changelog: [v0.1.0-alpha.4...v0.1.0-alpha.5](https://github.com/onkernel/kernel-python-sdk/compare/v0.1.0-alpha.4...v0.1.0-alpha.5)
6+
7+
### Features
8+
9+
* **api:** update via SDK Studio ([8bceece](https://github.com/onkernel/kernel-python-sdk/commit/8bceece9fb86d9dbc0446abd1018788ff4fbda80))
10+
311
## 0.1.0-alpha.4 (2025-05-10)
412

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

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ from kernel import Kernel
2929

3030
client = Kernel(
3131
api_key=os.environ.get("KERNEL_API_KEY"), # This is the default and can be omitted
32+
# defaults to "production".
33+
environment="development",
3234
)
3335

3436
response = client.apps.deploy(
@@ -55,6 +57,8 @@ from kernel import AsyncKernel
5557

5658
client = AsyncKernel(
5759
api_key=os.environ.get("KERNEL_API_KEY"), # This is the default and can be omitted
60+
# defaults to "production".
61+
environment="development",
5862
)
5963

6064

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "kernel"
3-
version = "0.1.0-alpha.4"
3+
version = "0.1.0-alpha.5"
44
description = "The official Python library for the kernel API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/kernel/__init__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,18 @@
55
from . import types
66
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
77
from ._utils import file_from_path
8-
from ._client import Client, Kernel, Stream, Timeout, Transport, AsyncClient, AsyncKernel, AsyncStream, RequestOptions
8+
from ._client import (
9+
ENVIRONMENTS,
10+
Client,
11+
Kernel,
12+
Stream,
13+
Timeout,
14+
Transport,
15+
AsyncClient,
16+
AsyncKernel,
17+
AsyncStream,
18+
RequestOptions,
19+
)
920
from ._models import BaseModel
1021
from ._version import __title__, __version__
1122
from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse
@@ -73,6 +84,7 @@
7384
"AsyncStream",
7485
"Kernel",
7586
"AsyncKernel",
87+
"ENVIRONMENTS",
7688
"file_from_path",
7789
"BaseModel",
7890
"DEFAULT_TIMEOUT",

src/kernel/_client.py

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from __future__ import annotations
44

55
import os
6-
from typing import Any, Union, Mapping
7-
from typing_extensions import Self, override
6+
from typing import Any, Dict, Union, Mapping, cast
7+
from typing_extensions import Self, Literal, override
88

99
import httpx
1010

@@ -30,7 +30,22 @@
3030
AsyncAPIClient,
3131
)
3232

33-
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Kernel", "AsyncKernel", "Client", "AsyncClient"]
33+
__all__ = [
34+
"ENVIRONMENTS",
35+
"Timeout",
36+
"Transport",
37+
"ProxiesTypes",
38+
"RequestOptions",
39+
"Kernel",
40+
"AsyncKernel",
41+
"Client",
42+
"AsyncClient",
43+
]
44+
45+
ENVIRONMENTS: Dict[str, str] = {
46+
"production": "https://api.onkernel.com/",
47+
"development": "https://localhost:3001/",
48+
}
3449

3550

3651
class Kernel(SyncAPIClient):
@@ -42,11 +57,14 @@ class Kernel(SyncAPIClient):
4257
# client options
4358
api_key: str
4459

60+
_environment: Literal["production", "development"] | NotGiven
61+
4562
def __init__(
4663
self,
4764
*,
4865
api_key: str | None = None,
49-
base_url: str | httpx.URL | None = None,
66+
environment: Literal["production", "development"] | NotGiven = NOT_GIVEN,
67+
base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN,
5068
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
5169
max_retries: int = DEFAULT_MAX_RETRIES,
5270
default_headers: Mapping[str, str] | None = None,
@@ -77,10 +95,31 @@ def __init__(
7795
)
7896
self.api_key = api_key
7997

80-
if base_url is None:
81-
base_url = os.environ.get("KERNEL_BASE_URL")
82-
if base_url is None:
83-
base_url = f"http://localhost:3001"
98+
self._environment = environment
99+
100+
base_url_env = os.environ.get("KERNEL_BASE_URL")
101+
if is_given(base_url) and base_url is not None:
102+
# cast required because mypy doesn't understand the type narrowing
103+
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
104+
elif is_given(environment):
105+
if base_url_env and base_url is not None:
106+
raise ValueError(
107+
"Ambiguous URL; The `KERNEL_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
108+
)
109+
110+
try:
111+
base_url = ENVIRONMENTS[environment]
112+
except KeyError as exc:
113+
raise ValueError(f"Unknown environment: {environment}") from exc
114+
elif base_url_env is not None:
115+
base_url = base_url_env
116+
else:
117+
self._environment = environment = "production"
118+
119+
try:
120+
base_url = ENVIRONMENTS[environment]
121+
except KeyError as exc:
122+
raise ValueError(f"Unknown environment: {environment}") from exc
84123

85124
super().__init__(
86125
version=__version__,
@@ -122,6 +161,7 @@ def copy(
122161
self,
123162
*,
124163
api_key: str | None = None,
164+
environment: Literal["production", "development"] | None = None,
125165
base_url: str | httpx.URL | None = None,
126166
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
127167
http_client: httpx.Client | None = None,
@@ -157,6 +197,7 @@ def copy(
157197
return self.__class__(
158198
api_key=api_key or self.api_key,
159199
base_url=base_url or self.base_url,
200+
environment=environment or self._environment,
160201
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
161202
http_client=http_client,
162203
max_retries=max_retries if is_given(max_retries) else self.max_retries,
@@ -212,11 +253,14 @@ class AsyncKernel(AsyncAPIClient):
212253
# client options
213254
api_key: str
214255

256+
_environment: Literal["production", "development"] | NotGiven
257+
215258
def __init__(
216259
self,
217260
*,
218261
api_key: str | None = None,
219-
base_url: str | httpx.URL | None = None,
262+
environment: Literal["production", "development"] | NotGiven = NOT_GIVEN,
263+
base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN,
220264
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
221265
max_retries: int = DEFAULT_MAX_RETRIES,
222266
default_headers: Mapping[str, str] | None = None,
@@ -247,10 +291,31 @@ def __init__(
247291
)
248292
self.api_key = api_key
249293

250-
if base_url is None:
251-
base_url = os.environ.get("KERNEL_BASE_URL")
252-
if base_url is None:
253-
base_url = f"http://localhost:3001"
294+
self._environment = environment
295+
296+
base_url_env = os.environ.get("KERNEL_BASE_URL")
297+
if is_given(base_url) and base_url is not None:
298+
# cast required because mypy doesn't understand the type narrowing
299+
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
300+
elif is_given(environment):
301+
if base_url_env and base_url is not None:
302+
raise ValueError(
303+
"Ambiguous URL; The `KERNEL_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
304+
)
305+
306+
try:
307+
base_url = ENVIRONMENTS[environment]
308+
except KeyError as exc:
309+
raise ValueError(f"Unknown environment: {environment}") from exc
310+
elif base_url_env is not None:
311+
base_url = base_url_env
312+
else:
313+
self._environment = environment = "production"
314+
315+
try:
316+
base_url = ENVIRONMENTS[environment]
317+
except KeyError as exc:
318+
raise ValueError(f"Unknown environment: {environment}") from exc
254319

255320
super().__init__(
256321
version=__version__,
@@ -292,6 +357,7 @@ def copy(
292357
self,
293358
*,
294359
api_key: str | None = None,
360+
environment: Literal["production", "development"] | None = None,
295361
base_url: str | httpx.URL | None = None,
296362
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
297363
http_client: httpx.AsyncClient | None = None,
@@ -327,6 +393,7 @@ def copy(
327393
return self.__class__(
328394
api_key=api_key or self.api_key,
329395
base_url=base_url or self.base_url,
396+
environment=environment or self._environment,
330397
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
331398
http_client=http_client,
332399
max_retries=max_retries if is_given(max_retries) else self.max_retries,

src/kernel/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "kernel"
4-
__version__ = "0.1.0-alpha.4" # x-release-please-version
4+
__version__ = "0.1.0-alpha.5" # x-release-please-version

tests/test_client.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,14 @@ def test_base_url_env(self) -> None:
553553
client = Kernel(api_key=api_key, _strict_response_validation=True)
554554
assert client.base_url == "http://localhost:5000/from/env/"
555555

556+
# explicit environment arg requires explicitness
557+
with update_env(KERNEL_BASE_URL="http://localhost:5000/from/env"):
558+
with pytest.raises(ValueError, match=r"you must pass base_url=None"):
559+
Kernel(api_key=api_key, _strict_response_validation=True, environment="production")
560+
561+
client = Kernel(base_url=None, api_key=api_key, _strict_response_validation=True, environment="production")
562+
assert str(client.base_url).startswith("https://api.onkernel.com/")
563+
556564
@pytest.mark.parametrize(
557565
"client",
558566
[
@@ -1341,6 +1349,16 @@ def test_base_url_env(self) -> None:
13411349
client = AsyncKernel(api_key=api_key, _strict_response_validation=True)
13421350
assert client.base_url == "http://localhost:5000/from/env/"
13431351

1352+
# explicit environment arg requires explicitness
1353+
with update_env(KERNEL_BASE_URL="http://localhost:5000/from/env"):
1354+
with pytest.raises(ValueError, match=r"you must pass base_url=None"):
1355+
AsyncKernel(api_key=api_key, _strict_response_validation=True, environment="production")
1356+
1357+
client = AsyncKernel(
1358+
base_url=None, api_key=api_key, _strict_response_validation=True, environment="production"
1359+
)
1360+
assert str(client.base_url).startswith("https://api.onkernel.com/")
1361+
13441362
@pytest.mark.parametrize(
13451363
"client",
13461364
[

0 commit comments

Comments
 (0)