22
33from __future__ import annotations
44
5+ from typing import Mapping , Iterable , cast
6+
57import httpx
68
79from .logs import (
2022 FsResourceWithStreamingResponse ,
2123 AsyncFsResourceWithStreamingResponse ,
2224)
23- from ...types import browser_create_params , browser_delete_params
25+ from ...types import browser_create_params , browser_delete_params , browser_upload_extensions_params
2426from .process import (
2527 ProcessResource ,
2628 AsyncProcessResource ,
3840 AsyncReplaysResourceWithStreamingResponse ,
3941)
4042from ..._types import Body , Omit , Query , Headers , NoneType , NotGiven , omit , not_given
41- from ..._utils import maybe_transform , async_maybe_transform
43+ from ..._utils import extract_files , maybe_transform , deepcopy_minimal , async_maybe_transform
4244from ..._compat import cached_property
4345from ..._resource import SyncAPIResource , AsyncAPIResource
4446from ..._response import (
@@ -95,6 +97,7 @@ def with_streaming_response(self) -> BrowsersResourceWithStreamingResponse:
9597 def create (
9698 self ,
9799 * ,
100+ extensions : Iterable [browser_create_params .Extension ] | Omit = omit ,
98101 headless : bool | Omit = omit ,
99102 invocation_id : str | Omit = omit ,
100103 persistence : BrowserPersistenceParam | Omit = omit ,
@@ -113,6 +116,8 @@ def create(
113116 Create a new browser session from within an action.
114117
115118 Args:
119+ extensions: List of browser extensions to load into the session. Provide each by id or name.
120+
116121 headless: If true, launches the browser using a headless image (no VNC/GUI). Defaults to
117122 false.
118123
@@ -149,6 +154,7 @@ def create(
149154 "/browsers" ,
150155 body = maybe_transform (
151156 {
157+ "extensions" : extensions ,
152158 "headless" : headless ,
153159 "invocation_id" : invocation_id ,
154160 "persistence" : persistence ,
@@ -289,6 +295,52 @@ def delete_by_id(
289295 cast_to = NoneType ,
290296 )
291297
298+ def upload_extensions (
299+ self ,
300+ id : str ,
301+ * ,
302+ extensions : Iterable [browser_upload_extensions_params .Extension ],
303+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
304+ # The extra values given here take precedence over values defined on the client or passed to this method.
305+ extra_headers : Headers | None = None ,
306+ extra_query : Query | None = None ,
307+ extra_body : Body | None = None ,
308+ timeout : float | httpx .Timeout | None | NotGiven = not_given ,
309+ ) -> None :
310+ """
311+ Loads one or more unpacked extensions and restarts Chromium on the browser
312+ instance.
313+
314+ Args:
315+ extensions: List of extensions to upload and activate
316+
317+ extra_headers: Send extra headers
318+
319+ extra_query: Add additional query parameters to the request
320+
321+ extra_body: Add additional JSON properties to the request
322+
323+ timeout: Override the client-level default timeout for this request, in seconds
324+ """
325+ if not id :
326+ raise ValueError (f"Expected a non-empty value for `id` but received { id !r} " )
327+ extra_headers = {"Accept" : "*/*" , ** (extra_headers or {})}
328+ body = deepcopy_minimal ({"extensions" : extensions })
329+ files = extract_files (cast (Mapping [str , object ], body ), paths = [["extensions" , "<array>" , "zip_file" ]])
330+ # It should be noted that the actual Content-Type header that will be
331+ # sent to the server will contain a `boundary` parameter, e.g.
332+ # multipart/form-data; boundary=---abc--
333+ extra_headers ["Content-Type" ] = "multipart/form-data"
334+ return self ._post (
335+ f"/browsers/{ id } /extensions" ,
336+ body = maybe_transform (body , browser_upload_extensions_params .BrowserUploadExtensionsParams ),
337+ files = files ,
338+ options = make_request_options (
339+ extra_headers = extra_headers , extra_query = extra_query , extra_body = extra_body , timeout = timeout
340+ ),
341+ cast_to = NoneType ,
342+ )
343+
292344
293345class AsyncBrowsersResource (AsyncAPIResource ):
294346 @cached_property
@@ -329,6 +381,7 @@ def with_streaming_response(self) -> AsyncBrowsersResourceWithStreamingResponse:
329381 async def create (
330382 self ,
331383 * ,
384+ extensions : Iterable [browser_create_params .Extension ] | Omit = omit ,
332385 headless : bool | Omit = omit ,
333386 invocation_id : str | Omit = omit ,
334387 persistence : BrowserPersistenceParam | Omit = omit ,
@@ -347,6 +400,8 @@ async def create(
347400 Create a new browser session from within an action.
348401
349402 Args:
403+ extensions: List of browser extensions to load into the session. Provide each by id or name.
404+
350405 headless: If true, launches the browser using a headless image (no VNC/GUI). Defaults to
351406 false.
352407
@@ -383,6 +438,7 @@ async def create(
383438 "/browsers" ,
384439 body = await async_maybe_transform (
385440 {
441+ "extensions" : extensions ,
386442 "headless" : headless ,
387443 "invocation_id" : invocation_id ,
388444 "persistence" : persistence ,
@@ -525,6 +581,52 @@ async def delete_by_id(
525581 cast_to = NoneType ,
526582 )
527583
584+ async def upload_extensions (
585+ self ,
586+ id : str ,
587+ * ,
588+ extensions : Iterable [browser_upload_extensions_params .Extension ],
589+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
590+ # The extra values given here take precedence over values defined on the client or passed to this method.
591+ extra_headers : Headers | None = None ,
592+ extra_query : Query | None = None ,
593+ extra_body : Body | None = None ,
594+ timeout : float | httpx .Timeout | None | NotGiven = not_given ,
595+ ) -> None :
596+ """
597+ Loads one or more unpacked extensions and restarts Chromium on the browser
598+ instance.
599+
600+ Args:
601+ extensions: List of extensions to upload and activate
602+
603+ extra_headers: Send extra headers
604+
605+ extra_query: Add additional query parameters to the request
606+
607+ extra_body: Add additional JSON properties to the request
608+
609+ timeout: Override the client-level default timeout for this request, in seconds
610+ """
611+ if not id :
612+ raise ValueError (f"Expected a non-empty value for `id` but received { id !r} " )
613+ extra_headers = {"Accept" : "*/*" , ** (extra_headers or {})}
614+ body = deepcopy_minimal ({"extensions" : extensions })
615+ files = extract_files (cast (Mapping [str , object ], body ), paths = [["extensions" , "<array>" , "zip_file" ]])
616+ # It should be noted that the actual Content-Type header that will be
617+ # sent to the server will contain a `boundary` parameter, e.g.
618+ # multipart/form-data; boundary=---abc--
619+ extra_headers ["Content-Type" ] = "multipart/form-data"
620+ return await self ._post (
621+ f"/browsers/{ id } /extensions" ,
622+ body = await async_maybe_transform (body , browser_upload_extensions_params .BrowserUploadExtensionsParams ),
623+ files = files ,
624+ options = make_request_options (
625+ extra_headers = extra_headers , extra_query = extra_query , extra_body = extra_body , timeout = timeout
626+ ),
627+ cast_to = NoneType ,
628+ )
629+
528630
529631class BrowsersResourceWithRawResponse :
530632 def __init__ (self , browsers : BrowsersResource ) -> None :
@@ -545,6 +647,9 @@ def __init__(self, browsers: BrowsersResource) -> None:
545647 self .delete_by_id = to_raw_response_wrapper (
546648 browsers .delete_by_id ,
547649 )
650+ self .upload_extensions = to_raw_response_wrapper (
651+ browsers .upload_extensions ,
652+ )
548653
549654 @cached_property
550655 def replays (self ) -> ReplaysResourceWithRawResponse :
@@ -582,6 +687,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
582687 self .delete_by_id = async_to_raw_response_wrapper (
583688 browsers .delete_by_id ,
584689 )
690+ self .upload_extensions = async_to_raw_response_wrapper (
691+ browsers .upload_extensions ,
692+ )
585693
586694 @cached_property
587695 def replays (self ) -> AsyncReplaysResourceWithRawResponse :
@@ -619,6 +727,9 @@ def __init__(self, browsers: BrowsersResource) -> None:
619727 self .delete_by_id = to_streamed_response_wrapper (
620728 browsers .delete_by_id ,
621729 )
730+ self .upload_extensions = to_streamed_response_wrapper (
731+ browsers .upload_extensions ,
732+ )
622733
623734 @cached_property
624735 def replays (self ) -> ReplaysResourceWithStreamingResponse :
@@ -656,6 +767,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
656767 self .delete_by_id = async_to_streamed_response_wrapper (
657768 browsers .delete_by_id ,
658769 )
770+ self .upload_extensions = async_to_streamed_response_wrapper (
771+ browsers .upload_extensions ,
772+ )
659773
660774 @cached_property
661775 def replays (self ) -> AsyncReplaysResourceWithStreamingResponse :
0 commit comments