|
1 | 1 | <img src="https://raw.githubusercontent.com/browser-use/browser-use-python/refs/heads/main/assets/cloud-banner-python.png" alt="Browser Use Python" width="full"/> |
2 | 2 |
|
3 | | -# BrowserUse Python Library |
| 3 | +## BrowserUse SDK has moved |
4 | 4 |
|
5 | | -[](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fbrowser-use%2Fbrowser-use-python) |
6 | | -[](https://pypi.python.org/pypi/browser-use) |
7 | | - |
8 | | -The BrowserUse Python library provides convenient access to the BrowserUse APIs from Python. |
9 | | - |
10 | | -## Three-Step QuickStart |
11 | | - |
12 | | -1. 📦 Install Browser Use SDK |
13 | | - |
14 | | - ```sh |
15 | | - # PIP |
16 | | - pip install browser-use-sdk |
17 | | - |
18 | | - # Poetry |
19 | | - poetry add browser-use-sdk |
20 | | - |
21 | | - # UV |
22 | | - uv add browser-use-sdk |
23 | | - ``` |
24 | | - |
25 | | -1. 🔑 Get your API Key at [Browser Use Cloud](https://cloud.browser-use.com)! |
26 | | - |
27 | | -1. 🦄 Automate the Internet! |
28 | | - |
29 | | - ```python |
30 | | - from browser_use_sdk import BrowserUse |
31 | | - |
32 | | - client = BrowserUse(api_key="bu_...") |
33 | | - |
34 | | - task = client.tasks.create_task( |
35 | | - task="Search for the top 10 Hacker News posts and return the title and url.", |
36 | | - llm="gpt-4.1" |
37 | | - ) |
38 | | - |
39 | | - result = task.complete() |
40 | | - |
41 | | - result.output |
42 | | - ``` |
43 | | - |
44 | | -> The full API of this library can be found in [api.md](api.md). |
45 | | -
|
46 | | -## Structured Output with Pydantic |
47 | | - |
48 | | -Browser Use Python SDK provides first class support for Pydantic models. |
49 | | - |
50 | | -```py |
51 | | -from browser_use_sdk import AsyncBrowserUse |
52 | | - |
53 | | -client = AsyncBrowserUse(api_key=API_KEY) |
54 | | - |
55 | | -class HackerNewsPost(BaseModel): |
56 | | - title: str |
57 | | - url: str |
58 | | - |
59 | | -class SearchResult(BaseModel): |
60 | | - posts: List[HackerNewsPost] |
61 | | - |
62 | | -async def main() -> None: |
63 | | - task = await client.tasks.create_task( |
64 | | - task=""" |
65 | | - Find top 10 Hacker News articles and return the title and url. |
66 | | - """, |
67 | | - schema=SearchResult, |
68 | | - ) |
69 | | - |
70 | | - result = await task.complete() |
71 | | - |
72 | | - if result.parsed_output is not None: |
73 | | - print("Top HackerNews Posts:") |
74 | | - for post in result.parsed_output.posts: |
75 | | - print(f" - {post.title} - {post.url}") |
76 | | - |
77 | | -asyncio.run(main()) |
78 | | -``` |
79 | | - |
80 | | -## Streaming Updates with Async Iterators |
81 | | - |
82 | | -> When presenting a long running task you might want to show updates as they happen. |
83 | | -
|
84 | | -Browser Use SDK exposes a `.stream` method that lets you subscribe to a sync or an async generator that automatically polls Browser Use Cloud servers and emits a new event when an update happens (e.g., live url becomes available, agent takes a new step, or agent completes the task). |
85 | | - |
86 | | -```py |
87 | | -class HackerNewsPost(BaseModel): |
88 | | - title: str |
89 | | - url: str |
90 | | - |
91 | | -class SearchResult(BaseModel): |
92 | | - posts: List[HackerNewsPost] |
93 | | - |
94 | | - |
95 | | -async def main() -> None: |
96 | | - task = await client.tasks.create_task( |
97 | | - task=""" |
98 | | - Find top 10 Hacker News articles and return the title and url. |
99 | | - """, |
100 | | - schema=SearchResult, |
101 | | - ) |
102 | | - |
103 | | - async for step in task.stream(): |
104 | | - print(f"Step {step.number}: {step.url} ({step.next_goal})") |
105 | | - |
106 | | - result = await task.complete() |
107 | | - |
108 | | - if result.parsed_output is not None: |
109 | | - print("Top HackerNews Posts:") |
110 | | - for post in result.parsed_output.posts: |
111 | | - print(f" - {post.title} - {post.url}") |
112 | | - |
113 | | -asyncio.run(main()) |
114 | | -``` |
115 | | - |
116 | | -## Verifying Webhook Events |
117 | | - |
118 | | -> You can configure Browser Use Cloud to emit Webhook events and process them easily with Browser Use Python SDK. |
119 | | -
|
120 | | -Browser Use SDK lets you easily verify the signature and structure of the payload you receive in the webhook. |
121 | | - |
122 | | -```py |
123 | | -import uvicorn |
124 | | -import os |
125 | | -from browser_use_sdk import Webhook, verify_webhook_event_signature |
126 | | - |
127 | | -from fastapi import FastAPI, Request, HTTPException |
128 | | - |
129 | | -app = FastAPI() |
130 | | - |
131 | | -SECRET_KEY = os.environ['SECRET_KEY'] |
132 | | - |
133 | | -@app.post('/webhook') |
134 | | -async def webhook(request: Request): |
135 | | - body = await request.json() |
136 | | - |
137 | | - timestamp = request.headers.get('X-Browser-Use-Timestamp') |
138 | | - signature = request.headers.get('X-Browser-Use-Signature') |
139 | | - |
140 | | - verified_webhook: Webhook = verify_webhook_event_signature( |
141 | | - body=body, |
142 | | - timestamp=timestamp, |
143 | | - secret=SECRET_KEY, |
144 | | - expected_signature=signature, |
145 | | - ) |
146 | | - |
147 | | - if verified_webhook is not None: |
148 | | - print('Webhook received:', verified_webhook) |
149 | | - else: |
150 | | - print('Invalid webhook received') |
151 | | - |
152 | | - return {'status': 'success', 'message': 'Webhook received'} |
153 | | - |
154 | | -if __name__ == '__main__': |
155 | | - uvicorn.run(app, host='0.0.0.0', port=8080) |
156 | | -``` |
157 | | - |
158 | | -## Async usage |
159 | | - |
160 | | -Simply import `AsyncBrowserUse` instead of `BrowserUse` and use `await` with each API call: |
161 | | - |
162 | | -```python |
163 | | -import os |
164 | | -import asyncio |
165 | | -from browser_use_sdk import AsyncBrowserUse |
166 | | - |
167 | | -client = AsyncBrowserUse( |
168 | | - api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted |
169 | | -) |
170 | | - |
171 | | - |
172 | | -async def main() -> None: |
173 | | - task = await client.tasks.create_task( |
174 | | - task="Search for the top 10 Hacker News posts and return the title and url.", |
175 | | - ) |
176 | | - |
177 | | - print(task.id) |
178 | | - |
179 | | - |
180 | | -asyncio.run(main()) |
181 | | -``` |
182 | | - |
183 | | -## Requirements |
184 | | - |
185 | | -Python 3.8 or higher. |
186 | | - |
187 | | -## Contributing |
188 | | - |
189 | | -While we value open-source contributions to this SDK, this library is generated programmatically. |
190 | | -Additions made directly to this library would have to be moved over to our generation code, |
191 | | -otherwise they would be overwritten upon the next generated release. Feel free to open a PR as |
192 | | -a proof of concept, but know that we will not be able to merge it as-is. We suggest opening |
193 | | -an issue first to discuss with us! |
194 | | - |
195 | | -On the other hand, contributions to the README are always very welcome! |
196 | | - |
197 | | -## Reference |
198 | | - |
199 | | -A full reference for this library is available [here](https://github.com/browser-use/browser-use-python/blob/HEAD/./reference.md). |
| 5 | +The new repository can be found at [browser-use/sdk](https://github.com/browser-use/sdk) |
0 commit comments