Source code for intelliscraper.browser.backend
"""Abstract base class for browser backends.
All browser lifecycle management starting, configuring, and tearing
down the browser is handled through this interface. ``AsyncScraper``
delegates to a concrete backend chosen at construction time.
"""
from __future__ import annotations
import abc
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from playwright.async_api import Browser, BrowserContext, Playwright
[docs]
class BrowserBackend(abc.ABC):
"""Abstract base for browser lifecycle management.
Subclasses handle how a browser is started, configured, and cleaned
up. The scraper delegates all browser-level concerns here.
Typical usage::
backend = ManagedBrowserBackend(headless=True, ...)
browser, context = await backend.initialize(playwright)
# ... use browser / context ...
await backend.cleanup(browser, context)
"""
[docs]
@abc.abstractmethod
async def initialize(
self,
playwright: Playwright,
) -> tuple[Browser, BrowserContext]:
"""Start the browser and return a ready-to-use context.
Args:
playwright: A started Playwright instance.
Returns:
A ``(browser, context)`` tuple.
Raises:
LocalBrowserConnectionError: If the local browser cannot be
reached (only from ``LocalBrowserBackend``).
"""
[docs]
@abc.abstractmethod
async def cleanup(
self,
browser: Browser,
context: BrowserContext,
) -> None:
"""Release browser resources.
What gets closed depends on the backend:
* **Local**: Only the pages opened by the scraper are closed.
The Chrome process and its context are left running.
* **Managed**: Pages, context, and browser process are all
closed.
Args:
browser: The browser instance to clean up.
context: The browser context to clean up.
"""
@property
@abc.abstractmethod
def owns_browser(self) -> bool:
"""Whether this backend owns (and should close) the browser process.
Returns:
``True`` for managed backends, ``False`` for local/CDP
backends where the browser belongs to the user.
"""