A high-level API to automate web browsers across Chromium, Firefox and WebKit with both synchronous and asynchronous execution models.
—
HTTP client for testing REST APIs and web services with request/response handling, authentication, and browser context integration.
HTTP client for making API requests independently or integrated with browser sessions.
class APIRequest:
def new_context(
self,
base_url: Optional[str] = None,
extra_http_headers: Optional[Dict[str, str]] = None,
http_credentials: Optional[HttpCredentials] = None,
ignore_https_errors: Optional[bool] = None,
proxy: Optional[ProxySettings] = None,
user_agent: Optional[str] = None,
timeout: Optional[float] = None,
storage_state: Union[str, StorageState, None] = None
) -> APIRequestContext:
"""
Create API request context.
Args:
base_url: Base URL for relative requests
extra_http_headers: Default headers for all requests
http_credentials: HTTP authentication credentials
ignore_https_errors: Ignore SSL certificate errors
proxy: Proxy settings
user_agent: User agent string
timeout: Default timeout for requests
storage_state: Browser storage state for authentication
Returns:
APIRequestContext: HTTP client context
"""
class APIRequestContext:
"""HTTP client for API testing."""
def get(
self,
url: str,
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""
Send GET request.
Args:
url: Request URL
params: Query parameters
headers: Request headers
timeout: Request timeout
fail_on_status_code: Throw on non-2xx status
ignore_https_errors: Ignore SSL errors
Returns:
APIResponse: HTTP response
"""
def post(
self,
url: str,
data: Optional[Union[str, bytes, Any]] = None,
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
form: Optional[Dict[str, Any]] = None,
multipart: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""Send POST request with data, form, or multipart body."""
def put(
self,
url: str,
data: Optional[Union[str, bytes, Any]] = None,
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
form: Optional[Dict[str, Any]] = None,
multipart: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""Send PUT request."""
def patch(
self,
url: str,
data: Optional[Union[str, bytes, Any]] = None,
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
form: Optional[Dict[str, Any]] = None,
multipart: Optional[Dict[str, Any]] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""Send PATCH request."""
def delete(
self,
url: str,
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""Send DELETE request."""
def head(
self,
url: str,
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""Send HEAD request."""
def fetch(
self,
url_or_request: Union[str, Request],
params: Optional[Dict[str, Any]] = None,
headers: Optional[Dict[str, str]] = None,
data: Optional[Union[str, bytes, Any]] = None,
form: Optional[Dict[str, Any]] = None,
multipart: Optional[Dict[str, Any]] = None,
method: Optional[str] = None,
timeout: Optional[float] = None,
fail_on_status_code: Optional[bool] = None,
ignore_https_errors: Optional[bool] = None
) -> APIResponse:
"""Send custom HTTP request."""
def storage_state(self, path: Optional[str] = None) -> StorageState:
"""Get current storage state for session persistence."""
def dispose(self) -> None:
"""Clean up API request context."""HTTP response object with data access methods.
class APIResponse:
"""HTTP response from API request."""
url: str
ok: bool
status: int
status_text: str
headers: Dict[str, str]
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."""
def header_value(self, name: str) -> Optional[str]:
"""Get specific header value."""
def headers_array(self) -> List[Dict[str, str]]:
"""Get headers as array of name-value pairs."""
def dispose(self) -> None:
"""Clean up response resources."""from playwright.sync_api import sync_playwright, expect
with sync_playwright() as p:
# Create API context
request_context = p.request.new_context(
base_url="https://api.example.com",
extra_http_headers={"Authorization": "Bearer token123"}
)
# GET request
response = request_context.get("/users")
expect(response).to_be_ok()
users = response.json()
assert len(users) > 0
# POST request
new_user = {
"name": "John Doe",
"email": "john@example.com"
}
response = request_context.post("/users", data=new_user)
expect(response).to_be_ok()
created_user = response.json()
assert created_user["id"] is not None
request_context.dispose()with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context()
page = context.new_page()
# Login through browser
page.goto("https://app.example.com/login")
page.fill("#username", "testuser")
page.fill("#password", "password")
page.click("#login-btn")
# Use browser's authentication for API calls
storage_state = context.storage_state()
api_context = p.request.new_context(
base_url="https://api.example.com",
storage_state=storage_state
)
# API calls now authenticated
response = api_context.get("/profile")
expect(response).to_be_ok()
profile = response.json()
assert profile["username"] == "testuser"
api_context.dispose()
browser.close()with sync_playwright() as p:
api_context = p.request.new_context(
base_url="https://api.example.com"
)
# Upload file with multipart data
response = api_context.post("/upload", multipart={
"file": {
"name": "document.pdf",
"mimeType": "application/pdf",
"buffer": open("document.pdf", "rb").read()
},
"description": "Important document"
})
expect(response).to_be_ok()
upload_result = response.json()
assert upload_result["file_id"] is not None
api_context.dispose()Install with Tessl CLI
npx tessl i tessl/pypi-playwright