This repository was archived by the owner on Oct 22, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathvertex_auth_example.py
More file actions
180 lines (147 loc) · 5.74 KB
/
Copy pathvertex_auth_example.py
File metadata and controls
180 lines (147 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""
Example: use Google Vertex AI model auth with the Stagehand Python SDK.
This runs the same model-backed flow against both:
- server="remote" (hosted Stagehand API + Browserbase browser)
- server="local" (local Stagehand server + local browser)
Required environment variables:
- BROWSERBASE_API_KEY
- GOOGLE_APPLICATION_CREDENTIALS: path to a service account JSON file
OR VERTEX_SERVICE_ACCOUNT_JSON: raw service account JSON
Optional environment variables:
- VERTEX_PROJECT: Google Cloud project ID. Defaults to credentials.project_id.
- VERTEX_LOCATION: Google Cloud location. Defaults to us-central1.
- VERTEX_MODEL: Vertex model name. Defaults to vertex/gemini-2.5-flash.
- STAGEHAND_BOOTSTRAP_MODEL: session start model. Defaults to openai/gpt-4.1-mini.
The service account JSON is read by this script and sent inline as credentials.
Do not pass key file paths to the Stagehand API server.
"""
from __future__ import annotations
import os
import sys
import json
from typing import Any, Literal, cast
from pathlib import Path
from stagehand import Stagehand
from stagehand.types.session_extract_params import (
OptionsModelVertexModelConfigObject as VertexModelConfig,
OptionsModelVertexModelConfigObjectAuthCredentials as VertexCredentials,
)
def load_example_env() -> None:
env_path = Path(__file__).parent / ".env"
if not env_path.exists():
return
for line in env_path.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
os.environ.setdefault(key, value)
def load_vertex_credentials() -> VertexCredentials:
inline_json = os.environ.get("VERTEX_SERVICE_ACCOUNT_JSON")
if inline_json:
credentials = json.loads(inline_json)
else:
credentials_path = os.environ.get("GOOGLE_APPLICATION_CREDENTIALS")
if not credentials_path:
sys.exit(
"Set GOOGLE_APPLICATION_CREDENTIALS to a service account JSON file "
"or VERTEX_SERVICE_ACCOUNT_JSON to raw service account JSON."
)
credentials = json.loads(Path(credentials_path).expanduser().read_text())
if not isinstance(credentials, dict):
sys.exit("Vertex credentials must be a JSON object.")
missing = [
key for key in ("client_email", "private_key") if not credentials.get(key)
]
if missing:
sys.exit("Vertex credentials are missing: " + ", ".join(missing))
return cast(VertexCredentials, credentials)
def build_vertex_model_config() -> VertexModelConfig:
credentials = load_vertex_credentials()
project = os.environ.get("VERTEX_PROJECT") or credentials.get("project_id")
if not project:
sys.exit("Set VERTEX_PROJECT or include project_id in the credentials JSON.")
location = os.environ.get("VERTEX_LOCATION", "us-central1")
model_name = os.environ.get("VERTEX_MODEL", "vertex/gemini-2.5-flash")
return {
"provider": "vertex",
"model_name": model_name,
"auth": {
"type": "googleServiceAccount",
"credentials": credentials,
},
"provider_options": {
"vertex": {
"project": project,
"location": location,
}
},
}
def run_vertex_flow(
server: Literal["remote", "local"], vertex_model: VertexModelConfig
) -> None:
browserbase_api_key = os.environ.get("BROWSERBASE_API_KEY")
if not browserbase_api_key:
sys.exit("Set BROWSERBASE_API_KEY to run this example.")
client_kwargs: dict[str, Any] = {
"server": server,
"browserbase_api_key": browserbase_api_key,
}
browser: dict[str, Any]
if server == "local":
client_kwargs["local_ready_timeout_s"] = 30.0
browser = {
"type": "local",
"launchOptions": {
"headless": True,
},
}
else:
browser = {"type": "browserbase"}
bootstrap_model = os.environ.get("STAGEHAND_BOOTSTRAP_MODEL", "openai/gpt-4.1-mini")
with Stagehand(**client_kwargs) as client:
session = client.sessions.start(
model_name=bootstrap_model,
browser=browser,
)
try:
session.navigate(url="https://example.com")
observe_result = session.observe(
instruction="Find the main heading on the page.",
options={"model": vertex_model},
)
print(f"[{server}] observe:", observe_result)
extract_result = session.extract(
instruction="Extract the page title and main heading.",
schema={
"type": "object",
"properties": {
"title": {"type": "string"},
"heading": {"type": "string"},
},
"required": ["title", "heading"],
"additionalProperties": False,
},
options={"model": vertex_model},
)
print(f"[{server}] extract:", extract_result)
execute_result = session.execute(
agent_config={
"model": vertex_model,
"cua": False,
},
execute_options={
"instruction": "Summarize the current page in one sentence.",
"max_steps": 3,
},
)
print(f"[{server}] execute:", execute_result)
finally:
session.end()
def main() -> None:
load_example_env()
vertex_model = build_vertex_model_config()
run_vertex_flow("remote", vertex_model)
run_vertex_flow("local", vertex_model)
if __name__ == "__main__":
main()