Skip to content

Commit ec709f4

Browse files
authored
Merge pull request #128 from steel-dev/release-please--branches--main--changes--next
release: 0.14.0
2 parents d8b8b94 + 151188a commit ec709f4

23 files changed

Lines changed: 2220 additions & 246 deletions

.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.13.0"
2+
".": "0.14.0"
33
}

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 35
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-498986007f2679d8f1a67744addb465b824b52370faa9076405a4cdc2a5475e1.yml
3-
openapi_spec_hash: c7b2aa9a13dd8416908df569bbc12840
4-
config_hash: 82777254c5d47bd0cf18d4e17a2e9964
1+
configured_endpoints: 36
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-a7c3e89bea1fa5763c069e476aa0296b237d3392485bb5b37058b8b7b0210ce1.yml
3+
openapi_spec_hash: 0451eda3557144cd15da8580e1e5d8fc
4+
config_hash: e49b3f69d57d7ffa0420acf772d5c846

CHANGELOG.md

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

3+
## 0.14.0 (2025-11-14)
4+
5+
Full Changelog: [v0.13.0...v0.14.0](https://github.com/steel-dev/steel-python/compare/v0.13.0...v0.14.0)
6+
7+
### Features
8+
9+
* **api:** api update ([8e574f7](https://github.com/steel-dev/steel-python/commit/8e574f7ac89ba7cd9d45c33ec1b574d0f5b24d46))
10+
* **api:** api update ([2081caf](https://github.com/steel-dev/steel-python/commit/2081cafc210ec3ef8719aa110c02c7169cd567a4))
11+
* **api:** api update ([9cf3f22](https://github.com/steel-dev/steel-python/commit/9cf3f22913a76ca9213d901b6fcc36083b770634))
12+
* **api:** api update ([3c50c72](https://github.com/steel-dev/steel-python/commit/3c50c72c7958753e3a1fc272e0a5f265dd52c1e9))
13+
* **api:** api update ([9484ce7](https://github.com/steel-dev/steel-python/commit/9484ce7490da8f5b08d51924b929a18658044bb5))
14+
15+
16+
### Bug Fixes
17+
18+
* **client:** close streams without requiring full consumption ([f8369a5](https://github.com/steel-dev/steel-python/commit/f8369a5fd241e51da8e21af879ebfab2b027b3c2))
19+
* compat with Python 3.14 ([7c47c34](https://github.com/steel-dev/steel-python/commit/7c47c34fc1dd806dff792304e8929ca8886e51f5))
20+
* **compat:** update signatures of `model_dump` and `model_dump_json` for Pydantic v1 ([3db59eb](https://github.com/steel-dev/steel-python/commit/3db59ebb31542e3432aa1ebef4a1f6f8176d7c9e))
21+
22+
23+
### Chores
24+
25+
* bump `httpx-aiohttp` version to 0.1.9 ([99fd534](https://github.com/steel-dev/steel-python/commit/99fd53418bb619da32d839e8fe6086e14e867159))
26+
* **internal/tests:** avoid race condition with implicit client cleanup ([6aefd1c](https://github.com/steel-dev/steel-python/commit/6aefd1cffd7e4c1418fa02ddc466e0ed841f5402))
27+
* **internal:** grammar fix (it's -> its) ([a9b53d6](https://github.com/steel-dev/steel-python/commit/a9b53d6c99d567cf08684188ee769f737777c258))
28+
* **package:** drop Python 3.8 support ([1cc7fed](https://github.com/steel-dev/steel-python/commit/1cc7fed7022c1b728868876930da637c4d946dd1))
29+
330
## 0.13.0 (2025-10-16)
431

532
Full Changelog: [v0.12.0...v0.13.0](https://github.com/steel-dev/steel-python/compare/v0.12.0...v0.13.0)

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<!-- prettier-ignore -->
44
[![PyPI version](https://img.shields.io/pypi/v/steel-sdk.svg?label=pypi%20(stable))](https://pypi.org/project/steel-sdk/)
55

6-
The Steel Python library provides convenient access to the Steel REST API from any Python 3.8+
6+
The Steel Python library provides convenient access to the Steel REST API from any Python 3.9+
77
application. The library includes type definitions for all request params and response fields,
88
and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
99

@@ -444,7 +444,7 @@ print(steel.__version__)
444444

445445
## Requirements
446446

447-
Python 3.8 or higher.
447+
Python 3.9 or higher.
448448

449449
## Contributing
450450

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ from steel.types import (
5656
Session,
5757
SessionContext,
5858
Sessionslist,
59+
SessionComputerResponse,
5960
SessionEventsResponse,
6061
SessionLiveDetailsResponse,
6162
SessionReleaseResponse,
@@ -68,6 +69,7 @@ Methods:
6869
- <code title="post /v1/sessions">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">create</a>(\*\*<a href="src/steel/types/session_create_params.py">params</a>) -> <a href="./src/steel/types/session.py">Session</a></code>
6970
- <code title="get /v1/sessions/{id}">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">retrieve</a>(id) -> <a href="./src/steel/types/session.py">Session</a></code>
7071
- <code title="get /v1/sessions">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">list</a>(\*\*<a href="src/steel/types/session_list_params.py">params</a>) -> SyncSessionsCursor[Session]</code>
72+
- <code title="post /v1/sessions/{sessionId}/computer">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">computer</a>(session_id, \*\*<a href="src/steel/types/session_computer_params.py">params</a>) -> <a href="./src/steel/types/session_computer_response.py">SessionComputerResponse</a></code>
7173
- <code title="get /v1/sessions/{id}/context">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">context</a>(id) -> <a href="./src/steel/types/session_context.py">SessionContext</a></code>
7274
- <code title="get /v1/sessions/{id}/events">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">events</a>(id) -> <a href="./src/steel/types/session_events_response.py">SessionEventsResponse</a></code>
7375
- <code title="get /v1/sessions/{id}/live-details">client.sessions.<a href="./src/steel/resources/sessions/sessions.py">live_details</a>(id) -> <a href="./src/steel/types/session_live_details_response.py">SessionLiveDetailsResponse</a></code>

pyproject.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "steel-sdk"
3-
version = "0.13.0"
3+
version = "0.14.0"
44
description = "The official Python library for the steel API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"
@@ -15,11 +15,10 @@ dependencies = [
1515
"distro>=1.7.0, <2",
1616
"sniffio",
1717
]
18-
requires-python = ">= 3.8"
18+
requires-python = ">= 3.9"
1919
classifiers = [
2020
"Typing :: Typed",
2121
"Intended Audience :: Developers",
22-
"Programming Language :: Python :: 3.8",
2322
"Programming Language :: Python :: 3.9",
2423
"Programming Language :: Python :: 3.10",
2524
"Programming Language :: Python :: 3.11",
@@ -39,7 +38,7 @@ Homepage = "https://github.com/steel-dev/steel-python"
3938
Repository = "https://github.com/steel-dev/steel-python"
4039

4140
[project.optional-dependencies]
42-
aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"]
41+
aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"]
4342

4443
[tool.rye]
4544
managed = true
@@ -141,7 +140,7 @@ filterwarnings = [
141140
# there are a couple of flags that are still disabled by
142141
# default in strict mode as they are experimental and niche.
143142
typeCheckingMode = "strict"
144-
pythonVersion = "3.8"
143+
pythonVersion = "3.9"
145144

146145
exclude = [
147146
"_dev",

requirements-dev.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ httpx==0.28.1
5656
# via httpx-aiohttp
5757
# via respx
5858
# via steel-sdk
59-
httpx-aiohttp==0.1.8
59+
httpx-aiohttp==0.1.9
6060
# via steel-sdk
6161
idna==3.4
6262
# via anyio

requirements.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ httpcore==1.0.9
4343
httpx==0.28.1
4444
# via httpx-aiohttp
4545
# via steel-sdk
46-
httpx-aiohttp==0.1.8
46+
httpx-aiohttp==0.1.9
4747
# via steel-sdk
4848
idna==3.4
4949
# via anyio

src/steel/_models.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import os
44
import inspect
5+
import weakref
56
from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
67
from datetime import date, datetime
78
from typing_extensions import (
@@ -256,32 +257,41 @@ def model_dump(
256257
mode: Literal["json", "python"] | str = "python",
257258
include: IncEx | None = None,
258259
exclude: IncEx | None = None,
260+
context: Any | None = None,
259261
by_alias: bool | None = None,
260262
exclude_unset: bool = False,
261263
exclude_defaults: bool = False,
262264
exclude_none: bool = False,
265+
exclude_computed_fields: bool = False,
263266
round_trip: bool = False,
264267
warnings: bool | Literal["none", "warn", "error"] = True,
265-
context: dict[str, Any] | None = None,
266-
serialize_as_any: bool = False,
267268
fallback: Callable[[Any], Any] | None = None,
269+
serialize_as_any: bool = False,
268270
) -> dict[str, Any]:
269271
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
270272
271273
Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
272274
273275
Args:
274276
mode: The mode in which `to_python` should run.
275-
If mode is 'json', the dictionary will only contain JSON serializable types.
276-
If mode is 'python', the dictionary may contain any Python objects.
277-
include: A list of fields to include in the output.
278-
exclude: A list of fields to exclude from the output.
277+
If mode is 'json', the output will only contain JSON serializable types.
278+
If mode is 'python', the output may contain non-JSON-serializable Python objects.
279+
include: A set of fields to include in the output.
280+
exclude: A set of fields to exclude from the output.
281+
context: Additional context to pass to the serializer.
279282
by_alias: Whether to use the field's alias in the dictionary key if defined.
280-
exclude_unset: Whether to exclude fields that are unset or None from the output.
281-
exclude_defaults: Whether to exclude fields that are set to their default value from the output.
282-
exclude_none: Whether to exclude fields that have a value of `None` from the output.
283-
round_trip: Whether to enable serialization and deserialization round-trip support.
284-
warnings: Whether to log warnings when invalid fields are encountered.
283+
exclude_unset: Whether to exclude fields that have not been explicitly set.
284+
exclude_defaults: Whether to exclude fields that are set to their default value.
285+
exclude_none: Whether to exclude fields that have a value of `None`.
286+
exclude_computed_fields: Whether to exclude computed fields.
287+
While this can be useful for round-tripping, it is usually recommended to use the dedicated
288+
`round_trip` parameter instead.
289+
round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].
290+
warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,
291+
"error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].
292+
fallback: A function to call when an unknown value is encountered. If not provided,
293+
a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
294+
serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
285295
286296
Returns:
287297
A dictionary representation of the model.
@@ -298,6 +308,8 @@ def model_dump(
298308
raise ValueError("serialize_as_any is only supported in Pydantic v2")
299309
if fallback is not None:
300310
raise ValueError("fallback is only supported in Pydantic v2")
311+
if exclude_computed_fields != False:
312+
raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
301313
dumped = super().dict( # pyright: ignore[reportDeprecated]
302314
include=include,
303315
exclude=exclude,
@@ -314,15 +326,17 @@ def model_dump_json(
314326
self,
315327
*,
316328
indent: int | None = None,
329+
ensure_ascii: bool = False,
317330
include: IncEx | None = None,
318331
exclude: IncEx | None = None,
332+
context: Any | None = None,
319333
by_alias: bool | None = None,
320334
exclude_unset: bool = False,
321335
exclude_defaults: bool = False,
322336
exclude_none: bool = False,
337+
exclude_computed_fields: bool = False,
323338
round_trip: bool = False,
324339
warnings: bool | Literal["none", "warn", "error"] = True,
325-
context: dict[str, Any] | None = None,
326340
fallback: Callable[[Any], Any] | None = None,
327341
serialize_as_any: bool = False,
328342
) -> str:
@@ -354,6 +368,10 @@ def model_dump_json(
354368
raise ValueError("serialize_as_any is only supported in Pydantic v2")
355369
if fallback is not None:
356370
raise ValueError("fallback is only supported in Pydantic v2")
371+
if ensure_ascii != False:
372+
raise ValueError("ensure_ascii is only supported in Pydantic v2")
373+
if exclude_computed_fields != False:
374+
raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
357375
return super().json( # type: ignore[reportDeprecated]
358376
indent=indent,
359377
include=include,
@@ -573,6 +591,9 @@ class CachedDiscriminatorType(Protocol):
573591
__discriminator__: DiscriminatorDetails
574592

575593

594+
DISCRIMINATOR_CACHE: weakref.WeakKeyDictionary[type, DiscriminatorDetails] = weakref.WeakKeyDictionary()
595+
596+
576597
class DiscriminatorDetails:
577598
field_name: str
578599
"""The name of the discriminator field in the variant class, e.g.
@@ -615,8 +636,9 @@ def __init__(
615636

616637

617638
def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None:
618-
if isinstance(union, CachedDiscriminatorType):
619-
return union.__discriminator__
639+
cached = DISCRIMINATOR_CACHE.get(union)
640+
if cached is not None:
641+
return cached
620642

621643
discriminator_field_name: str | None = None
622644

@@ -669,7 +691,7 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
669691
discriminator_field=discriminator_field_name,
670692
discriminator_alias=discriminator_alias,
671693
)
672-
cast(CachedDiscriminatorType, union).__discriminator__ = details
694+
DISCRIMINATOR_CACHE.setdefault(union, details)
673695
return details
674696

675697

src/steel/_streaming.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ def __stream__(self) -> Iterator[_T]:
5757
for sse in iterator:
5858
yield process_data(data=sse.json(), cast_to=cast_to, response=response)
5959

60-
# Ensure the entire stream is consumed
61-
for _sse in iterator:
62-
...
60+
# As we might not fully consume the response stream, we need to close it explicitly
61+
response.close()
6362

6463
def __enter__(self) -> Self:
6564
return self
@@ -121,9 +120,8 @@ async def __stream__(self) -> AsyncIterator[_T]:
121120
async for sse in iterator:
122121
yield process_data(data=sse.json(), cast_to=cast_to, response=response)
123122

124-
# Ensure the entire stream is consumed
125-
async for _sse in iterator:
126-
...
123+
# As we might not fully consume the response stream, we need to close it explicitly
124+
await response.aclose()
127125

128126
async def __aenter__(self) -> Self:
129127
return self

0 commit comments

Comments
 (0)