Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "3.6.0"
".": "3.7.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 8
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-87b4d9e349de9d33d5d89439f7ac9507133700a9f072fdf0d756471961768d2c.yml
openapi_spec_hash: 0f6ae6d10a0227a3482914728cf901ba
config_hash: 7baf2daccae5913216bb74c52d63eaff
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-a4e672f457dd99336f4b2a113fd7c7c6c9db0941b38d57cff6e3641549a6c4ed.yml
openapi_spec_hash: eae9c8561e420db8e4d238c1e59617fb
config_hash: 2a565ad6662259a2e90fa5f1f5095525
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 3.7.0 (2026-02-26)

Full Changelog: [v3.6.0...v3.7.0](https://github.com/browserbase/stagehand-python/compare/v3.6.0...v3.7.0)

### Features

* Add bedrock to provider enum in Zod schemas and OpenAPI spec ([5ace8c9](https://github.com/browserbase/stagehand-python/commit/5ace8c9ee306ff8cc09c258500c24b6b55e9562b))

## 3.6.0 (2026-02-25)

Full Changelog: [v3.5.0...v3.6.0](https://github.com/browserbase/stagehand-python/compare/v3.5.0...v3.6.0)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ Examples and dependencies:
- `examples/byob_example.py`: Playwright + Playwright browsers
- `examples/pydoll_tab_example.py`: `pydoll-python` (Python 3.10+)

Multiregion support: see `examples/local_server_multiregion_browser_example.py`.

Run any example:

```bash
Expand Down
173 changes: 173 additions & 0 deletions examples/local_server_multiregion_browser_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
"""
Example: local Stagehand server + multiregion Browserbase browser in eu-central-1.

What this demonstrates:
- Run Stagehand server locally (SEA) with Browserbase cloud browser
- Request a Browserbase session in eu-central-1
- Attach Playwright to the same browser via CDP (`cdp_url`)
- Stream SSE events by default for observe/act/extract/execute
- Run the full flow: start → observe → act → extract → agent/execute → end

Environment variables required:
- MODEL_API_KEY
- BROWSERBASE_API_KEY
- BROWSERBASE_PROJECT_ID

Optional:
- STAGEHAND_BASE_URL (defaults to http://127.0.0.1:3000 when server="local")
"""

from __future__ import annotations

import os
import sys
from typing import Any, Optional

from env import load_example_env

from stagehand import Stagehand


def _print_stream_events(stream: Any, label: str) -> object | None:
result_payload: object | None = None
for event in stream:
if event.type == "log":
print(f"[{label}][log] {event.data.message}")
continue

status = event.data.status
print(f"[{label}][system] status={status}")
if status == "finished":
result_payload = event.data.result
elif status == "error":
error_message = event.data.error or "unknown error"
raise RuntimeError(f"{label} stream reported error: {error_message}")

return result_payload


def main() -> None:
load_example_env()
model_api_key = os.environ.get("MODEL_API_KEY")
if not model_api_key:
sys.exit("Set the MODEL_API_KEY environment variable to run this example.")

bb_api_key = os.environ.get("BROWSERBASE_API_KEY")
bb_project_id = os.environ.get("BROWSERBASE_PROJECT_ID")
if not bb_api_key or not bb_project_id:
sys.exit(
"Set BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID to run this example."
)

try:
from playwright.sync_api import sync_playwright # type: ignore[import-not-found]
except Exception:
sys.exit(
"Playwright is not installed. Install it with:\n"
" uv pip install playwright\n"
"and ensure browsers are installed (e.g. `playwright install chromium`)."
)

session_id: Optional[str] = None

with Stagehand(
server="local",
browserbase_api_key=bb_api_key,
browserbase_project_id=bb_project_id,
model_api_key=model_api_key,
local_openai_api_key=model_api_key,
local_ready_timeout_s=30.0,
) as client:
print("⏳ Starting Stagehand session (local server + Browserbase browser)...")
session = client.sessions.start(
model_name="anthropic/claude-sonnet-4-6",
browser={"type": "browserbase"},
browserbase_session_create_params={"region": "eu-central-1"},
verbose=2,
)
session_id = session.id

cdp_url = session.data.cdp_url
if not cdp_url:
sys.exit(
"No cdp_url returned from the API for this session; cannot attach Playwright."
)

print(f"✅ Session started: {session_id}")
print("🔌 Connecting Playwright to the same browser over CDP...")

try:
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp_url)
try:
context = browser.contexts[0] if browser.contexts else browser.new_context()
page = context.pages[0] if context.pages else context.new_page()

page.goto("https://example.com", wait_until="domcontentloaded")

print("👀 Stagehand.observe(page=...) with SSE streaming...")
observe_stream = session.observe(
instruction="Find the most relevant click target on this page",
page=page,
stream_response=True,
x_stream_response="true",
)
observe_result = _print_stream_events(observe_stream, "observe")

actions = observe_result or []
if not actions:
print("No actions found; ending session.")
return

print("🖱️ Stagehand.act(page=...) with SSE streaming...")
act_stream = session.act(
input=actions[0],
page=page,
stream_response=True,
x_stream_response="true",
)
_ = _print_stream_events(act_stream, "act")

print("🧠 Stagehand.extract(page=...) with SSE streaming...")
extract_stream = session.extract(
instruction="Extract the page title and the primary heading (h1) text",
schema={
"type": "object",
"properties": {
"title": {"type": "string"},
"h1": {"type": "string"},
},
"required": ["title", "h1"],
"additionalProperties": False,
},
page=page,
stream_response=True,
x_stream_response="true",
)
extracted = _print_stream_events(extract_stream, "extract")
print("Extracted:", extracted)

print("🤖 Stagehand.execute(page=...) with SSE streaming...")
execute_stream = session.execute(
agent_config={"model": "anthropic/claude-opus-4-6"},
execute_options={
"instruction": (
"Open the 'Learn more' link if present and summarize the destination in one sentence."
),
"max_steps": 5,
},
page=page,
stream_response=True,
x_stream_response="true",
)
execute_result = _print_stream_events(execute_stream, "execute")
print("Execute result:", execute_result)
finally:
browser.close()
finally:
session.end()
print("✅ Session ended.")


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "stagehand"
version = "3.6.0"
version = "3.7.0"
description = "The official Python library for the stagehand API"
dynamic = ["readme"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion src/stagehand/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "stagehand"
__version__ = "3.6.0" # x-release-please-version
__version__ = "3.7.0" # x-release-please-version
2 changes: 1 addition & 1 deletion src/stagehand/types/model_config_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ class ModelConfigParam(TypedDict, total=False):
base_url: Annotated[str, PropertyInfo(alias="baseURL")]
"""Base URL for the model provider"""

provider: Literal["openai", "anthropic", "google", "microsoft"]
provider: Literal["openai", "anthropic", "google", "microsoft", "bedrock"]
"""AI provider for the model (or provide a baseURL endpoint instead)"""
2 changes: 1 addition & 1 deletion src/stagehand/types/session_execute_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class AgentConfig(TypedDict, total=False):
'anthropic/claude-4.5-opus')
"""

provider: Literal["openai", "anthropic", "google", "microsoft"]
provider: Literal["openai", "anthropic", "google", "microsoft", "bedrock"]
"""AI provider for the agent (legacy, use model: openai/gpt-5-nano instead)"""

system_prompt: Annotated[str, PropertyInfo(alias="systemPrompt")]
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.