Skip to content

Commit 1f5e0d2

Browse files
release: 0.1.0-alpha.7 (#30)
* chore(internal): bump pyright (#29) * chore(internal): add support for TypeAliasType (#31) * chore(internal): codegen related update (#32) * chore(internal): fix some typos (#33) * chore(internal): codegen related update (#34) * chore: add missing isclass check (#35) * chore(internal): bump httpx dependency (#36) * fix(client): only call .close() when needed (#37) * docs: fix typos (#38) * chore(internal): codegen related update (#39) * feat(api): update via SDK Studio (#40) * release: 0.1.0-alpha.7 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 59621fc commit 1f5e0d2

20 files changed

+193
-77
lines changed

.release-please-manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.1.0-alpha.6"
2+
".": "0.1.0-alpha.7"
33
}

.stats.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 5
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude%2Fprelude-c2d315d9176eaab871bd9caca815b3806646706b9ef1af0ddbb2253ffd821efb.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude%2Fprelude-f4068a5a3ee027f16de68f9f411e9f52a83354e76ad8291ec02c4b7a1b53ccd3.yml

CHANGELOG.md

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
# Changelog
22

3+
## 0.1.0-alpha.7 (2025-01-08)
4+
5+
Full Changelog: [v0.1.0-alpha.6...v0.1.0-alpha.7](https://github.com/prelude-so/python-sdk/compare/v0.1.0-alpha.6...v0.1.0-alpha.7)
6+
7+
### Features
8+
9+
* **api:** update via SDK Studio ([#40](https://github.com/prelude-so/python-sdk/issues/40)) ([a16ad08](https://github.com/prelude-so/python-sdk/commit/a16ad08cc54132be9f0d3553b21d98ca983edcba))
10+
11+
12+
### Bug Fixes
13+
14+
* **client:** only call .close() when needed ([#37](https://github.com/prelude-so/python-sdk/issues/37)) ([9d64934](https://github.com/prelude-so/python-sdk/commit/9d64934403b4cfa4becd15b3d4f9934354ce1135))
15+
16+
17+
### Chores
18+
19+
* add missing isclass check ([#35](https://github.com/prelude-so/python-sdk/issues/35)) ([09b83f5](https://github.com/prelude-so/python-sdk/commit/09b83f50fd71367bee93758a31cd53621ba56ab3))
20+
* **internal:** add support for TypeAliasType ([#31](https://github.com/prelude-so/python-sdk/issues/31)) ([a734093](https://github.com/prelude-so/python-sdk/commit/a7340937bba33d659b17e001c3dc98d7f4b8d009))
21+
* **internal:** bump httpx dependency ([#36](https://github.com/prelude-so/python-sdk/issues/36)) ([39a4778](https://github.com/prelude-so/python-sdk/commit/39a4778690edc67b96e4b7a67e8d75b3d184502a))
22+
* **internal:** bump pyright ([#29](https://github.com/prelude-so/python-sdk/issues/29)) ([d10ba94](https://github.com/prelude-so/python-sdk/commit/d10ba94c17a48a69d6de2551f91d417dfd1a14e2))
23+
* **internal:** codegen related update ([#32](https://github.com/prelude-so/python-sdk/issues/32)) ([f68da06](https://github.com/prelude-so/python-sdk/commit/f68da06af9e1db5524256ee91adeb46746e2d9ce))
24+
* **internal:** codegen related update ([#34](https://github.com/prelude-so/python-sdk/issues/34)) ([9ac58c5](https://github.com/prelude-so/python-sdk/commit/9ac58c502a1247208c6bc77d482f87b6389dd1a9))
25+
* **internal:** codegen related update ([#39](https://github.com/prelude-so/python-sdk/issues/39)) ([655d237](https://github.com/prelude-so/python-sdk/commit/655d237f79cf048671378fdfa340b9c32cc36484))
26+
* **internal:** fix some typos ([#33](https://github.com/prelude-so/python-sdk/issues/33)) ([f720959](https://github.com/prelude-so/python-sdk/commit/f72095954c5f648759c52261916944c4363f2614))
27+
28+
29+
### Documentation
30+
31+
* fix typos ([#38](https://github.com/prelude-so/python-sdk/issues/38)) ([84b1be6](https://github.com/prelude-so/python-sdk/commit/84b1be6c4450fbed3d9436dc48ad22a10ec75e0d))
32+
333
## 0.1.0-alpha.6 (2024-12-11)
434

535
Full Changelog: [v0.1.0-alpha.5...v0.1.0-alpha.6](https://github.com/prelude-so/python-sdk/compare/v0.1.0-alpha.5...v0.1.0-alpha.6)

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2024 Prelude
189+
Copyright 2025 Prelude
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

README.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ except prelude_python_sdk.APIStatusError as e:
116116
print(e.response)
117117
```
118118

119-
Error codes are as followed:
119+
Error codes are as follows:
120120

121121
| Status Code | Error Type |
122122
| ----------- | -------------------------- |
@@ -267,8 +267,7 @@ If you need to access undocumented endpoints, params, or response properties, th
267267
#### Undocumented endpoints
268268

269269
To make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other
270-
http verbs. Options on the client will be respected (such as retries) will be respected when making this
271-
request.
270+
http verbs. Options on the client will be respected (such as retries) when making this request.
272271

273272
```py
274273
import httpx
@@ -325,12 +324,22 @@ client.with_options(http_client=DefaultHttpxClient(...))
325324

326325
By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.
327326

327+
```py
328+
from prelude_python_sdk import Prelude
329+
330+
with Prelude() as client:
331+
# make requests here
332+
...
333+
334+
# HTTP client is now closed
335+
```
336+
328337
## Versioning
329338

330339
This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
331340

332341
1. Changes that only affect static types, without breaking runtime behavior.
333-
2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
342+
2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
334343
3. Changes that we do not expect to impact the vast majority of users in practice.
335344

336345
We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.

pyproject.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "prelude-python-sdk"
3-
version = "0.1.0-alpha.6"
3+
version = "0.1.0-alpha.7"
44
description = "The official Python library for the Prelude API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"
@@ -10,7 +10,7 @@ authors = [
1010
dependencies = [
1111
"httpx>=0.23.0, <1",
1212
"pydantic>=1.9.0, <3",
13-
"typing-extensions>=4.7, <5",
13+
"typing-extensions>=4.10, <5",
1414
"anyio>=3.5.0, <5",
1515
"distro>=1.7.0, <2",
1616
"sniffio",
@@ -54,7 +54,7 @@ dev-dependencies = [
5454
"dirty-equals>=0.6.0",
5555
"importlib-metadata>=6.7.0",
5656
"rich>=13.7.1",
57-
"nest_asyncio==1.6.0"
57+
"nest_asyncio==1.6.0",
5858
]
5959

6060
[tool.rye.scripts]

requirements-dev.lock

+3-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ h11==0.14.0
3535
# via httpcore
3636
httpcore==1.0.2
3737
# via httpx
38-
httpx==0.25.2
38+
httpx==0.28.1
3939
# via prelude-python-sdk
4040
# via respx
4141
idna==3.4
@@ -68,15 +68,15 @@ pydantic-core==2.27.1
6868
# via pydantic
6969
pygments==2.18.0
7070
# via rich
71-
pyright==1.1.389
71+
pyright==1.1.390
7272
pytest==8.3.3
7373
# via pytest-asyncio
7474
pytest-asyncio==0.24.0
7575
python-dateutil==2.8.2
7676
# via time-machine
7777
pytz==2023.3.post1
7878
# via dirty-equals
79-
respx==0.20.2
79+
respx==0.22.0
8080
rich==13.7.1
8181
ruff==0.6.9
8282
setuptools==68.2.2
@@ -85,7 +85,6 @@ six==1.16.0
8585
# via python-dateutil
8686
sniffio==1.3.0
8787
# via anyio
88-
# via httpx
8988
# via prelude-python-sdk
9089
time-machine==2.9.0
9190
tomli==2.0.2

requirements.lock

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ h11==0.14.0
2525
# via httpcore
2626
httpcore==1.0.2
2727
# via httpx
28-
httpx==0.25.2
28+
httpx==0.28.1
2929
# via prelude-python-sdk
3030
idna==3.4
3131
# via anyio
@@ -36,7 +36,6 @@ pydantic-core==2.27.1
3636
# via pydantic
3737
sniffio==1.3.0
3838
# via anyio
39-
# via httpx
4039
# via prelude-python-sdk
4140
typing-extensions==4.12.2
4241
# via anyio

src/prelude_python_sdk/_base_client.py

+6
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,9 @@ def __init__(self, **kwargs: Any) -> None:
767767

768768
class SyncHttpxClientWrapper(DefaultHttpxClient):
769769
def __del__(self) -> None:
770+
if self.is_closed:
771+
return
772+
770773
try:
771774
self.close()
772775
except Exception:
@@ -1334,6 +1337,9 @@ def __init__(self, **kwargs: Any) -> None:
13341337

13351338
class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
13361339
def __del__(self) -> None:
1340+
if self.is_closed:
1341+
return
1342+
13371343
try:
13381344
# TODO(someday): support non asyncio runtimes here
13391345
asyncio.get_running_loop().create_task(self.aclose())

src/prelude_python_sdk/_client.py

+27-36
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import httpx
1010

11-
from . import resources, _exceptions
11+
from . import _exceptions
1212
from ._qs import Querystring
1313
from ._types import (
1414
NOT_GIVEN,
@@ -24,6 +24,7 @@
2424
get_async_library,
2525
)
2626
from ._version import __version__
27+
from .resources import watch, verification, transactional
2728
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
2829
from ._exceptions import PreludeError, APIStatusError
2930
from ._base_client import (
@@ -32,23 +33,13 @@
3233
AsyncAPIClient,
3334
)
3435

35-
__all__ = [
36-
"Timeout",
37-
"Transport",
38-
"ProxiesTypes",
39-
"RequestOptions",
40-
"resources",
41-
"Prelude",
42-
"AsyncPrelude",
43-
"Client",
44-
"AsyncClient",
45-
]
36+
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Prelude", "AsyncPrelude", "Client", "AsyncClient"]
4637

4738

4839
class Prelude(SyncAPIClient):
49-
transactional: resources.TransactionalResource
50-
verification: resources.VerificationResource
51-
watch: resources.WatchResource
40+
transactional: transactional.TransactionalResource
41+
verification: verification.VerificationResource
42+
watch: watch.WatchResource
5243
with_raw_response: PreludeWithRawResponse
5344
with_streaming_response: PreludeWithStreamedResponse
5445

@@ -106,9 +97,9 @@ def __init__(
10697
_strict_response_validation=_strict_response_validation,
10798
)
10899

109-
self.transactional = resources.TransactionalResource(self)
110-
self.verification = resources.VerificationResource(self)
111-
self.watch = resources.WatchResource(self)
100+
self.transactional = transactional.TransactionalResource(self)
101+
self.verification = verification.VerificationResource(self)
102+
self.watch = watch.WatchResource(self)
112103
self.with_raw_response = PreludeWithRawResponse(self)
113104
self.with_streaming_response = PreludeWithStreamedResponse(self)
114105

@@ -218,9 +209,9 @@ def _make_status_error(
218209

219210

220211
class AsyncPrelude(AsyncAPIClient):
221-
transactional: resources.AsyncTransactionalResource
222-
verification: resources.AsyncVerificationResource
223-
watch: resources.AsyncWatchResource
212+
transactional: transactional.AsyncTransactionalResource
213+
verification: verification.AsyncVerificationResource
214+
watch: watch.AsyncWatchResource
224215
with_raw_response: AsyncPreludeWithRawResponse
225216
with_streaming_response: AsyncPreludeWithStreamedResponse
226217

@@ -278,9 +269,9 @@ def __init__(
278269
_strict_response_validation=_strict_response_validation,
279270
)
280271

281-
self.transactional = resources.AsyncTransactionalResource(self)
282-
self.verification = resources.AsyncVerificationResource(self)
283-
self.watch = resources.AsyncWatchResource(self)
272+
self.transactional = transactional.AsyncTransactionalResource(self)
273+
self.verification = verification.AsyncVerificationResource(self)
274+
self.watch = watch.AsyncWatchResource(self)
284275
self.with_raw_response = AsyncPreludeWithRawResponse(self)
285276
self.with_streaming_response = AsyncPreludeWithStreamedResponse(self)
286277

@@ -391,30 +382,30 @@ def _make_status_error(
391382

392383
class PreludeWithRawResponse:
393384
def __init__(self, client: Prelude) -> None:
394-
self.transactional = resources.TransactionalResourceWithRawResponse(client.transactional)
395-
self.verification = resources.VerificationResourceWithRawResponse(client.verification)
396-
self.watch = resources.WatchResourceWithRawResponse(client.watch)
385+
self.transactional = transactional.TransactionalResourceWithRawResponse(client.transactional)
386+
self.verification = verification.VerificationResourceWithRawResponse(client.verification)
387+
self.watch = watch.WatchResourceWithRawResponse(client.watch)
397388

398389

399390
class AsyncPreludeWithRawResponse:
400391
def __init__(self, client: AsyncPrelude) -> None:
401-
self.transactional = resources.AsyncTransactionalResourceWithRawResponse(client.transactional)
402-
self.verification = resources.AsyncVerificationResourceWithRawResponse(client.verification)
403-
self.watch = resources.AsyncWatchResourceWithRawResponse(client.watch)
392+
self.transactional = transactional.AsyncTransactionalResourceWithRawResponse(client.transactional)
393+
self.verification = verification.AsyncVerificationResourceWithRawResponse(client.verification)
394+
self.watch = watch.AsyncWatchResourceWithRawResponse(client.watch)
404395

405396

406397
class PreludeWithStreamedResponse:
407398
def __init__(self, client: Prelude) -> None:
408-
self.transactional = resources.TransactionalResourceWithStreamingResponse(client.transactional)
409-
self.verification = resources.VerificationResourceWithStreamingResponse(client.verification)
410-
self.watch = resources.WatchResourceWithStreamingResponse(client.watch)
399+
self.transactional = transactional.TransactionalResourceWithStreamingResponse(client.transactional)
400+
self.verification = verification.VerificationResourceWithStreamingResponse(client.verification)
401+
self.watch = watch.WatchResourceWithStreamingResponse(client.watch)
411402

412403

413404
class AsyncPreludeWithStreamedResponse:
414405
def __init__(self, client: AsyncPrelude) -> None:
415-
self.transactional = resources.AsyncTransactionalResourceWithStreamingResponse(client.transactional)
416-
self.verification = resources.AsyncVerificationResourceWithStreamingResponse(client.verification)
417-
self.watch = resources.AsyncWatchResourceWithStreamingResponse(client.watch)
406+
self.transactional = transactional.AsyncTransactionalResourceWithStreamingResponse(client.transactional)
407+
self.verification = verification.AsyncVerificationResourceWithStreamingResponse(client.verification)
408+
self.watch = watch.AsyncWatchResourceWithStreamingResponse(client.watch)
418409

419410

420411
Client = Prelude

src/prelude_python_sdk/_models.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
strip_not_given,
4747
extract_type_arg,
4848
is_annotated_type,
49+
is_type_alias_type,
4950
strip_annotated_type,
5051
)
5152
from ._compat import (
@@ -428,6 +429,8 @@ def construct_type(*, value: object, type_: object) -> object:
428429
# we allow `object` as the input type because otherwise, passing things like
429430
# `Literal['value']` will be reported as a type error by type checkers
430431
type_ = cast("type[object]", type_)
432+
if is_type_alias_type(type_):
433+
type_ = type_.__value__ # type: ignore[unreachable]
431434

432435
# unwrap `Annotated[T, ...]` -> `T`
433436
if is_annotated_type(type_):
@@ -485,7 +488,11 @@ def construct_type(*, value: object, type_: object) -> object:
485488
_, items_type = get_args(type_) # Dict[_, items_type]
486489
return {key: construct_type(value=item, type_=items_type) for key, item in value.items()}
487490

488-
if not is_literal_type(type_) and (issubclass(origin, BaseModel) or issubclass(origin, GenericModel)):
491+
if (
492+
not is_literal_type(type_)
493+
and inspect.isclass(origin)
494+
and (issubclass(origin, BaseModel) or issubclass(origin, GenericModel))
495+
):
489496
if is_list(value):
490497
return [cast(Any, type_).construct(**entry) if is_mapping(entry) else entry for entry in value]
491498

src/prelude_python_sdk/_response.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import pydantic
2626

2727
from ._types import NoneType
28-
from ._utils import is_given, extract_type_arg, is_annotated_type, extract_type_var_from_base
28+
from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type, extract_type_var_from_base
2929
from ._models import BaseModel, is_basemodel
3030
from ._constants import RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER
3131
from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type
@@ -126,9 +126,15 @@ def __repr__(self) -> str:
126126
)
127127

128128
def _parse(self, *, to: type[_T] | None = None) -> R | _T:
129+
cast_to = to if to is not None else self._cast_to
130+
131+
# unwrap `TypeAlias('Name', T)` -> `T`
132+
if is_type_alias_type(cast_to):
133+
cast_to = cast_to.__value__ # type: ignore[unreachable]
134+
129135
# unwrap `Annotated[T, ...]` -> `T`
130-
if to and is_annotated_type(to):
131-
to = extract_type_arg(to, 0)
136+
if cast_to and is_annotated_type(cast_to):
137+
cast_to = extract_type_arg(cast_to, 0)
132138

133139
if self._is_sse_stream:
134140
if to:
@@ -164,18 +170,12 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
164170
return cast(
165171
R,
166172
stream_cls(
167-
cast_to=self._cast_to,
173+
cast_to=cast_to,
168174
response=self.http_response,
169175
client=cast(Any, self._client),
170176
),
171177
)
172178

173-
cast_to = to if to is not None else self._cast_to
174-
175-
# unwrap `Annotated[T, ...]` -> `T`
176-
if is_annotated_type(cast_to):
177-
cast_to = extract_type_arg(cast_to, 0)
178-
179179
if cast_to is NoneType:
180180
return cast(R, None)
181181

0 commit comments

Comments
 (0)