Skip to content

Commit 78727c0

Browse files
feat(api): manual updates
1 parent 5867532 commit 78727c0

35 files changed

+1899
-350
lines changed

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 21
1+
configured_endpoints: 26
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-9ff5409663c58ae9e3ecc9ac764956189e3a70600f5ba1b961bb1dedf0208271.yml
33
openapi_spec_hash: 9865acb75430d9b799502acbae860df0
4-
config_hash: 99e0e445bc20c5723030c315bab52940
4+
config_hash: 9d52be5177b2ede4cb0633c04f4cc4ef

README.md

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,39 @@ pip install browser-use-sdk
2525
The full API of this library can be found in [api.md](api.md).
2626

2727
```python
28+
import os
2829
from browser_use_sdk import BrowserUse
2930

3031
client = BrowserUse(
31-
api_key="My API Key",
32+
api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
3233
)
3334

34-
tasks = client.tasks.list()
35-
print(tasks.items)
35+
me = client.users.me.retrieve()
36+
print(me.additional_credits_balance_usd)
3637
```
3738

39+
While you can provide an `api_key` keyword argument,
40+
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
41+
to add `BROWSER_USE_API_KEY="My API Key"` to your `.env` file
42+
so that your API Key is not stored in source control.
43+
3844
## Async usage
3945

4046
Simply import `AsyncBrowserUse` instead of `BrowserUse` and use `await` with each API call:
4147

4248
```python
49+
import os
4350
import asyncio
4451
from browser_use_sdk import AsyncBrowserUse
4552

4653
client = AsyncBrowserUse(
47-
api_key="My API Key",
54+
api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
4855
)
4956

5057

5158
async def main() -> None:
52-
tasks = await client.tasks.list()
53-
print(tasks.items)
59+
me = await client.users.me.retrieve()
60+
print(me.additional_credits_balance_usd)
5461

5562

5663
asyncio.run(main())
@@ -82,8 +89,8 @@ async def main() -> None:
8289
api_key="My API Key",
8390
http_client=DefaultAioHttpClient(),
8491
) as client:
85-
tasks = await client.tasks.list()
86-
print(tasks.items)
92+
me = await client.users.me.retrieve()
93+
print(me.additional_credits_balance_usd)
8794

8895

8996
asyncio.run(main())
@@ -105,9 +112,7 @@ Nested parameters are dictionaries, typed using `TypedDict`, for example:
105112
```python
106113
from browser_use_sdk import BrowserUse
107114

108-
client = BrowserUse(
109-
api_key="My API Key",
110-
)
115+
client = BrowserUse()
111116

112117
task_view = client.tasks.create(
113118
task="x",
@@ -129,12 +134,10 @@ All errors inherit from `browser_use_sdk.APIError`.
129134
import browser_use_sdk
130135
from browser_use_sdk import BrowserUse
131136

132-
client = BrowserUse(
133-
api_key="My API Key",
134-
)
137+
client = BrowserUse()
135138

136139
try:
137-
client.tasks.list()
140+
client.users.me.retrieve()
138141
except browser_use_sdk.APIConnectionError as e:
139142
print("The server could not be reached")
140143
print(e.__cause__) # an underlying Exception, likely raised within httpx.
@@ -172,13 +175,12 @@ from browser_use_sdk import BrowserUse
172175

173176
# Configure the default for all requests:
174177
client = BrowserUse(
175-
api_key="My API Key",
176178
# default is 2
177179
max_retries=0,
178180
)
179181

180182
# Or, configure per-request:
181-
client.with_options(max_retries=5).tasks.list()
183+
client.with_options(max_retries=5).users.me.retrieve()
182184
```
183185

184186
### Timeouts
@@ -191,19 +193,17 @@ from browser_use_sdk import BrowserUse
191193

192194
# Configure the default for all requests:
193195
client = BrowserUse(
194-
api_key="My API Key",
195196
# 20 seconds (default is 1 minute)
196197
timeout=20.0,
197198
)
198199

199200
# More granular control:
200201
client = BrowserUse(
201-
api_key="My API Key",
202202
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
203203
)
204204

205205
# Override per-request:
206-
client.with_options(timeout=5.0).tasks.list()
206+
client.with_options(timeout=5.0).users.me.retrieve()
207207
```
208208

209209
On timeout, an `APITimeoutError` is thrown.
@@ -243,14 +243,12 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
243243
```py
244244
from browser_use_sdk import BrowserUse
245245

246-
client = BrowserUse(
247-
api_key="My API Key",
248-
)
249-
response = client.tasks.with_raw_response.list()
246+
client = BrowserUse()
247+
response = client.users.me.with_raw_response.retrieve()
250248
print(response.headers.get('X-My-Header'))
251249

252-
task = response.parse() # get the object that `tasks.list()` would have returned
253-
print(task.items)
250+
me = response.parse() # get the object that `users.me.retrieve()` would have returned
251+
print(me.additional_credits_balance_usd)
254252
```
255253

256254
These methods return an [`APIResponse`](https://github.com/browser-use/browser-use-python/tree/main/src/browser_use_sdk/_response.py) object.
@@ -264,7 +262,7 @@ The above interface eagerly reads the full response body when you make the reque
264262
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.
265263

266264
```python
267-
with client.tasks.with_streaming_response.list() as response:
265+
with client.users.me.with_streaming_response.retrieve() as response:
268266
print(response.headers.get("X-My-Header"))
269267

270268
for line in response.iter_lines():
@@ -320,7 +318,6 @@ import httpx
320318
from browser_use_sdk import BrowserUse, DefaultHttpxClient
321319

322320
client = BrowserUse(
323-
api_key="My API Key",
324321
# Or use the `BROWSER_USE_BASE_URL` env var
325322
base_url="http://my.test.server.example.com:8083",
326323
http_client=DefaultHttpxClient(
@@ -343,9 +340,7 @@ By default the library closes underlying HTTP connections whenever the client is
343340
```py
344341
from browser_use_sdk import BrowserUse
345342

346-
with BrowserUse(
347-
api_key="My API Key",
348-
) as client:
343+
with BrowserUse() as client:
349344
# make requests here
350345
...
351346

api.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,45 @@
1+
# Users
2+
3+
## Me
4+
5+
Types:
6+
7+
```python
8+
from browser_use_sdk.types.users import MeRetrieveResponse
9+
```
10+
11+
Methods:
12+
13+
- <code title="get /users/me">client.users.me.<a href="./src/browser_use_sdk/resources/users/me/me.py">retrieve</a>() -> <a href="./src/browser_use_sdk/types/users/me_retrieve_response.py">MeRetrieveResponse</a></code>
14+
15+
### Files
16+
17+
Types:
18+
19+
```python
20+
from browser_use_sdk.types.users.me import FileCreatePresignedURLResponse
21+
```
22+
23+
Methods:
24+
25+
- <code title="post /users/me/files/presigned-url">client.users.me.files.<a href="./src/browser_use_sdk/resources/users/me/files.py">create_presigned_url</a>(\*\*<a href="src/browser_use_sdk/types/users/me/file_create_presigned_url_params.py">params</a>) -> <a href="./src/browser_use_sdk/types/users/me/file_create_presigned_url_response.py">FileCreatePresignedURLResponse</a></code>
26+
127
# Tasks
228

329
Types:
430

531
```python
632
from browser_use_sdk.types import (
33+
FileView,
734
LlmModel,
35+
TaskItemView,
836
TaskStatus,
37+
TaskStepView,
938
TaskView,
1039
TaskListResponse,
11-
TaskRetrieveLogsResponse,
40+
TaskGetLogsResponse,
41+
TaskGetOutputFileResponse,
42+
TaskGetUserUploadedFileResponse,
1243
)
1344
```
1445

@@ -18,7 +49,9 @@ Methods:
1849
- <code title="get /tasks/{task_id}">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">retrieve</a>(task_id) -> <a href="./src/browser_use_sdk/types/task_view.py">TaskView</a></code>
1950
- <code title="patch /tasks/{task_id}">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">update</a>(task_id, \*\*<a href="src/browser_use_sdk/types/task_update_params.py">params</a>) -> <a href="./src/browser_use_sdk/types/task_view.py">TaskView</a></code>
2051
- <code title="get /tasks">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">list</a>(\*\*<a href="src/browser_use_sdk/types/task_list_params.py">params</a>) -> <a href="./src/browser_use_sdk/types/task_list_response.py">TaskListResponse</a></code>
21-
- <code title="get /tasks/{task_id}/logs">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">retrieve_logs</a>(task_id) -> <a href="./src/browser_use_sdk/types/task_retrieve_logs_response.py">TaskRetrieveLogsResponse</a></code>
52+
- <code title="get /tasks/{task_id}/logs">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">get_logs</a>(task_id) -> <a href="./src/browser_use_sdk/types/task_get_logs_response.py">TaskGetLogsResponse</a></code>
53+
- <code title="get /tasks/{task_id}/output-files/{file_id}">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">get_output_file</a>(file_id, \*, task_id) -> <a href="./src/browser_use_sdk/types/task_get_output_file_response.py">TaskGetOutputFileResponse</a></code>
54+
- <code title="get /tasks/{task_id}/user-uploaded-files/{file_id}">client.tasks.<a href="./src/browser_use_sdk/resources/tasks.py">get_user_uploaded_file</a>(file_id, \*, task_id) -> <a href="./src/browser_use_sdk/types/task_get_user_uploaded_file_response.py">TaskGetUserUploadedFileResponse</a></code>
2255

2356
# Sessions
2457

@@ -33,6 +66,7 @@ Methods:
3366
- <code title="get /sessions/{session_id}">client.sessions.<a href="./src/browser_use_sdk/resources/sessions/sessions.py">retrieve</a>(session_id, \*\*<a href="src/browser_use_sdk/types/session_retrieve_params.py">params</a>) -> <a href="./src/browser_use_sdk/types/session_view.py">SessionView</a></code>
3467
- <code title="patch /sessions/{session_id}">client.sessions.<a href="./src/browser_use_sdk/resources/sessions/sessions.py">update</a>(session_id, \*\*<a href="src/browser_use_sdk/types/session_update_params.py">params</a>) -> <a href="./src/browser_use_sdk/types/session_view.py">SessionView</a></code>
3568
- <code title="get /sessions">client.sessions.<a href="./src/browser_use_sdk/resources/sessions/sessions.py">list</a>(\*\*<a href="src/browser_use_sdk/types/session_list_params.py">params</a>) -> <a href="./src/browser_use_sdk/types/session_list_response.py">SessionListResponse</a></code>
69+
- <code title="delete /sessions/{session_id}">client.sessions.<a href="./src/browser_use_sdk/resources/sessions/sessions.py">delete</a>(session_id) -> None</code>
3670

3771
## PublicShare
3872

src/browser_use_sdk/_client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
SyncAPIClient,
3030
AsyncAPIClient,
3131
)
32+
from .resources.users import users
3233
from .resources.sessions import sessions
3334

3435
__all__ = [
@@ -44,6 +45,7 @@
4445

4546

4647
class BrowserUse(SyncAPIClient):
48+
users: users.UsersResource
4749
tasks: tasks.TasksResource
4850
sessions: sessions.SessionsResource
4951
browser_profiles: browser_profiles.BrowserProfilesResource
@@ -105,6 +107,7 @@ def __init__(
105107
_strict_response_validation=_strict_response_validation,
106108
)
107109

110+
self.users = users.UsersResource(self)
108111
self.tasks = tasks.TasksResource(self)
109112
self.sessions = sessions.SessionsResource(self)
110113
self.browser_profiles = browser_profiles.BrowserProfilesResource(self)
@@ -117,6 +120,12 @@ def __init__(
117120
def qs(self) -> Querystring:
118121
return Querystring(array_format="comma")
119122

123+
@property
124+
@override
125+
def auth_headers(self) -> dict[str, str]:
126+
api_key = self.api_key
127+
return {"X-Browser-Use-API-Key": api_key}
128+
120129
@property
121130
@override
122131
def default_headers(self) -> dict[str, str | Omit]:
@@ -212,6 +221,7 @@ def _make_status_error(
212221

213222

214223
class AsyncBrowserUse(AsyncAPIClient):
224+
users: users.AsyncUsersResource
215225
tasks: tasks.AsyncTasksResource
216226
sessions: sessions.AsyncSessionsResource
217227
browser_profiles: browser_profiles.AsyncBrowserProfilesResource
@@ -273,6 +283,7 @@ def __init__(
273283
_strict_response_validation=_strict_response_validation,
274284
)
275285

286+
self.users = users.AsyncUsersResource(self)
276287
self.tasks = tasks.AsyncTasksResource(self)
277288
self.sessions = sessions.AsyncSessionsResource(self)
278289
self.browser_profiles = browser_profiles.AsyncBrowserProfilesResource(self)
@@ -285,6 +296,12 @@ def __init__(
285296
def qs(self) -> Querystring:
286297
return Querystring(array_format="comma")
287298

299+
@property
300+
@override
301+
def auth_headers(self) -> dict[str, str]:
302+
api_key = self.api_key
303+
return {"X-Browser-Use-API-Key": api_key}
304+
288305
@property
289306
@override
290307
def default_headers(self) -> dict[str, str | Omit]:
@@ -381,6 +398,7 @@ def _make_status_error(
381398

382399
class BrowserUseWithRawResponse:
383400
def __init__(self, client: BrowserUse) -> None:
401+
self.users = users.UsersResourceWithRawResponse(client.users)
384402
self.tasks = tasks.TasksResourceWithRawResponse(client.tasks)
385403
self.sessions = sessions.SessionsResourceWithRawResponse(client.sessions)
386404
self.browser_profiles = browser_profiles.BrowserProfilesResourceWithRawResponse(client.browser_profiles)
@@ -389,6 +407,7 @@ def __init__(self, client: BrowserUse) -> None:
389407

390408
class AsyncBrowserUseWithRawResponse:
391409
def __init__(self, client: AsyncBrowserUse) -> None:
410+
self.users = users.AsyncUsersResourceWithRawResponse(client.users)
392411
self.tasks = tasks.AsyncTasksResourceWithRawResponse(client.tasks)
393412
self.sessions = sessions.AsyncSessionsResourceWithRawResponse(client.sessions)
394413
self.browser_profiles = browser_profiles.AsyncBrowserProfilesResourceWithRawResponse(client.browser_profiles)
@@ -397,6 +416,7 @@ def __init__(self, client: AsyncBrowserUse) -> None:
397416

398417
class BrowserUseWithStreamedResponse:
399418
def __init__(self, client: BrowserUse) -> None:
419+
self.users = users.UsersResourceWithStreamingResponse(client.users)
400420
self.tasks = tasks.TasksResourceWithStreamingResponse(client.tasks)
401421
self.sessions = sessions.SessionsResourceWithStreamingResponse(client.sessions)
402422
self.browser_profiles = browser_profiles.BrowserProfilesResourceWithStreamingResponse(client.browser_profiles)
@@ -405,6 +425,7 @@ def __init__(self, client: BrowserUse) -> None:
405425

406426
class AsyncBrowserUseWithStreamedResponse:
407427
def __init__(self, client: AsyncBrowserUse) -> None:
428+
self.users = users.AsyncUsersResourceWithStreamingResponse(client.users)
408429
self.tasks = tasks.AsyncTasksResourceWithStreamingResponse(client.tasks)
409430
self.sessions = sessions.AsyncSessionsResourceWithStreamingResponse(client.sessions)
410431
self.browser_profiles = browser_profiles.AsyncBrowserProfilesResourceWithStreamingResponse(

src/browser_use_sdk/resources/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88
TasksResourceWithStreamingResponse,
99
AsyncTasksResourceWithStreamingResponse,
1010
)
11+
from .users import (
12+
UsersResource,
13+
AsyncUsersResource,
14+
UsersResourceWithRawResponse,
15+
AsyncUsersResourceWithRawResponse,
16+
UsersResourceWithStreamingResponse,
17+
AsyncUsersResourceWithStreamingResponse,
18+
)
1119
from .sessions import (
1220
SessionsResource,
1321
AsyncSessionsResource,
@@ -34,6 +42,12 @@
3442
)
3543

3644
__all__ = [
45+
"UsersResource",
46+
"AsyncUsersResource",
47+
"UsersResourceWithRawResponse",
48+
"AsyncUsersResourceWithRawResponse",
49+
"UsersResourceWithStreamingResponse",
50+
"AsyncUsersResourceWithStreamingResponse",
3751
"TasksResource",
3852
"AsyncTasksResource",
3953
"TasksResourceWithRawResponse",

0 commit comments

Comments
 (0)