1- """Browser-scoped view over a session: metro-routed subresources and raw HTTP via /curl/raw."""
1+ """Browser-scoped view over a session: VM subresources and raw HTTP via internal /curl/raw."""
22
33from __future__ import annotations
44
1111
1212from .util import (
1313 jwt_from_cdp_ws_url ,
14+ sanitize_curl_raw_params ,
1415 base_url_from_browser_like ,
1516 cdp_ws_url_from_browser_like ,
1617 session_id_from_browser_like ,
1718)
1819from ..._types import Body , Timeout , NotGiven , BinaryTypes , not_given
1920from ..._models import FinalRequestOptions
20- from .metro_client import metro_kernel_from_browser , metro_async_kernel_from_browser
21+ from .browser_session_kernel import build_browser_session_kernel , build_async_browser_session_kernel
2122
2223if TYPE_CHECKING :
2324 from ..._client import Kernel , AsyncKernel
@@ -60,12 +61,14 @@ def bound(*args: Any, **kwargs: Any) -> Any:
6061class BrowserScopedClient :
6162 """Session-scoped API: subresources without repeating session id; HTTP via browser /curl/raw."""
6263
63- def __init__ (self , parent : Kernel , * , session_id : str , metro_base_url : str , jwt : str ) -> None :
64+ def __init__ (self , parent : Kernel , * , session_id : str , session_base_url : str , jwt : str ) -> None :
6465 self ._parent = parent
6566 self .session_id = session_id
66- self ._metro_base_url = metro_base_url
67+ self ._session_base_url = session_base_url
6768 self ._jwt = jwt
68- self ._metro = metro_kernel_from_browser (parent , session_id = session_id , metro_base_url = metro_base_url , jwt = jwt )
69+ self ._http = build_browser_session_kernel (
70+ parent , session_id = session_id , session_base_url = session_base_url , jwt = jwt
71+ )
6972
7073 @property
7174 def parent (self ) -> Kernel :
@@ -74,43 +77,43 @@ def parent(self) -> Kernel:
7477
7578 @property
7679 def base_url (self ) -> str :
77- return self ._metro_base_url
80+ return self ._session_base_url
7881
7982 @property
8083 def process (self ) -> ProcessResource :
8184 from ...resources .browsers .process import ProcessResource
8285
83- return cast (ProcessResource , _BoundBrowserSubresource (ProcessResource (self ._metro ), self .session_id ))
86+ return cast (ProcessResource , _BoundBrowserSubresource (ProcessResource (self ._http ), self .session_id ))
8487
8588 @property
8689 def computer (self ) -> ComputerResource :
8790 from ...resources .browsers .computer import ComputerResource
8891
89- return cast (ComputerResource , _BoundBrowserSubresource (ComputerResource (self ._metro ), self .session_id ))
92+ return cast (ComputerResource , _BoundBrowserSubresource (ComputerResource (self ._http ), self .session_id ))
9093
9194 @property
9295 def fs (self ) -> FsResource :
9396 from ...resources .browsers .fs .fs import FsResource
9497
95- return cast (FsResource , _BoundBrowserSubresource (FsResource (self ._metro ), self .session_id ))
98+ return cast (FsResource , _BoundBrowserSubresource (FsResource (self ._http ), self .session_id ))
9699
97100 @property
98101 def logs (self ) -> LogsResource :
99102 from ...resources .browsers .logs import LogsResource
100103
101- return cast (LogsResource , _BoundBrowserSubresource (LogsResource (self ._metro ), self .session_id ))
104+ return cast (LogsResource , _BoundBrowserSubresource (LogsResource (self ._http ), self .session_id ))
102105
103106 @property
104107 def playwright (self ) -> PlaywrightResource :
105108 from ...resources .browsers .playwright import PlaywrightResource
106109
107- return cast (PlaywrightResource , _BoundBrowserSubresource (PlaywrightResource (self ._metro ), self .session_id ))
110+ return cast (PlaywrightResource , _BoundBrowserSubresource (PlaywrightResource (self ._http ), self .session_id ))
108111
109112 @property
110113 def replays (self ) -> ReplaysResource :
111114 from ...resources .browsers .replays import ReplaysResource
112115
113- return cast (ReplaysResource , _BoundBrowserSubresource (ReplaysResource (self ._metro ), self .session_id ))
116+ return cast (ReplaysResource , _BoundBrowserSubresource (ReplaysResource (self ._http ), self .session_id ))
114117
115118 def request (
116119 self ,
@@ -125,9 +128,7 @@ def request(
125128 ) -> httpx .Response :
126129 if json is not None and content is not None :
127130 raise TypeError ("Passing both `json` and `content` is not supported" )
128- q : dict [str , object ] = {"url" : url }
129- if params :
130- q .update (dict (params ))
131+ q : dict [str , object ] = {** sanitize_curl_raw_params (params ), "url" : url }
131132 opts = FinalRequestOptions .construct (
132133 method = method .upper (),
133134 url = "/curl/raw" ,
@@ -137,7 +138,7 @@ def request(
137138 json_data = json ,
138139 timeout = timeout ,
139140 )
140- return self ._metro .request (httpx .Response , opts )
141+ return self ._http .request (httpx .Response , opts )
141142
142143 @contextmanager
143144 def stream (
@@ -150,19 +151,18 @@ def stream(
150151 params : Mapping [str , object ] | None = None ,
151152 timeout : float | Timeout | None | NotGiven = not_given ,
152153 ) -> Iterator [httpx .Response ]:
153- q : dict [str , Any ] = dict (self ._metro .default_query )
154+ q : dict [str , Any ] = dict (self ._http .default_query )
155+ q .update (sanitize_curl_raw_params (params ))
154156 q ["url" ] = url
155- if params :
156- q .update (dict (params ))
157- h = {k : v for k , v in self ._metro .default_headers .items () if isinstance (v , str )}
157+ h = {k : v for k , v in self ._http .default_headers .items () if isinstance (v , str )}
158158 if content is None :
159159 h .pop ("Content-Type" , None )
160160 if headers :
161161 h .update (headers )
162- eff_timeout = self ._metro .timeout if isinstance (timeout , NotGiven ) else timeout
163- cm = self ._metro ._client .stream (
162+ eff_timeout = self ._http .timeout if isinstance (timeout , NotGiven ) else timeout
163+ cm = self ._http ._client .stream (
164164 method .upper (),
165- self ._metro ._prepare_url ("/curl/raw" ),
165+ self ._http ._prepare_url ("/curl/raw" ),
166166 params = q ,
167167 headers = h ,
168168 content = content ,
@@ -173,13 +173,13 @@ def stream(
173173
174174
175175class AsyncBrowserScopedClient :
176- def __init__ (self , parent : AsyncKernel , * , session_id : str , metro_base_url : str , jwt : str ) -> None :
176+ def __init__ (self , parent : AsyncKernel , * , session_id : str , session_base_url : str , jwt : str ) -> None :
177177 self ._parent = parent
178178 self .session_id = session_id
179- self ._metro_base_url = metro_base_url
179+ self ._session_base_url = session_base_url
180180 self ._jwt = jwt
181- self ._metro = metro_async_kernel_from_browser (
182- parent , session_id = session_id , metro_base_url = metro_base_url , jwt = jwt
181+ self ._http = build_async_browser_session_kernel (
182+ parent , session_id = session_id , session_base_url = session_base_url , jwt = jwt
183183 )
184184
185185 @property
@@ -188,47 +188,47 @@ def parent(self) -> AsyncKernel:
188188
189189 @property
190190 def base_url (self ) -> str :
191- return self ._metro_base_url
191+ return self ._session_base_url
192192
193193 @property
194194 def process (self ) -> AsyncProcessResource :
195195 from ...resources .browsers .process import AsyncProcessResource
196196
197- return cast (AsyncProcessResource , _BoundBrowserSubresource (AsyncProcessResource (self ._metro ), self .session_id ))
197+ return cast (AsyncProcessResource , _BoundBrowserSubresource (AsyncProcessResource (self ._http ), self .session_id ))
198198
199199 @property
200200 def computer (self ) -> AsyncComputerResource :
201201 from ...resources .browsers .computer import AsyncComputerResource
202202
203203 return cast (
204- AsyncComputerResource , _BoundBrowserSubresource (AsyncComputerResource (self ._metro ), self .session_id )
204+ AsyncComputerResource , _BoundBrowserSubresource (AsyncComputerResource (self ._http ), self .session_id )
205205 )
206206
207207 @property
208208 def fs (self ) -> AsyncFsResource :
209209 from ...resources .browsers .fs .fs import AsyncFsResource
210210
211- return cast (AsyncFsResource , _BoundBrowserSubresource (AsyncFsResource (self ._metro ), self .session_id ))
211+ return cast (AsyncFsResource , _BoundBrowserSubresource (AsyncFsResource (self ._http ), self .session_id ))
212212
213213 @property
214214 def logs (self ) -> AsyncLogsResource :
215215 from ...resources .browsers .logs import AsyncLogsResource
216216
217- return cast (AsyncLogsResource , _BoundBrowserSubresource (AsyncLogsResource (self ._metro ), self .session_id ))
217+ return cast (AsyncLogsResource , _BoundBrowserSubresource (AsyncLogsResource (self ._http ), self .session_id ))
218218
219219 @property
220220 def playwright (self ) -> AsyncPlaywrightResource :
221221 from ...resources .browsers .playwright import AsyncPlaywrightResource
222222
223223 return cast (
224- AsyncPlaywrightResource , _BoundBrowserSubresource (AsyncPlaywrightResource (self ._metro ), self .session_id )
224+ AsyncPlaywrightResource , _BoundBrowserSubresource (AsyncPlaywrightResource (self ._http ), self .session_id )
225225 )
226226
227227 @property
228228 def replays (self ) -> AsyncReplaysResource :
229229 from ...resources .browsers .replays import AsyncReplaysResource
230230
231- return cast (AsyncReplaysResource , _BoundBrowserSubresource (AsyncReplaysResource (self ._metro ), self .session_id ))
231+ return cast (AsyncReplaysResource , _BoundBrowserSubresource (AsyncReplaysResource (self ._http ), self .session_id ))
232232
233233 async def request (
234234 self ,
@@ -243,9 +243,7 @@ async def request(
243243 ) -> httpx .Response :
244244 if json is not None and content is not None :
245245 raise TypeError ("Passing both `json` and `content` is not supported" )
246- q : dict [str , object ] = {"url" : url }
247- if params :
248- q .update (dict (params ))
246+ q : dict [str , object ] = {** sanitize_curl_raw_params (params ), "url" : url }
249247 opts = FinalRequestOptions .construct (
250248 method = method .upper (),
251249 url = "/curl/raw" ,
@@ -255,7 +253,7 @@ async def request(
255253 json_data = json ,
256254 timeout = timeout ,
257255 )
258- return await self ._metro .request (httpx .Response , opts )
256+ return await self ._http .request (httpx .Response , opts )
259257
260258 @asynccontextmanager
261259 async def stream (
@@ -268,19 +266,18 @@ async def stream(
268266 params : Mapping [str , object ] | None = None ,
269267 timeout : float | Timeout | None | NotGiven = not_given ,
270268 ) -> AsyncIterator [httpx .Response ]:
271- q : dict [str , Any ] = dict (self ._metro .default_query )
269+ q : dict [str , Any ] = dict (self ._http .default_query )
270+ q .update (sanitize_curl_raw_params (params ))
272271 q ["url" ] = url
273- if params :
274- q .update (dict (params ))
275- h = {k : v for k , v in self ._metro .default_headers .items () if isinstance (v , str )}
272+ h = {k : v for k , v in self ._http .default_headers .items () if isinstance (v , str )}
276273 if content is None :
277274 h .pop ("Content-Type" , None )
278275 if headers :
279276 h .update (headers )
280- eff_timeout = self ._metro .timeout if isinstance (timeout , NotGiven ) else timeout
281- async with self ._metro ._client .stream (
277+ eff_timeout = self ._http .timeout if isinstance (timeout , NotGiven ) else timeout
278+ async with self ._http ._client .stream (
282279 method .upper (),
283- self ._metro ._prepare_url ("/curl/raw" ),
280+ self ._http ._prepare_url ("/curl/raw" ),
284281 params = q ,
285282 headers = h ,
286283 content = content ,
@@ -291,21 +288,21 @@ async def stream(
291288
292289def browser_scoped_from_browser (parent : Kernel , browser : Any ) -> BrowserScopedClient :
293290 session_id = session_id_from_browser_like (browser )
294- metro = base_url_from_browser_like (browser )
295- if not metro :
291+ session_base = base_url_from_browser_like (browser )
292+ if not session_base :
296293 raise ValueError ("browser.base_url is required for a browser-scoped client" )
297294 jwt = jwt_from_cdp_ws_url (cdp_ws_url_from_browser_like (browser ))
298295 if not jwt :
299- raise ValueError ("could not parse jwt from browser.cdp_ws_url; required for metro requests " )
300- return BrowserScopedClient (parent , session_id = session_id , metro_base_url = metro , jwt = jwt )
296+ raise ValueError ("could not parse jwt from browser.cdp_ws_url; required for browser session HTTP " )
297+ return BrowserScopedClient (parent , session_id = session_id , session_base_url = session_base , jwt = jwt )
301298
302299
303300def async_browser_scoped_from_browser (parent : AsyncKernel , browser : Any ) -> AsyncBrowserScopedClient :
304301 session_id = session_id_from_browser_like (browser )
305- metro = base_url_from_browser_like (browser )
306- if not metro :
302+ session_base = base_url_from_browser_like (browser )
303+ if not session_base :
307304 raise ValueError ("browser.base_url is required for a browser-scoped client" )
308305 jwt = jwt_from_cdp_ws_url (cdp_ws_url_from_browser_like (browser ))
309306 if not jwt :
310- raise ValueError ("could not parse jwt from browser.cdp_ws_url; required for metro requests " )
311- return AsyncBrowserScopedClient (parent , session_id = session_id , metro_base_url = metro , jwt = jwt )
307+ raise ValueError ("could not parse jwt from browser.cdp_ws_url; required for browser session HTTP " )
308+ return AsyncBrowserScopedClient (parent , session_id = session_id , session_base_url = session_base , jwt = jwt )
0 commit comments