Skip to content

Commit 1c7f7d4

Browse files
authored
Merge pull request #18 from hanzoai/release-please--branches--main--changes--next
release: 2.0.1
2 parents 5b204a6 + 908819d commit 1c7f7d4

File tree

9 files changed

+129
-20
lines changed

9 files changed

+129
-20
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-
".": "2.0.0"
2+
".": "2.0.1"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 188
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hanzo-industries-inc%2FHanzo-AI-d52d95e1cfea66db609fe20a4ebf5612dbb3b8f6bd1d444f43953dedf8fe55c5.yml
3-
openapi_spec_hash: cab16da993c22dfa62f6e845990ff29f
4-
config_hash: ba350ab5c18ad5058636cd0062736ace
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hanzo-industries-inc%2FHanzo-AI-ec4be99f95dc46e9442eb60f233b2bff271d6f5bf57d7c61a52bc4804f55bbd1.yml
3+
openapi_spec_hash: 87bc62c36bb6028ffd1f3e54a2809099
4+
config_hash: 830747463ff4d018b5633ce511e88558

CHANGELOG.md

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

3+
## 2.0.1 (2025-03-28)
4+
5+
Full Changelog: [v2.0.0...v2.0.1](https://github.com/hanzoai/python-sdk/compare/v2.0.0...v2.0.1)
6+
7+
### Chores
8+
9+
* update SDK settings ([#17](https://github.com/hanzoai/python-sdk/issues/17)) ([01f71f1](https://github.com/hanzoai/python-sdk/commit/01f71f1ddb19bae7479b1375bfc247ce0e74802e))
10+
311
## 2.0.0 (2025-03-27)
412

513
Full Changelog: [v1.1.0...v2.0.0](https://github.com/hanzoai/python-sdk/compare/v1.1.0...v2.0.0)

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ from hanzoai import Hanzo
2727

2828
client = Hanzo(
2929
api_key=os.environ.get("HANZO_API_KEY"), # This is the default and can be omitted
30+
# defaults to "production".
31+
environment="sandbox",
3032
)
3133

3234
response = client.get_home()
@@ -48,6 +50,8 @@ from hanzoai import AsyncHanzo
4850

4951
client = AsyncHanzo(
5052
api_key=os.environ.get("HANZO_API_KEY"), # This is the default and can be omitted
53+
# defaults to "production".
54+
environment="sandbox",
5155
)
5256

5357

pyproject.toml

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

src/hanzoai/__init__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,18 @@
33
from . import types
44
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
55
from ._utils import file_from_path
6-
from ._client import Hanzo, Client, Stream, Timeout, Transport, AsyncHanzo, AsyncClient, AsyncStream, RequestOptions
6+
from ._client import (
7+
ENVIRONMENTS,
8+
Hanzo,
9+
Client,
10+
Stream,
11+
Timeout,
12+
Transport,
13+
AsyncHanzo,
14+
AsyncClient,
15+
AsyncStream,
16+
RequestOptions,
17+
)
718
from ._models import BaseModel
819
from ._version import __title__, __version__
920
from ._response import APIResponse as APIResponse, AsyncAPIResponse as AsyncAPIResponse
@@ -59,6 +70,7 @@
5970
"AsyncStream",
6071
"Hanzo",
6172
"AsyncHanzo",
73+
"ENVIRONMENTS",
6274
"file_from_path",
6375
"BaseModel",
6476
"DEFAULT_TIMEOUT",

src/hanzoai/_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

@@ -92,7 +92,22 @@
9292
from .resources.fine_tuning import fine_tuning
9393
from .resources.organization import organization
9494

95-
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Hanzo", "AsyncHanzo", "Client", "AsyncClient"]
95+
__all__ = [
96+
"ENVIRONMENTS",
97+
"Timeout",
98+
"Transport",
99+
"ProxiesTypes",
100+
"RequestOptions",
101+
"Hanzo",
102+
"AsyncHanzo",
103+
"Client",
104+
"AsyncClient",
105+
]
106+
107+
ENVIRONMENTS: Dict[str, str] = {
108+
"production": "https://api.hanzo.ai",
109+
"sandbox": "https://api.sandbox.hanzo.ai",
110+
}
96111

97112

98113
class Hanzo(SyncAPIClient):
@@ -150,11 +165,14 @@ class Hanzo(SyncAPIClient):
150165
# client options
151166
api_key: str
152167

168+
_environment: Literal["production", "sandbox"] | NotGiven
169+
153170
def __init__(
154171
self,
155172
*,
156173
api_key: str | None = None,
157-
base_url: str | httpx.URL | None = None,
174+
environment: Literal["production", "sandbox"] | NotGiven = NOT_GIVEN,
175+
base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN,
158176
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
159177
max_retries: int = DEFAULT_MAX_RETRIES,
160178
default_headers: Mapping[str, str] | None = None,
@@ -185,10 +203,31 @@ def __init__(
185203
)
186204
self.api_key = api_key
187205

188-
if base_url is None:
189-
base_url = os.environ.get("HANZO_BASE_URL")
190-
if base_url is None:
191-
base_url = f"https://api.hanzo.ai"
206+
self._environment = environment
207+
208+
base_url_env = os.environ.get("HANZO_BASE_URL")
209+
if is_given(base_url) and base_url is not None:
210+
# cast required because mypy doesn't understand the type narrowing
211+
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
212+
elif is_given(environment):
213+
if base_url_env and base_url is not None:
214+
raise ValueError(
215+
"Ambiguous URL; The `HANZO_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
216+
)
217+
218+
try:
219+
base_url = ENVIRONMENTS[environment]
220+
except KeyError as exc:
221+
raise ValueError(f"Unknown environment: {environment}") from exc
222+
elif base_url_env is not None:
223+
base_url = base_url_env
224+
else:
225+
self._environment = environment = "production"
226+
227+
try:
228+
base_url = ENVIRONMENTS[environment]
229+
except KeyError as exc:
230+
raise ValueError(f"Unknown environment: {environment}") from exc
192231

193232
super().__init__(
194233
version=__version__,
@@ -276,6 +315,7 @@ def copy(
276315
self,
277316
*,
278317
api_key: str | None = None,
318+
environment: Literal["production", "sandbox"] | None = None,
279319
base_url: str | httpx.URL | None = None,
280320
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
281321
http_client: httpx.Client | None = None,
@@ -311,6 +351,7 @@ def copy(
311351
return self.__class__(
312352
api_key=api_key or self.api_key,
313353
base_url=base_url or self.base_url,
354+
environment=environment or self._environment,
314355
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
315356
http_client=http_client,
316357
max_retries=max_retries if is_given(max_retries) else self.max_retries,
@@ -431,11 +472,14 @@ class AsyncHanzo(AsyncAPIClient):
431472
# client options
432473
api_key: str
433474

475+
_environment: Literal["production", "sandbox"] | NotGiven
476+
434477
def __init__(
435478
self,
436479
*,
437480
api_key: str | None = None,
438-
base_url: str | httpx.URL | None = None,
481+
environment: Literal["production", "sandbox"] | NotGiven = NOT_GIVEN,
482+
base_url: str | httpx.URL | None | NotGiven = NOT_GIVEN,
439483
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
440484
max_retries: int = DEFAULT_MAX_RETRIES,
441485
default_headers: Mapping[str, str] | None = None,
@@ -466,10 +510,31 @@ def __init__(
466510
)
467511
self.api_key = api_key
468512

469-
if base_url is None:
470-
base_url = os.environ.get("HANZO_BASE_URL")
471-
if base_url is None:
472-
base_url = f"https://api.hanzo.ai"
513+
self._environment = environment
514+
515+
base_url_env = os.environ.get("HANZO_BASE_URL")
516+
if is_given(base_url) and base_url is not None:
517+
# cast required because mypy doesn't understand the type narrowing
518+
base_url = cast("str | httpx.URL", base_url) # pyright: ignore[reportUnnecessaryCast]
519+
elif is_given(environment):
520+
if base_url_env and base_url is not None:
521+
raise ValueError(
522+
"Ambiguous URL; The `HANZO_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None",
523+
)
524+
525+
try:
526+
base_url = ENVIRONMENTS[environment]
527+
except KeyError as exc:
528+
raise ValueError(f"Unknown environment: {environment}") from exc
529+
elif base_url_env is not None:
530+
base_url = base_url_env
531+
else:
532+
self._environment = environment = "production"
533+
534+
try:
535+
base_url = ENVIRONMENTS[environment]
536+
except KeyError as exc:
537+
raise ValueError(f"Unknown environment: {environment}") from exc
473538

474539
super().__init__(
475540
version=__version__,
@@ -557,6 +622,7 @@ def copy(
557622
self,
558623
*,
559624
api_key: str | None = None,
625+
environment: Literal["production", "sandbox"] | None = None,
560626
base_url: str | httpx.URL | None = None,
561627
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
562628
http_client: httpx.AsyncClient | None = None,
@@ -592,6 +658,7 @@ def copy(
592658
return self.__class__(
593659
api_key=api_key or self.api_key,
594660
base_url=base_url or self.base_url,
661+
environment=environment or self._environment,
595662
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
596663
http_client=http_client,
597664
max_retries=max_retries if is_given(max_retries) else self.max_retries,

src/hanzoai/_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__ = "hanzoai"
4-
__version__ = "2.0.0" # x-release-please-version
4+
__version__ = "2.0.1" # x-release-please-version

tests/test_client.py

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

559+
# explicit environment arg requires explicitness
560+
with update_env(HANZO_BASE_URL="http://localhost:5000/from/env"):
561+
with pytest.raises(ValueError, match=r"you must pass base_url=None"):
562+
Hanzo(api_key=api_key, _strict_response_validation=True, environment="production")
563+
564+
client = Hanzo(base_url=None, api_key=api_key, _strict_response_validation=True, environment="production")
565+
assert str(client.base_url).startswith("https://api.hanzo.ai")
566+
559567
@pytest.mark.parametrize(
560568
"client",
561569
[
@@ -1306,6 +1314,16 @@ def test_base_url_env(self) -> None:
13061314
client = AsyncHanzo(api_key=api_key, _strict_response_validation=True)
13071315
assert client.base_url == "http://localhost:5000/from/env/"
13081316

1317+
# explicit environment arg requires explicitness
1318+
with update_env(HANZO_BASE_URL="http://localhost:5000/from/env"):
1319+
with pytest.raises(ValueError, match=r"you must pass base_url=None"):
1320+
AsyncHanzo(api_key=api_key, _strict_response_validation=True, environment="production")
1321+
1322+
client = AsyncHanzo(
1323+
base_url=None, api_key=api_key, _strict_response_validation=True, environment="production"
1324+
)
1325+
assert str(client.base_url).startswith("https://api.hanzo.ai")
1326+
13091327
@pytest.mark.parametrize(
13101328
"client",
13111329
[

0 commit comments

Comments
 (0)