diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8ba6b37d..97f05b2a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -61,14 +61,18 @@ jobs:
run: rye build
- name: Get GitHub OIDC Token
- if: github.repository == 'stainless-sdks/steel-python'
+ if: |-
+ github.repository == 'stainless-sdks/steel-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());
- name: Upload tarball
- if: github.repository == 'stainless-sdks/steel-python'
+ if: |-
+ github.repository == 'stainless-sdks/steel-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b4e9013b..6db19b95 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.16.0"
+ ".": "0.17.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 416f1d7a..35acfccf 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 39
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-45efcdf3e5ccffb6e94a86be505b24b7b4ff05d8f1a2978c2a281729af68cb82.yml
-openapi_spec_hash: 9a7724672b05d44888d67b6ed0ffc7ca
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nen-labs%2Fsteel-f51ce05f6128dcdd6b500492869910d3a43737c66d0bc13c3f2e67f42362605c.yml
+openapi_spec_hash: c573fb6f26d5fb14eaf92e0a107323ec
config_hash: dce4dea59023b0a00890fa654fbfffb4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f1805a8..ab379643 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
# Changelog
+## 0.17.0 (2026-03-16)
+
+Full Changelog: [v0.16.0...v0.17.0](https://github.com/steel-dev/steel-python/compare/v0.16.0...v0.17.0)
+
+### Features
+
+* **api:** api update ([b341bdb](https://github.com/steel-dev/steel-python/commit/b341bdb0c251b50c85d862b77bb23df08562186b))
+* **api:** api update ([bfcb31e](https://github.com/steel-dev/steel-python/commit/bfcb31ebdff79c4115bc2bb6c4f7e0c48a55f469))
+* **api:** api update ([20160d0](https://github.com/steel-dev/steel-python/commit/20160d01b7660dc2b3856a2069d3fe3bde7ad2c0))
+
+
+### Chores
+
+* **ci:** skip uploading artifacts on stainless-internal branches ([54e6339](https://github.com/steel-dev/steel-python/commit/54e6339015586e3ffe196c459385cbc2dd6eb94a))
+* format all `api.md` files ([99ec714](https://github.com/steel-dev/steel-python/commit/99ec714917e3375108409099c28ce0a8efc2171e))
+* **internal:** add request options to SSE classes ([5e72d8e](https://github.com/steel-dev/steel-python/commit/5e72d8e76a7e017a7611d87d3b49a1d7e25cd21e))
+* **internal:** bump dependencies ([d04a927](https://github.com/steel-dev/steel-python/commit/d04a92742a449ee597cc68b2312e90a835f9e8b2))
+* **internal:** fix lint error on Python 3.14 ([5bfdbc9](https://github.com/steel-dev/steel-python/commit/5bfdbc994392efd19eb97b366113416dddb4eb69))
+* **internal:** make `test_proxy_environment_variables` more resilient ([2e233ea](https://github.com/steel-dev/steel-python/commit/2e233ea37507adb2f05b4419ef0e8fd1932f6ba4))
+* **internal:** make `test_proxy_environment_variables` more resilient to env ([8b312f4](https://github.com/steel-dev/steel-python/commit/8b312f41858a4abf129a5e5da1ed75d5cddffe16))
+* **test:** do not count install time for mock server timeout ([faf3551](https://github.com/steel-dev/steel-python/commit/faf3551f91a527bada3b902550742dca0668d91f))
+* update mock server docs ([98b44de](https://github.com/steel-dev/steel-python/commit/98b44de2a1a0eb2f17878fe3d01a2b45d5d0ded5))
+* update placeholder string ([3af093a](https://github.com/steel-dev/steel-python/commit/3af093a33381b2436287bdeb87ff0b3e0f997385))
+
## 0.16.0 (2026-02-06)
Full Changelog: [v0.15.0...v0.16.0](https://github.com/steel-dev/steel-python/compare/v0.15.0...v0.16.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5c571fbe..fbd86d24 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -88,8 +88,7 @@ $ pip install ./path-to-wheel-file.whl
Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
```sh
-# you will need npm installed
-$ npx prism mock path/to/your/openapi.yml
+$ ./scripts/mock
```
```sh
diff --git a/api.md b/api.md
index 49ae21fe..8f08616f 100644
--- a/api.md
+++ b/api.md
@@ -71,7 +71,7 @@ Methods:
- client.sessions.list(\*\*params) -> SyncSessionsCursor[Session]
- client.sessions.computer(session_id, \*\*params) -> SessionComputerResponse
- client.sessions.context(id) -> SessionContext
-- client.sessions.events(id) -> SessionEventsResponse
+- client.sessions.events(id, \*\*params) -> SessionEventsResponse
- client.sessions.live_details(id) -> SessionLiveDetailsResponse
- client.sessions.release(id) -> SessionReleaseResponse
- client.sessions.release_all() -> SessionReleaseAllResponse
diff --git a/pyproject.toml b/pyproject.toml
index 10d2c916..8219a00b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "steel-sdk"
-version = "0.16.0"
+version = "0.17.0"
description = "The official Python library for the steel API"
dynamic = ["readme"]
license = "Apache-2.0"
@@ -69,7 +69,7 @@ format = { chain = [
# run formatting again to fix any inconsistencies when imports are stripped
"format:ruff",
]}
-"format:docs" = "python scripts/utils/ruffen-docs.py README.md api.md"
+"format:docs" = "bash -c 'python scripts/utils/ruffen-docs.py README.md $(find . -type f -name api.md)'"
"format:ruff" = "ruff format"
"lint" = { chain = [
diff --git a/requirements-dev.lock b/requirements-dev.lock
index a25ec1b0..e55c751c 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -12,14 +12,14 @@
-e file:.
aiohappyeyeballs==2.6.1
# via aiohttp
-aiohttp==3.13.2
+aiohttp==3.13.3
# via httpx-aiohttp
# via steel-sdk
aiosignal==1.4.0
# via aiohttp
annotated-types==0.7.0
# via pydantic
-anyio==4.12.0
+anyio==4.12.1
# via httpx
# via steel-sdk
argcomplete==3.6.3
@@ -31,7 +31,7 @@ attrs==25.4.0
# via nox
backports-asyncio-runner==1.2.0
# via pytest-asyncio
-certifi==2025.11.12
+certifi==2026.1.4
# via httpcore
# via httpx
colorlog==6.10.1
@@ -61,7 +61,7 @@ httpx==0.28.1
# via httpx-aiohttp
# via respx
# via steel-sdk
-httpx-aiohttp==0.1.9
+httpx-aiohttp==0.1.12
# via steel-sdk
humanize==4.13.0
# via nox
@@ -69,7 +69,7 @@ idna==3.11
# via anyio
# via httpx
# via yarl
-importlib-metadata==8.7.0
+importlib-metadata==8.7.1
iniconfig==2.1.0
# via pytest
markdown-it-py==3.0.0
@@ -82,14 +82,14 @@ multidict==6.7.0
mypy==1.17.0
mypy-extensions==1.1.0
# via mypy
-nodeenv==1.9.1
+nodeenv==1.10.0
# via pyright
nox==2025.11.12
packaging==25.0
# via dependency-groups
# via nox
# via pytest
-pathspec==0.12.1
+pathspec==1.0.3
# via mypy
platformdirs==4.4.0
# via virtualenv
@@ -115,13 +115,13 @@ python-dateutil==2.9.0.post0
# via time-machine
respx==0.22.0
rich==14.2.0
-ruff==0.14.7
+ruff==0.14.13
six==1.17.0
# via python-dateutil
sniffio==1.3.1
# via steel-sdk
time-machine==2.19.0
-tomli==2.3.0
+tomli==2.4.0
# via dependency-groups
# via mypy
# via nox
@@ -141,7 +141,7 @@ typing-extensions==4.15.0
# via virtualenv
typing-inspection==0.4.2
# via pydantic
-virtualenv==20.35.4
+virtualenv==20.36.1
# via nox
yarl==1.22.0
# via aiohttp
diff --git a/requirements.lock b/requirements.lock
index 2ceaf4b6..b4878467 100644
--- a/requirements.lock
+++ b/requirements.lock
@@ -12,21 +12,21 @@
-e file:.
aiohappyeyeballs==2.6.1
# via aiohttp
-aiohttp==3.13.2
+aiohttp==3.13.3
# via httpx-aiohttp
# via steel-sdk
aiosignal==1.4.0
# via aiohttp
annotated-types==0.7.0
# via pydantic
-anyio==4.12.0
+anyio==4.12.1
# via httpx
# via steel-sdk
async-timeout==5.0.1
# via aiohttp
attrs==25.4.0
# via aiohttp
-certifi==2025.11.12
+certifi==2026.1.4
# via httpcore
# via httpx
distro==1.9.0
@@ -43,7 +43,7 @@ httpcore==1.0.9
httpx==0.28.1
# via httpx-aiohttp
# via steel-sdk
-httpx-aiohttp==0.1.9
+httpx-aiohttp==0.1.12
# via steel-sdk
idna==3.11
# via anyio
diff --git a/scripts/mock b/scripts/mock
index 0b28f6ea..bcf3b392 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -21,11 +21,22 @@ echo "==> Starting mock server with URL ${URL}"
# Run prism mock on the given spec
if [ "$1" == "--daemon" ]; then
+ # Pre-install the package so the download doesn't eat into the startup timeout
+ npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism --version
+
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
- # Wait for server to come online
+ # Wait for server to come online (max 30s)
echo -n "Waiting for server"
+ attempts=0
while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
+ attempts=$((attempts + 1))
+ if [ "$attempts" -ge 300 ]; then
+ echo
+ echo "Timed out waiting for Prism server to start"
+ cat .prism.log
+ exit 1
+ fi
echo -n "."
sleep 0.1
done
diff --git a/src/steel/_response.py b/src/steel/_response.py
index 4a4b497b..db760162 100644
--- a/src/steel/_response.py
+++ b/src/steel/_response.py
@@ -152,6 +152,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -162,6 +163,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=extract_stream_chunk_type(self._stream_cls),
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
@@ -175,6 +177,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
+ options=self._options,
),
)
diff --git a/src/steel/_streaming.py b/src/steel/_streaming.py
index 3f2344fa..a5f00069 100644
--- a/src/steel/_streaming.py
+++ b/src/steel/_streaming.py
@@ -4,7 +4,7 @@
import json
import inspect
from types import TracebackType
-from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, AsyncIterator, cast
+from typing import TYPE_CHECKING, Any, Generic, TypeVar, Iterator, Optional, AsyncIterator, cast
from typing_extensions import Self, Protocol, TypeGuard, override, get_origin, runtime_checkable
import httpx
@@ -13,6 +13,7 @@
if TYPE_CHECKING:
from ._client import Steel, AsyncSteel
+ from ._models import FinalRequestOptions
_T = TypeVar("_T")
@@ -22,7 +23,7 @@ class Stream(Generic[_T]):
"""Provides the core interface to iterate over a synchronous stream response."""
response: httpx.Response
-
+ _options: Optional[FinalRequestOptions] = None
_decoder: SSEBytesDecoder
def __init__(
@@ -31,10 +32,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: Steel,
+ options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
+ self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()
@@ -85,7 +88,7 @@ class AsyncStream(Generic[_T]):
"""Provides the core interface to iterate over an asynchronous stream response."""
response: httpx.Response
-
+ _options: Optional[FinalRequestOptions] = None
_decoder: SSEDecoder | SSEBytesDecoder
def __init__(
@@ -94,10 +97,12 @@ def __init__(
cast_to: type[_T],
response: httpx.Response,
client: AsyncSteel,
+ options: Optional[FinalRequestOptions] = None,
) -> None:
self.response = response
self._cast_to = cast_to
self._client = client
+ self._options = options
self._decoder = client._make_sse_decoder()
self._iterator = self.__stream__()
diff --git a/src/steel/_utils/_compat.py b/src/steel/_utils/_compat.py
index dd703233..2c70b299 100644
--- a/src/steel/_utils/_compat.py
+++ b/src/steel/_utils/_compat.py
@@ -26,7 +26,7 @@ def is_union(tp: Optional[Type[Any]]) -> bool:
else:
import types
- return tp is Union or tp is types.UnionType
+ return tp is Union or tp is types.UnionType # type: ignore[comparison-overlap]
def is_typeddict(tp: Type[Any]) -> bool:
diff --git a/src/steel/_version.py b/src/steel/_version.py
index b8580980..06fdcfc6 100644
--- a/src/steel/_version.py
+++ b/src/steel/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "steel"
-__version__ = "0.16.0" # x-release-please-version
+__version__ = "0.17.0" # x-release-please-version
diff --git a/src/steel/resources/sessions/sessions.py b/src/steel/resources/sessions/sessions.py
index a02b81c8..d54ca834 100644
--- a/src/steel/resources/sessions/sessions.py
+++ b/src/steel/resources/sessions/sessions.py
@@ -15,7 +15,7 @@
FilesResourceWithStreamingResponse,
AsyncFilesResourceWithStreamingResponse,
)
-from ...types import session_list_params, session_create_params, session_computer_params
+from ...types import session_list_params, session_create_params, session_events_params, session_computer_params
from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from ..._utils import required_args, maybe_transform, async_maybe_transform
from .captchas import (
@@ -85,6 +85,7 @@ def create(
debug_config: session_create_params.DebugConfig | Omit = omit,
device_config: session_create_params.DeviceConfig | Omit = omit,
dimensions: session_create_params.Dimensions | Omit = omit,
+ experimental_features: SequenceNotStr[str] | Omit = omit,
extension_ids: SequenceNotStr[str] | Omit = omit,
headless: bool | Omit = omit,
is_selenium: bool | Omit = omit,
@@ -126,6 +127,8 @@ def create(
dimensions: Viewport and browser window dimensions for the session
+ experimental_features: Enable experimental features for the session.
+
extension_ids: Array of extension IDs to install in the session. Use ['all_ext'] to install all
uploaded extensions.
@@ -183,6 +186,7 @@ def create(
"debug_config": debug_config,
"device_config": device_config,
"dimensions": dimensions,
+ "experimental_features": experimental_features,
"extension_ids": extension_ids,
"headless": headless,
"is_selenium": is_selenium,
@@ -716,6 +720,9 @@ def events(
self,
id: str,
*,
+ compressed: bool | Omit = omit,
+ limit: int | Omit = omit,
+ pointer: str | Omit = omit,
# 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,
@@ -727,6 +734,12 @@ def events(
This endpoint allows you to get the recorded session events in the RRWeb format
Args:
+ compressed: Compress the events
+
+ limit: Optional pagination limit
+
+ pointer: Opaque pagination token. Pass the Next-Cursor header value to get the next page.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -740,7 +753,18 @@ def events(
return self._get(
f"/v1/sessions/{id}/events",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "compressed": compressed,
+ "limit": limit,
+ "pointer": pointer,
+ },
+ session_events_params.SessionEventsParams,
+ ),
),
cast_to=SessionEventsResponse,
)
@@ -868,6 +892,7 @@ async def create(
debug_config: session_create_params.DebugConfig | Omit = omit,
device_config: session_create_params.DeviceConfig | Omit = omit,
dimensions: session_create_params.Dimensions | Omit = omit,
+ experimental_features: SequenceNotStr[str] | Omit = omit,
extension_ids: SequenceNotStr[str] | Omit = omit,
headless: bool | Omit = omit,
is_selenium: bool | Omit = omit,
@@ -909,6 +934,8 @@ async def create(
dimensions: Viewport and browser window dimensions for the session
+ experimental_features: Enable experimental features for the session.
+
extension_ids: Array of extension IDs to install in the session. Use ['all_ext'] to install all
uploaded extensions.
@@ -966,6 +993,7 @@ async def create(
"debug_config": debug_config,
"device_config": device_config,
"dimensions": dimensions,
+ "experimental_features": experimental_features,
"extension_ids": extension_ids,
"headless": headless,
"is_selenium": is_selenium,
@@ -1499,6 +1527,9 @@ async def events(
self,
id: str,
*,
+ compressed: bool | Omit = omit,
+ limit: int | Omit = omit,
+ pointer: str | Omit = omit,
# 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,
@@ -1510,6 +1541,12 @@ async def events(
This endpoint allows you to get the recorded session events in the RRWeb format
Args:
+ compressed: Compress the events
+
+ limit: Optional pagination limit
+
+ pointer: Opaque pagination token. Pass the Next-Cursor header value to get the next page.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1523,7 +1560,18 @@ async def events(
return await self._get(
f"/v1/sessions/{id}/events",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "compressed": compressed,
+ "limit": limit,
+ "pointer": pointer,
+ },
+ session_events_params.SessionEventsParams,
+ ),
),
cast_to=SessionEventsResponse,
)
diff --git a/src/steel/types/__init__.py b/src/steel/types/__init__.py
index e33ce8a3..f2739660 100644
--- a/src/steel/types/__init__.py
+++ b/src/steel/types/__init__.py
@@ -19,6 +19,7 @@
from .profile_list_response import ProfileListResponse as ProfileListResponse
from .profile_update_params import ProfileUpdateParams as ProfileUpdateParams
from .session_create_params import SessionCreateParams as SessionCreateParams
+from .session_events_params import SessionEventsParams as SessionEventsParams
from .credential_list_params import CredentialListParams as CredentialListParams
from .extension_list_response import ExtensionListResponse as ExtensionListResponse
from .extension_update_params import ExtensionUpdateParams as ExtensionUpdateParams
diff --git a/src/steel/types/session_create_params.py b/src/steel/types/session_create_params.py
index b98d7f3f..cfb5d8fa 100644
--- a/src/steel/types/session_create_params.py
+++ b/src/steel/types/session_create_params.py
@@ -58,6 +58,9 @@ class SessionCreateParams(TypedDict, total=False):
dimensions: Dimensions
"""Viewport and browser window dimensions for the session"""
+ experimental_features: Annotated[SequenceNotStr[str], PropertyInfo(alias="experimentalFeatures")]
+ """Enable experimental features for the session."""
+
extension_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="extensionIds")]
"""Array of extension IDs to install in the session.
diff --git a/src/steel/types/session_events_params.py b/src/steel/types/session_events_params.py
new file mode 100644
index 00000000..d66997c4
--- /dev/null
+++ b/src/steel/types/session_events_params.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["SessionEventsParams"]
+
+
+class SessionEventsParams(TypedDict, total=False):
+ compressed: bool
+ """Compress the events"""
+
+ limit: int
+ """Optional pagination limit"""
+
+ pointer: str
+ """Opaque pagination token.
+
+ Pass the Next-Cursor header value to get the next page.
+ """
diff --git a/src/steel/types/sessionslist.py b/src/steel/types/sessionslist.py
index 05604e7e..58dfd383 100644
--- a/src/steel/types/sessionslist.py
+++ b/src/steel/types/sessionslist.py
@@ -177,5 +177,8 @@ class Sessionslist(BaseModel):
sessions: List[Session]
"""List of browser sessions"""
- total_count: int = FieldInfo(alias="totalCount")
- """Total number of sessions matching the query"""
+ total_count: Optional[int] = FieldInfo(alias="totalCount", default=None)
+ """Total number of sessions matching the query.
+
+ Only included for filtered queries (e.g. status=live).
+ """
diff --git a/tests/api_resources/sessions/test_files.py b/tests/api_resources/sessions/test_files.py
index be2dbb03..ed641c70 100644
--- a/tests/api_resources/sessions/test_files.py
+++ b/tests/api_resources/sessions/test_files.py
@@ -263,7 +263,7 @@ def test_path_params_download_archive(self, client: Steel) -> None:
def test_method_upload(self, client: Steel) -> None:
file = client.sessions.files.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(File, file, path=["response"])
@@ -271,7 +271,7 @@ def test_method_upload(self, client: Steel) -> None:
def test_method_upload_with_all_params(self, client: Steel) -> None:
file = client.sessions.files.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
path="path",
)
assert_matches_type(File, file, path=["response"])
@@ -280,7 +280,7 @@ def test_method_upload_with_all_params(self, client: Steel) -> None:
def test_raw_response_upload(self, client: Steel) -> None:
response = client.sessions.files.with_raw_response.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -292,7 +292,7 @@ def test_raw_response_upload(self, client: Steel) -> None:
def test_streaming_response_upload(self, client: Steel) -> None:
with client.sessions.files.with_streaming_response.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -307,7 +307,7 @@ def test_path_params_upload(self, client: Steel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
client.sessions.files.with_raw_response.upload(
session_id="",
- file=b"raw file contents",
+ file=b"Example data",
)
@@ -554,7 +554,7 @@ async def test_path_params_download_archive(self, async_client: AsyncSteel) -> N
async def test_method_upload(self, async_client: AsyncSteel) -> None:
file = await async_client.sessions.files.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(File, file, path=["response"])
@@ -562,7 +562,7 @@ async def test_method_upload(self, async_client: AsyncSteel) -> None:
async def test_method_upload_with_all_params(self, async_client: AsyncSteel) -> None:
file = await async_client.sessions.files.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
path="path",
)
assert_matches_type(File, file, path=["response"])
@@ -571,7 +571,7 @@ async def test_method_upload_with_all_params(self, async_client: AsyncSteel) ->
async def test_raw_response_upload(self, async_client: AsyncSteel) -> None:
response = await async_client.sessions.files.with_raw_response.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -583,7 +583,7 @@ async def test_raw_response_upload(self, async_client: AsyncSteel) -> None:
async def test_streaming_response_upload(self, async_client: AsyncSteel) -> None:
async with async_client.sessions.files.with_streaming_response.upload(
session_id="sessionId",
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -598,5 +598,5 @@ async def test_path_params_upload(self, async_client: AsyncSteel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
await async_client.sessions.files.with_raw_response.upload(
session_id="",
- file=b"raw file contents",
+ file=b"Example data",
)
diff --git a/tests/api_resources/test_extensions.py b/tests/api_resources/test_extensions.py
index b996a46b..e9ceafd5 100644
--- a/tests/api_resources/test_extensions.py
+++ b/tests/api_resources/test_extensions.py
@@ -34,7 +34,7 @@ def test_method_update(self, client: Steel) -> None:
def test_method_update_with_all_params(self, client: Steel) -> None:
extension = client.extensions.update(
extension_id="extensionId",
- file=b"raw file contents",
+ file=b"Example data",
url="https://example.com",
)
assert_matches_type(ExtensionUpdateResponse, extension, path=["response"])
@@ -204,7 +204,7 @@ def test_method_upload(self, client: Steel) -> None:
@parametrize
def test_method_upload_with_all_params(self, client: Steel) -> None:
extension = client.extensions.upload(
- file=b"raw file contents",
+ file=b"Example data",
url="https://example.com",
)
assert_matches_type(ExtensionUploadResponse, extension, path=["response"])
@@ -246,7 +246,7 @@ async def test_method_update(self, async_client: AsyncSteel) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncSteel) -> None:
extension = await async_client.extensions.update(
extension_id="extensionId",
- file=b"raw file contents",
+ file=b"Example data",
url="https://example.com",
)
assert_matches_type(ExtensionUpdateResponse, extension, path=["response"])
@@ -416,7 +416,7 @@ async def test_method_upload(self, async_client: AsyncSteel) -> None:
@parametrize
async def test_method_upload_with_all_params(self, async_client: AsyncSteel) -> None:
extension = await async_client.extensions.upload(
- file=b"raw file contents",
+ file=b"Example data",
url="https://example.com",
)
assert_matches_type(ExtensionUploadResponse, extension, path=["response"])
diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py
index 5ca440d0..efcb9da6 100644
--- a/tests/api_resources/test_files.py
+++ b/tests/api_resources/test_files.py
@@ -141,14 +141,14 @@ def test_path_params_download(self, client: Steel) -> None:
@parametrize
def test_method_upload(self, client: Steel) -> None:
file = client.files.upload(
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(File, file, path=["response"])
@parametrize
def test_method_upload_with_all_params(self, client: Steel) -> None:
file = client.files.upload(
- file=b"raw file contents",
+ file=b"Example data",
path="path",
)
assert_matches_type(File, file, path=["response"])
@@ -156,7 +156,7 @@ def test_method_upload_with_all_params(self, client: Steel) -> None:
@parametrize
def test_raw_response_upload(self, client: Steel) -> None:
response = client.files.with_raw_response.upload(
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -167,7 +167,7 @@ def test_raw_response_upload(self, client: Steel) -> None:
@parametrize
def test_streaming_response_upload(self, client: Steel) -> None:
with client.files.with_streaming_response.upload(
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -299,14 +299,14 @@ async def test_path_params_download(self, async_client: AsyncSteel) -> None:
@parametrize
async def test_method_upload(self, async_client: AsyncSteel) -> None:
file = await async_client.files.upload(
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(File, file, path=["response"])
@parametrize
async def test_method_upload_with_all_params(self, async_client: AsyncSteel) -> None:
file = await async_client.files.upload(
- file=b"raw file contents",
+ file=b"Example data",
path="path",
)
assert_matches_type(File, file, path=["response"])
@@ -314,7 +314,7 @@ async def test_method_upload_with_all_params(self, async_client: AsyncSteel) ->
@parametrize
async def test_raw_response_upload(self, async_client: AsyncSteel) -> None:
response = await async_client.files.with_raw_response.upload(
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -325,7 +325,7 @@ async def test_raw_response_upload(self, async_client: AsyncSteel) -> None:
@parametrize
async def test_streaming_response_upload(self, async_client: AsyncSteel) -> None:
async with async_client.files.with_streaming_response.upload(
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/test_profiles.py b/tests/api_resources/test_profiles.py
index 24a3cd08..52324e1a 100644
--- a/tests/api_resources/test_profiles.py
+++ b/tests/api_resources/test_profiles.py
@@ -25,14 +25,14 @@ class TestProfiles:
@parametrize
def test_method_create(self, client: Steel) -> None:
profile = client.profiles.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert_matches_type(ProfileCreateResponse, profile, path=["response"])
@parametrize
def test_method_create_with_all_params(self, client: Steel) -> None:
profile = client.profiles.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
dimensions={
"height": 0,
"width": 0,
@@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: Steel) -> None:
@parametrize
def test_raw_response_create(self, client: Steel) -> None:
response = client.profiles.with_raw_response.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert response.is_closed is True
@@ -56,7 +56,7 @@ def test_raw_response_create(self, client: Steel) -> None:
@parametrize
def test_streaming_response_create(self, client: Steel) -> None:
with client.profiles.with_streaming_response.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -70,7 +70,7 @@ def test_streaming_response_create(self, client: Steel) -> None:
def test_method_update(self, client: Steel) -> None:
profile = client.profiles.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert_matches_type(ProfileUpdateResponse, profile, path=["response"])
@@ -78,7 +78,7 @@ def test_method_update(self, client: Steel) -> None:
def test_method_update_with_all_params(self, client: Steel) -> None:
profile = client.profiles.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
dimensions={
"height": 0,
"width": 0,
@@ -92,7 +92,7 @@ def test_method_update_with_all_params(self, client: Steel) -> None:
def test_raw_response_update(self, client: Steel) -> None:
response = client.profiles.with_raw_response.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert response.is_closed is True
@@ -104,7 +104,7 @@ def test_raw_response_update(self, client: Steel) -> None:
def test_streaming_response_update(self, client: Steel) -> None:
with client.profiles.with_streaming_response.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -119,7 +119,7 @@ def test_path_params_update(self, client: Steel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.profiles.with_raw_response.update(
id="",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
@parametrize
@@ -194,14 +194,14 @@ class TestAsyncProfiles:
@parametrize
async def test_method_create(self, async_client: AsyncSteel) -> None:
profile = await async_client.profiles.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert_matches_type(ProfileCreateResponse, profile, path=["response"])
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncSteel) -> None:
profile = await async_client.profiles.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
dimensions={
"height": 0,
"width": 0,
@@ -214,7 +214,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncSteel) ->
@parametrize
async def test_raw_response_create(self, async_client: AsyncSteel) -> None:
response = await async_client.profiles.with_raw_response.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert response.is_closed is True
@@ -225,7 +225,7 @@ async def test_raw_response_create(self, async_client: AsyncSteel) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncSteel) -> None:
async with async_client.profiles.with_streaming_response.create(
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -239,7 +239,7 @@ async def test_streaming_response_create(self, async_client: AsyncSteel) -> None
async def test_method_update(self, async_client: AsyncSteel) -> None:
profile = await async_client.profiles.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert_matches_type(ProfileUpdateResponse, profile, path=["response"])
@@ -247,7 +247,7 @@ async def test_method_update(self, async_client: AsyncSteel) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncSteel) -> None:
profile = await async_client.profiles.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
dimensions={
"height": 0,
"width": 0,
@@ -261,7 +261,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncSteel) ->
async def test_raw_response_update(self, async_client: AsyncSteel) -> None:
response = await async_client.profiles.with_raw_response.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
assert response.is_closed is True
@@ -273,7 +273,7 @@ async def test_raw_response_update(self, async_client: AsyncSteel) -> None:
async def test_streaming_response_update(self, async_client: AsyncSteel) -> None:
async with async_client.profiles.with_streaming_response.update(
id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -288,7 +288,7 @@ async def test_path_params_update(self, async_client: AsyncSteel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.profiles.with_raw_response.update(
id="",
- user_data_dir=b"raw file contents",
+ user_data_dir=b"Example data",
)
@parametrize
diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py
index 05d575d7..9fabc926 100644
--- a/tests/api_resources/test_sessions.py
+++ b/tests/api_resources/test_sessions.py
@@ -52,6 +52,7 @@ def test_method_create_with_all_params(self, client: Steel) -> None:
"height": -9007199254740991,
"width": -9007199254740991,
},
+ experimental_features=["string"],
extension_ids=["string"],
headless=True,
is_selenium=True,
@@ -747,14 +748,24 @@ def test_path_params_context(self, client: Steel) -> None:
@parametrize
def test_method_events(self, client: Steel) -> None:
session = client.sessions.events(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(SessionEventsResponse, session, path=["response"])
+
+ @parametrize
+ def test_method_events_with_all_params(self, client: Steel) -> None:
+ session = client.sessions.events(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ compressed=True,
+ limit=1,
+ pointer="pointer",
)
assert_matches_type(SessionEventsResponse, session, path=["response"])
@parametrize
def test_raw_response_events(self, client: Steel) -> None:
response = client.sessions.with_raw_response.events(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -765,7 +776,7 @@ def test_raw_response_events(self, client: Steel) -> None:
@parametrize
def test_streaming_response_events(self, client: Steel) -> None:
with client.sessions.with_streaming_response.events(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -779,7 +790,7 @@ def test_streaming_response_events(self, client: Steel) -> None:
def test_path_params_events(self, client: Steel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.sessions.with_raw_response.events(
- "",
+ id="",
)
@parametrize
@@ -913,6 +924,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncSteel) ->
"height": -9007199254740991,
"width": -9007199254740991,
},
+ experimental_features=["string"],
extension_ids=["string"],
headless=True,
is_selenium=True,
@@ -1608,14 +1620,24 @@ async def test_path_params_context(self, async_client: AsyncSteel) -> None:
@parametrize
async def test_method_events(self, async_client: AsyncSteel) -> None:
session = await async_client.sessions.events(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(SessionEventsResponse, session, path=["response"])
+
+ @parametrize
+ async def test_method_events_with_all_params(self, async_client: AsyncSteel) -> None:
+ session = await async_client.sessions.events(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ compressed=True,
+ limit=1,
+ pointer="pointer",
)
assert_matches_type(SessionEventsResponse, session, path=["response"])
@parametrize
async def test_raw_response_events(self, async_client: AsyncSteel) -> None:
response = await async_client.sessions.with_raw_response.events(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -1626,7 +1648,7 @@ async def test_raw_response_events(self, async_client: AsyncSteel) -> None:
@parametrize
async def test_streaming_response_events(self, async_client: AsyncSteel) -> None:
async with async_client.sessions.with_streaming_response.events(
- "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -1640,7 +1662,7 @@ async def test_streaming_response_events(self, async_client: AsyncSteel) -> None
async def test_path_params_events(self, async_client: AsyncSteel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.sessions.with_raw_response.events(
- "",
+ id="",
)
@parametrize
diff --git a/tests/test_client.py b/tests/test_client.py
index fe612e5a..410bcac6 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -904,6 +904,14 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Test that the proxy environment variables are set correctly
monkeypatch.setenv("HTTPS_PROXY", "https://example.org")
+ # Delete in case our environment has any proxy env vars set
+ monkeypatch.delenv("HTTP_PROXY", raising=False)
+ monkeypatch.delenv("ALL_PROXY", raising=False)
+ monkeypatch.delenv("NO_PROXY", raising=False)
+ monkeypatch.delenv("http_proxy", raising=False)
+ monkeypatch.delenv("https_proxy", raising=False)
+ monkeypatch.delenv("all_proxy", raising=False)
+ monkeypatch.delenv("no_proxy", raising=False)
client = DefaultHttpxClient()
@@ -1756,6 +1764,14 @@ async def test_get_platform(self) -> None:
async def test_proxy_environment_variables(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Test that the proxy environment variables are set correctly
monkeypatch.setenv("HTTPS_PROXY", "https://example.org")
+ # Delete in case our environment has any proxy env vars set
+ monkeypatch.delenv("HTTP_PROXY", raising=False)
+ monkeypatch.delenv("ALL_PROXY", raising=False)
+ monkeypatch.delenv("NO_PROXY", raising=False)
+ monkeypatch.delenv("http_proxy", raising=False)
+ monkeypatch.delenv("https_proxy", raising=False)
+ monkeypatch.delenv("all_proxy", raising=False)
+ monkeypatch.delenv("no_proxy", raising=False)
client = DefaultAsyncHttpxClient()