feat(sdk-python): add Browserbase client_options to launch and connect

Merged
MI
9d ago
+255-38

why

Stacked on #3118, which adds clientOptions to the TypeScript SDK. This PR adds the same option to Python, so callers can tune the Browserbase client Stagehand builds for session management without injecting their own client.

what changed

  • client_options: BrowserbaseClientOptions on browserbase.launch() and browserbase.connect(). Fields: timeout (seconds), max_retries, default_headers, default_query, http_client. It's a public TypedDict backed by a strict Pydantic runtime model, so unknown keys such as api_key or base_url are rejected.
  • _OfficialBrowserbaseAPI builds every AsyncBrowserbase with these options. api_key and base_url stay top-level.
  • http_client: httpx.AsyncClient is the Python counterpart to TS fetch: custom transports, proxies, mocks, request/response hooks. The SDK's AsyncBrowserbase.close() closes its HTTP client, so for a caller-supplied client Stagehand builds AsyncBrowserbase around it without closing it. The caller owns the client and must keep it open until browser.close() returns. Clients Stagehand creates are still closed. httpx becomes a direct dependency because it now appears in a public type; it was already in the lock file through browserbase.
  • Removes the Python exemption #3118 added to the parity test, and adds BrowserbaseClientOptions to the check that keeps Python's input types and runtime models in sync.
  • Extends the docs section with a Python example and a minor changeset for stagehand-python.

test plan

  • pytest: 754 passed. New tests cover passing options through launch and connect, rejecting invalid options before any API call (including a sync httpx.Client), and building a real AsyncBrowserbase with the options applied.
  • A full launch-and-close lifecycle through a caller http_client with a mock transport: all four requests (extension upload, session create, release, extension delete) go through it, and it is still open afterwards. With the ownership check disabled, this test fails at session create.
  • ty check, ruff check and ruff format, uv lock --check, generate.py --check
  • rules/ast-grep parity tests with the Python exemption removed, and the docs tests
  • No live Browserbase session was launched