A high-level API to automate web browsers across Chromium, Firefox and WebKit with both synchronous and asynchronous execution models.
—
Comprehensive browser lifecycle management including launching browser instances, creating isolated contexts, and managing browser configurations across Chromium, Firefox, and WebKit.
Launch Playwright and get access to browser types.
def sync_playwright() -> PlaywrightContextManager:
"""
Returns synchronous Playwright context manager.
Returns:
PlaywrightContextManager: Context manager for browser automation
"""
def async_playwright() -> PlaywrightContextManager:
"""
Returns asynchronous Playwright context manager.
Returns:
PlaywrightContextManager: Async context manager for browser automation
"""
class PlaywrightContextManager:
def __enter__(self) -> Playwright: ...
def __exit__(self, *args) -> None: ...
async def __aenter__(self) -> Playwright: ...
async def __aexit__(self, *args) -> None: ...Access to different browser engines with launch capabilities.
class Playwright:
"""Main Playwright interface providing access to browser types."""
chromium: BrowserType
firefox: BrowserType
webkit: BrowserType
devices: Dict[str, Dict[str, Any]]
selectors: Selectors
request: APIRequest
class BrowserType:
"""Represents a browser engine (Chromium, Firefox, WebKit)."""
name: str
executable_path: str
def launch(
self,
executable_path: Optional[str] = None,
channel: Optional[str] = None,
args: Optional[List[str]] = None,
ignore_default_args: Union[bool, List[str], None] = None,
handle_sigint: Optional[bool] = None,
handle_sigterm: Optional[bool] = None,
handle_sighup: Optional[bool] = None,
timeout: Optional[float] = None,
env: Optional[Dict[str, Union[str, int, bool]]] = None,
headless: Optional[bool] = None,
devtools: Optional[bool] = None,
proxy: Optional[ProxySettings] = None,
downloads_path: Optional[str] = None,
slow_mo: Optional[float] = None,
traces_dir: Optional[str] = None,
chromium_sandbox: Optional[bool] = None,
firefox_user_prefs: Optional[Dict[str, Any]] = None
) -> Browser:
"""
Launch new browser instance.
Args:
executable_path: Path to browser executable
channel: Browser channel (chrome, chrome-beta, msedge, etc.)
args: Additional command line arguments
ignore_default_args: Skip default arguments
handle_sigint: Handle SIGINT signal
handle_sigterm: Handle SIGTERM signal
handle_sighup: Handle SIGHUP signal
timeout: Launch timeout in milliseconds
env: Environment variables
headless: Run in headless mode
devtools: Open devtools
proxy: Proxy configuration
downloads_path: Download directory
slow_mo: Slow down operations by milliseconds
traces_dir: Directory for traces
chromium_sandbox: Enable/disable sandbox (Chromium only)
firefox_user_prefs: Firefox preferences
Returns:
Browser: New browser instance
"""
def launch_persistent_context(
self,
user_data_dir: str,
executable_path: Optional[str] = None,
channel: Optional[str] = None,
args: Optional[List[str]] = None,
ignore_default_args: Union[bool, List[str], None] = None,
handle_sigint: Optional[bool] = None,
handle_sigterm: Optional[bool] = None,
handle_sighup: Optional[bool] = None,
timeout: Optional[float] = None,
env: Optional[Dict[str, Union[str, int, bool]]] = None,
headless: Optional[bool] = None,
devtools: Optional[bool] = None,
proxy: Optional[ProxySettings] = None,
downloads_path: Optional[str] = None,
slow_mo: Optional[float] = None,
traces_dir: Optional[str] = None,
chromium_sandbox: Optional[bool] = None,
firefox_user_prefs: Optional[Dict[str, Any]] = None,
viewport: Optional[ViewportSize] = None,
screen: Optional[Dict] = None,
no_viewport: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None,
java_script_enabled: Optional[bool] = None,
bypass_csp: Optional[bool] = None,
user_agent: Optional[str] = None,
locale: Optional[str] = None,
timezone_id: Optional[str] = None,
geolocation: Optional[Geolocation] = None,
permissions: Optional[List[str]] = None,
extra_http_headers: Optional[Dict[str, str]] = None,
offline: Optional[bool] = None,
http_credentials: Optional[HttpCredentials] = None,
device_scale_factor: Optional[float] = None,
is_mobile: Optional[bool] = None,
has_touch: Optional[bool] = None,
color_scheme: Optional[str] = None,
reduced_motion: Optional[str] = None,
forced_colors: Optional[str] = None,
accept_downloads: Optional[bool] = None,
record_har_path: Optional[str] = None,
record_har_omit_content: Optional[bool] = None,
record_video_dir: Optional[str] = None,
record_video_size: Optional[ViewportSize] = None,
storage_state: Union[str, StorageState, None] = None,
base_url: Optional[str] = None,
strict_selectors: Optional[bool] = None,
service_workers: Optional[str] = None,
record_har_url_filter: Union[str, Pattern, None] = None,
record_har_mode: Optional[str] = None,
record_har_content: Optional[str] = None
) -> BrowserContext:
"""
Launch browser instance with persistent user data directory.
Args:
user_data_dir: Directory for persistent user data
(other args same as launch())
viewport: Browser viewport size
screen: Screen size and settings
no_viewport: Disable default viewport
ignore_https_errors: Ignore HTTPS errors
java_script_enabled: Enable JavaScript
bypass_csp: Bypass Content Security Policy
user_agent: Custom user agent
locale: Locale setting
timezone_id: Timezone identifier
geolocation: Geolocation coordinates
permissions: Browser permissions to grant
extra_http_headers: Default HTTP headers
offline: Start in offline mode
http_credentials: HTTP authentication
device_scale_factor: Device scale factor
is_mobile: Mobile emulation
has_touch: Touch support
color_scheme: Color scheme preference
reduced_motion: Reduced motion preference
forced_colors: Forced colors setting
accept_downloads: Allow downloads
record_har_path: HAR file recording path
record_har_omit_content: Omit content from HAR
record_video_dir: Video recording directory
record_video_size: Video recording size
storage_state: Initial storage state
base_url: Base URL for relative navigation
strict_selectors: Enable strict selector mode
service_workers: Service worker handling
record_har_url_filter: HAR URL filter
record_har_mode: HAR recording mode
record_har_content: HAR content handling
Returns:
BrowserContext: Browser context with persistent state
"""
def connect(
self,
ws_endpoint: str,
timeout: Optional[float] = None,
slow_mo: Optional[float] = None,
headers: Optional[Dict[str, str]] = None
) -> Browser:
"""
Connect to existing browser instance via WebSocket.
Args:
ws_endpoint: WebSocket endpoint URL
timeout: Connection timeout in milliseconds
slow_mo: Slow down operations by milliseconds
headers: WebSocket headers
Returns:
Browser: Connected browser instance
"""
def connect_over_cdp(
self,
endpoint_url: str,
timeout: Optional[float] = None,
slow_mo: Optional[float] = None,
headers: Optional[Dict[str, str]] = None
) -> Browser:
"""
Connect to existing browser via Chrome DevTools Protocol.
Args:
endpoint_url: CDP endpoint URL
timeout: Connection timeout in milliseconds
slow_mo: Slow down operations by milliseconds
headers: Connection headers
Returns:
Browser: Connected browser instance
"""Manage browser instances and their lifecycle.
class Browser:
"""Browser instance controlling browser process and contexts."""
contexts: List[BrowserContext]
browser_type: BrowserType
version: str
def new_context(
self,
viewport: Optional[ViewportSize] = None,
screen: Optional[Dict] = None,
no_viewport: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None,
java_script_enabled: Optional[bool] = None,
bypass_csp: Optional[bool] = None,
user_agent: Optional[str] = None,
locale: Optional[str] = None,
timezone_id: Optional[str] = None,
geolocation: Optional[Geolocation] = None,
permissions: Optional[List[str]] = None,
extra_http_headers: Optional[Dict[str, str]] = None,
offline: Optional[bool] = None,
http_credentials: Optional[HttpCredentials] = None,
device_scale_factor: Optional[float] = None,
is_mobile: Optional[bool] = None,
has_touch: Optional[bool] = None,
color_scheme: Optional[str] = None,
reduced_motion: Optional[str] = None,
forced_colors: Optional[str] = None,
accept_downloads: Optional[bool] = None,
proxy: Optional[ProxySettings] = None,
record_har_path: Optional[str] = None,
record_har_omit_content: Optional[bool] = None,
record_video_dir: Optional[str] = None,
record_video_size: Optional[ViewportSize] = None,
storage_state: Union[str, StorageState, None] = None,
base_url: Optional[str] = None,
strict_selectors: Optional[bool] = None,
service_workers: Optional[str] = None,
record_har_url_filter: Union[str, Pattern, None] = None,
record_har_mode: Optional[str] = None,
record_har_content: Optional[str] = None
) -> BrowserContext:
"""
Create new browser context with independent state.
Args:
viewport: Browser viewport size
screen: Screen configuration
no_viewport: Disable default viewport
ignore_https_errors: Ignore HTTPS certificate errors
java_script_enabled: Enable/disable JavaScript
bypass_csp: Bypass Content Security Policy
user_agent: Custom user agent string
locale: Browser locale (en-US, de-DE, etc.)
timezone_id: Timezone identifier (America/New_York, etc.)
geolocation: GPS coordinates
permissions: Browser permissions to grant
extra_http_headers: Default headers for all requests
offline: Start in offline mode
http_credentials: HTTP authentication credentials
device_scale_factor: Device pixel ratio
is_mobile: Enable mobile viewport
has_touch: Enable touch events
color_scheme: 'light', 'dark', or 'no-preference'
reduced_motion: 'reduce', 'no-preference'
forced_colors: 'active', 'none'
accept_downloads: Allow file downloads
proxy: Proxy server configuration
record_har_path: Path to record HAR file
record_har_omit_content: Exclude response bodies from HAR
record_video_dir: Directory for video recording
record_video_size: Video dimensions
storage_state: Initial cookies and localStorage
base_url: Base URL for relative navigation
strict_selectors: Throw on ambiguous selectors
service_workers: 'allow', 'block'
record_har_url_filter: Filter URLs in HAR recording
record_har_mode: 'full', 'minimal'
record_har_content: 'omit', 'embed', 'attach'
Returns:
BrowserContext: New isolated browser context
"""
def new_page(self) -> Page:
"""
Create new page in default browser context.
Returns:
Page: New page instance
"""
def is_connected(self) -> bool:
"""
Check if browser is connected.
Returns:
bool: True if browser is connected
"""
def close(self) -> None:
"""Close browser instance and all contexts."""
def start_tracing(
self,
page: Optional[Page] = None,
path: Optional[str] = None,
screenshots: Optional[bool] = None,
categories: Optional[List[str]] = None
) -> None:
"""
Start tracing for performance analysis.
Args:
page: Page to trace (traces all if None)
path: Output file path
screenshots: Include screenshots in trace
categories: Trace categories to include
"""
def stop_tracing(self) -> bytes:
"""
Stop tracing and return trace data.
Returns:
bytes: Trace data
"""Manage isolated browser sessions with independent state.
class BrowserContext:
"""Isolated browser session with independent cookies, storage, and permissions."""
pages: List[Page]
browser: Optional[Browser]
def new_page(self) -> Page:
"""
Create new page in this context.
Returns:
Page: New page instance
"""
def close(self) -> None:
"""Close context and all associated pages."""
def cookies(self, urls: Optional[Union[str, List[str]]] = None) -> List[Cookie]:
"""
Get cookies for specified URLs.
Args:
urls: URL(s) to get cookies for (all if None)
Returns:
List[Cookie]: Current cookies
"""
def add_cookies(self, cookies: List[Cookie]) -> None:
"""
Add cookies to the context.
Args:
cookies: Cookies to add
"""
def clear_cookies(self) -> None:
"""Clear all cookies in the context."""
def grant_permissions(
self,
permissions: List[str],
origin: Optional[str] = None
) -> None:
"""
Grant specified permissions.
Args:
permissions: Permission names (geolocation, notifications, etc.)
origin: Origin to grant permissions for (all if None)
"""
def clear_permissions(self) -> None:
"""Clear all granted permissions."""
def set_geolocation(self, geolocation: Optional[Geolocation]) -> None:
"""
Set geolocation coordinates.
Args:
geolocation: GPS coordinates (clears if None)
"""
def set_extra_http_headers(self, headers: Dict[str, str]) -> None:
"""
Set default HTTP headers for all requests.
Args:
headers: Headers to set
"""
def set_offline(self, offline: bool) -> None:
"""
Toggle offline mode.
Args:
offline: True for offline mode
"""
def storage_state(self, path: Optional[str] = None) -> StorageState:
"""
Get current storage state (cookies and localStorage).
Args:
path: Optional file path to save state
Returns:
StorageState: Current storage state
"""
def route(
self,
url: Union[str, Pattern, Callable[[str], bool]],
handler: Callable[[Route], None]
) -> None:
"""
Intercept network requests matching URL pattern.
Args:
url: URL pattern to intercept
handler: Function to handle intercepted requests
"""
def unroute(
self,
url: Union[str, Pattern, Callable[[str], bool]],
handler: Optional[Callable[[Route], None]] = None
) -> None:
"""
Remove request interception.
Args:
url: URL pattern to stop intercepting
handler: Specific handler to remove (all if None)
"""
def expect_event(
self,
event: str,
predicate: Optional[Callable] = None,
timeout: Optional[float] = None
) -> EventContextManager:
"""
Wait for context event.
Args:
event: Event name (page, close, request, etc.)
predicate: Event filter function
timeout: Wait timeout in milliseconds
Returns:
EventContextManager: Context manager for event
"""
def wait_for_event(
self,
event: str,
predicate: Optional[Callable] = None,
timeout: Optional[float] = None
) -> Any:
"""
Wait for context event and return event data.
Args:
event: Event name
predicate: Event filter function
timeout: Wait timeout in milliseconds
Returns:
Any: Event data
"""from playwright.sync_api import sync_playwright
# Launch different browsers
with sync_playwright() as p:
# Chromium (default)
browser = p.chromium.launch(headless=False)
# Firefox
firefox = p.firefox.launch()
# WebKit
webkit = p.webkit.launch()
page = browser.new_page()
page.goto("https://example.com")
browser.close()with sync_playwright() as p:
browser = p.chromium.launch(
headless=False,
slow_mo=1000, # Slow down by 1 second
args=['--start-maximized'],
env={'LANG': 'en_US.UTF-8'}
)
context = browser.new_context(
viewport={'width': 1920, 'height': 1080},
locale='en-US',
timezone_id='America/New_York',
permissions=['geolocation'],
geolocation={'latitude': 40.7128, 'longitude': -74.0060}
)
page = context.new_page()
page.goto("https://example.com")
browser.close()with sync_playwright() as p:
# Browser with persistent data
context = p.chromium.launch_persistent_context(
user_data_dir="./user-data",
headless=False,
locale='en-US'
)
page = context.new_page()
page.goto("https://gmail.com") # Login will persist
context.close()with sync_playwright() as p:
browser = p.chromium.launch()
# Context 1: User session
user_context = browser.new_context(
storage_state={'cookies': [], 'origins': []}
)
user_page = user_context.new_page()
# Context 2: Admin session
admin_context = browser.new_context(
http_credentials={'username': 'admin', 'password': 'secret'}
)
admin_page = admin_context.new_page()
# Independent sessions
user_page.goto("https://app.com/user")
admin_page.goto("https://app.com/admin")
browser.close()Direct access to Chrome DevTools Protocol for advanced browser automation and debugging capabilities.
class CDPSession:
"""Chrome DevTools Protocol session for low-level browser control."""
def send(
self,
method: str,
params: Optional[Dict] = None
) -> Dict:
"""
Send CDP command to browser.
Args:
method: CDP method name (e.g., 'Runtime.evaluate')
params: Optional method parameters
Returns:
Dict: CDP response data
"""
def detach(self) -> None:
"""Detach from CDP session."""Usage example:
# Access CDP session from browser context
cdp = context.new_cdp_session(page)
# Execute JavaScript via CDP
result = cdp.send("Runtime.evaluate", {
"expression": "document.title",
"returnByValue": True
})
print(result["result"]["value"])
# Set up event listeners
cdp.send("Runtime.enable")Install with Tessl CLI
npx tessl i tessl/pypi-playwright