async def connect( self, ws_endpoint: str, timeout: float = None, slow_mo: float = None, headers: Dict[str, str] = None, ) -> Browser: transport = WebSocketTransport(ws_endpoint, timeout, headers) connection = Connection( self._connection._dispatcher_fiber, self._connection._object_factory, transport, ) connection._is_sync = self._connection._is_sync connection._loop = self._connection._loop connection._loop.create_task(connection.run()) self._connection._child_ws_connections.append(connection) playwright = await connection.wait_for_object_with_known_name( "Playwright") pre_launched_browser = playwright._initializer.get( "preLaunchedBrowser") assert pre_launched_browser browser = cast(Browser, from_channel(pre_launched_browser)) browser._is_remote = True browser._is_connected_over_websocket = True transport.once("close", browser._on_close) return browser
class PlaywrightContextManager: def __init__(self) -> None: self._connection: Connection async def __aenter__(self) -> AsyncPlaywright: self._connection = Connection( None, create_remote_object, PipeTransport(asyncio.get_event_loop(), compute_driver_executable()), ) loop = asyncio.get_running_loop() self._connection._loop = loop loop.create_task(self._connection.run()) playwright_future = asyncio.create_task( self._connection.wait_for_object_with_known_name("Playwright") ) done, pending = await asyncio.wait( {self._connection._transport.on_error_future, playwright_future}, return_when=asyncio.FIRST_COMPLETED, ) if not playwright_future.done(): playwright_future.cancel() playwright = AsyncPlaywright(next(iter(done)).result()) playwright.stop = self.__aexit__ # type: ignore return playwright async def start(self) -> AsyncPlaywright: return await self.__aenter__() async def __aexit__(self, *args: Any) -> None: await self._connection.stop_async()
async def __aenter__(self) -> AsyncPlaywright: self._connection = Connection(None, create_remote_object, compute_driver_executable()) loop = asyncio.get_running_loop() self._connection._loop = loop loop.create_task(self._connection.run()) playwright = AsyncPlaywright( await self._connection.wait_for_object_with_known_name("Playwright")) playwright.stop = self.__aexit__ # type: ignore return playwright
def __enter__(self) -> SyncPlaywright: try: self._loop = asyncio.get_running_loop() except RuntimeError: self._loop = asyncio.new_event_loop() self._own_loop = True if self._loop.is_running(): raise Error( """It looks like you are using Playwright Sync API inside the asyncio loop. Please use the Async API instead.""") # In Python 3.7, asyncio.Process.wait() hangs because it does not use ThreadedChildWatcher # which is used in Python 3.8+. This is unix specific and also takes care about # cleaning up zombie processes. See https://bugs.python.org/issue35621 if (sys.version_info[0] == 3 and sys.version_info[1] == 7 and sys.platform != "win32" and isinstance( asyncio.get_child_watcher(), asyncio.SafeChildWatcher)): from ._py37ThreadedChildWatcher import ThreadedChildWatcher # type: ignore self._watcher = ThreadedChildWatcher() asyncio.set_child_watcher(self._watcher) # type: ignore # Create a new fiber for the protocol dispatcher. It will be pumping events # until the end of times. We will pass control to that fiber every time we # block while waiting for a response. def greenlet_main() -> None: self._loop.run_until_complete(self._connection.run_as_sync()) dispatcher_fiber = greenlet(greenlet_main) self._connection = Connection( dispatcher_fiber, create_remote_object, PipeTransport(self._loop, compute_driver_executable()), self._loop, ) g_self = greenlet.getcurrent() def callback_wrapper(playwright_impl: Playwright) -> None: self._playwright = SyncPlaywright(playwright_impl) g_self.switch() # Switch control to the dispatcher, it'll fire an event and pass control to # the calling greenlet. self._connection.call_on_object_with_known_name( "Playwright", callback_wrapper) dispatcher_fiber.switch() playwright = self._playwright playwright.stop = self.__exit__ # type: ignore return playwright
class PlaywrightContextManager: def __init__(self) -> None: self._playwright: SyncPlaywright def __enter__(self) -> SyncPlaywright: loop: asyncio.AbstractEventLoop own_loop = None try: loop = asyncio.get_running_loop() except RuntimeError: loop = asyncio.new_event_loop() own_loop = loop if loop.is_running(): raise Error( """It looks like you are using Playwright Sync API inside the asyncio loop. Please use the Async API instead.""") def greenlet_main() -> None: loop.run_until_complete(self._connection.run_as_sync()) if own_loop: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close() global dispatcher_fiber dispatcher_fiber = greenlet(greenlet_main) self._connection = Connection( dispatcher_fiber, create_remote_object, PipeTransport(loop, compute_driver_executable()), loop, ) g_self = greenlet.getcurrent() def callback_wrapper(playwright_impl: Playwright) -> None: self._playwright = SyncPlaywright(playwright_impl) g_self.switch() self._connection.call_on_object_with_known_name( "Playwright", callback_wrapper) dispatcher_fiber.switch() playwright = self._playwright playwright.stop = self.__exit__ # type: ignore return playwright def start(self) -> SyncPlaywright: return self.__enter__() def __exit__(self, *args: Any) -> None: self._connection.stop_sync()
class PlaywrightContextManager: def __init__(self) -> None: self._playwright: SyncPlaywright def __enter__(self) -> SyncPlaywright: def greenlet_main() -> None: loop = None own_loop = None try: loop = asyncio.get_running_loop() except RuntimeError: loop = asyncio.new_event_loop() own_loop = loop if loop.is_running(): raise Error("Can only run one Playwright at a time.") loop.run_until_complete(self._connection.run_as_sync()) if own_loop: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close() dispatcher_fiber = greenlet(greenlet_main) self._connection = Connection(dispatcher_fiber, create_remote_object, compute_driver_executable()) g_self = greenlet.getcurrent() def callback_wrapper(playwright_impl: Playwright) -> None: self._playwright = SyncPlaywright(playwright_impl) g_self.switch() self._connection.call_on_object_with_known_name( "Playwright", callback_wrapper) dispatcher_fiber.switch() playwright = self._playwright playwright.stop = self.__exit__ # type: ignore return playwright def start(self) -> SyncPlaywright: return self.__enter__() def __exit__(self, *args: Any) -> None: self._connection.stop_sync()
async def __aenter__(self) -> AsyncPlaywright: loop = asyncio.get_running_loop() self._connection = Connection( None, create_remote_object, PipeTransport(loop, compute_driver_executable()), loop, ) loop.create_task(self._connection.run()) playwright_future = self._connection.playwright_future done, pending = await asyncio.wait( {self._connection._transport.on_error_future, playwright_future}, return_when=asyncio.FIRST_COMPLETED, ) if not playwright_future.done(): playwright_future.cancel() playwright = AsyncPlaywright(next(iter(done)).result()) playwright.stop = self.__aexit__ # type: ignore return playwright
class PlaywrightContextManager: def __init__(self) -> None: self._connection: Connection async def __aenter__(self) -> AsyncPlaywright: self._connection = Connection(None, create_remote_object, compute_driver_executable()) loop = asyncio.get_running_loop() self._connection._loop = loop loop.create_task(self._connection.run()) playwright = AsyncPlaywright( await self._connection.wait_for_object_with_known_name("Playwright")) playwright.stop = self.__aexit__ # type: ignore return playwright async def start(self) -> AsyncPlaywright: return await self.__aenter__() async def __aexit__(self, *args: Any) -> None: self._connection.stop_async()
async def connect( self, ws_endpoint: str, timeout: float = None, slow_mo: float = None, headers: Dict[str, str] = None, ) -> Browser: if timeout is None: timeout = 30000 headers = { **(headers if headers else {}), "x-playwright-browser": self.name } transport = WebSocketTransport(self._connection._loop, ws_endpoint, headers, slow_mo) connection = Connection( self._connection._dispatcher_fiber, self._connection._object_factory, transport, self._connection._loop, ) connection.mark_as_remote() connection._is_sync = self._connection._is_sync connection._loop.create_task(connection.run()) playwright_future = connection.playwright_future timeout_future = throw_on_timeout(timeout, Error("Connection timed out")) done, pending = await asyncio.wait( {transport.on_error_future, playwright_future, timeout_future}, return_when=asyncio.FIRST_COMPLETED, ) if not playwright_future.done(): playwright_future.cancel() if not timeout_future.done(): timeout_future.cancel() playwright: "Playwright" = next(iter(done)).result() playwright._set_selectors(self._playwright.selectors) self._connection._child_ws_connections.append(connection) pre_launched_browser = playwright._initializer.get( "preLaunchedBrowser") assert pre_launched_browser browser = cast(Browser, from_channel(pre_launched_browser)) browser._should_close_connection_on_close = True browser._local_utils = self._playwright._utils def handle_transport_close() -> None: for context in browser.contexts: for page in context.pages: page._on_close() context._on_close() browser._on_close() connection.cleanup() transport.once("close", handle_transport_close) return browser
async def __aenter__(self) -> AsyncPlaywright: self._connection = Connection( None, create_remote_object, PipeTransport(compute_driver_executable()) ) loop = asyncio.get_running_loop() self._connection._loop = loop obj = asyncio.create_task( self._connection.wait_for_object_with_known_name("Playwright") ) await self._connection._transport.start() loop.create_task(self._connection.run()) done, pending = await asyncio.wait( { obj, self._connection._transport.on_error_future, # type: ignore }, return_when=asyncio.FIRST_COMPLETED, ) if not obj.done(): obj.cancel() obj = next(iter(done)).result() playwright = AsyncPlaywright(obj) # type: ignore playwright.stop = self.__aexit__ # type: ignore return playwright
async def connect( self, ws_endpoint: str, timeout: float = None, slow_mo: float = None, headers: Dict[str, str] = None, ) -> Browser: if timeout is None: timeout = 30000 transport = WebSocketTransport(self._connection._loop, ws_endpoint, headers, slow_mo) connection = Connection( self._connection._dispatcher_fiber, self._connection._object_factory, transport, ) connection._is_sync = self._connection._is_sync connection._loop = self._connection._loop connection._loop.create_task(connection.run()) future = connection._loop.create_task( connection.wait_for_object_with_known_name("Playwright")) timeout_future = throw_on_timeout(timeout, Error("Connection timed out")) done, pending = await asyncio.wait( {transport.on_error_future, future, timeout_future}, return_when=asyncio.FIRST_COMPLETED, ) if not future.done(): future.cancel() if not timeout_future.done(): timeout_future.cancel() playwright = next(iter(done)).result() self._connection._child_ws_connections.append(connection) pre_launched_browser = playwright._initializer.get( "preLaunchedBrowser") assert pre_launched_browser browser = cast(Browser, from_channel(pre_launched_browser)) browser._is_remote = True browser._is_connected_over_websocket = True def handle_transport_close() -> None: for context in browser.contexts: for page in context.pages: page._on_close() context._on_close() browser._on_close() transport.once("close", handle_transport_close) return browser
async def connect( self, ws_endpoint: str, timeout: float = None, slow_mo: float = None, headers: Dict[str, str] = None, ) -> Browser: transport = WebSocketTransport(ws_endpoint, timeout, headers) connection = Connection( self._connection._dispatcher_fiber, self._connection._object_factory, transport, ) await connection._transport.start() connection._is_sync = self._connection._is_sync connection._loop = self._connection._loop connection._loop.create_task(connection.run()) obj = asyncio.create_task( connection.wait_for_object_with_known_name("Playwright")) done, pending = await asyncio.wait( { obj, connection._transport.on_error_future, # type: ignore }, return_when=asyncio.FIRST_COMPLETED, ) if not obj.done(): obj.cancel() playwright = next(iter(done)).result() self._connection._child_ws_connections.append(connection) pre_launched_browser = playwright._initializer.get( "preLaunchedBrowser") assert pre_launched_browser browser = cast(Browser, from_channel(pre_launched_browser)) browser._is_remote = True browser._is_connected_over_websocket = True transport.once("close", browser._on_close) return browser
class PlaywrightContextManager: def __init__(self) -> None: self._playwright: SyncPlaywright self._loop: asyncio.AbstractEventLoop self._own_loop = False self._watcher: Optional[asyncio.AbstractChildWatcher] = None def __enter__(self) -> SyncPlaywright: try: self._loop = asyncio.get_running_loop() except RuntimeError: self._loop = asyncio.new_event_loop() self._own_loop = True if self._loop.is_running(): raise Error( """It looks like you are using Playwright Sync API inside the asyncio loop. Please use the Async API instead.""" ) # In Python 3.7, asyncio.Process.wait() hangs because it does not use ThreadedChildWatcher # which is used in Python 3.8+. This is unix specific and also takes care about # cleaning up zombie processes. See https://bugs.python.org/issue35621 if ( sys.version_info[0] == 3 and sys.version_info[1] == 7 and sys.platform != "win32" and isinstance(asyncio.get_child_watcher(), asyncio.SafeChildWatcher) ): from ._py37ThreadedChildWatcher import ThreadedChildWatcher # type: ignore self._watcher = ThreadedChildWatcher() asyncio.set_child_watcher(self._watcher) # type: ignore def greenlet_main() -> None: self._loop.run_until_complete(self._connection.run_as_sync()) dispatcher_fiber = greenlet(greenlet_main) self._connection = Connection( dispatcher_fiber, create_remote_object, PipeTransport(self._loop, compute_driver_executable()), self._loop, ) g_self = greenlet.getcurrent() def callback_wrapper(playwright_impl: Playwright) -> None: self._playwright = SyncPlaywright(playwright_impl) g_self.switch() self._connection.call_on_object_with_known_name("Playwright", callback_wrapper) dispatcher_fiber.switch() playwright = self._playwright playwright.stop = self.__exit__ # type: ignore return playwright def start(self) -> SyncPlaywright: return self.__enter__() def __exit__(self, *args: Any) -> None: self._connection.stop_sync() if self._watcher: self._watcher.close() if self._own_loop: self._loop.run_until_complete(self._loop.shutdown_asyncgens()) self._loop.close()