예제 #1
0
    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()
예제 #3
0
 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
예제 #5
0
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()
예제 #6
0
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()
예제 #7
0
    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
예제 #8
0
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()
예제 #9
0
    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
예제 #10
0
 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
예제 #11
0
    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
예제 #12
0
    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()