Skip to content

Commit f24078b

Browse files
committed
Added full example + updated readme
1 parent 779eca5 commit f24078b

File tree

3 files changed

+200
-14
lines changed

3 files changed

+200
-14
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
BROWSERBASE_API_KEY=bb_live_your_api_key_here
2+
BROWSERBASE_PROJECT_ID=your-bb-project-uuid-here
3+
MODEL_API_KEY=sk-proj-your-llm-api-key-here

README.md

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,62 @@ The REST API documentation can be found on [docs.stagehand.dev](https://docs.sta
2929
pip install stagehand-alpha
3030
```
3131

32+
## Running the Example
33+
34+
A complete working example is available at [`examples/full_example.py`](examples/full_example.py).
35+
36+
To run it, first export the required environment variables, then use Python:
37+
38+
```bash
39+
export BROWSERBASE_API_KEY="your-bb-api-key"
40+
export BROWSERBASE_PROJECT_ID="your-bb-project-uuid"
41+
export MODEL_API_KEY="sk-proj-your-llm-api-key"
42+
43+
python examples/full_example.py
44+
```
45+
3246
## Usage
3347

3448
The full API of this library can be found in [api.md](api.md).
3549

50+
## Client configuration
51+
52+
Configure the client using environment variables:
53+
54+
```python
55+
from stagehand import Stagehand
56+
57+
# Configures using the BROWSERBASE_API_KEY, BROWSERBASE_PROJECT_ID, and MODEL_API_KEY environment variables
58+
client = Stagehand()
59+
```
60+
61+
Or manually:
62+
3663
```python
37-
import os
3864
from stagehand import Stagehand
3965

4066
client = Stagehand(
41-
browserbase_api_key=os.environ.get(
42-
"BROWSERBASE_API_KEY"
43-
), # This is the default and can be omitted
44-
browserbase_project_id=os.environ.get(
45-
"BROWSERBASE_PROJECT_ID"
46-
), # This is the default and can be omitted
47-
model_api_key=os.environ.get("MODEL_API_KEY"), # This is the default and can be omitted
67+
browserbase_api_key="My Browserbase API Key",
68+
browserbase_project_id="My Browserbase Project ID",
69+
model_api_key="My Model API Key",
4870
)
71+
```
4972

50-
response = client.sessions.act(
51-
id="00000000-your-session-id-000000000000",
52-
input="click the first link on the page",
73+
Or using a combination of the two approaches:
74+
75+
```python
76+
from stagehand import Stagehand
77+
78+
client = Stagehand(
79+
# Configures using environment variables
80+
browserbase_api_key="My Browserbase API Key", # Override just this one
5381
)
54-
print(response.data)
5582
```
5683

57-
While you can provide a `browserbase_api_key` keyword argument,
84+
While you can provide API keys as keyword arguments,
5885
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
5986
to add `BROWSERBASE_API_KEY="My Browserbase API Key"` to your `.env` file
60-
so that your Browserbase API Key is not stored in source control.
87+
so that your API keys are not stored in source control.
6188

6289
## Async usage
6390

examples/full_example.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
"""
2+
Basic example demonstrating the Stagehand Python SDK.
3+
4+
This example shows the full flow of:
5+
1. Starting a browser session
6+
2. Navigating to a webpage
7+
3. Observing to find possible actions
8+
4. Acting on an element
9+
5. Extracting structured data
10+
6. Running an autonomous agent
11+
7. Ending the session
12+
13+
Required environment variables:
14+
- BROWSERBASE_API_KEY: Your Browserbase API key
15+
- BROWSERBASE_PROJECT_ID: Your Browserbase project ID
16+
- MODEL_API_KEY: Your OpenAI API key
17+
"""
18+
19+
import os
20+
21+
from stagehand import Stagehand
22+
23+
24+
def main() -> None:
25+
# SDK version for API compatibility (matches TypeScript SDK v3)
26+
SDK_VERSION = "3.0.6"
27+
28+
# Create client using environment variables
29+
# BROWSERBASE_API_KEY, BROWSERBASE_PROJECT_ID, MODEL_API_KEY
30+
client = Stagehand(
31+
browserbase_api_key=os.environ.get("BROWSERBASE_API_KEY"),
32+
browserbase_project_id=os.environ.get("BROWSERBASE_PROJECT_ID"),
33+
model_api_key=os.environ.get("MODEL_API_KEY"),
34+
)
35+
36+
# Start a new browser session
37+
start_response = client.sessions.start(
38+
model_name="openai/gpt-5-nano",
39+
x_language="typescript",
40+
x_sdk_version=SDK_VERSION,
41+
)
42+
43+
session_id = start_response.data.session_id
44+
print(f"Session started: {session_id}")
45+
46+
try:
47+
# Navigate to Hacker News
48+
client.sessions.navigate(
49+
id=session_id,
50+
url="https://news.ycombinator.com",
51+
frame_id="", # Empty string for main frame
52+
x_language="typescript",
53+
x_sdk_version=SDK_VERSION,
54+
)
55+
print("Navigated to Hacker News")
56+
57+
# Observe to find possible actions - looking for the comments link
58+
observe_response = client.sessions.observe(
59+
id=session_id,
60+
instruction="find the link to view comments for the top post",
61+
x_language="typescript",
62+
x_sdk_version=SDK_VERSION,
63+
)
64+
65+
results = observe_response.data.result
66+
print(f"Found {len(results)} possible actions")
67+
68+
if not results:
69+
print("No actions found")
70+
return
71+
72+
# Use the first result
73+
result = results[0]
74+
print(f"Acting on: {result.description}")
75+
76+
# Pass the action to Act
77+
act_response = client.sessions.act(
78+
id=session_id,
79+
input=result,
80+
x_language="typescript",
81+
x_sdk_version=SDK_VERSION,
82+
)
83+
print(f"Act completed: {act_response.data.result.message}")
84+
85+
# Extract data from the page
86+
# We're now on the comments page, so extract the top comment text
87+
extract_response = client.sessions.extract(
88+
id=session_id,
89+
instruction="extract the text of the top comment on this page",
90+
schema={
91+
"type": "object",
92+
"properties": {
93+
"commentText": {
94+
"type": "string",
95+
"description": "The text content of the top comment"
96+
},
97+
"author": {
98+
"type": "string",
99+
"description": "The username of the comment author"
100+
}
101+
},
102+
"required": ["commentText"]
103+
},
104+
x_language="typescript",
105+
x_sdk_version=SDK_VERSION,
106+
)
107+
108+
# Get the extracted result
109+
extracted_result = extract_response.data.result
110+
print(f"Extracted data: {extracted_result}")
111+
112+
# Get the author from the extracted data
113+
author = extracted_result.get("author", "unknown") if isinstance(extracted_result, dict) else "unknown"
114+
print(f"Looking up profile for author: {author}")
115+
116+
# Use the Agent to find the author's profile
117+
# Execute runs an autonomous agent that can navigate and interact with pages
118+
# Use a longer timeout (5 minutes) since agent execution can take a while
119+
execute_response = client.sessions.execute(
120+
id=session_id,
121+
execute_options={
122+
"instruction": (
123+
f"Find any personal website, GitHub, LinkedIn, or other best profile URL for the Hacker News user '{author}'. "
124+
f"Click on their username to go to their profile page and look for any links they have shared. "
125+
f"Use Google Search with their username or other details from their profile if you dont find any direct links."
126+
),
127+
"max_steps": 15,
128+
},
129+
agent_config={
130+
"model": {
131+
"model_name": "openai/gpt-5-nano",
132+
"api_key": os.environ.get("MODEL_API_KEY"),
133+
},
134+
"cua": False,
135+
},
136+
x_language="typescript",
137+
x_sdk_version=SDK_VERSION,
138+
timeout=300.0, # 5 minutes
139+
)
140+
141+
print(f"Agent completed: {execute_response.data.result.message}")
142+
print(f"Agent success: {execute_response.data.result.success}")
143+
print(f"Agent actions taken: {len(execute_response.data.result.actions)}")
144+
145+
finally:
146+
# End the session to clean up resources
147+
client.sessions.end(
148+
id=session_id,
149+
x_language="typescript",
150+
x_sdk_version=SDK_VERSION,
151+
)
152+
print("Session ended")
153+
154+
155+
if __name__ == "__main__":
156+
main()

0 commit comments

Comments
 (0)