Skip to content

Commit 9690923

Browse files
committed
fix: address python browser routing ci follow-ups
Make the browser routing helpers type-check cleanly in CI, keep copy() signatures aligned with __init__, and avoid cache-warming errors on raw response wrappers. Made-with: Cursor
1 parent 694907a commit 9690923

4 files changed

Lines changed: 16 additions & 14 deletions

File tree

examples/browser_routing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def main() -> None:
1717
response = cast(httpx.Response, browsers.request(browser.session_id, "GET", "https://example.com"))
1818
print("status", response.status_code)
1919

20-
with cast(Any, browsers.stream(browser.session_id, "GET", "https://example.com")) as streamed:
20+
with browsers.stream(browser.session_id, "GET", "https://example.com") as streamed:
2121
print("streamed-bytes", len(streamed.read()))
2222
finally:
2323
browsers.delete_by_id(browser.session_id)

src/kernel/lib/browser_routing/raw_http.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
from __future__ import annotations
22

3-
from typing import IO, Any, Mapping, cast
3+
from typing import IO, Any, Union, Mapping, cast
44
from contextlib import contextmanager, asynccontextmanager
55
from collections.abc import Iterable, Iterator, AsyncIterator
66

77
import httpx
88

99
from .util import sanitize_curl_raw_params
1010
from .routing import BrowserRoute
11-
from ..._types import Body, Timeout, NotGiven, BinaryTypes, not_given
11+
from ..._types import Body, Timeout, NotGiven, not_given
1212
from ..._models import FinalRequestOptions
1313

14+
BrowserRawContent = Union[bytes, bytearray, memoryview, str, IO[bytes], Iterable[bytes]]
15+
1416

1517
def request_via_browser_route(
1618
parent: Any,
1719
route: BrowserRoute,
1820
method: str,
1921
url: str,
2022
*,
21-
content: BinaryTypes | None = None,
23+
content: BrowserRawContent | None = None,
2224
json: Body | None = None,
2325
headers: Mapping[str, str] | None = None,
2426
params: Mapping[str, object] | None = None,
@@ -34,7 +36,7 @@ def request_via_browser_route(
3436
headers=headers or {},
3537
content=_normalize_binary_content(content),
3638
json_data=json,
37-
timeout=timeout,
39+
timeout=_normalize_timeout(timeout),
3840
)
3941
return cast(httpx.Response, parent.request(httpx.Response, options))
4042

@@ -46,7 +48,7 @@ def stream_via_browser_route(
4648
method: str,
4749
url: str,
4850
*,
49-
content: BinaryTypes | None = None,
51+
content: BrowserRawContent | None = None,
5052
headers: Mapping[str, str] | None = None,
5153
params: Mapping[str, object] | None = None,
5254
timeout: float | Timeout | None | NotGiven = not_given,
@@ -78,7 +80,7 @@ async def async_request_via_browser_route(
7880
method: str,
7981
url: str,
8082
*,
81-
content: BinaryTypes | None = None,
83+
content: BrowserRawContent | None = None,
8284
json: Body | None = None,
8385
headers: Mapping[str, str] | None = None,
8486
params: Mapping[str, object] | None = None,
@@ -94,7 +96,7 @@ async def async_request_via_browser_route(
9496
headers=headers or {},
9597
content=_normalize_binary_content(content),
9698
json_data=json,
97-
timeout=timeout,
99+
timeout=_normalize_timeout(timeout),
98100
)
99101
return cast(httpx.Response, await parent.request(httpx.Response, options))
100102

@@ -106,7 +108,7 @@ async def async_stream_via_browser_route(
106108
method: str,
107109
url: str,
108110
*,
109-
content: BinaryTypes | None = None,
111+
content: BrowserRawContent | None = None,
110112
headers: Mapping[str, str] | None = None,
111113
params: Mapping[str, object] | None = None,
112114
timeout: float | Timeout | None | NotGiven = not_given,
@@ -136,7 +138,7 @@ def _normalize_timeout(timeout: float | Timeout | None | NotGiven) -> float | Ti
136138
return None if isinstance(timeout, NotGiven) else timeout
137139

138140

139-
def _normalize_binary_content(content: BinaryTypes | None) -> bytes | IO[bytes] | Iterable[bytes] | None:
141+
def _normalize_binary_content(content: BrowserRawContent | None) -> bytes | str | IO[bytes] | Iterable[bytes] | None:
140142
if content is None:
141143
return None
142144
if isinstance(content, bytearray):

src/kernel/lib/browser_routing/routing.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, Mapping, cast
3+
from typing import Any
44
from dataclasses import field, dataclass
55

66
import httpx
@@ -95,8 +95,7 @@ def rewrite_direct_vm_options(
9595
rewritten.url = f"{route.base_url.rstrip('/')}/{subresource}{suffix}"
9696

9797
params: dict[str, object] = {}
98-
if isinstance(options.params, Mapping):
99-
params.update(cast(Mapping[str, object], options.params))
98+
params.update(options.params)
10099
params["jwt"] = route.jwt
101100
rewritten.params = params or options.params
102101
return rewritten

src/kernel/resources/browsers/browsers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,8 @@ def list(
999999
),
10001000
model=BrowserListResponse,
10011001
)
1002-
for item in page.items:
1002+
typed_page = cast(AsyncOffsetPagination[BrowserListResponse], page)
1003+
for item in typed_page.items:
10031004
route = browser_route_from_browser(item)
10041005
if route is not None:
10051006
self._client.browser_route_cache.set(route)

0 commit comments

Comments
 (0)