A high-level API to automate web browsers across Chromium, Firefox and WebKit with both synchronous and asynchronous execution models.
—
Intercept, modify, and mock network requests and responses for testing offline scenarios, API mocking, and comprehensive network monitoring.
Intercept and modify network requests at the page or context level.
class Page:
def route(
self,
url: Union[str, Pattern, Callable[[str], bool]],
handler: Callable[[Route], None]
) -> None:
"""
Intercept 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)
"""
class BrowserContext:
def route(
self,
url: Union[str, Pattern, Callable[[str], bool]],
handler: Callable[[Route], None]
) -> None:
"""Intercept requests across all pages in context."""
def unroute(
self,
url: Union[str, Pattern, Callable[[str], bool]],
handler: Optional[Callable[[Route], None]] = None
) -> None:
"""Remove context-level request interception."""
class Route:
"""Handle intercepted network requests."""
request: Request
def abort(self, error_code: Optional[str] = None) -> None:
"""
Abort request with error.
Args:
error_code: Error code ('failed', 'aborted', 'timedout', etc.)
"""
def continue_(
self,
url: Optional[str] = None,
method: Optional[str] = None,
post_data: Optional[str] = None,
headers: Optional[Dict[str, str]] = None
) -> None:
"""
Continue request with optional modifications.
Args:
url: Override request URL
method: Override HTTP method
post_data: Override POST data
headers: Override/add headers
"""
def fulfill(
self,
status: Optional[int] = None,
headers: Optional[Dict[str, str]] = None,
body: Optional[Union[str, bytes]] = None,
json: Optional[Any] = None,
path: Optional[str] = None,
content_type: Optional[str] = None,
response: Optional[APIResponse] = None
) -> None:
"""
Fulfill request with custom response.
Args:
status: HTTP status code
headers: Response headers
body: Response body
json: JSON response body
path: File path for response body
content_type: Content-Type header
response: Copy response from APIResponse
"""Access request and response data for monitoring and debugging.
class Request:
"""HTTP request representation."""
url: str
method: str
post_data: Optional[str]
post_data_json: Optional[Any]
post_data_buffer: Optional[bytes]
headers: Dict[str, str]
resource_type: str
frame: Frame
def response(self) -> Optional[Response]:
"""Get response for this request."""
def is_navigation_request(self) -> bool:
"""Check if this is a navigation request."""
class Response:
"""HTTP response representation."""
url: str
ok: bool
status: int
status_text: str
headers: Dict[str, str]
request: Request
def body(self) -> bytes:
"""Get response body as bytes."""
def text(self) -> str:
"""Get response body as text."""
def json(self) -> Any:
"""Parse response body as JSON."""from playwright.sync_api import sync_playwright
def handle_api_route(route):
if "api/users" in route.request.url:
route.fulfill(
status=200,
json={"users": [{"id": 1, "name": "Test User"}]}
)
else:
route.continue_()
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
# Mock API responses
page.route("**/api/**", handle_api_route)
page.goto("https://app.com")
browser.close()requests = []
responses = []
def log_request(request):
requests.append({
"url": request.url,
"method": request.method,
"headers": request.headers
})
def log_response(response):
responses.append({
"url": response.url,
"status": response.status,
"size": len(response.body())
})
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.on("request", log_request)
page.on("response", log_response)
page.goto("https://example.com")
print(f"Requests: {len(requests)}")
print(f"Responses: {len(responses)}")
browser.close()Install with Tessl CLI
npx tessl i tessl/pypi-playwright