Files
Dorod-Sky/skyvern/library/skyvern_browser.py
2025-11-12 22:44:53 +00:00

108 lines
3.8 KiB
Python

from typing import TYPE_CHECKING, Any
from playwright.async_api import BrowserContext, Page
from skyvern.library.skyvern_browser_page import SkyvernBrowserPage
if TYPE_CHECKING:
from skyvern.library.skyvern import Skyvern
class SkyvernBrowser(BrowserContext):
"""A browser context wrapper that creates Skyvern-enabled pages.
This class extends Playwright BrowserContext and provides methods to create
SkyvernBrowserPage instances that combine traditional browser automation with
AI-powered task execution capabilities. It manages browser session state and
enables persistent browser sessions across multiple pages.
Example:
```python
skyvern = Skyvern()
browser = await skyvern.launch_local_browser()
# Get or create the working page
page = await browser.get_working_page()
# Create a new page
new_page = await browser.new_page()
```
Attributes:
_browser_context: The underlying Playwright BrowserContext.
_browser_session_id: Optional session ID for persistent browser sessions.
_browser_address: Optional address for remote browser connections.
_client: The AsyncSkyvern client for API communication.
"""
def __init__(
self,
skyvern: "Skyvern",
browser_context: BrowserContext,
*,
browser_session_id: str | None = None,
browser_address: str | None = None,
):
super().__init__(browser_context)
self._skyvern = skyvern
self._browser_context = browser_context
self._browser_session_id = browser_session_id
self._browser_address = browser_address
self.workflow_run_id: None | str = None
def __getattribute__(self, name: str) -> Any:
browser_context = object.__getattribute__(self, "_browser_context")
if hasattr(browser_context, name):
for cls in type(self).__mro__:
if cls is BrowserContext:
break
if name in cls.__dict__:
return object.__getattribute__(self, name)
return getattr(browser_context, name)
return object.__getattribute__(self, name)
@property
def browser_session_id(self) -> str | None:
return self._browser_session_id
@property
def browser_address(self) -> str | None:
return self._browser_address
@property
def skyvern(self) -> "Skyvern":
return self._skyvern
async def get_working_page(self) -> SkyvernBrowserPage:
"""Get the most recent page or create a new one if none exists.
This method returns the last page in the browser context, or creates a new page
if the context has no pages. This is useful for continuing work on an existing
page without creating unnecessary new tabs.
Returns:
SkyvernBrowserPage: The most recent page wrapped with Skyvern capabilities.
"""
if self._browser_context.pages:
page = self._browser_context.pages[-1]
else:
page = await self._browser_context.new_page()
return await self._create_skyvern_page(page)
async def new_page(self) -> SkyvernBrowserPage:
"""Create a new page (tab) in the browser context.
This method always creates a new page, similar to opening a new tab in a browser.
The new page will have both Playwright's standard API and Skyvern's AI capabilities.
Returns:
SkyvernBrowserPage: A new page wrapped with Skyvern capabilities.
"""
page = await self._browser_context.new_page()
return await self._create_skyvern_page(page)
async def _create_skyvern_page(self, page: Page) -> SkyvernBrowserPage:
return SkyvernBrowserPage(self, page)