From 44309e8db95f13f034319924d9cca74b8da054c0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 9 Aug 2025 20:38:29 +0000
Subject: [PATCH 01/10] codegen metadata
---
.stats.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.stats.yml b/.stats.yml
index 27116f1..c28d532 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-86040fd18419e7b4e0947660d9c0ff1abe21550528d2d2a549736cd16f85a92d.yml
openapi_spec_hash: 7c5de9d0f633db35fd9e250fcc834d1f
-config_hash: 771e55285d36ab0c796ac0f29840fa8f
+config_hash: 99e0e445bc20c5723030c315bab52940
From b283386b805435a87114e807f8919185cb6a5b7b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 9 Aug 2025 20:24:56 +0000
Subject: [PATCH 02/10] feat(api): update via SDK Studio
---
CONTRIBUTING.md | 2 +-
README.md | 44 +++++++--------
api.md | 54 +++++++++----------
mypy.ini | 2 +-
pyproject.toml | 8 +--
release-please-config.json | 2 +-
scripts/lint | 2 +-
.../__init__.py | 4 +-
.../_base_client.py | 2 +-
.../_client.py | 0
.../_compat.py | 0
.../_constants.py | 0
.../_exceptions.py | 0
.../_files.py | 0
.../_models.py | 0
src/{browser_use => browser_use_sdk}/_qs.py | 0
.../_resource.py | 0
.../_response.py | 8 +--
.../_streaming.py | 0
.../_types.py | 2 +-
.../_utils/__init__.py | 0
.../_utils/_logs.py | 4 +-
.../_utils/_proxy.py | 0
.../_utils/_reflection.py | 0
.../_utils/_resources_proxy.py | 8 +--
.../_utils/_streams.py | 0
.../_utils/_sync.py | 0
.../_utils/_transform.py | 0
.../_utils/_typing.py | 0
.../_utils/_utils.py | 0
.../_version.py | 2 +-
src/browser_use_sdk/lib/.keep | 4 ++
src/{browser_use => browser_use_sdk}/py.typed | 0
.../resources/__init__.py | 0
.../resources/agent_profiles.py | 0
.../resources/browser_profiles.py | 0
.../resources/sessions/__init__.py | 0
.../resources/sessions/public_share.py | 0
.../resources/sessions/sessions.py | 0
.../resources/tasks.py | 0
.../types/__init__.py | 0
.../types/agent_profile_create_params.py | 0
.../types/agent_profile_list_params.py | 0
.../types/agent_profile_list_response.py | 0
.../types/agent_profile_update_params.py | 0
.../types/agent_profile_view.py | 0
.../types/browser_profile_create_params.py | 0
.../types/browser_profile_list_params.py | 0
.../types/browser_profile_list_response.py | 0
.../types/browser_profile_update_params.py | 0
.../types/browser_profile_view.py | 0
.../types/llm_model.py | 0
.../types/proxy_country_code.py | 0
.../types/session_list_params.py | 0
.../types/session_list_response.py | 0
.../types/session_retrieve_params.py | 0
.../types/session_status.py | 0
.../types/session_update_params.py | 0
.../types/session_view.py | 0
.../types/sessions/__init__.py | 0
.../types/sessions/share_view.py | 0
.../types/task_create_params.py | 0
.../types/task_list_params.py | 0
.../types/task_list_response.py | 0
.../types/task_retrieve_logs_response.py | 0
.../task_retrieve_output_file_response.py | 0
.../types/task_retrieve_params.py | 0
.../types/task_retrieve_response.py | 0
.../types/task_status.py | 0
.../types/task_update_params.py | 0
.../types/task_view.py | 0
.../sessions/test_public_share.py | 4 +-
tests/api_resources/test_agent_profiles.py | 4 +-
tests/api_resources/test_browser_profiles.py | 4 +-
tests/api_resources/test_sessions.py | 4 +-
tests/api_resources/test_tasks.py | 4 +-
tests/conftest.py | 6 +--
tests/test_client.py | 46 ++++++++--------
tests/test_deepcopy.py | 2 +-
tests/test_extract_files.py | 4 +-
tests/test_files.py | 2 +-
tests/test_models.py | 6 +--
tests/test_qs.py | 2 +-
tests/test_required_args.py | 2 +-
tests/test_response.py | 14 ++---
tests/test_streaming.py | 4 +-
tests/test_transform.py | 8 +--
tests/test_utils/test_proxy.py | 2 +-
tests/test_utils/test_typing.py | 2 +-
tests/utils.py | 8 +--
90 files changed, 140 insertions(+), 136 deletions(-)
rename src/{browser_use => browser_use_sdk}/__init__.py (94%)
rename src/{browser_use => browser_use_sdk}/_base_client.py (99%)
rename src/{browser_use => browser_use_sdk}/_client.py (100%)
rename src/{browser_use => browser_use_sdk}/_compat.py (100%)
rename src/{browser_use => browser_use_sdk}/_constants.py (100%)
rename src/{browser_use => browser_use_sdk}/_exceptions.py (100%)
rename src/{browser_use => browser_use_sdk}/_files.py (100%)
rename src/{browser_use => browser_use_sdk}/_models.py (100%)
rename src/{browser_use => browser_use_sdk}/_qs.py (100%)
rename src/{browser_use => browser_use_sdk}/_resource.py (100%)
rename src/{browser_use => browser_use_sdk}/_response.py (99%)
rename src/{browser_use => browser_use_sdk}/_streaming.py (100%)
rename src/{browser_use => browser_use_sdk}/_types.py (99%)
rename src/{browser_use => browser_use_sdk}/_utils/__init__.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_logs.py (75%)
rename src/{browser_use => browser_use_sdk}/_utils/_proxy.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_reflection.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_resources_proxy.py (50%)
rename src/{browser_use => browser_use_sdk}/_utils/_streams.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_sync.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_transform.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_typing.py (100%)
rename src/{browser_use => browser_use_sdk}/_utils/_utils.py (100%)
rename src/{browser_use => browser_use_sdk}/_version.py (82%)
create mode 100644 src/browser_use_sdk/lib/.keep
rename src/{browser_use => browser_use_sdk}/py.typed (100%)
rename src/{browser_use => browser_use_sdk}/resources/__init__.py (100%)
rename src/{browser_use => browser_use_sdk}/resources/agent_profiles.py (100%)
rename src/{browser_use => browser_use_sdk}/resources/browser_profiles.py (100%)
rename src/{browser_use => browser_use_sdk}/resources/sessions/__init__.py (100%)
rename src/{browser_use => browser_use_sdk}/resources/sessions/public_share.py (100%)
rename src/{browser_use => browser_use_sdk}/resources/sessions/sessions.py (100%)
rename src/{browser_use => browser_use_sdk}/resources/tasks.py (100%)
rename src/{browser_use => browser_use_sdk}/types/__init__.py (100%)
rename src/{browser_use => browser_use_sdk}/types/agent_profile_create_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/agent_profile_list_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/agent_profile_list_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/agent_profile_update_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/agent_profile_view.py (100%)
rename src/{browser_use => browser_use_sdk}/types/browser_profile_create_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/browser_profile_list_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/browser_profile_list_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/browser_profile_update_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/browser_profile_view.py (100%)
rename src/{browser_use => browser_use_sdk}/types/llm_model.py (100%)
rename src/{browser_use => browser_use_sdk}/types/proxy_country_code.py (100%)
rename src/{browser_use => browser_use_sdk}/types/session_list_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/session_list_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/session_retrieve_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/session_status.py (100%)
rename src/{browser_use => browser_use_sdk}/types/session_update_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/session_view.py (100%)
rename src/{browser_use => browser_use_sdk}/types/sessions/__init__.py (100%)
rename src/{browser_use => browser_use_sdk}/types/sessions/share_view.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_create_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_list_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_list_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_retrieve_logs_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_retrieve_output_file_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_retrieve_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_retrieve_response.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_status.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_update_params.py (100%)
rename src/{browser_use => browser_use_sdk}/types/task_view.py (100%)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 673519a..5338abc 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -36,7 +36,7 @@ $ pip install -r requirements-dev.lock
Most of the SDK is generated code. Modifications to code will be persisted between generations, but may
result in merge conflicts between manual patches and changes from the generator. The generator will never
-modify the contents of the `src/browser_use/lib/` and `examples/` directories.
+modify the contents of the `src/browser_use_sdk/lib/` and `examples/` directories.
## Adding and running examples
diff --git a/README.md b/README.md
index 2d5cae8..ffe6e1e 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ The full API of this library can be found in [api.md](api.md).
```python
import os
-from browser_use import BrowserUse
+from browser_use_sdk import BrowserUse
client = BrowserUse(
api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
@@ -48,7 +48,7 @@ Simply import `AsyncBrowserUse` instead of `BrowserUse` and use `await` with eac
```python
import os
import asyncio
-from browser_use import AsyncBrowserUse
+from browser_use_sdk import AsyncBrowserUse
client = AsyncBrowserUse(
api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
@@ -80,8 +80,8 @@ Then you can enable it by instantiating the client with `http_client=DefaultAioH
```python
import asyncio
-from browser_use import DefaultAioHttpClient
-from browser_use import AsyncBrowserUse
+from browser_use_sdk import DefaultAioHttpClient
+from browser_use_sdk import AsyncBrowserUse
async def main() -> None:
@@ -110,7 +110,7 @@ Typed requests and responses provide autocomplete and documentation within your
Nested parameters are dictionaries, typed using `TypedDict`, for example:
```python
-from browser_use import BrowserUse
+from browser_use_sdk import BrowserUse
client = BrowserUse()
@@ -123,27 +123,27 @@ print(task_view.agent_settings)
## Handling errors
-When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `browser_use.APIConnectionError` is raised.
+When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `browser_use_sdk.APIConnectionError` is raised.
When the API returns a non-success status code (that is, 4xx or 5xx
-response), a subclass of `browser_use.APIStatusError` is raised, containing `status_code` and `response` properties.
+response), a subclass of `browser_use_sdk.APIStatusError` is raised, containing `status_code` and `response` properties.
-All errors inherit from `browser_use.APIError`.
+All errors inherit from `browser_use_sdk.APIError`.
```python
-import browser_use
-from browser_use import BrowserUse
+import browser_use_sdk
+from browser_use_sdk import BrowserUse
client = BrowserUse()
try:
client.tasks.list()
-except browser_use.APIConnectionError as e:
+except browser_use_sdk.APIConnectionError as e:
print("The server could not be reached")
print(e.__cause__) # an underlying Exception, likely raised within httpx.
-except browser_use.RateLimitError as e:
+except browser_use_sdk.RateLimitError as e:
print("A 429 status code was received; we should back off a bit.")
-except browser_use.APIStatusError as e:
+except browser_use_sdk.APIStatusError as e:
print("Another non-200-range status code was received")
print(e.status_code)
print(e.response)
@@ -171,7 +171,7 @@ Connection errors (for example, due to a network connectivity problem), 408 Requ
You can use the `max_retries` option to configure or disable retry settings:
```python
-from browser_use import BrowserUse
+from browser_use_sdk import BrowserUse
# Configure the default for all requests:
client = BrowserUse(
@@ -189,7 +189,7 @@ By default requests time out after 1 minute. You can configure this with a `time
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
```python
-from browser_use import BrowserUse
+from browser_use_sdk import BrowserUse
# Configure the default for all requests:
client = BrowserUse(
@@ -241,7 +241,7 @@ if response.my_field is None:
The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,
```py
-from browser_use import BrowserUse
+from browser_use_sdk import BrowserUse
client = BrowserUse()
response = client.tasks.with_raw_response.list()
@@ -251,9 +251,9 @@ task = response.parse() # get the object that `tasks.list()` would have returne
print(task.items)
```
-These methods return an [`APIResponse`](https://github.com/browser-use/browser-use-python/tree/main/src/browser_use/_response.py) object.
+These methods return an [`APIResponse`](https://github.com/browser-use/browser-use-python/tree/main/src/browser_use_sdk/_response.py) object.
-The async client returns an [`AsyncAPIResponse`](https://github.com/browser-use/browser-use-python/tree/main/src/browser_use/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.
+The async client returns an [`AsyncAPIResponse`](https://github.com/browser-use/browser-use-python/tree/main/src/browser_use_sdk/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.
#### `.with_streaming_response`
@@ -315,7 +315,7 @@ You can directly override the [httpx client](https://www.python-httpx.org/api/#c
```python
import httpx
-from browser_use import BrowserUse, DefaultHttpxClient
+from browser_use_sdk import BrowserUse, DefaultHttpxClient
client = BrowserUse(
# Or use the `BROWSER_USE_BASE_URL` env var
@@ -338,7 +338,7 @@ client.with_options(http_client=DefaultHttpxClient(...))
By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.
```py
-from browser_use import BrowserUse
+from browser_use_sdk import BrowserUse
with BrowserUse() as client:
# make requests here
@@ -366,8 +366,8 @@ If you've upgraded to the latest version but aren't seeing any new features you
You can determine the version that is being used at runtime with:
```py
-import browser_use
-print(browser_use.__version__)
+import browser_use_sdk
+print(browser_use_sdk.__version__)
```
## Requirements
diff --git a/api.md b/api.md
index 44030a3..e0e24fd 100644
--- a/api.md
+++ b/api.md
@@ -3,7 +3,7 @@
Types:
```python
-from browser_use.types import (
+from browser_use_sdk.types import (
LlmModel,
TaskStatus,
TaskView,
@@ -16,69 +16,69 @@ from browser_use.types import (
Methods:
-- client.tasks.create(\*\*params) -> TaskView
-- client.tasks.retrieve(task_id, \*\*params) -> TaskRetrieveResponse
-- client.tasks.update(task_id, \*\*params) -> TaskView
-- client.tasks.list(\*\*params) -> TaskListResponse
-- client.tasks.retrieve_logs(task_id) -> TaskRetrieveLogsResponse
-- client.tasks.retrieve_output_file(file_name, \*, task_id) -> TaskRetrieveOutputFileResponse
+- client.tasks.create(\*\*params) -> TaskView
+- client.tasks.retrieve(task_id, \*\*params) -> TaskRetrieveResponse
+- client.tasks.update(task_id, \*\*params) -> TaskView
+- client.tasks.list(\*\*params) -> TaskListResponse
+- client.tasks.retrieve_logs(task_id) -> TaskRetrieveLogsResponse
+- client.tasks.retrieve_output_file(file_name, \*, task_id) -> TaskRetrieveOutputFileResponse
# Sessions
Types:
```python
-from browser_use.types import SessionStatus, SessionView, SessionListResponse
+from browser_use_sdk.types import SessionStatus, SessionView, SessionListResponse
```
Methods:
-- client.sessions.retrieve(session_id, \*\*params) -> SessionView
-- client.sessions.update(session_id, \*\*params) -> SessionView
-- client.sessions.list(\*\*params) -> SessionListResponse
+- client.sessions.retrieve(session_id, \*\*params) -> SessionView
+- client.sessions.update(session_id, \*\*params) -> SessionView
+- client.sessions.list(\*\*params) -> SessionListResponse
## PublicShare
Types:
```python
-from browser_use.types.sessions import ShareView
+from browser_use_sdk.types.sessions import ShareView
```
Methods:
-- client.sessions.public_share.create(session_id) -> ShareView
-- client.sessions.public_share.retrieve(session_id) -> ShareView
-- client.sessions.public_share.delete(session_id) -> object
+- client.sessions.public_share.create(session_id) -> ShareView
+- client.sessions.public_share.retrieve(session_id) -> ShareView
+- client.sessions.public_share.delete(session_id) -> object
# BrowserProfiles
Types:
```python
-from browser_use.types import BrowserProfileView, ProxyCountryCode, BrowserProfileListResponse
+from browser_use_sdk.types import BrowserProfileView, ProxyCountryCode, BrowserProfileListResponse
```
Methods:
-- client.browser_profiles.create(\*\*params) -> BrowserProfileView
-- client.browser_profiles.retrieve(profile_id) -> BrowserProfileView
-- client.browser_profiles.update(profile_id, \*\*params) -> BrowserProfileView
-- client.browser_profiles.list(\*\*params) -> BrowserProfileListResponse
-- client.browser_profiles.delete(profile_id) -> object
+- client.browser_profiles.create(\*\*params) -> BrowserProfileView
+- client.browser_profiles.retrieve(profile_id) -> BrowserProfileView
+- client.browser_profiles.update(profile_id, \*\*params) -> BrowserProfileView
+- client.browser_profiles.list(\*\*params) -> BrowserProfileListResponse
+- client.browser_profiles.delete(profile_id) -> object
# AgentProfiles
Types:
```python
-from browser_use.types import AgentProfileView, AgentProfileListResponse
+from browser_use_sdk.types import AgentProfileView, AgentProfileListResponse
```
Methods:
-- client.agent_profiles.create(\*\*params) -> AgentProfileView
-- client.agent_profiles.retrieve(profile_id) -> AgentProfileView
-- client.agent_profiles.update(profile_id, \*\*params) -> AgentProfileView
-- client.agent_profiles.list(\*\*params) -> AgentProfileListResponse
-- client.agent_profiles.delete(profile_id) -> object
+- client.agent_profiles.create(\*\*params) -> AgentProfileView
+- client.agent_profiles.retrieve(profile_id) -> AgentProfileView
+- client.agent_profiles.update(profile_id, \*\*params) -> AgentProfileView
+- client.agent_profiles.list(\*\*params) -> AgentProfileListResponse
+- client.agent_profiles.delete(profile_id) -> object
diff --git a/mypy.ini b/mypy.ini
index a4a2b13..d128e00 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -8,7 +8,7 @@ show_error_codes = True
#
# We also exclude our `tests` as mypy doesn't always infer
# types correctly and Pyright will still catch any type errors.
-exclude = ^(src/browser_use/_files\.py|_dev/.*\.py|tests/.*)$
+exclude = ^(src/browser_use_sdk/_files\.py|_dev/.*\.py|tests/.*)$
strict_equality = True
implicit_reexport = True
diff --git a/pyproject.toml b/pyproject.toml
index a690c81..c1a1a97 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -79,14 +79,14 @@ format = { chain = [
"check:ruff" = "ruff check ."
"fix:ruff" = "ruff check --fix ."
-"check:importable" = "python -c 'import browser_use'"
+"check:importable" = "python -c 'import browser_use_sdk'"
typecheck = { chain = [
"typecheck:pyright",
"typecheck:mypy"
]}
"typecheck:pyright" = "pyright"
-"typecheck:verify-types" = "pyright --verifytypes browser_use --ignoreexternal"
+"typecheck:verify-types" = "pyright --verifytypes browser_use_sdk --ignoreexternal"
"typecheck:mypy" = "mypy ."
[build-system]
@@ -99,7 +99,7 @@ include = [
]
[tool.hatch.build.targets.wheel]
-packages = ["src/browser_use"]
+packages = ["src/browser_use_sdk"]
[tool.hatch.build.targets.sdist]
# Basically everything except hidden files/directories (such as .github, .devcontainers, .python-version, etc)
@@ -202,7 +202,7 @@ length-sort = true
length-sort-straight = true
combine-as-imports = true
extra-standard-library = ["typing_extensions"]
-known-first-party = ["browser_use", "tests"]
+known-first-party = ["browser_use_sdk", "tests"]
[tool.ruff.lint.per-file-ignores]
"bin/**.py" = ["T201", "T203"]
diff --git a/release-please-config.json b/release-please-config.json
index 7fdd77c..1225639 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -61,6 +61,6 @@
],
"release-type": "python",
"extra-files": [
- "src/browser_use/_version.py"
+ "src/browser_use_sdk/_version.py"
]
}
\ No newline at end of file
diff --git a/scripts/lint b/scripts/lint
index dbaef9a..3094ad3 100755
--- a/scripts/lint
+++ b/scripts/lint
@@ -8,4 +8,4 @@ echo "==> Running lints"
rye run lint
echo "==> Making sure it imports"
-rye run python -c 'import browser_use'
+rye run python -c 'import browser_use_sdk'
diff --git a/src/browser_use/__init__.py b/src/browser_use_sdk/__init__.py
similarity index 94%
rename from src/browser_use/__init__.py
rename to src/browser_use_sdk/__init__.py
index be0c71c..235c0b0 100644
--- a/src/browser_use/__init__.py
+++ b/src/browser_use_sdk/__init__.py
@@ -89,12 +89,12 @@
# Update the __module__ attribute for exported symbols so that
# error messages point to this module instead of the module
# it was originally defined in, e.g.
-# browser_use._exceptions.NotFoundError -> browser_use.NotFoundError
+# browser_use_sdk._exceptions.NotFoundError -> browser_use_sdk.NotFoundError
__locals = locals()
for __name in __all__:
if not __name.startswith("__"):
try:
- __locals[__name].__module__ = "browser_use"
+ __locals[__name].__module__ = "browser_use_sdk"
except (TypeError, AttributeError):
# Some of our exported symbols are builtins which we can't set attributes for.
pass
diff --git a/src/browser_use/_base_client.py b/src/browser_use_sdk/_base_client.py
similarity index 99%
rename from src/browser_use/_base_client.py
rename to src/browser_use_sdk/_base_client.py
index 0c7b43b..f182716 100644
--- a/src/browser_use/_base_client.py
+++ b/src/browser_use_sdk/_base_client.py
@@ -389,7 +389,7 @@ def __init__(
if max_retries is None: # pyright: ignore[reportUnnecessaryComparison]
raise TypeError(
- "max_retries cannot be None. If you want to disable retries, pass `0`; if you want unlimited retries, pass `math.inf` or a very high number; if you want the default behavior, pass `browser_use.DEFAULT_MAX_RETRIES`"
+ "max_retries cannot be None. If you want to disable retries, pass `0`; if you want unlimited retries, pass `math.inf` or a very high number; if you want the default behavior, pass `browser_use_sdk.DEFAULT_MAX_RETRIES`"
)
def _enforce_trailing_slash(self, url: URL) -> URL:
diff --git a/src/browser_use/_client.py b/src/browser_use_sdk/_client.py
similarity index 100%
rename from src/browser_use/_client.py
rename to src/browser_use_sdk/_client.py
diff --git a/src/browser_use/_compat.py b/src/browser_use_sdk/_compat.py
similarity index 100%
rename from src/browser_use/_compat.py
rename to src/browser_use_sdk/_compat.py
diff --git a/src/browser_use/_constants.py b/src/browser_use_sdk/_constants.py
similarity index 100%
rename from src/browser_use/_constants.py
rename to src/browser_use_sdk/_constants.py
diff --git a/src/browser_use/_exceptions.py b/src/browser_use_sdk/_exceptions.py
similarity index 100%
rename from src/browser_use/_exceptions.py
rename to src/browser_use_sdk/_exceptions.py
diff --git a/src/browser_use/_files.py b/src/browser_use_sdk/_files.py
similarity index 100%
rename from src/browser_use/_files.py
rename to src/browser_use_sdk/_files.py
diff --git a/src/browser_use/_models.py b/src/browser_use_sdk/_models.py
similarity index 100%
rename from src/browser_use/_models.py
rename to src/browser_use_sdk/_models.py
diff --git a/src/browser_use/_qs.py b/src/browser_use_sdk/_qs.py
similarity index 100%
rename from src/browser_use/_qs.py
rename to src/browser_use_sdk/_qs.py
diff --git a/src/browser_use/_resource.py b/src/browser_use_sdk/_resource.py
similarity index 100%
rename from src/browser_use/_resource.py
rename to src/browser_use_sdk/_resource.py
diff --git a/src/browser_use/_response.py b/src/browser_use_sdk/_response.py
similarity index 99%
rename from src/browser_use/_response.py
rename to src/browser_use_sdk/_response.py
index 183a4c8..28a84a0 100644
--- a/src/browser_use/_response.py
+++ b/src/browser_use_sdk/_response.py
@@ -218,7 +218,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
and issubclass(origin, pydantic.BaseModel)
):
raise TypeError(
- "Pydantic models must subclass our base model type, e.g. `from browser_use import BaseModel`"
+ "Pydantic models must subclass our base model type, e.g. `from browser_use_sdk import BaseModel`"
)
if (
@@ -285,7 +285,7 @@ def parse(self, *, to: type[_T] | None = None) -> R | _T:
the `to` argument, e.g.
```py
- from browser_use import BaseModel
+ from browser_use_sdk import BaseModel
class MyModel(BaseModel):
@@ -387,7 +387,7 @@ async def parse(self, *, to: type[_T] | None = None) -> R | _T:
the `to` argument, e.g.
```py
- from browser_use import BaseModel
+ from browser_use_sdk import BaseModel
class MyModel(BaseModel):
@@ -558,7 +558,7 @@ async def stream_to_file(
class MissingStreamClassError(TypeError):
def __init__(self) -> None:
super().__init__(
- "The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `browser_use._streaming` for reference",
+ "The `stream` argument was set to `True` but the `stream_cls` argument was not given. See `browser_use_sdk._streaming` for reference",
)
diff --git a/src/browser_use/_streaming.py b/src/browser_use_sdk/_streaming.py
similarity index 100%
rename from src/browser_use/_streaming.py
rename to src/browser_use_sdk/_streaming.py
diff --git a/src/browser_use/_types.py b/src/browser_use_sdk/_types.py
similarity index 99%
rename from src/browser_use/_types.py
rename to src/browser_use_sdk/_types.py
index 8d1aae8..450c5bb 100644
--- a/src/browser_use/_types.py
+++ b/src/browser_use_sdk/_types.py
@@ -81,7 +81,7 @@
# This unfortunately means that you will either have
# to import this type and pass it explicitly:
#
-# from browser_use import NoneType
+# from browser_use_sdk import NoneType
# client.get('/foo', cast_to=NoneType)
#
# or build it yourself:
diff --git a/src/browser_use/_utils/__init__.py b/src/browser_use_sdk/_utils/__init__.py
similarity index 100%
rename from src/browser_use/_utils/__init__.py
rename to src/browser_use_sdk/_utils/__init__.py
diff --git a/src/browser_use/_utils/_logs.py b/src/browser_use_sdk/_utils/_logs.py
similarity index 75%
rename from src/browser_use/_utils/_logs.py
rename to src/browser_use_sdk/_utils/_logs.py
index f37e60c..8398493 100644
--- a/src/browser_use/_utils/_logs.py
+++ b/src/browser_use_sdk/_utils/_logs.py
@@ -1,12 +1,12 @@
import os
import logging
-logger: logging.Logger = logging.getLogger("browser_use")
+logger: logging.Logger = logging.getLogger("browser_use_sdk")
httpx_logger: logging.Logger = logging.getLogger("httpx")
def _basic_config() -> None:
- # e.g. [2023-10-05 14:12:26 - browser_use._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK"
+ # e.g. [2023-10-05 14:12:26 - browser_use_sdk._base_client:818 - DEBUG] HTTP Request: POST http://127.0.0.1:4010/foo/bar "200 OK"
logging.basicConfig(
format="[%(asctime)s - %(name)s:%(lineno)d - %(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
diff --git a/src/browser_use/_utils/_proxy.py b/src/browser_use_sdk/_utils/_proxy.py
similarity index 100%
rename from src/browser_use/_utils/_proxy.py
rename to src/browser_use_sdk/_utils/_proxy.py
diff --git a/src/browser_use/_utils/_reflection.py b/src/browser_use_sdk/_utils/_reflection.py
similarity index 100%
rename from src/browser_use/_utils/_reflection.py
rename to src/browser_use_sdk/_utils/_reflection.py
diff --git a/src/browser_use/_utils/_resources_proxy.py b/src/browser_use_sdk/_utils/_resources_proxy.py
similarity index 50%
rename from src/browser_use/_utils/_resources_proxy.py
rename to src/browser_use_sdk/_utils/_resources_proxy.py
index 6618037..9451692 100644
--- a/src/browser_use/_utils/_resources_proxy.py
+++ b/src/browser_use_sdk/_utils/_resources_proxy.py
@@ -7,17 +7,17 @@
class ResourcesProxy(LazyProxy[Any]):
- """A proxy for the `browser_use.resources` module.
+ """A proxy for the `browser_use_sdk.resources` module.
- This is used so that we can lazily import `browser_use.resources` only when
- needed *and* so that users can just import `browser_use` and reference `browser_use.resources`
+ This is used so that we can lazily import `browser_use_sdk.resources` only when
+ needed *and* so that users can just import `browser_use_sdk` and reference `browser_use_sdk.resources`
"""
@override
def __load__(self) -> Any:
import importlib
- mod = importlib.import_module("browser_use.resources")
+ mod = importlib.import_module("browser_use_sdk.resources")
return mod
diff --git a/src/browser_use/_utils/_streams.py b/src/browser_use_sdk/_utils/_streams.py
similarity index 100%
rename from src/browser_use/_utils/_streams.py
rename to src/browser_use_sdk/_utils/_streams.py
diff --git a/src/browser_use/_utils/_sync.py b/src/browser_use_sdk/_utils/_sync.py
similarity index 100%
rename from src/browser_use/_utils/_sync.py
rename to src/browser_use_sdk/_utils/_sync.py
diff --git a/src/browser_use/_utils/_transform.py b/src/browser_use_sdk/_utils/_transform.py
similarity index 100%
rename from src/browser_use/_utils/_transform.py
rename to src/browser_use_sdk/_utils/_transform.py
diff --git a/src/browser_use/_utils/_typing.py b/src/browser_use_sdk/_utils/_typing.py
similarity index 100%
rename from src/browser_use/_utils/_typing.py
rename to src/browser_use_sdk/_utils/_typing.py
diff --git a/src/browser_use/_utils/_utils.py b/src/browser_use_sdk/_utils/_utils.py
similarity index 100%
rename from src/browser_use/_utils/_utils.py
rename to src/browser_use_sdk/_utils/_utils.py
diff --git a/src/browser_use/_version.py b/src/browser_use_sdk/_version.py
similarity index 82%
rename from src/browser_use/_version.py
rename to src/browser_use_sdk/_version.py
index 6533e52..695f607 100644
--- a/src/browser_use/_version.py
+++ b/src/browser_use_sdk/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-__title__ = "browser_use"
+__title__ = "browser_use_sdk"
__version__ = "0.0.2" # x-release-please-version
diff --git a/src/browser_use_sdk/lib/.keep b/src/browser_use_sdk/lib/.keep
new file mode 100644
index 0000000..5e2c99f
--- /dev/null
+++ b/src/browser_use_sdk/lib/.keep
@@ -0,0 +1,4 @@
+File generated from our OpenAPI spec by Stainless.
+
+This directory can be used to store custom files to expand the SDK.
+It is ignored by Stainless code generation and its content (other than this keep file) won't be touched.
\ No newline at end of file
diff --git a/src/browser_use/py.typed b/src/browser_use_sdk/py.typed
similarity index 100%
rename from src/browser_use/py.typed
rename to src/browser_use_sdk/py.typed
diff --git a/src/browser_use/resources/__init__.py b/src/browser_use_sdk/resources/__init__.py
similarity index 100%
rename from src/browser_use/resources/__init__.py
rename to src/browser_use_sdk/resources/__init__.py
diff --git a/src/browser_use/resources/agent_profiles.py b/src/browser_use_sdk/resources/agent_profiles.py
similarity index 100%
rename from src/browser_use/resources/agent_profiles.py
rename to src/browser_use_sdk/resources/agent_profiles.py
diff --git a/src/browser_use/resources/browser_profiles.py b/src/browser_use_sdk/resources/browser_profiles.py
similarity index 100%
rename from src/browser_use/resources/browser_profiles.py
rename to src/browser_use_sdk/resources/browser_profiles.py
diff --git a/src/browser_use/resources/sessions/__init__.py b/src/browser_use_sdk/resources/sessions/__init__.py
similarity index 100%
rename from src/browser_use/resources/sessions/__init__.py
rename to src/browser_use_sdk/resources/sessions/__init__.py
diff --git a/src/browser_use/resources/sessions/public_share.py b/src/browser_use_sdk/resources/sessions/public_share.py
similarity index 100%
rename from src/browser_use/resources/sessions/public_share.py
rename to src/browser_use_sdk/resources/sessions/public_share.py
diff --git a/src/browser_use/resources/sessions/sessions.py b/src/browser_use_sdk/resources/sessions/sessions.py
similarity index 100%
rename from src/browser_use/resources/sessions/sessions.py
rename to src/browser_use_sdk/resources/sessions/sessions.py
diff --git a/src/browser_use/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
similarity index 100%
rename from src/browser_use/resources/tasks.py
rename to src/browser_use_sdk/resources/tasks.py
diff --git a/src/browser_use/types/__init__.py b/src/browser_use_sdk/types/__init__.py
similarity index 100%
rename from src/browser_use/types/__init__.py
rename to src/browser_use_sdk/types/__init__.py
diff --git a/src/browser_use/types/agent_profile_create_params.py b/src/browser_use_sdk/types/agent_profile_create_params.py
similarity index 100%
rename from src/browser_use/types/agent_profile_create_params.py
rename to src/browser_use_sdk/types/agent_profile_create_params.py
diff --git a/src/browser_use/types/agent_profile_list_params.py b/src/browser_use_sdk/types/agent_profile_list_params.py
similarity index 100%
rename from src/browser_use/types/agent_profile_list_params.py
rename to src/browser_use_sdk/types/agent_profile_list_params.py
diff --git a/src/browser_use/types/agent_profile_list_response.py b/src/browser_use_sdk/types/agent_profile_list_response.py
similarity index 100%
rename from src/browser_use/types/agent_profile_list_response.py
rename to src/browser_use_sdk/types/agent_profile_list_response.py
diff --git a/src/browser_use/types/agent_profile_update_params.py b/src/browser_use_sdk/types/agent_profile_update_params.py
similarity index 100%
rename from src/browser_use/types/agent_profile_update_params.py
rename to src/browser_use_sdk/types/agent_profile_update_params.py
diff --git a/src/browser_use/types/agent_profile_view.py b/src/browser_use_sdk/types/agent_profile_view.py
similarity index 100%
rename from src/browser_use/types/agent_profile_view.py
rename to src/browser_use_sdk/types/agent_profile_view.py
diff --git a/src/browser_use/types/browser_profile_create_params.py b/src/browser_use_sdk/types/browser_profile_create_params.py
similarity index 100%
rename from src/browser_use/types/browser_profile_create_params.py
rename to src/browser_use_sdk/types/browser_profile_create_params.py
diff --git a/src/browser_use/types/browser_profile_list_params.py b/src/browser_use_sdk/types/browser_profile_list_params.py
similarity index 100%
rename from src/browser_use/types/browser_profile_list_params.py
rename to src/browser_use_sdk/types/browser_profile_list_params.py
diff --git a/src/browser_use/types/browser_profile_list_response.py b/src/browser_use_sdk/types/browser_profile_list_response.py
similarity index 100%
rename from src/browser_use/types/browser_profile_list_response.py
rename to src/browser_use_sdk/types/browser_profile_list_response.py
diff --git a/src/browser_use/types/browser_profile_update_params.py b/src/browser_use_sdk/types/browser_profile_update_params.py
similarity index 100%
rename from src/browser_use/types/browser_profile_update_params.py
rename to src/browser_use_sdk/types/browser_profile_update_params.py
diff --git a/src/browser_use/types/browser_profile_view.py b/src/browser_use_sdk/types/browser_profile_view.py
similarity index 100%
rename from src/browser_use/types/browser_profile_view.py
rename to src/browser_use_sdk/types/browser_profile_view.py
diff --git a/src/browser_use/types/llm_model.py b/src/browser_use_sdk/types/llm_model.py
similarity index 100%
rename from src/browser_use/types/llm_model.py
rename to src/browser_use_sdk/types/llm_model.py
diff --git a/src/browser_use/types/proxy_country_code.py b/src/browser_use_sdk/types/proxy_country_code.py
similarity index 100%
rename from src/browser_use/types/proxy_country_code.py
rename to src/browser_use_sdk/types/proxy_country_code.py
diff --git a/src/browser_use/types/session_list_params.py b/src/browser_use_sdk/types/session_list_params.py
similarity index 100%
rename from src/browser_use/types/session_list_params.py
rename to src/browser_use_sdk/types/session_list_params.py
diff --git a/src/browser_use/types/session_list_response.py b/src/browser_use_sdk/types/session_list_response.py
similarity index 100%
rename from src/browser_use/types/session_list_response.py
rename to src/browser_use_sdk/types/session_list_response.py
diff --git a/src/browser_use/types/session_retrieve_params.py b/src/browser_use_sdk/types/session_retrieve_params.py
similarity index 100%
rename from src/browser_use/types/session_retrieve_params.py
rename to src/browser_use_sdk/types/session_retrieve_params.py
diff --git a/src/browser_use/types/session_status.py b/src/browser_use_sdk/types/session_status.py
similarity index 100%
rename from src/browser_use/types/session_status.py
rename to src/browser_use_sdk/types/session_status.py
diff --git a/src/browser_use/types/session_update_params.py b/src/browser_use_sdk/types/session_update_params.py
similarity index 100%
rename from src/browser_use/types/session_update_params.py
rename to src/browser_use_sdk/types/session_update_params.py
diff --git a/src/browser_use/types/session_view.py b/src/browser_use_sdk/types/session_view.py
similarity index 100%
rename from src/browser_use/types/session_view.py
rename to src/browser_use_sdk/types/session_view.py
diff --git a/src/browser_use/types/sessions/__init__.py b/src/browser_use_sdk/types/sessions/__init__.py
similarity index 100%
rename from src/browser_use/types/sessions/__init__.py
rename to src/browser_use_sdk/types/sessions/__init__.py
diff --git a/src/browser_use/types/sessions/share_view.py b/src/browser_use_sdk/types/sessions/share_view.py
similarity index 100%
rename from src/browser_use/types/sessions/share_view.py
rename to src/browser_use_sdk/types/sessions/share_view.py
diff --git a/src/browser_use/types/task_create_params.py b/src/browser_use_sdk/types/task_create_params.py
similarity index 100%
rename from src/browser_use/types/task_create_params.py
rename to src/browser_use_sdk/types/task_create_params.py
diff --git a/src/browser_use/types/task_list_params.py b/src/browser_use_sdk/types/task_list_params.py
similarity index 100%
rename from src/browser_use/types/task_list_params.py
rename to src/browser_use_sdk/types/task_list_params.py
diff --git a/src/browser_use/types/task_list_response.py b/src/browser_use_sdk/types/task_list_response.py
similarity index 100%
rename from src/browser_use/types/task_list_response.py
rename to src/browser_use_sdk/types/task_list_response.py
diff --git a/src/browser_use/types/task_retrieve_logs_response.py b/src/browser_use_sdk/types/task_retrieve_logs_response.py
similarity index 100%
rename from src/browser_use/types/task_retrieve_logs_response.py
rename to src/browser_use_sdk/types/task_retrieve_logs_response.py
diff --git a/src/browser_use/types/task_retrieve_output_file_response.py b/src/browser_use_sdk/types/task_retrieve_output_file_response.py
similarity index 100%
rename from src/browser_use/types/task_retrieve_output_file_response.py
rename to src/browser_use_sdk/types/task_retrieve_output_file_response.py
diff --git a/src/browser_use/types/task_retrieve_params.py b/src/browser_use_sdk/types/task_retrieve_params.py
similarity index 100%
rename from src/browser_use/types/task_retrieve_params.py
rename to src/browser_use_sdk/types/task_retrieve_params.py
diff --git a/src/browser_use/types/task_retrieve_response.py b/src/browser_use_sdk/types/task_retrieve_response.py
similarity index 100%
rename from src/browser_use/types/task_retrieve_response.py
rename to src/browser_use_sdk/types/task_retrieve_response.py
diff --git a/src/browser_use/types/task_status.py b/src/browser_use_sdk/types/task_status.py
similarity index 100%
rename from src/browser_use/types/task_status.py
rename to src/browser_use_sdk/types/task_status.py
diff --git a/src/browser_use/types/task_update_params.py b/src/browser_use_sdk/types/task_update_params.py
similarity index 100%
rename from src/browser_use/types/task_update_params.py
rename to src/browser_use_sdk/types/task_update_params.py
diff --git a/src/browser_use/types/task_view.py b/src/browser_use_sdk/types/task_view.py
similarity index 100%
rename from src/browser_use/types/task_view.py
rename to src/browser_use_sdk/types/task_view.py
diff --git a/tests/api_resources/sessions/test_public_share.py b/tests/api_resources/sessions/test_public_share.py
index 981c56d..9514a4b 100644
--- a/tests/api_resources/sessions/test_public_share.py
+++ b/tests/api_resources/sessions/test_public_share.py
@@ -7,9 +7,9 @@
import pytest
-from browser_use import BrowserUse, AsyncBrowserUse
from tests.utils import assert_matches_type
-from browser_use.types.sessions import ShareView
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types.sessions import ShareView
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
diff --git a/tests/api_resources/test_agent_profiles.py b/tests/api_resources/test_agent_profiles.py
index 39ee837..d54d1a7 100644
--- a/tests/api_resources/test_agent_profiles.py
+++ b/tests/api_resources/test_agent_profiles.py
@@ -7,9 +7,9 @@
import pytest
-from browser_use import BrowserUse, AsyncBrowserUse
from tests.utils import assert_matches_type
-from browser_use.types import (
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types import (
AgentProfileView,
AgentProfileListResponse,
)
diff --git a/tests/api_resources/test_browser_profiles.py b/tests/api_resources/test_browser_profiles.py
index 27df0d3..33d3564 100644
--- a/tests/api_resources/test_browser_profiles.py
+++ b/tests/api_resources/test_browser_profiles.py
@@ -7,9 +7,9 @@
import pytest
-from browser_use import BrowserUse, AsyncBrowserUse
from tests.utils import assert_matches_type
-from browser_use.types import (
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types import (
BrowserProfileView,
BrowserProfileListResponse,
)
diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py
index 7e17295..c76b9e5 100644
--- a/tests/api_resources/test_sessions.py
+++ b/tests/api_resources/test_sessions.py
@@ -7,9 +7,9 @@
import pytest
-from browser_use import BrowserUse, AsyncBrowserUse
from tests.utils import assert_matches_type
-from browser_use.types import (
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types import (
SessionView,
SessionListResponse,
)
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index 9944a33..1765e3e 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -7,9 +7,9 @@
import pytest
-from browser_use import BrowserUse, AsyncBrowserUse
from tests.utils import assert_matches_type
-from browser_use.types import (
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types import (
TaskView,
TaskListResponse,
TaskRetrieveResponse,
diff --git a/tests/conftest.py b/tests/conftest.py
index 17f88d9..ef9cc12 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -10,15 +10,15 @@
import pytest
from pytest_asyncio import is_async_test
-from browser_use import BrowserUse, AsyncBrowserUse, DefaultAioHttpClient
-from browser_use._utils import is_dict
+from browser_use_sdk import BrowserUse, AsyncBrowserUse, DefaultAioHttpClient
+from browser_use_sdk._utils import is_dict
if TYPE_CHECKING:
from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
pytest.register_assert_rewrite("tests.utils")
-logging.getLogger("browser_use").setLevel(logging.DEBUG)
+logging.getLogger("browser_use_sdk").setLevel(logging.DEBUG)
# automatically add `pytest.mark.asyncio()` to all of our async tests
diff --git a/tests/test_client.py b/tests/test_client.py
index 61d73bd..44034c9 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -21,11 +21,11 @@
from respx import MockRouter
from pydantic import ValidationError
-from browser_use import BrowserUse, AsyncBrowserUse, APIResponseValidationError
-from browser_use._types import Omit
-from browser_use._models import BaseModel, FinalRequestOptions
-from browser_use._exceptions import APIStatusError, APITimeoutError, BrowserUseError, APIResponseValidationError
-from browser_use._base_client import (
+from browser_use_sdk import BrowserUse, AsyncBrowserUse, APIResponseValidationError
+from browser_use_sdk._types import Omit
+from browser_use_sdk._models import BaseModel, FinalRequestOptions
+from browser_use_sdk._exceptions import APIStatusError, APITimeoutError, BrowserUseError, APIResponseValidationError
+from browser_use_sdk._base_client import (
DEFAULT_TIMEOUT,
HTTPX_DEFAULT_TIMEOUT,
BaseClient,
@@ -232,10 +232,10 @@ def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.Statistic
# to_raw_response_wrapper leaks through the @functools.wraps() decorator.
#
# removing the decorator fixes the leak for reasons we don't understand.
- "browser_use/_legacy_response.py",
- "browser_use/_response.py",
+ "browser_use_sdk/_legacy_response.py",
+ "browser_use_sdk/_response.py",
# pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
- "browser_use/_compat.py",
+ "browser_use_sdk/_compat.py",
# Standard library leaks we don't care about.
"/logging/__init__.py",
]
@@ -719,7 +719,7 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: BrowserUse) -> None:
respx_mock.get("/tasks").mock(side_effect=httpx.TimeoutException("Test timeout error"))
@@ -729,7 +729,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien
assert _get_open_connections(self.client) == 0
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: BrowserUse) -> None:
respx_mock.get("/tasks").mock(return_value=httpx.Response(500))
@@ -739,7 +739,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
def test_retries_taken(
@@ -770,7 +770,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_omit_retry_count_header(
self, client: BrowserUse, failures_before_success: int, respx_mock: MockRouter
@@ -793,7 +793,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_overwrite_retry_count_header(
self, client: BrowserUse, failures_before_success: int, respx_mock: MockRouter
@@ -1041,10 +1041,10 @@ def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.Statistic
# to_raw_response_wrapper leaks through the @functools.wraps() decorator.
#
# removing the decorator fixes the leak for reasons we don't understand.
- "browser_use/_legacy_response.py",
- "browser_use/_response.py",
+ "browser_use_sdk/_legacy_response.py",
+ "browser_use_sdk/_response.py",
# pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
- "browser_use/_compat.py",
+ "browser_use_sdk/_compat.py",
# Standard library leaks we don't care about.
"/logging/__init__.py",
]
@@ -1534,7 +1534,7 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte
calculated = client._calculate_retry_timeout(remaining_retries, options, headers)
assert calculated == pytest.approx(timeout, 0.5 * 0.875) # pyright: ignore[reportUnknownMemberType]
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
async def test_retrying_timeout_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncBrowserUse
@@ -1546,7 +1546,7 @@ async def test_retrying_timeout_errors_doesnt_leak(
assert _get_open_connections(self.client) == 0
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
async def test_retrying_status_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncBrowserUse
@@ -1558,7 +1558,7 @@ async def test_retrying_status_errors_doesnt_leak(
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
@pytest.mark.asyncio
@pytest.mark.parametrize("failure_mode", ["status", "exception"])
@@ -1590,7 +1590,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
@pytest.mark.asyncio
async def test_omit_retry_count_header(
@@ -1614,7 +1614,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
- @mock.patch("browser_use._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
+ @mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
@pytest.mark.asyncio
async def test_overwrite_retry_count_header(
@@ -1648,8 +1648,8 @@ def test_get_platform(self) -> None:
import nest_asyncio
import threading
- from browser_use._utils import asyncify
- from browser_use._base_client import get_platform
+ from browser_use_sdk._utils import asyncify
+ from browser_use_sdk._base_client import get_platform
async def test_main() -> None:
result = await asyncify(get_platform)()
diff --git a/tests/test_deepcopy.py b/tests/test_deepcopy.py
index fb58ebe..852adc3 100644
--- a/tests/test_deepcopy.py
+++ b/tests/test_deepcopy.py
@@ -1,4 +1,4 @@
-from browser_use._utils import deepcopy_minimal
+from browser_use_sdk._utils import deepcopy_minimal
def assert_different_identities(obj1: object, obj2: object) -> None:
diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py
index da97c73..151f6c6 100644
--- a/tests/test_extract_files.py
+++ b/tests/test_extract_files.py
@@ -4,8 +4,8 @@
import pytest
-from browser_use._types import FileTypes
-from browser_use._utils import extract_files
+from browser_use_sdk._types import FileTypes
+from browser_use_sdk._utils import extract_files
def test_removes_files_from_input() -> None:
diff --git a/tests/test_files.py b/tests/test_files.py
index 661756f..f14804f 100644
--- a/tests/test_files.py
+++ b/tests/test_files.py
@@ -4,7 +4,7 @@
import pytest
from dirty_equals import IsDict, IsList, IsBytes, IsTuple
-from browser_use._files import to_httpx_files, async_to_httpx_files
+from browser_use_sdk._files import to_httpx_files, async_to_httpx_files
readme_path = Path(__file__).parent.parent.joinpath("README.md")
diff --git a/tests/test_models.py b/tests/test_models.py
index 72d4485..ee8ad87 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -7,9 +7,9 @@
import pydantic
from pydantic import Field
-from browser_use._utils import PropertyInfo
-from browser_use._compat import PYDANTIC_V2, parse_obj, model_dump, model_json
-from browser_use._models import BaseModel, construct_type
+from browser_use_sdk._utils import PropertyInfo
+from browser_use_sdk._compat import PYDANTIC_V2, parse_obj, model_dump, model_json
+from browser_use_sdk._models import BaseModel, construct_type
class BasicModel(BaseModel):
diff --git a/tests/test_qs.py b/tests/test_qs.py
index c45435d..b47f757 100644
--- a/tests/test_qs.py
+++ b/tests/test_qs.py
@@ -4,7 +4,7 @@
import pytest
-from browser_use._qs import Querystring, stringify
+from browser_use_sdk._qs import Querystring, stringify
def test_empty() -> None:
diff --git a/tests/test_required_args.py b/tests/test_required_args.py
index dda707d..eb5821a 100644
--- a/tests/test_required_args.py
+++ b/tests/test_required_args.py
@@ -2,7 +2,7 @@
import pytest
-from browser_use._utils import required_args
+from browser_use_sdk._utils import required_args
def test_too_many_positional_params() -> None:
diff --git a/tests/test_response.py b/tests/test_response.py
index 97cf7da..c64b9ed 100644
--- a/tests/test_response.py
+++ b/tests/test_response.py
@@ -6,8 +6,8 @@
import pytest
import pydantic
-from browser_use import BaseModel, BrowserUse, AsyncBrowserUse
-from browser_use._response import (
+from browser_use_sdk import BaseModel, BrowserUse, AsyncBrowserUse
+from browser_use_sdk._response import (
APIResponse,
BaseAPIResponse,
AsyncAPIResponse,
@@ -15,8 +15,8 @@
AsyncBinaryAPIResponse,
extract_response_type,
)
-from browser_use._streaming import Stream
-from browser_use._base_client import FinalRequestOptions
+from browser_use_sdk._streaming import Stream
+from browser_use_sdk._base_client import FinalRequestOptions
class ConcreteBaseAPIResponse(APIResponse[bytes]): ...
@@ -37,7 +37,7 @@ def test_extract_response_type_direct_classes() -> None:
def test_extract_response_type_direct_class_missing_type_arg() -> None:
with pytest.raises(
RuntimeError,
- match="Expected type to have a type argument at index 0 but it did not",
+ match="Expected type to have a type argument at index 0 but it did not",
):
extract_response_type(AsyncAPIResponse)
@@ -68,7 +68,7 @@ def test_response_parse_mismatched_basemodel(client: BrowserUse) -> None:
with pytest.raises(
TypeError,
- match="Pydantic models must subclass our base model type, e.g. `from browser_use import BaseModel`",
+ match="Pydantic models must subclass our base model type, e.g. `from browser_use_sdk import BaseModel`",
):
response.parse(to=PydanticModel)
@@ -86,7 +86,7 @@ async def test_async_response_parse_mismatched_basemodel(async_client: AsyncBrow
with pytest.raises(
TypeError,
- match="Pydantic models must subclass our base model type, e.g. `from browser_use import BaseModel`",
+ match="Pydantic models must subclass our base model type, e.g. `from browser_use_sdk import BaseModel`",
):
await response.parse(to=PydanticModel)
diff --git a/tests/test_streaming.py b/tests/test_streaming.py
index 73fb1c3..84f2452 100644
--- a/tests/test_streaming.py
+++ b/tests/test_streaming.py
@@ -5,8 +5,8 @@
import httpx
import pytest
-from browser_use import BrowserUse, AsyncBrowserUse
-from browser_use._streaming import Stream, AsyncStream, ServerSentEvent
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk._streaming import Stream, AsyncStream, ServerSentEvent
@pytest.mark.asyncio
diff --git a/tests/test_transform.py b/tests/test_transform.py
index 89aa594..b336597 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -8,15 +8,15 @@
import pytest
-from browser_use._types import NOT_GIVEN, Base64FileInput
-from browser_use._utils import (
+from browser_use_sdk._types import NOT_GIVEN, Base64FileInput
+from browser_use_sdk._utils import (
PropertyInfo,
transform as _transform,
parse_datetime,
async_transform as _async_transform,
)
-from browser_use._compat import PYDANTIC_V2
-from browser_use._models import BaseModel
+from browser_use_sdk._compat import PYDANTIC_V2
+from browser_use_sdk._models import BaseModel
_T = TypeVar("_T")
diff --git a/tests/test_utils/test_proxy.py b/tests/test_utils/test_proxy.py
index 50e1b43..a76d3a9 100644
--- a/tests/test_utils/test_proxy.py
+++ b/tests/test_utils/test_proxy.py
@@ -2,7 +2,7 @@
from typing import Any
from typing_extensions import override
-from browser_use._utils import LazyProxy
+from browser_use_sdk._utils import LazyProxy
class RecursiveLazyProxy(LazyProxy[Any]):
diff --git a/tests/test_utils/test_typing.py b/tests/test_utils/test_typing.py
index b329aab..e12cde1 100644
--- a/tests/test_utils/test_typing.py
+++ b/tests/test_utils/test_typing.py
@@ -2,7 +2,7 @@
from typing import Generic, TypeVar, cast
-from browser_use._utils import extract_type_var_from_base
+from browser_use_sdk._utils import extract_type_var_from_base
_T = TypeVar("_T")
_T2 = TypeVar("_T2")
diff --git a/tests/utils.py b/tests/utils.py
index 2a8ebf0..858cc96 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -8,8 +8,8 @@
from datetime import date, datetime
from typing_extensions import Literal, get_args, get_origin, assert_type
-from browser_use._types import Omit, NoneType
-from browser_use._utils import (
+from browser_use_sdk._types import Omit, NoneType
+from browser_use_sdk._utils import (
is_dict,
is_list,
is_list_type,
@@ -18,8 +18,8 @@
is_annotated_type,
is_type_alias_type,
)
-from browser_use._compat import PYDANTIC_V2, field_outer_type, get_model_fields
-from browser_use._models import BaseModel
+from browser_use_sdk._compat import PYDANTIC_V2, field_outer_type, get_model_fields
+from browser_use_sdk._models import BaseModel
BaseModelT = TypeVar("BaseModelT", bound=BaseModel)
From 151d56ba67c2d09970ff415472c0a1d259716bbc Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 12 Aug 2025 02:07:26 +0000
Subject: [PATCH 03/10] chore(internal): codegen related update
---
.../sessions/test_public_share.py | 48 ++++-----
tests/api_resources/test_agent_profiles.py | 84 +++++++--------
tests/api_resources/test_browser_profiles.py | 84 +++++++--------
tests/api_resources/test_sessions.py | 52 ++++-----
tests/api_resources/test_tasks.py | 100 +++++++++---------
5 files changed, 184 insertions(+), 184 deletions(-)
diff --git a/tests/api_resources/sessions/test_public_share.py b/tests/api_resources/sessions/test_public_share.py
index 9514a4b..3a83c4e 100644
--- a/tests/api_resources/sessions/test_public_share.py
+++ b/tests/api_resources/sessions/test_public_share.py
@@ -17,7 +17,7 @@
class TestPublicShare:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create(self, client: BrowserUse) -> None:
public_share = client.sessions.public_share.create(
@@ -25,7 +25,7 @@ def test_method_create(self, client: BrowserUse) -> None:
)
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_create(self, client: BrowserUse) -> None:
response = client.sessions.public_share.with_raw_response.create(
@@ -37,7 +37,7 @@ def test_raw_response_create(self, client: BrowserUse) -> None:
public_share = response.parse()
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_create(self, client: BrowserUse) -> None:
with client.sessions.public_share.with_streaming_response.create(
@@ -51,7 +51,7 @@ def test_streaming_response_create(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_create(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -59,7 +59,7 @@ def test_path_params_create(self, client: BrowserUse) -> None:
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
public_share = client.sessions.public_share.retrieve(
@@ -67,7 +67,7 @@ def test_method_retrieve(self, client: BrowserUse) -> None:
)
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.sessions.public_share.with_raw_response.retrieve(
@@ -79,7 +79,7 @@ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
public_share = response.parse()
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.sessions.public_share.with_streaming_response.retrieve(
@@ -93,7 +93,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -101,7 +101,7 @@ def test_path_params_retrieve(self, client: BrowserUse) -> None:
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_delete(self, client: BrowserUse) -> None:
public_share = client.sessions.public_share.delete(
@@ -109,7 +109,7 @@ def test_method_delete(self, client: BrowserUse) -> None:
)
assert_matches_type(object, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_delete(self, client: BrowserUse) -> None:
response = client.sessions.public_share.with_raw_response.delete(
@@ -121,7 +121,7 @@ def test_raw_response_delete(self, client: BrowserUse) -> None:
public_share = response.parse()
assert_matches_type(object, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_delete(self, client: BrowserUse) -> None:
with client.sessions.public_share.with_streaming_response.delete(
@@ -135,7 +135,7 @@ def test_streaming_response_delete(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_delete(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -149,7 +149,7 @@ class TestAsyncPublicShare:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
public_share = await async_client.sessions.public_share.create(
@@ -157,7 +157,7 @@ async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.public_share.with_raw_response.create(
@@ -169,7 +169,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
public_share = await response.parse()
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_create(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.public_share.with_streaming_response.create(
@@ -183,7 +183,7 @@ async def test_streaming_response_create(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_create(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -191,7 +191,7 @@ async def test_path_params_create(self, async_client: AsyncBrowserUse) -> None:
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
public_share = await async_client.sessions.public_share.retrieve(
@@ -199,7 +199,7 @@ async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.public_share.with_raw_response.retrieve(
@@ -211,7 +211,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> Non
public_share = await response.parse()
assert_matches_type(ShareView, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.public_share.with_streaming_response.retrieve(
@@ -225,7 +225,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -233,7 +233,7 @@ async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
public_share = await async_client.sessions.public_share.delete(
@@ -241,7 +241,7 @@ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(object, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.public_share.with_raw_response.delete(
@@ -253,7 +253,7 @@ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
public_share = await response.parse()
assert_matches_type(object, public_share, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.public_share.with_streaming_response.delete(
@@ -267,7 +267,7 @@ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_delete(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
diff --git a/tests/api_resources/test_agent_profiles.py b/tests/api_resources/test_agent_profiles.py
index d54d1a7..2c4af8a 100644
--- a/tests/api_resources/test_agent_profiles.py
+++ b/tests/api_resources/test_agent_profiles.py
@@ -20,7 +20,7 @@
class TestAgentProfiles:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.create(
@@ -28,7 +28,7 @@ def test_method_create(self, client: BrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create_with_all_params(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.create(
@@ -44,7 +44,7 @@ def test_method_create_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_create(self, client: BrowserUse) -> None:
response = client.agent_profiles.with_raw_response.create(
@@ -56,7 +56,7 @@ def test_raw_response_create(self, client: BrowserUse) -> None:
agent_profile = response.parse()
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_create(self, client: BrowserUse) -> None:
with client.agent_profiles.with_streaming_response.create(
@@ -70,7 +70,7 @@ def test_streaming_response_create(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.retrieve(
@@ -78,7 +78,7 @@ def test_method_retrieve(self, client: BrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.agent_profiles.with_raw_response.retrieve(
@@ -90,7 +90,7 @@ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
agent_profile = response.parse()
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.agent_profiles.with_streaming_response.retrieve(
@@ -104,7 +104,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -112,7 +112,7 @@ def test_path_params_retrieve(self, client: BrowserUse) -> None:
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_update(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.update(
@@ -120,7 +120,7 @@ def test_method_update(self, client: BrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_update_with_all_params(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.update(
@@ -137,7 +137,7 @@ def test_method_update_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_update(self, client: BrowserUse) -> None:
response = client.agent_profiles.with_raw_response.update(
@@ -149,7 +149,7 @@ def test_raw_response_update(self, client: BrowserUse) -> None:
agent_profile = response.parse()
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_update(self, client: BrowserUse) -> None:
with client.agent_profiles.with_streaming_response.update(
@@ -163,7 +163,7 @@ def test_streaming_response_update(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_update(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -171,13 +171,13 @@ def test_path_params_update(self, client: BrowserUse) -> None:
profile_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.list()
assert_matches_type(AgentProfileListResponse, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.list(
@@ -186,7 +186,7 @@ def test_method_list_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(AgentProfileListResponse, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_list(self, client: BrowserUse) -> None:
response = client.agent_profiles.with_raw_response.list()
@@ -196,7 +196,7 @@ def test_raw_response_list(self, client: BrowserUse) -> None:
agent_profile = response.parse()
assert_matches_type(AgentProfileListResponse, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_list(self, client: BrowserUse) -> None:
with client.agent_profiles.with_streaming_response.list() as response:
@@ -208,7 +208,7 @@ def test_streaming_response_list(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_delete(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.delete(
@@ -216,7 +216,7 @@ def test_method_delete(self, client: BrowserUse) -> None:
)
assert_matches_type(object, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_delete(self, client: BrowserUse) -> None:
response = client.agent_profiles.with_raw_response.delete(
@@ -228,7 +228,7 @@ def test_raw_response_delete(self, client: BrowserUse) -> None:
agent_profile = response.parse()
assert_matches_type(object, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_delete(self, client: BrowserUse) -> None:
with client.agent_profiles.with_streaming_response.delete(
@@ -242,7 +242,7 @@ def test_streaming_response_delete(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_delete(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -256,7 +256,7 @@ class TestAsyncAgentProfiles:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.create(
@@ -264,7 +264,7 @@ async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.create(
@@ -280,7 +280,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.agent_profiles.with_raw_response.create(
@@ -292,7 +292,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await response.parse()
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_create(self, async_client: AsyncBrowserUse) -> None:
async with async_client.agent_profiles.with_streaming_response.create(
@@ -306,7 +306,7 @@ async def test_streaming_response_create(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.retrieve(
@@ -314,7 +314,7 @@ async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.agent_profiles.with_raw_response.retrieve(
@@ -326,7 +326,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> Non
agent_profile = await response.parse()
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.agent_profiles.with_streaming_response.retrieve(
@@ -340,7 +340,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -348,7 +348,7 @@ async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.update(
@@ -356,7 +356,7 @@ async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_update_with_all_params(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.update(
@@ -373,7 +373,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncBrowserUse
)
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.agent_profiles.with_raw_response.update(
@@ -385,7 +385,7 @@ async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await response.parse()
assert_matches_type(AgentProfileView, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_update(self, async_client: AsyncBrowserUse) -> None:
async with async_client.agent_profiles.with_streaming_response.update(
@@ -399,7 +399,7 @@ async def test_streaming_response_update(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -407,13 +407,13 @@ async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
profile_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.list()
assert_matches_type(AgentProfileListResponse, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.list(
@@ -422,7 +422,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse)
)
assert_matches_type(AgentProfileListResponse, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.agent_profiles.with_raw_response.list()
@@ -432,7 +432,7 @@ async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await response.parse()
assert_matches_type(AgentProfileListResponse, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> None:
async with async_client.agent_profiles.with_streaming_response.list() as response:
@@ -444,7 +444,7 @@ async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> N
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.delete(
@@ -452,7 +452,7 @@ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(object, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.agent_profiles.with_raw_response.delete(
@@ -464,7 +464,7 @@ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await response.parse()
assert_matches_type(object, agent_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) -> None:
async with async_client.agent_profiles.with_streaming_response.delete(
@@ -478,7 +478,7 @@ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_delete(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
diff --git a/tests/api_resources/test_browser_profiles.py b/tests/api_resources/test_browser_profiles.py
index 33d3564..974c2db 100644
--- a/tests/api_resources/test_browser_profiles.py
+++ b/tests/api_resources/test_browser_profiles.py
@@ -20,7 +20,7 @@
class TestBrowserProfiles:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.create(
@@ -28,7 +28,7 @@ def test_method_create(self, client: BrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create_with_all_params(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.create(
@@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_create(self, client: BrowserUse) -> None:
response = client.browser_profiles.with_raw_response.create(
@@ -57,7 +57,7 @@ def test_raw_response_create(self, client: BrowserUse) -> None:
browser_profile = response.parse()
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_create(self, client: BrowserUse) -> None:
with client.browser_profiles.with_streaming_response.create(
@@ -71,7 +71,7 @@ def test_streaming_response_create(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.retrieve(
@@ -79,7 +79,7 @@ def test_method_retrieve(self, client: BrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.browser_profiles.with_raw_response.retrieve(
@@ -91,7 +91,7 @@ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
browser_profile = response.parse()
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.browser_profiles.with_streaming_response.retrieve(
@@ -105,7 +105,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -113,7 +113,7 @@ def test_path_params_retrieve(self, client: BrowserUse) -> None:
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_update(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.update(
@@ -121,7 +121,7 @@ def test_method_update(self, client: BrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_update_with_all_params(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.update(
@@ -139,7 +139,7 @@ def test_method_update_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_update(self, client: BrowserUse) -> None:
response = client.browser_profiles.with_raw_response.update(
@@ -151,7 +151,7 @@ def test_raw_response_update(self, client: BrowserUse) -> None:
browser_profile = response.parse()
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_update(self, client: BrowserUse) -> None:
with client.browser_profiles.with_streaming_response.update(
@@ -165,7 +165,7 @@ def test_streaming_response_update(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_update(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -173,13 +173,13 @@ def test_path_params_update(self, client: BrowserUse) -> None:
profile_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.list()
assert_matches_type(BrowserProfileListResponse, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.list(
@@ -188,7 +188,7 @@ def test_method_list_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(BrowserProfileListResponse, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_list(self, client: BrowserUse) -> None:
response = client.browser_profiles.with_raw_response.list()
@@ -198,7 +198,7 @@ def test_raw_response_list(self, client: BrowserUse) -> None:
browser_profile = response.parse()
assert_matches_type(BrowserProfileListResponse, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_list(self, client: BrowserUse) -> None:
with client.browser_profiles.with_streaming_response.list() as response:
@@ -210,7 +210,7 @@ def test_streaming_response_list(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_delete(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.delete(
@@ -218,7 +218,7 @@ def test_method_delete(self, client: BrowserUse) -> None:
)
assert_matches_type(object, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_delete(self, client: BrowserUse) -> None:
response = client.browser_profiles.with_raw_response.delete(
@@ -230,7 +230,7 @@ def test_raw_response_delete(self, client: BrowserUse) -> None:
browser_profile = response.parse()
assert_matches_type(object, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_delete(self, client: BrowserUse) -> None:
with client.browser_profiles.with_streaming_response.delete(
@@ -244,7 +244,7 @@ def test_streaming_response_delete(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_delete(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -258,7 +258,7 @@ class TestAsyncBrowserProfiles:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.create(
@@ -266,7 +266,7 @@ async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.create(
@@ -283,7 +283,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.browser_profiles.with_raw_response.create(
@@ -295,7 +295,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await response.parse()
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_create(self, async_client: AsyncBrowserUse) -> None:
async with async_client.browser_profiles.with_streaming_response.create(
@@ -309,7 +309,7 @@ async def test_streaming_response_create(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.retrieve(
@@ -317,7 +317,7 @@ async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.browser_profiles.with_raw_response.retrieve(
@@ -329,7 +329,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> Non
browser_profile = await response.parse()
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.browser_profiles.with_streaming_response.retrieve(
@@ -343,7 +343,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -351,7 +351,7 @@ async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.update(
@@ -359,7 +359,7 @@ async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_update_with_all_params(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.update(
@@ -377,7 +377,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncBrowserUse
)
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.browser_profiles.with_raw_response.update(
@@ -389,7 +389,7 @@ async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await response.parse()
assert_matches_type(BrowserProfileView, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_update(self, async_client: AsyncBrowserUse) -> None:
async with async_client.browser_profiles.with_streaming_response.update(
@@ -403,7 +403,7 @@ async def test_streaming_response_update(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
@@ -411,13 +411,13 @@ async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
profile_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.list()
assert_matches_type(BrowserProfileListResponse, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.list(
@@ -426,7 +426,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse)
)
assert_matches_type(BrowserProfileListResponse, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.browser_profiles.with_raw_response.list()
@@ -436,7 +436,7 @@ async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await response.parse()
assert_matches_type(BrowserProfileListResponse, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> None:
async with async_client.browser_profiles.with_streaming_response.list() as response:
@@ -448,7 +448,7 @@ async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> N
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.delete(
@@ -456,7 +456,7 @@ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(object, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.browser_profiles.with_raw_response.delete(
@@ -468,7 +468,7 @@ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await response.parse()
assert_matches_type(object, browser_profile, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) -> None:
async with async_client.browser_profiles.with_streaming_response.delete(
@@ -482,7 +482,7 @@ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_delete(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `profile_id` but received ''"):
diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py
index c76b9e5..52fb550 100644
--- a/tests/api_resources/test_sessions.py
+++ b/tests/api_resources/test_sessions.py
@@ -20,7 +20,7 @@
class TestSessions:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
session = client.sessions.retrieve(
@@ -28,7 +28,7 @@ def test_method_retrieve(self, client: BrowserUse) -> None:
)
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
session = client.sessions.retrieve(
@@ -37,7 +37,7 @@ def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.sessions.with_raw_response.retrieve(
@@ -49,7 +49,7 @@ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
session = response.parse()
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.sessions.with_streaming_response.retrieve(
@@ -63,7 +63,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -71,7 +71,7 @@ def test_path_params_retrieve(self, client: BrowserUse) -> None:
session_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_update(self, client: BrowserUse) -> None:
session = client.sessions.update(
@@ -80,7 +80,7 @@ def test_method_update(self, client: BrowserUse) -> None:
)
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_update(self, client: BrowserUse) -> None:
response = client.sessions.with_raw_response.update(
@@ -93,7 +93,7 @@ def test_raw_response_update(self, client: BrowserUse) -> None:
session = response.parse()
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_update(self, client: BrowserUse) -> None:
with client.sessions.with_streaming_response.update(
@@ -108,7 +108,7 @@ def test_streaming_response_update(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_update(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -117,13 +117,13 @@ def test_path_params_update(self, client: BrowserUse) -> None:
action="stop",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list(self, client: BrowserUse) -> None:
session = client.sessions.list()
assert_matches_type(SessionListResponse, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
session = client.sessions.list(
@@ -134,7 +134,7 @@ def test_method_list_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(SessionListResponse, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_list(self, client: BrowserUse) -> None:
response = client.sessions.with_raw_response.list()
@@ -144,7 +144,7 @@ def test_raw_response_list(self, client: BrowserUse) -> None:
session = response.parse()
assert_matches_type(SessionListResponse, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_list(self, client: BrowserUse) -> None:
with client.sessions.with_streaming_response.list() as response:
@@ -162,7 +162,7 @@ class TestAsyncSessions:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.retrieve(
@@ -170,7 +170,7 @@ async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.retrieve(
@@ -179,7 +179,7 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserU
)
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.with_raw_response.retrieve(
@@ -191,7 +191,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> Non
session = await response.parse()
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.with_streaming_response.retrieve(
@@ -205,7 +205,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -213,7 +213,7 @@ async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None
session_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.update(
@@ -222,7 +222,7 @@ async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.with_raw_response.update(
@@ -235,7 +235,7 @@ async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
session = await response.parse()
assert_matches_type(SessionView, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_update(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.with_streaming_response.update(
@@ -250,7 +250,7 @@ async def test_streaming_response_update(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
@@ -259,13 +259,13 @@ async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
action="stop",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.list()
assert_matches_type(SessionListResponse, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.list(
@@ -276,7 +276,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse)
)
assert_matches_type(SessionListResponse, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.with_raw_response.list()
@@ -286,7 +286,7 @@ async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
session = await response.parse()
assert_matches_type(SessionListResponse, session, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.with_streaming_response.list() as response:
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index 1765e3e..0012ef2 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -23,7 +23,7 @@
class TestTasks:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create(self, client: BrowserUse) -> None:
task = client.tasks.create(
@@ -31,7 +31,7 @@ def test_method_create(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_create_with_all_params(self, client: BrowserUse) -> None:
task = client.tasks.create(
@@ -52,7 +52,7 @@ def test_method_create_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_create(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.create(
@@ -64,7 +64,7 @@ def test_raw_response_create(self, client: BrowserUse) -> None:
task = response.parse()
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_create(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.create(
@@ -78,7 +78,7 @@ def test_streaming_response_create(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
task = client.tasks.retrieve(
@@ -86,7 +86,7 @@ def test_method_retrieve(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskRetrieveResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
task = client.tasks.retrieve(
@@ -95,7 +95,7 @@ def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskRetrieveResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.retrieve(
@@ -107,7 +107,7 @@ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
task = response.parse()
assert_matches_type(TaskRetrieveResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.retrieve(
@@ -121,7 +121,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -129,7 +129,7 @@ def test_path_params_retrieve(self, client: BrowserUse) -> None:
task_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_update(self, client: BrowserUse) -> None:
task = client.tasks.update(
@@ -138,7 +138,7 @@ def test_method_update(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_update(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.update(
@@ -151,7 +151,7 @@ def test_raw_response_update(self, client: BrowserUse) -> None:
task = response.parse()
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_update(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.update(
@@ -166,7 +166,7 @@ def test_streaming_response_update(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_update(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -175,13 +175,13 @@ def test_path_params_update(self, client: BrowserUse) -> None:
action="stop",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list(self, client: BrowserUse) -> None:
task = client.tasks.list()
assert_matches_type(TaskListResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
task = client.tasks.list(
@@ -193,7 +193,7 @@ def test_method_list_with_all_params(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskListResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_list(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.list()
@@ -203,7 +203,7 @@ def test_raw_response_list(self, client: BrowserUse) -> None:
task = response.parse()
assert_matches_type(TaskListResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_list(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.list() as response:
@@ -215,7 +215,7 @@ def test_streaming_response_list(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve_logs(self, client: BrowserUse) -> None:
task = client.tasks.retrieve_logs(
@@ -223,7 +223,7 @@ def test_method_retrieve_logs(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve_logs(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.retrieve_logs(
@@ -235,7 +235,7 @@ def test_raw_response_retrieve_logs(self, client: BrowserUse) -> None:
task = response.parse()
assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve_logs(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.retrieve_logs(
@@ -249,7 +249,7 @@ def test_streaming_response_retrieve_logs(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve_logs(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -257,7 +257,7 @@ def test_path_params_retrieve_logs(self, client: BrowserUse) -> None:
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_method_retrieve_output_file(self, client: BrowserUse) -> None:
task = client.tasks.retrieve_output_file(
@@ -266,7 +266,7 @@ def test_method_retrieve_output_file(self, client: BrowserUse) -> None:
)
assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve_output_file(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.retrieve_output_file(
@@ -279,7 +279,7 @@ def test_raw_response_retrieve_output_file(self, client: BrowserUse) -> None:
task = response.parse()
assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve_output_file(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.retrieve_output_file(
@@ -294,7 +294,7 @@ def test_streaming_response_retrieve_output_file(self, client: BrowserUse) -> No
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_path_params_retrieve_output_file(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -315,7 +315,7 @@ class TestAsyncTasks:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.create(
@@ -323,7 +323,7 @@ async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.create(
@@ -344,7 +344,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse
)
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.create(
@@ -356,7 +356,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
task = await response.parse()
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_create(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.create(
@@ -370,7 +370,7 @@ async def test_streaming_response_create(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.retrieve(
@@ -378,7 +378,7 @@ async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(TaskRetrieveResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.retrieve(
@@ -387,7 +387,7 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserU
)
assert_matches_type(TaskRetrieveResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.retrieve(
@@ -399,7 +399,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> Non
task = await response.parse()
assert_matches_type(TaskRetrieveResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.retrieve(
@@ -413,7 +413,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -421,7 +421,7 @@ async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None
task_id="",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.update(
@@ -430,7 +430,7 @@ async def test_method_update(self, async_client: AsyncBrowserUse) -> None:
)
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.update(
@@ -443,7 +443,7 @@ async def test_raw_response_update(self, async_client: AsyncBrowserUse) -> None:
task = await response.parse()
assert_matches_type(TaskView, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_update(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.update(
@@ -458,7 +458,7 @@ async def test_streaming_response_update(self, async_client: AsyncBrowserUse) ->
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -467,13 +467,13 @@ async def test_path_params_update(self, async_client: AsyncBrowserUse) -> None:
action="stop",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.list()
assert_matches_type(TaskListResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.list(
@@ -485,7 +485,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse)
)
assert_matches_type(TaskListResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.list()
@@ -495,7 +495,7 @@ async def test_raw_response_list(self, async_client: AsyncBrowserUse) -> None:
task = await response.parse()
assert_matches_type(TaskListResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.list() as response:
@@ -507,7 +507,7 @@ async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> N
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.retrieve_logs(
@@ -515,7 +515,7 @@ async def test_method_retrieve_logs(self, async_client: AsyncBrowserUse) -> None
)
assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.retrieve_logs(
@@ -527,7 +527,7 @@ async def test_raw_response_retrieve_logs(self, async_client: AsyncBrowserUse) -
task = await response.parse()
assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.retrieve_logs(
@@ -541,7 +541,7 @@ async def test_streaming_response_retrieve_logs(self, async_client: AsyncBrowser
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
@@ -549,7 +549,7 @@ async def test_path_params_retrieve_logs(self, async_client: AsyncBrowserUse) ->
"",
)
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_method_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.retrieve_output_file(
@@ -558,7 +558,7 @@ async def test_method_retrieve_output_file(self, async_client: AsyncBrowserUse)
)
assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.retrieve_output_file(
@@ -571,7 +571,7 @@ async def test_raw_response_retrieve_output_file(self, async_client: AsyncBrowse
task = await response.parse()
assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.retrieve_output_file(
@@ -586,7 +586,7 @@ async def test_streaming_response_retrieve_output_file(self, async_client: Async
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip()
+ @pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_path_params_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
From 58675327b6a0e7ba41f312e4887062a9b6dc2852 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 14 Aug 2025 23:43:25 +0000
Subject: [PATCH 04/10] feat(api): api update
---
.stats.yml | 6 +-
README.md | 31 +-
api.md | 11 +-
src/browser_use_sdk/_client.py | 12 -
.../resources/agent_profiles.py | 210 +++++++-
.../resources/browser_profiles.py | 196 +++++++-
.../resources/sessions/public_share.py | 132 ++++-
.../resources/sessions/sessions.py | 138 +++++-
src/browser_use_sdk/resources/tasks.py | 464 ++++++++++++------
src/browser_use_sdk/types/__init__.py | 3 -
.../types/agent_profile_create_params.py | 4 +-
.../types/agent_profile_update_params.py | 4 +-
.../types/agent_profile_view.py | 4 +-
.../types/session_list_params.py | 5 +-
.../types/session_list_response.py | 98 +++-
.../types/session_update_params.py | 3 +-
src/browser_use_sdk/types/session_view.py | 82 +++-
.../types/task_create_params.py | 12 +-
src/browser_use_sdk/types/task_list_params.py | 16 +-
.../types/task_list_response.py | 78 ++-
.../task_retrieve_output_file_response.py | 11 -
.../types/task_retrieve_params.py | 13 -
.../types/task_retrieve_response.py | 23 -
src/browser_use_sdk/types/task_view.py | 38 +-
.../sessions/test_public_share.py | 12 +-
tests/api_resources/test_agent_profiles.py | 20 +-
tests/api_resources/test_browser_profiles.py | 12 +-
tests/api_resources/test_tasks.py | 156 +-----
tests/test_client.py | 22 +-
29 files changed, 1304 insertions(+), 512 deletions(-)
delete mode 100644 src/browser_use_sdk/types/task_retrieve_output_file_response.py
delete mode 100644 src/browser_use_sdk/types/task_retrieve_params.py
delete mode 100644 src/browser_use_sdk/types/task_retrieve_response.py
diff --git a/.stats.yml b/.stats.yml
index c28d532..1126772 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 22
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-86040fd18419e7b4e0947660d9c0ff1abe21550528d2d2a549736cd16f85a92d.yml
-openapi_spec_hash: 7c5de9d0f633db35fd9e250fcc834d1f
+configured_endpoints: 21
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-9ff5409663c58ae9e3ecc9ac764956189e3a70600f5ba1b961bb1dedf0208271.yml
+openapi_spec_hash: 9865acb75430d9b799502acbae860df0
config_hash: 99e0e445bc20c5723030c315bab52940
diff --git a/README.md b/README.md
index ffe6e1e..a0a310f 100644
--- a/README.md
+++ b/README.md
@@ -25,33 +25,26 @@ pip install browser-use-sdk
The full API of this library can be found in [api.md](api.md).
```python
-import os
from browser_use_sdk import BrowserUse
client = BrowserUse(
- api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
+ api_key="My API Key",
)
tasks = client.tasks.list()
print(tasks.items)
```
-While you can provide an `api_key` keyword argument,
-we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
-to add `BROWSER_USE_API_KEY="My API Key"` to your `.env` file
-so that your API Key is not stored in source control.
-
## Async usage
Simply import `AsyncBrowserUse` instead of `BrowserUse` and use `await` with each API call:
```python
-import os
import asyncio
from browser_use_sdk import AsyncBrowserUse
client = AsyncBrowserUse(
- api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
+ api_key="My API Key",
)
@@ -112,7 +105,9 @@ Nested parameters are dictionaries, typed using `TypedDict`, for example:
```python
from browser_use_sdk import BrowserUse
-client = BrowserUse()
+client = BrowserUse(
+ api_key="My API Key",
+)
task_view = client.tasks.create(
task="x",
@@ -134,7 +129,9 @@ All errors inherit from `browser_use_sdk.APIError`.
import browser_use_sdk
from browser_use_sdk import BrowserUse
-client = BrowserUse()
+client = BrowserUse(
+ api_key="My API Key",
+)
try:
client.tasks.list()
@@ -175,6 +172,7 @@ from browser_use_sdk import BrowserUse
# Configure the default for all requests:
client = BrowserUse(
+ api_key="My API Key",
# default is 2
max_retries=0,
)
@@ -193,12 +191,14 @@ from browser_use_sdk import BrowserUse
# Configure the default for all requests:
client = BrowserUse(
+ api_key="My API Key",
# 20 seconds (default is 1 minute)
timeout=20.0,
)
# More granular control:
client = BrowserUse(
+ api_key="My API Key",
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
)
@@ -243,7 +243,9 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
```py
from browser_use_sdk import BrowserUse
-client = BrowserUse()
+client = BrowserUse(
+ api_key="My API Key",
+)
response = client.tasks.with_raw_response.list()
print(response.headers.get('X-My-Header'))
@@ -318,6 +320,7 @@ import httpx
from browser_use_sdk import BrowserUse, DefaultHttpxClient
client = BrowserUse(
+ api_key="My API Key",
# Or use the `BROWSER_USE_BASE_URL` env var
base_url="http://my.test.server.example.com:8083",
http_client=DefaultHttpxClient(
@@ -340,7 +343,9 @@ By default the library closes underlying HTTP connections whenever the client is
```py
from browser_use_sdk import BrowserUse
-with BrowserUse() as client:
+with BrowserUse(
+ api_key="My API Key",
+) as client:
# make requests here
...
diff --git a/api.md b/api.md
index e0e24fd..22f0b35 100644
--- a/api.md
+++ b/api.md
@@ -7,21 +7,18 @@ from browser_use_sdk.types import (
LlmModel,
TaskStatus,
TaskView,
- TaskRetrieveResponse,
TaskListResponse,
TaskRetrieveLogsResponse,
- TaskRetrieveOutputFileResponse,
)
```
Methods:
- client.tasks.create(\*\*params) -> TaskView
-- client.tasks.retrieve(task_id, \*\*params) -> TaskRetrieveResponse
+- client.tasks.retrieve(task_id) -> TaskView
- client.tasks.update(task_id, \*\*params) -> TaskView
- client.tasks.list(\*\*params) -> TaskListResponse
- client.tasks.retrieve_logs(task_id) -> TaskRetrieveLogsResponse
-- client.tasks.retrieve_output_file(file_name, \*, task_id) -> TaskRetrieveOutputFileResponse
# Sessions
@@ -49,7 +46,7 @@ Methods:
- client.sessions.public_share.create(session_id) -> ShareView
- client.sessions.public_share.retrieve(session_id) -> ShareView
-- client.sessions.public_share.delete(session_id) -> object
+- client.sessions.public_share.delete(session_id) -> None
# BrowserProfiles
@@ -65,7 +62,7 @@ Methods:
- client.browser_profiles.retrieve(profile_id) -> BrowserProfileView
- client.browser_profiles.update(profile_id, \*\*params) -> BrowserProfileView
- client.browser_profiles.list(\*\*params) -> BrowserProfileListResponse
-- client.browser_profiles.delete(profile_id) -> object
+- client.browser_profiles.delete(profile_id) -> None
# AgentProfiles
@@ -81,4 +78,4 @@ Methods:
- client.agent_profiles.retrieve(profile_id) -> AgentProfileView
- client.agent_profiles.update(profile_id, \*\*params) -> AgentProfileView
- client.agent_profiles.list(\*\*params) -> AgentProfileListResponse
-- client.agent_profiles.delete(profile_id) -> object
+- client.agent_profiles.delete(profile_id) -> None
diff --git a/src/browser_use_sdk/_client.py b/src/browser_use_sdk/_client.py
index 2c3f8fc..fc2fd46 100644
--- a/src/browser_use_sdk/_client.py
+++ b/src/browser_use_sdk/_client.py
@@ -117,12 +117,6 @@ def __init__(
def qs(self) -> Querystring:
return Querystring(array_format="comma")
- @property
- @override
- def auth_headers(self) -> dict[str, str]:
- api_key = self.api_key
- return {"X-Browser-Use-API-Key": api_key}
-
@property
@override
def default_headers(self) -> dict[str, str | Omit]:
@@ -291,12 +285,6 @@ def __init__(
def qs(self) -> Querystring:
return Querystring(array_format="comma")
- @property
- @override
- def auth_headers(self) -> dict[str, str]:
- api_key = self.api_key
- return {"X-Browser-Use-API-Key": api_key}
-
@property
@override
def default_headers(self) -> dict[str, str | Omit]:
diff --git a/src/browser_use_sdk/resources/agent_profiles.py b/src/browser_use_sdk/resources/agent_profiles.py
index 2d78b3a..b596dbc 100644
--- a/src/browser_use_sdk/resources/agent_profiles.py
+++ b/src/browser_use_sdk/resources/agent_profiles.py
@@ -7,7 +7,7 @@
import httpx
from ..types import agent_profile_list_params, agent_profile_create_params, agent_profile_update_params
-from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -49,11 +49,11 @@ def create(
*,
name: str,
allowed_domains: List[str] | NotGiven = NOT_GIVEN,
+ custom_system_prompt_extension: str | NotGiven = NOT_GIVEN,
description: str | NotGiven = NOT_GIVEN,
flash_mode: bool | NotGiven = NOT_GIVEN,
highlight_elements: bool | NotGiven = NOT_GIVEN,
max_agent_steps: int | NotGiven = NOT_GIVEN,
- system_prompt: str | NotGiven = NOT_GIVEN,
thinking: bool | NotGiven = NOT_GIVEN,
vision: bool | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -64,7 +64,34 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileView:
"""
- Create Agent Profile
+ Create a new agent profile for the authenticated user.
+
+ Agent profiles define how your AI agents behave during tasks. You can create
+ multiple profiles for different use cases (e.g., customer support, data
+ analysis, web scraping). Free users can create 1 profile; paid users can create
+ unlimited profiles.
+
+ Key features you can configure:
+
+ - System prompt: The core instructions that define the agent's personality and
+ behavior
+ - Allowed domains: Restrict which websites the agent can access
+ - Max steps: Limit how many actions the agent can take in a single task
+ - Vision: Enable/disable the agent's ability to see and analyze screenshots
+ - Thinking: Enable/disable the agent's reasoning process
+
+ Args:
+
+ - request: The agent profile configuration including name, description, and
+ behavior settings
+
+ Returns:
+
+ - The newly created agent profile with all its details
+
+ Raises:
+
+ - 402: If user needs a subscription to create additional profiles
Args:
extra_headers: Send extra headers
@@ -81,11 +108,11 @@ def create(
{
"name": name,
"allowed_domains": allowed_domains,
+ "custom_system_prompt_extension": custom_system_prompt_extension,
"description": description,
"flash_mode": flash_mode,
"highlight_elements": highlight_elements,
"max_agent_steps": max_agent_steps,
- "system_prompt": system_prompt,
"thinking": thinking,
"vision": vision,
},
@@ -109,7 +136,22 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileView:
"""
- Get Agent Profile
+ Get a specific agent profile by its ID.
+
+ Retrieves the complete details of an agent profile, including all its
+ configuration settings like system prompts, allowed domains, and behavior flags.
+
+ Args:
+
+ - profile_id: The unique identifier of the agent profile
+
+ Returns:
+
+ - Complete agent profile information
+
+ Raises:
+
+ - 404: If the user agent profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -135,12 +177,12 @@ def update(
profile_id: str,
*,
allowed_domains: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ custom_system_prompt_extension: Optional[str] | NotGiven = NOT_GIVEN,
description: Optional[str] | NotGiven = NOT_GIVEN,
flash_mode: Optional[bool] | NotGiven = NOT_GIVEN,
highlight_elements: Optional[bool] | NotGiven = NOT_GIVEN,
max_agent_steps: Optional[int] | NotGiven = NOT_GIVEN,
name: Optional[str] | NotGiven = NOT_GIVEN,
- system_prompt: Optional[str] | NotGiven = NOT_GIVEN,
thinking: Optional[bool] | NotGiven = NOT_GIVEN,
vision: Optional[bool] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -151,7 +193,24 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileView:
"""
- Update Agent Profile
+ Update an existing agent profile.
+
+ Modify any aspect of an agent profile, such as its name, description, system
+ prompt, or behavior settings. Only the fields you provide will be updated; other
+ fields remain unchanged.
+
+ Args:
+
+ - profile_id: The unique identifier of the agent profile to update
+ - request: The fields to update (only provided fields will be changed)
+
+ Returns:
+
+ - The updated agent profile with all its current details
+
+ Raises:
+
+ - 404: If the user agent profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -169,12 +228,12 @@ def update(
body=maybe_transform(
{
"allowed_domains": allowed_domains,
+ "custom_system_prompt_extension": custom_system_prompt_extension,
"description": description,
"flash_mode": flash_mode,
"highlight_elements": highlight_elements,
"max_agent_steps": max_agent_steps,
"name": name,
- "system_prompt": system_prompt,
"thinking": thinking,
"vision": vision,
},
@@ -199,7 +258,17 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileListResponse:
"""
- List Agent Profiles
+ Get a paginated list of all agent profiles for the authenticated user.
+
+ Agent profiles define how your AI agents behave, including their personality,
+ capabilities, and limitations. Use this endpoint to see all your configured
+ agent profiles.
+
+ Returns:
+
+ - A paginated list of agent profiles
+ - Total count of profiles
+ - Page information for navigation
Args:
extra_headers: Send extra headers
@@ -238,9 +307,21 @@ def delete(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> None:
"""
- Delete Agent Profile
+ Delete an agent profile.
+
+ Permanently removes an agent profile and all its configuration. This action
+ cannot be undone. Any tasks that were using this profile will continue to work,
+ but you won't be able to create new tasks with the deleted profile.
+
+ Args:
+
+ - profile_id: The unique identifier of the agent profile to delete
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
Args:
extra_headers: Send extra headers
@@ -253,12 +334,13 @@ def delete(
"""
if not profile_id:
raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
f"/agent-profiles/{profile_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=object,
+ cast_to=NoneType,
)
@@ -287,11 +369,11 @@ async def create(
*,
name: str,
allowed_domains: List[str] | NotGiven = NOT_GIVEN,
+ custom_system_prompt_extension: str | NotGiven = NOT_GIVEN,
description: str | NotGiven = NOT_GIVEN,
flash_mode: bool | NotGiven = NOT_GIVEN,
highlight_elements: bool | NotGiven = NOT_GIVEN,
max_agent_steps: int | NotGiven = NOT_GIVEN,
- system_prompt: str | NotGiven = NOT_GIVEN,
thinking: bool | NotGiven = NOT_GIVEN,
vision: bool | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -302,7 +384,34 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileView:
"""
- Create Agent Profile
+ Create a new agent profile for the authenticated user.
+
+ Agent profiles define how your AI agents behave during tasks. You can create
+ multiple profiles for different use cases (e.g., customer support, data
+ analysis, web scraping). Free users can create 1 profile; paid users can create
+ unlimited profiles.
+
+ Key features you can configure:
+
+ - System prompt: The core instructions that define the agent's personality and
+ behavior
+ - Allowed domains: Restrict which websites the agent can access
+ - Max steps: Limit how many actions the agent can take in a single task
+ - Vision: Enable/disable the agent's ability to see and analyze screenshots
+ - Thinking: Enable/disable the agent's reasoning process
+
+ Args:
+
+ - request: The agent profile configuration including name, description, and
+ behavior settings
+
+ Returns:
+
+ - The newly created agent profile with all its details
+
+ Raises:
+
+ - 402: If user needs a subscription to create additional profiles
Args:
extra_headers: Send extra headers
@@ -319,11 +428,11 @@ async def create(
{
"name": name,
"allowed_domains": allowed_domains,
+ "custom_system_prompt_extension": custom_system_prompt_extension,
"description": description,
"flash_mode": flash_mode,
"highlight_elements": highlight_elements,
"max_agent_steps": max_agent_steps,
- "system_prompt": system_prompt,
"thinking": thinking,
"vision": vision,
},
@@ -347,7 +456,22 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileView:
"""
- Get Agent Profile
+ Get a specific agent profile by its ID.
+
+ Retrieves the complete details of an agent profile, including all its
+ configuration settings like system prompts, allowed domains, and behavior flags.
+
+ Args:
+
+ - profile_id: The unique identifier of the agent profile
+
+ Returns:
+
+ - Complete agent profile information
+
+ Raises:
+
+ - 404: If the user agent profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -373,12 +497,12 @@ async def update(
profile_id: str,
*,
allowed_domains: Optional[List[str]] | NotGiven = NOT_GIVEN,
+ custom_system_prompt_extension: Optional[str] | NotGiven = NOT_GIVEN,
description: Optional[str] | NotGiven = NOT_GIVEN,
flash_mode: Optional[bool] | NotGiven = NOT_GIVEN,
highlight_elements: Optional[bool] | NotGiven = NOT_GIVEN,
max_agent_steps: Optional[int] | NotGiven = NOT_GIVEN,
name: Optional[str] | NotGiven = NOT_GIVEN,
- system_prompt: Optional[str] | NotGiven = NOT_GIVEN,
thinking: Optional[bool] | NotGiven = NOT_GIVEN,
vision: Optional[bool] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -389,7 +513,24 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileView:
"""
- Update Agent Profile
+ Update an existing agent profile.
+
+ Modify any aspect of an agent profile, such as its name, description, system
+ prompt, or behavior settings. Only the fields you provide will be updated; other
+ fields remain unchanged.
+
+ Args:
+
+ - profile_id: The unique identifier of the agent profile to update
+ - request: The fields to update (only provided fields will be changed)
+
+ Returns:
+
+ - The updated agent profile with all its current details
+
+ Raises:
+
+ - 404: If the user agent profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -407,12 +548,12 @@ async def update(
body=await async_maybe_transform(
{
"allowed_domains": allowed_domains,
+ "custom_system_prompt_extension": custom_system_prompt_extension,
"description": description,
"flash_mode": flash_mode,
"highlight_elements": highlight_elements,
"max_agent_steps": max_agent_steps,
"name": name,
- "system_prompt": system_prompt,
"thinking": thinking,
"vision": vision,
},
@@ -437,7 +578,17 @@ async def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> AgentProfileListResponse:
"""
- List Agent Profiles
+ Get a paginated list of all agent profiles for the authenticated user.
+
+ Agent profiles define how your AI agents behave, including their personality,
+ capabilities, and limitations. Use this endpoint to see all your configured
+ agent profiles.
+
+ Returns:
+
+ - A paginated list of agent profiles
+ - Total count of profiles
+ - Page information for navigation
Args:
extra_headers: Send extra headers
@@ -476,9 +627,21 @@ async def delete(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> None:
"""
- Delete Agent Profile
+ Delete an agent profile.
+
+ Permanently removes an agent profile and all its configuration. This action
+ cannot be undone. Any tasks that were using this profile will continue to work,
+ but you won't be able to create new tasks with the deleted profile.
+
+ Args:
+
+ - profile_id: The unique identifier of the agent profile to delete
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
Args:
extra_headers: Send extra headers
@@ -491,12 +654,13 @@ async def delete(
"""
if not profile_id:
raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
f"/agent-profiles/{profile_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=object,
+ cast_to=NoneType,
)
diff --git a/src/browser_use_sdk/resources/browser_profiles.py b/src/browser_use_sdk/resources/browser_profiles.py
index 74befe1..3a8b417 100644
--- a/src/browser_use_sdk/resources/browser_profiles.py
+++ b/src/browser_use_sdk/resources/browser_profiles.py
@@ -12,7 +12,7 @@
browser_profile_create_params,
browser_profile_update_params,
)
-from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -71,7 +71,33 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileView:
"""
- Create Browser Profile
+ Create a new browser profile for the authenticated user.
+
+ Browser profiles define how your web browsers behave during AI agent tasks. You
+ can create multiple profiles for different use cases (e.g., mobile testing,
+ desktop browsing, proxy-enabled scraping). Free users can create up to 10
+ profiles; paid users can create unlimited profiles.
+
+ Key features you can configure:
+
+ - Viewport dimensions: Set the browser window size for consistent rendering
+ - Mobile emulation: Enable mobile device simulation
+ - Proxy settings: Route traffic through specific locations or proxy servers
+ - Ad blocking: Enable/disable ad blocking for cleaner browsing
+ - Cache persistence: Choose whether to save browser data between sessions
+
+ Args:
+
+ - request: The browser profile configuration including name, description, and
+ browser settings
+
+ Returns:
+
+ - The newly created browser profile with all its details
+
+ Raises:
+
+ - 402: If user needs a subscription to create additional profiles
Args:
extra_headers: Send extra headers
@@ -117,7 +143,23 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileView:
"""
- Get Browser Profile
+ Get a specific browser profile by its ID.
+
+ Retrieves the complete details of a browser profile, including all its
+ configuration settings like viewport dimensions, proxy settings, and behavior
+ flags.
+
+ Args:
+
+ - profile_id: The unique identifier of the browser profile
+
+ Returns:
+
+ - Complete browser profile information
+
+ Raises:
+
+ - 404: If the user browser profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -160,7 +202,24 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileView:
"""
- Update Browser Profile
+ Update an existing browser profile.
+
+ Modify any aspect of a browser profile, such as its name, description, viewport
+ settings, or proxy configuration. Only the fields you provide will be updated;
+ other fields remain unchanged.
+
+ Args:
+
+ - profile_id: The unique identifier of the browser profile to update
+ - request: The fields to update (only provided fields will be changed)
+
+ Returns:
+
+ - The updated browser profile with all its current details
+
+ Raises:
+
+ - 404: If the user browser profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -209,7 +268,17 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileListResponse:
"""
- List Browser Profiles
+ Get a paginated list of all browser profiles for the authenticated user.
+
+ Browser profiles define how your web browsers behave during AI agent tasks,
+ including settings like viewport size, mobile emulation, proxy configuration,
+ and ad blocking. Use this endpoint to see all your configured browser profiles.
+
+ Returns:
+
+ - A paginated list of browser profiles
+ - Total count of profiles
+ - Page information for navigation
Args:
extra_headers: Send extra headers
@@ -248,9 +317,22 @@ def delete(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> None:
"""
- Delete Browser Profile
+ Delete a browser profile.
+
+ Permanently removes a browser profile and all its configuration. This action
+ cannot be undone. The profile will also be removed from the browser service. Any
+ active sessions using this profile will continue to work, but you won't be able
+ to create new sessions with the deleted profile.
+
+ Args:
+
+ - profile_id: The unique identifier of the browser profile to delete
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
Args:
extra_headers: Send extra headers
@@ -263,12 +345,13 @@ def delete(
"""
if not profile_id:
raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
f"/browser-profiles/{profile_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=object,
+ cast_to=NoneType,
)
@@ -313,7 +396,33 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileView:
"""
- Create Browser Profile
+ Create a new browser profile for the authenticated user.
+
+ Browser profiles define how your web browsers behave during AI agent tasks. You
+ can create multiple profiles for different use cases (e.g., mobile testing,
+ desktop browsing, proxy-enabled scraping). Free users can create up to 10
+ profiles; paid users can create unlimited profiles.
+
+ Key features you can configure:
+
+ - Viewport dimensions: Set the browser window size for consistent rendering
+ - Mobile emulation: Enable mobile device simulation
+ - Proxy settings: Route traffic through specific locations or proxy servers
+ - Ad blocking: Enable/disable ad blocking for cleaner browsing
+ - Cache persistence: Choose whether to save browser data between sessions
+
+ Args:
+
+ - request: The browser profile configuration including name, description, and
+ browser settings
+
+ Returns:
+
+ - The newly created browser profile with all its details
+
+ Raises:
+
+ - 402: If user needs a subscription to create additional profiles
Args:
extra_headers: Send extra headers
@@ -359,7 +468,23 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileView:
"""
- Get Browser Profile
+ Get a specific browser profile by its ID.
+
+ Retrieves the complete details of a browser profile, including all its
+ configuration settings like viewport dimensions, proxy settings, and behavior
+ flags.
+
+ Args:
+
+ - profile_id: The unique identifier of the browser profile
+
+ Returns:
+
+ - Complete browser profile information
+
+ Raises:
+
+ - 404: If the user browser profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -402,7 +527,24 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileView:
"""
- Update Browser Profile
+ Update an existing browser profile.
+
+ Modify any aspect of a browser profile, such as its name, description, viewport
+ settings, or proxy configuration. Only the fields you provide will be updated;
+ other fields remain unchanged.
+
+ Args:
+
+ - profile_id: The unique identifier of the browser profile to update
+ - request: The fields to update (only provided fields will be changed)
+
+ Returns:
+
+ - The updated browser profile with all its current details
+
+ Raises:
+
+ - 404: If the user browser profile doesn't exist
Args:
extra_headers: Send extra headers
@@ -451,7 +593,17 @@ async def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> BrowserProfileListResponse:
"""
- List Browser Profiles
+ Get a paginated list of all browser profiles for the authenticated user.
+
+ Browser profiles define how your web browsers behave during AI agent tasks,
+ including settings like viewport size, mobile emulation, proxy configuration,
+ and ad blocking. Use this endpoint to see all your configured browser profiles.
+
+ Returns:
+
+ - A paginated list of browser profiles
+ - Total count of profiles
+ - Page information for navigation
Args:
extra_headers: Send extra headers
@@ -490,9 +642,22 @@ async def delete(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> None:
"""
- Delete Browser Profile
+ Delete a browser profile.
+
+ Permanently removes a browser profile and all its configuration. This action
+ cannot be undone. The profile will also be removed from the browser service. Any
+ active sessions using this profile will continue to work, but you won't be able
+ to create new sessions with the deleted profile.
+
+ Args:
+
+ - profile_id: The unique identifier of the browser profile to delete
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
Args:
extra_headers: Send extra headers
@@ -505,12 +670,13 @@ async def delete(
"""
if not profile_id:
raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
f"/browser-profiles/{profile_id}",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=object,
+ cast_to=NoneType,
)
diff --git a/src/browser_use_sdk/resources/sessions/public_share.py b/src/browser_use_sdk/resources/sessions/public_share.py
index f7381d0..8a235d9 100644
--- a/src/browser_use_sdk/resources/sessions/public_share.py
+++ b/src/browser_use_sdk/resources/sessions/public_share.py
@@ -4,7 +4,7 @@
import httpx
-from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -51,7 +51,29 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ShareView:
"""
- Create Session Public Share
+ Create a public share for a session.
+
+ Generates a public sharing link that allows anyone with the URL to view the
+ session and its tasks. If a public share already exists for the session, it will
+ return the existing share instead of creating a new one.
+
+ Public shares are useful for:
+
+ - Sharing results with clients or team members
+ - Demonstrating AI agent capabilities
+ - Collaborative review of automated tasks
+
+ Args:
+
+ - session_id: The unique identifier of the agent session to share
+
+ Returns:
+
+ - Public share information including the share URL and usage statistics
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
extra_headers: Send extra headers
@@ -84,7 +106,23 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ShareView:
"""
- Get Session Public Share
+ Get information about the public share for a session.
+
+ Retrieves details about the public sharing link for a session, including the
+ share token, public URL, view count, and last viewed timestamp. This is useful
+ for monitoring how your shared sessions are being accessed.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session
+
+ Returns:
+
+ - Public share information including the share URL and usage statistics
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist or doesn't have a public share
Args:
extra_headers: Send extra headers
@@ -115,9 +153,25 @@ def delete(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> None:
"""
- Delete Session Public Share
+ Remove the public share for a session.
+
+ Deletes the public sharing link for a session, making it no longer accessible to
+ anyone with the previous share URL. This is useful for removing access to
+ sensitive sessions or when you no longer want to share the results.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
extra_headers: Send extra headers
@@ -130,12 +184,13 @@ def delete(
"""
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._delete(
f"/sessions/{session_id}/public-share",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=object,
+ cast_to=NoneType,
)
@@ -171,7 +226,29 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ShareView:
"""
- Create Session Public Share
+ Create a public share for a session.
+
+ Generates a public sharing link that allows anyone with the URL to view the
+ session and its tasks. If a public share already exists for the session, it will
+ return the existing share instead of creating a new one.
+
+ Public shares are useful for:
+
+ - Sharing results with clients or team members
+ - Demonstrating AI agent capabilities
+ - Collaborative review of automated tasks
+
+ Args:
+
+ - session_id: The unique identifier of the agent session to share
+
+ Returns:
+
+ - Public share information including the share URL and usage statistics
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
extra_headers: Send extra headers
@@ -204,7 +281,23 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> ShareView:
"""
- Get Session Public Share
+ Get information about the public share for a session.
+
+ Retrieves details about the public sharing link for a session, including the
+ share token, public URL, view count, and last viewed timestamp. This is useful
+ for monitoring how your shared sessions are being accessed.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session
+
+ Returns:
+
+ - Public share information including the share URL and usage statistics
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist or doesn't have a public share
Args:
extra_headers: Send extra headers
@@ -235,9 +328,25 @@ async def delete(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> object:
+ ) -> None:
"""
- Delete Session Public Share
+ Remove the public share for a session.
+
+ Deletes the public sharing link for a session, making it no longer accessible to
+ anyone with the previous share URL. This is useful for removing access to
+ sensitive sessions or when you no longer want to share the results.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
extra_headers: Send extra headers
@@ -250,12 +359,13 @@ async def delete(
"""
if not session_id:
raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._delete(
f"/sessions/{session_id}/public-share",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=object,
+ cast_to=NoneType,
)
diff --git a/src/browser_use_sdk/resources/sessions/sessions.py b/src/browser_use_sdk/resources/sessions/sessions.py
index 6b6a664..eb99bba 100644
--- a/src/browser_use_sdk/resources/sessions/sessions.py
+++ b/src/browser_use_sdk/resources/sessions/sessions.py
@@ -71,7 +71,25 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SessionView:
"""
- Get Session
+ Get detailed information about a specific AI agent session.
+
+ Retrieves comprehensive information about a session, including its current
+ status, live browser URL (if active), recording URL (if completed), and optional
+ task details. This endpoint is useful for monitoring active sessions or
+ reviewing completed ones.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session
+ - params: Optional parameters to control what data is included
+
+ Returns:
+
+ - Complete session information including status, URLs, and optional task details
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
extra_headers: Send extra headers
@@ -109,12 +127,36 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SessionView:
"""
- Update Session
+ Update a session's status or perform actions on it.
+
+ Currently supports stopping a session, which will:
+
+ 1. Stop any running tasks in the session
+ 2. End the browser session
+ 3. Generate a recording URL if available
+ 4. Update the session status to 'stopped'
+
+ This is useful for manually stopping long-running sessions or when you want to
+ end a session before all tasks are complete.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session to update
+ - request: The action to perform on the session
+
+ Returns:
+
+ - The updated session information including the new status and recording URL
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
action: Available actions that can be performed on a session
- Attributes: STOP: Stop the session and all its associated tasks
+ Attributes: STOP: Stop the session and all its associated tasks (cannot be
+ undone)
extra_headers: Send extra headers
@@ -150,14 +192,27 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SessionListResponse:
"""
- List Sessions
+ Get a paginated list of all AI agent sessions for the authenticated user.
+
+ AI agent sessions represent active or completed browsing sessions where your AI
+ agents perform tasks. Each session can contain multiple tasks and maintains
+ browser state throughout the session lifecycle.
+
+ You can filter sessions by status and optionally include task details for each
+ session.
+
+ Returns:
+
+ - A paginated list of agent sessions
+ - Total count of sessions
+ - Page information for navigation
+ - Optional task details for each session (if requested)
Args:
filter_by: Enumeration of possible (browser) session states
- Attributes: ACTIVE: Session is currently active and running (aka browser is
- running) STOPPED: Session has been stopped and is no longer active (aka browser
- is stopped)
+ Attributes: ACTIVE: Session is currently active and running (browser is running)
+ STOPPED: Session has been stopped and is no longer active (browser is stopped)
extra_headers: Send extra headers
@@ -225,7 +280,25 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SessionView:
"""
- Get Session
+ Get detailed information about a specific AI agent session.
+
+ Retrieves comprehensive information about a session, including its current
+ status, live browser URL (if active), recording URL (if completed), and optional
+ task details. This endpoint is useful for monitoring active sessions or
+ reviewing completed ones.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session
+ - params: Optional parameters to control what data is included
+
+ Returns:
+
+ - Complete session information including status, URLs, and optional task details
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
extra_headers: Send extra headers
@@ -265,12 +338,36 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SessionView:
"""
- Update Session
+ Update a session's status or perform actions on it.
+
+ Currently supports stopping a session, which will:
+
+ 1. Stop any running tasks in the session
+ 2. End the browser session
+ 3. Generate a recording URL if available
+ 4. Update the session status to 'stopped'
+
+ This is useful for manually stopping long-running sessions or when you want to
+ end a session before all tasks are complete.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session to update
+ - request: The action to perform on the session
+
+ Returns:
+
+ - The updated session information including the new status and recording URL
+
+ Raises:
+
+ - 404: If the user agent session doesn't exist
Args:
action: Available actions that can be performed on a session
- Attributes: STOP: Stop the session and all its associated tasks
+ Attributes: STOP: Stop the session and all its associated tasks (cannot be
+ undone)
extra_headers: Send extra headers
@@ -306,14 +403,27 @@ async def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SessionListResponse:
"""
- List Sessions
+ Get a paginated list of all AI agent sessions for the authenticated user.
+
+ AI agent sessions represent active or completed browsing sessions where your AI
+ agents perform tasks. Each session can contain multiple tasks and maintains
+ browser state throughout the session lifecycle.
+
+ You can filter sessions by status and optionally include task details for each
+ session.
+
+ Returns:
+
+ - A paginated list of agent sessions
+ - Total count of sessions
+ - Page information for navigation
+ - Optional task details for each session (if requested)
Args:
filter_by: Enumeration of possible (browser) session states
- Attributes: ACTIVE: Session is currently active and running (aka browser is
- running) STOPPED: Session has been stopped and is no longer active (aka browser
- is stopped)
+ Attributes: ACTIVE: Session is currently active and running (browser is running)
+ STOPPED: Session has been stopped and is no longer active (browser is stopped)
extra_headers: Send extra headers
diff --git a/src/browser_use_sdk/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
index de55623..3db6831 100644
--- a/src/browser_use_sdk/resources/tasks.py
+++ b/src/browser_use_sdk/resources/tasks.py
@@ -2,12 +2,12 @@
from __future__ import annotations
-from typing import Any, Dict, List, Optional, cast
+from typing import Dict, List, Optional
from typing_extensions import Literal
import httpx
-from ..types import task_list_params, task_create_params, task_update_params, task_retrieve_params
+from ..types import task_list_params, task_create_params, task_update_params
from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -21,9 +21,7 @@
from .._base_client import make_request_options
from ..types.task_view import TaskView
from ..types.task_list_response import TaskListResponse
-from ..types.task_retrieve_response import TaskRetrieveResponse
from ..types.task_retrieve_logs_response import TaskRetrieveLogsResponse
-from ..types.task_retrieve_output_file_response import TaskRetrieveOutputFileResponse
__all__ = ["TasksResource", "AsyncTasksResource"]
@@ -66,21 +64,62 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskView:
"""
- Create Task
+ Create and start a new AI agent task.
+
+ This is the main endpoint for running AI agents. You can either:
+
+ 1. Start a new session with a new task
+ 2. Add a follow-up task to an existing session
+
+ When starting a new session:
+
+ - A new browser session is created
+ - Credits are deducted from your account
+ - The agent begins executing your task immediately
+
+ When adding to an existing session:
+
+ - The agent continues in the same browser context
+ - No additional browser start up costs are charged (browser session is already
+ active)
+ - The agent can build on previous work
+
+ Key features:
+
+ - Agent profiles: Define agent behavior and capabilities
+ - Browser profiles: Control browser settings and environment (only used for new
+ sessions)
+ - File uploads: Include documents for the agent to work with
+ - Structured output: Define the format you want results in
+ - Task metadata: Add custom data for tracking and organization (useful when
+ using webhooks)
+
+ Args:
+
+ - request: Complete task configuration including agent settings, browser
+ settings, and task description
+
+ Returns:
+
+ - The created task with its initial details
+
+ Raises:
+
+ - 402: If user has insufficient credits for a new session
+ - 404: If referenced agent/browser profiles don't exist
+ - 400: If session is stopped or already has a running task
Args:
agent_settings: Configuration settings for the AI agent
- Attributes: llm: The LLM model to use for the agent (default: O3 - best
- performance for now) profile_id: ID of the agent profile to use for the task
- (None for default)
+ Attributes: llm: The LLM model to use for the agent profile_id: Unique
+ identifier of the agent profile to use for the task
browser_settings: Configuration settings for the browser session
- Attributes: session_id: ID of existing session to continue (None for new
- session) profile_id: ID of browser profile to use (None for default)
- save_browser_data: Whether to save browser state/data for the user to download
- later
+ Attributes: session_id: Unique identifier of existing session to continue
+ profile_id: Unique identifier of browser profile to use save_browser_data:
+ Whether to save browser state/data for the user to download later
extra_headers: Send extra headers
@@ -114,16 +153,38 @@ def retrieve(
self,
task_id: str,
*,
- status_only: bool | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskRetrieveResponse:
+ ) -> TaskView:
"""
- Get Task
+ Get detailed information about a specific AI agent task.
+
+ Retrieves comprehensive information about a task, including its current status,
+ progress, and detailed execution data. You can choose to get just the status
+ (for quick polling) or full details including steps and file information.
+
+ Use this endpoint to:
+
+ - Monitor task progress in real-time
+ - Review completed task results
+ - Debug failed tasks by examining steps
+ - Download output files and logs
+
+ Args:
+
+ - task_id: The unique identifier of the agent task
+
+ Returns:
+
+ - Complete task information
+
+ Raises:
+
+ - 404: If the user agent task doesn't exist
Args:
extra_headers: Send extra headers
@@ -136,21 +197,12 @@ def retrieve(
"""
if not task_id:
raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
- return cast(
- TaskRetrieveResponse,
- self._get(
- f"/tasks/{task_id}",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"status_only": status_only}, task_retrieve_params.TaskRetrieveParams),
- ),
- cast_to=cast(
- Any, TaskRetrieveResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return self._get(
+ f"/tasks/{task_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=TaskView,
)
def update(
@@ -166,7 +218,34 @@ def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskView:
"""
- Update Task
+ Control the execution of an AI agent task.
+
+ Allows you to pause, resume, or stop tasks, and optionally stop the entire
+ session. This is useful for:
+
+ - Pausing long-running tasks to review progress
+ - Stopping tasks that are taking too long
+ - Ending sessions when you're done with all tasks
+
+ Available actions:
+
+ - STOP: Stop the current task
+ - PAUSE: Pause the task (can be resumed later)
+ - RESUME: Resume a paused task
+ - STOP_TASK_AND_SESSION: Stop the task and end the entire session
+
+ Args:
+
+ - task_id: The unique identifier of the agent task to control
+ - request: The action to perform on the task
+
+ Returns:
+
+ - The updated task information
+
+ Raises:
+
+ - 404: If the user agent task doesn't exist
Args:
action: Available actions that can be performed on a task
@@ -197,11 +276,14 @@ def update(
def list(
self,
*,
+ filter_by: Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]]
+ | NotGiven = NOT_GIVEN,
include_output_files: bool | NotGiven = NOT_GIVEN,
include_steps: bool | NotGiven = NOT_GIVEN,
include_user_uploaded_files: bool | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
+ session_id: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -210,9 +292,33 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskListResponse:
"""
- List Tasks
+ Get a paginated list of all AI agent tasks for the authenticated user.
+
+ AI agent tasks are the individual jobs that your agents perform within a
+ session. Each task represents a specific instruction or goal that the agent
+ works on, such as filling out a form, extracting data, or navigating to specific
+ pages.
+
+ You can control what data is included for each task:
+
+ - Task steps: Detailed actions the agent took
+ - User uploaded files: Files you provided for the task
+ - Output files: Files generated by the agent during the task
+
+ Returns:
+
+ - A paginated list of agent tasks
+ - Total count of tasks
+ - Page information for navigation
+ - Optional detailed data based on your parameters
Args:
+ filter_by: Enumeration of possible task filters
+
+ Attributes: STARTED: All started tasks PAUSED: All paused tasks STOPPED: All
+ stopped tasks FINISHED: All finished tasks SUCCESSFUL: All successful tasks
+ UNSUCCESSFUL: All unsuccessful tasks
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -230,11 +336,13 @@ def list(
timeout=timeout,
query=maybe_transform(
{
+ "filter_by": filter_by,
"include_output_files": include_output_files,
"include_steps": include_steps,
"include_user_uploaded_files": include_user_uploaded_files,
"page_number": page_number,
"page_size": page_size,
+ "session_id": session_id,
},
task_list_params.TaskListParams,
),
@@ -254,41 +362,35 @@ def retrieve_logs(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskRetrieveLogsResponse:
"""
- Get Task Logs
+ Get a download URL for the execution logs of an AI agent task.
+
+ Task logs contain detailed information about how the AI agent executed the task,
+ including:
+
+ - Step-by-step reasoning and decisions
+ - Actions taken on web pages
+ - Error messages and debugging information
+ - Performance metrics and timing data
+
+ This is useful for:
+
+ - Understanding how the agent solved the task
+ - Debugging failed or unexpected results
+ - Optimizing agent behavior and prompts
+ - Auditing agent actions for compliance
Args:
- extra_headers: Send extra headers
- extra_query: Add additional query parameters to the request
+ - task_id: The unique identifier of the agent task
- extra_body: Add additional JSON properties to the request
+ Returns:
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not task_id:
- raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
- return self._get(
- f"/tasks/{task_id}/logs",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=TaskRetrieveLogsResponse,
- )
+ - A presigned download URL for the task log file
- def retrieve_output_file(
- self,
- file_name: str,
- *,
- task_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskRetrieveOutputFileResponse:
- """
- Get Task Output File
+ Raises:
+
+ - 404: If the user agent task doesn't exist
+ - 500: If the download URL cannot be generated (should not happen)
Args:
extra_headers: Send extra headers
@@ -301,14 +403,12 @@ def retrieve_output_file(
"""
if not task_id:
raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
- if not file_name:
- raise ValueError(f"Expected a non-empty value for `file_name` but received {file_name!r}")
return self._get(
- f"/tasks/{task_id}/output-files/{file_name}",
+ f"/tasks/{task_id}/logs",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TaskRetrieveOutputFileResponse,
+ cast_to=TaskRetrieveLogsResponse,
)
@@ -350,21 +450,62 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskView:
"""
- Create Task
+ Create and start a new AI agent task.
+
+ This is the main endpoint for running AI agents. You can either:
+
+ 1. Start a new session with a new task
+ 2. Add a follow-up task to an existing session
+
+ When starting a new session:
+
+ - A new browser session is created
+ - Credits are deducted from your account
+ - The agent begins executing your task immediately
+
+ When adding to an existing session:
+
+ - The agent continues in the same browser context
+ - No additional browser start up costs are charged (browser session is already
+ active)
+ - The agent can build on previous work
+
+ Key features:
+
+ - Agent profiles: Define agent behavior and capabilities
+ - Browser profiles: Control browser settings and environment (only used for new
+ sessions)
+ - File uploads: Include documents for the agent to work with
+ - Structured output: Define the format you want results in
+ - Task metadata: Add custom data for tracking and organization (useful when
+ using webhooks)
+
+ Args:
+
+ - request: Complete task configuration including agent settings, browser
+ settings, and task description
+
+ Returns:
+
+ - The created task with its initial details
+
+ Raises:
+
+ - 402: If user has insufficient credits for a new session
+ - 404: If referenced agent/browser profiles don't exist
+ - 400: If session is stopped or already has a running task
Args:
agent_settings: Configuration settings for the AI agent
- Attributes: llm: The LLM model to use for the agent (default: O3 - best
- performance for now) profile_id: ID of the agent profile to use for the task
- (None for default)
+ Attributes: llm: The LLM model to use for the agent profile_id: Unique
+ identifier of the agent profile to use for the task
browser_settings: Configuration settings for the browser session
- Attributes: session_id: ID of existing session to continue (None for new
- session) profile_id: ID of browser profile to use (None for default)
- save_browser_data: Whether to save browser state/data for the user to download
- later
+ Attributes: session_id: Unique identifier of existing session to continue
+ profile_id: Unique identifier of browser profile to use save_browser_data:
+ Whether to save browser state/data for the user to download later
extra_headers: Send extra headers
@@ -398,16 +539,38 @@ async def retrieve(
self,
task_id: str,
*,
- status_only: bool | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskRetrieveResponse:
+ ) -> TaskView:
"""
- Get Task
+ Get detailed information about a specific AI agent task.
+
+ Retrieves comprehensive information about a task, including its current status,
+ progress, and detailed execution data. You can choose to get just the status
+ (for quick polling) or full details including steps and file information.
+
+ Use this endpoint to:
+
+ - Monitor task progress in real-time
+ - Review completed task results
+ - Debug failed tasks by examining steps
+ - Download output files and logs
+
+ Args:
+
+ - task_id: The unique identifier of the agent task
+
+ Returns:
+
+ - Complete task information
+
+ Raises:
+
+ - 404: If the user agent task doesn't exist
Args:
extra_headers: Send extra headers
@@ -420,23 +583,12 @@ async def retrieve(
"""
if not task_id:
raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
- return cast(
- TaskRetrieveResponse,
- await self._get(
- f"/tasks/{task_id}",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {"status_only": status_only}, task_retrieve_params.TaskRetrieveParams
- ),
- ),
- cast_to=cast(
- Any, TaskRetrieveResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return await self._get(
+ f"/tasks/{task_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=TaskView,
)
async def update(
@@ -452,7 +604,34 @@ async def update(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskView:
"""
- Update Task
+ Control the execution of an AI agent task.
+
+ Allows you to pause, resume, or stop tasks, and optionally stop the entire
+ session. This is useful for:
+
+ - Pausing long-running tasks to review progress
+ - Stopping tasks that are taking too long
+ - Ending sessions when you're done with all tasks
+
+ Available actions:
+
+ - STOP: Stop the current task
+ - PAUSE: Pause the task (can be resumed later)
+ - RESUME: Resume a paused task
+ - STOP_TASK_AND_SESSION: Stop the task and end the entire session
+
+ Args:
+
+ - task_id: The unique identifier of the agent task to control
+ - request: The action to perform on the task
+
+ Returns:
+
+ - The updated task information
+
+ Raises:
+
+ - 404: If the user agent task doesn't exist
Args:
action: Available actions that can be performed on a task
@@ -483,11 +662,14 @@ async def update(
async def list(
self,
*,
+ filter_by: Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]]
+ | NotGiven = NOT_GIVEN,
include_output_files: bool | NotGiven = NOT_GIVEN,
include_steps: bool | NotGiven = NOT_GIVEN,
include_user_uploaded_files: bool | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
+ session_id: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -496,9 +678,33 @@ async def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskListResponse:
"""
- List Tasks
+ Get a paginated list of all AI agent tasks for the authenticated user.
+
+ AI agent tasks are the individual jobs that your agents perform within a
+ session. Each task represents a specific instruction or goal that the agent
+ works on, such as filling out a form, extracting data, or navigating to specific
+ pages.
+
+ You can control what data is included for each task:
+
+ - Task steps: Detailed actions the agent took
+ - User uploaded files: Files you provided for the task
+ - Output files: Files generated by the agent during the task
+
+ Returns:
+
+ - A paginated list of agent tasks
+ - Total count of tasks
+ - Page information for navigation
+ - Optional detailed data based on your parameters
Args:
+ filter_by: Enumeration of possible task filters
+
+ Attributes: STARTED: All started tasks PAUSED: All paused tasks STOPPED: All
+ stopped tasks FINISHED: All finished tasks SUCCESSFUL: All successful tasks
+ UNSUCCESSFUL: All unsuccessful tasks
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -516,11 +722,13 @@ async def list(
timeout=timeout,
query=await async_maybe_transform(
{
+ "filter_by": filter_by,
"include_output_files": include_output_files,
"include_steps": include_steps,
"include_user_uploaded_files": include_user_uploaded_files,
"page_number": page_number,
"page_size": page_size,
+ "session_id": session_id,
},
task_list_params.TaskListParams,
),
@@ -540,41 +748,35 @@ async def retrieve_logs(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskRetrieveLogsResponse:
"""
- Get Task Logs
+ Get a download URL for the execution logs of an AI agent task.
+
+ Task logs contain detailed information about how the AI agent executed the task,
+ including:
+
+ - Step-by-step reasoning and decisions
+ - Actions taken on web pages
+ - Error messages and debugging information
+ - Performance metrics and timing data
+
+ This is useful for:
+
+ - Understanding how the agent solved the task
+ - Debugging failed or unexpected results
+ - Optimizing agent behavior and prompts
+ - Auditing agent actions for compliance
Args:
- extra_headers: Send extra headers
- extra_query: Add additional query parameters to the request
+ - task_id: The unique identifier of the agent task
- extra_body: Add additional JSON properties to the request
+ Returns:
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not task_id:
- raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
- return await self._get(
- f"/tasks/{task_id}/logs",
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=TaskRetrieveLogsResponse,
- )
+ - A presigned download URL for the task log file
- async def retrieve_output_file(
- self,
- file_name: str,
- *,
- task_id: str,
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this method.
- extra_headers: Headers | None = None,
- extra_query: Query | None = None,
- extra_body: Body | None = None,
- timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskRetrieveOutputFileResponse:
- """
- Get Task Output File
+ Raises:
+
+ - 404: If the user agent task doesn't exist
+ - 500: If the download URL cannot be generated (should not happen)
Args:
extra_headers: Send extra headers
@@ -587,14 +789,12 @@ async def retrieve_output_file(
"""
if not task_id:
raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
- if not file_name:
- raise ValueError(f"Expected a non-empty value for `file_name` but received {file_name!r}")
return await self._get(
- f"/tasks/{task_id}/output-files/{file_name}",
+ f"/tasks/{task_id}/logs",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TaskRetrieveOutputFileResponse,
+ cast_to=TaskRetrieveLogsResponse,
)
@@ -617,9 +817,6 @@ def __init__(self, tasks: TasksResource) -> None:
self.retrieve_logs = to_raw_response_wrapper(
tasks.retrieve_logs,
)
- self.retrieve_output_file = to_raw_response_wrapper(
- tasks.retrieve_output_file,
- )
class AsyncTasksResourceWithRawResponse:
@@ -641,9 +838,6 @@ def __init__(self, tasks: AsyncTasksResource) -> None:
self.retrieve_logs = async_to_raw_response_wrapper(
tasks.retrieve_logs,
)
- self.retrieve_output_file = async_to_raw_response_wrapper(
- tasks.retrieve_output_file,
- )
class TasksResourceWithStreamingResponse:
@@ -665,9 +859,6 @@ def __init__(self, tasks: TasksResource) -> None:
self.retrieve_logs = to_streamed_response_wrapper(
tasks.retrieve_logs,
)
- self.retrieve_output_file = to_streamed_response_wrapper(
- tasks.retrieve_output_file,
- )
class AsyncTasksResourceWithStreamingResponse:
@@ -689,6 +880,3 @@ def __init__(self, tasks: AsyncTasksResource) -> None:
self.retrieve_logs = async_to_streamed_response_wrapper(
tasks.retrieve_logs,
)
- self.retrieve_output_file = async_to_streamed_response_wrapper(
- tasks.retrieve_output_file,
- )
diff --git a/src/browser_use_sdk/types/__init__.py b/src/browser_use_sdk/types/__init__.py
index b2eac92..cd963cf 100644
--- a/src/browser_use_sdk/types/__init__.py
+++ b/src/browser_use_sdk/types/__init__.py
@@ -15,10 +15,8 @@
from .task_update_params import TaskUpdateParams as TaskUpdateParams
from .session_list_params import SessionListParams as SessionListParams
from .browser_profile_view import BrowserProfileView as BrowserProfileView
-from .task_retrieve_params import TaskRetrieveParams as TaskRetrieveParams
from .session_list_response import SessionListResponse as SessionListResponse
from .session_update_params import SessionUpdateParams as SessionUpdateParams
-from .task_retrieve_response import TaskRetrieveResponse as TaskRetrieveResponse
from .session_retrieve_params import SessionRetrieveParams as SessionRetrieveParams
from .agent_profile_list_params import AgentProfileListParams as AgentProfileListParams
from .agent_profile_create_params import AgentProfileCreateParams as AgentProfileCreateParams
@@ -29,4 +27,3 @@
from .browser_profile_create_params import BrowserProfileCreateParams as BrowserProfileCreateParams
from .browser_profile_list_response import BrowserProfileListResponse as BrowserProfileListResponse
from .browser_profile_update_params import BrowserProfileUpdateParams as BrowserProfileUpdateParams
-from .task_retrieve_output_file_response import TaskRetrieveOutputFileResponse as TaskRetrieveOutputFileResponse
diff --git a/src/browser_use_sdk/types/agent_profile_create_params.py b/src/browser_use_sdk/types/agent_profile_create_params.py
index a1adf02..ef3080b 100644
--- a/src/browser_use_sdk/types/agent_profile_create_params.py
+++ b/src/browser_use_sdk/types/agent_profile_create_params.py
@@ -15,6 +15,8 @@ class AgentProfileCreateParams(TypedDict, total=False):
allowed_domains: Annotated[List[str], PropertyInfo(alias="allowedDomains")]
+ custom_system_prompt_extension: Annotated[str, PropertyInfo(alias="customSystemPromptExtension")]
+
description: str
flash_mode: Annotated[bool, PropertyInfo(alias="flashMode")]
@@ -23,8 +25,6 @@ class AgentProfileCreateParams(TypedDict, total=False):
max_agent_steps: Annotated[int, PropertyInfo(alias="maxAgentSteps")]
- system_prompt: Annotated[str, PropertyInfo(alias="systemPrompt")]
-
thinking: bool
vision: bool
diff --git a/src/browser_use_sdk/types/agent_profile_update_params.py b/src/browser_use_sdk/types/agent_profile_update_params.py
index 850ade8..8595815 100644
--- a/src/browser_use_sdk/types/agent_profile_update_params.py
+++ b/src/browser_use_sdk/types/agent_profile_update_params.py
@@ -13,6 +13,8 @@
class AgentProfileUpdateParams(TypedDict, total=False):
allowed_domains: Annotated[Optional[List[str]], PropertyInfo(alias="allowedDomains")]
+ custom_system_prompt_extension: Annotated[Optional[str], PropertyInfo(alias="customSystemPromptExtension")]
+
description: Optional[str]
flash_mode: Annotated[Optional[bool], PropertyInfo(alias="flashMode")]
@@ -23,8 +25,6 @@ class AgentProfileUpdateParams(TypedDict, total=False):
name: Optional[str]
- system_prompt: Annotated[Optional[str], PropertyInfo(alias="systemPrompt")]
-
thinking: Optional[bool]
vision: Optional[bool]
diff --git a/src/browser_use_sdk/types/agent_profile_view.py b/src/browser_use_sdk/types/agent_profile_view.py
index bd98d00..1c10f12 100644
--- a/src/browser_use_sdk/types/agent_profile_view.py
+++ b/src/browser_use_sdk/types/agent_profile_view.py
@@ -17,6 +17,8 @@ class AgentProfileView(BaseModel):
created_at: datetime = FieldInfo(alias="createdAt")
+ custom_system_prompt_extension: str = FieldInfo(alias="customSystemPromptExtension")
+
description: str
flash_mode: bool = FieldInfo(alias="flashMode")
@@ -27,8 +29,6 @@ class AgentProfileView(BaseModel):
name: str
- system_prompt: str = FieldInfo(alias="systemPrompt")
-
thinking: bool
updated_at: datetime = FieldInfo(alias="updatedAt")
diff --git a/src/browser_use_sdk/types/session_list_params.py b/src/browser_use_sdk/types/session_list_params.py
index 2de4f0d..70df445 100644
--- a/src/browser_use_sdk/types/session_list_params.py
+++ b/src/browser_use_sdk/types/session_list_params.py
@@ -15,9 +15,8 @@ class SessionListParams(TypedDict, total=False):
filter_by: Annotated[Optional[SessionStatus], PropertyInfo(alias="filterBy")]
"""Enumeration of possible (browser) session states
- Attributes: ACTIVE: Session is currently active and running (aka browser is
- running) STOPPED: Session has been stopped and is no longer active (aka browser
- is stopped)
+ Attributes: ACTIVE: Session is currently active and running (browser is running)
+ STOPPED: Session has been stopped and is no longer active (browser is stopped)
"""
include_tasks: Annotated[bool, PropertyInfo(alias="includeTasks")]
diff --git a/src/browser_use_sdk/types/session_list_response.py b/src/browser_use_sdk/types/session_list_response.py
index ed6951c..7fae531 100644
--- a/src/browser_use_sdk/types/session_list_response.py
+++ b/src/browser_use_sdk/types/session_list_response.py
@@ -1,17 +1,107 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import Dict, List, Optional
+from datetime import datetime
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .session_view import SessionView
+from .llm_model import LlmModel
+from .task_status import TaskStatus
+from .session_status import SessionStatus
-__all__ = ["SessionListResponse"]
+__all__ = ["SessionListResponse", "Item", "ItemTask", "ItemTaskOutputFile", "ItemTaskStep", "ItemTaskUserUploadedFile"]
+
+
+class ItemTaskOutputFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class ItemTaskStep(BaseModel):
+ actions: List[str]
+
+ evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
+
+ memory: str
+
+ next_goal: str = FieldInfo(alias="nextGoal")
+
+ number: int
+
+ url: str
+
+ screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
+
+
+class ItemTaskUserUploadedFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class ItemTask(BaseModel):
+ id: str
+
+ is_scheduled: bool = FieldInfo(alias="isScheduled")
+
+ llm: LlmModel
+
+ session_id: str = FieldInfo(alias="sessionId")
+
+ started_at: datetime = FieldInfo(alias="startedAt")
+
+ status: TaskStatus
+ """Enumeration of possible task execution states
+
+ Attributes: STARTED: Task has been started and is currently running PAUSED: Task
+ execution has been temporarily paused (can be resumed) STOPPED: Task execution
+ has been stopped (cannot be resumed) FINISHED: Task has completed successfully
+ """
+
+ task: str
+
+ browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
+
+ done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
+
+ finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
+
+ is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
+
+ metadata: Optional[Dict[str, object]] = None
+
+ output_files: Optional[List[ItemTaskOutputFile]] = FieldInfo(alias="outputFiles", default=None)
+
+ session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
+
+ steps: Optional[List[ItemTaskStep]] = None
+
+ user_uploaded_files: Optional[List[ItemTaskUserUploadedFile]] = FieldInfo(alias="userUploadedFiles", default=None)
+
+
+class Item(BaseModel):
+ id: str
+
+ started_at: datetime = FieldInfo(alias="startedAt")
+
+ status: SessionStatus
+ """Enumeration of possible (browser) session states
+
+ Attributes: ACTIVE: Session is currently active and running (browser is running)
+ STOPPED: Session has been stopped and is no longer active (browser is stopped)
+ """
+
+ finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
+
+ live_url: Optional[str] = FieldInfo(alias="liveUrl", default=None)
+
+ tasks: Optional[List[ItemTask]] = None
class SessionListResponse(BaseModel):
- items: List[SessionView]
+ items: List[Item]
page_number: int = FieldInfo(alias="pageNumber")
diff --git a/src/browser_use_sdk/types/session_update_params.py b/src/browser_use_sdk/types/session_update_params.py
index f722648..92734a7 100644
--- a/src/browser_use_sdk/types/session_update_params.py
+++ b/src/browser_use_sdk/types/session_update_params.py
@@ -11,5 +11,6 @@ class SessionUpdateParams(TypedDict, total=False):
action: Required[Literal["stop"]]
"""Available actions that can be performed on a session
- Attributes: STOP: Stop the session and all its associated tasks
+ Attributes: STOP: Stop the session and all its associated tasks (cannot be
+ undone)
"""
diff --git a/src/browser_use_sdk/types/session_view.py b/src/browser_use_sdk/types/session_view.py
index 0ad8e00..9d00083 100644
--- a/src/browser_use_sdk/types/session_view.py
+++ b/src/browser_use_sdk/types/session_view.py
@@ -1,15 +1,84 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Dict, List, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .task_view import TaskView
+from .llm_model import LlmModel
+from .task_status import TaskStatus
from .session_status import SessionStatus
-__all__ = ["SessionView"]
+__all__ = ["SessionView", "Task", "TaskOutputFile", "TaskStep", "TaskUserUploadedFile"]
+
+
+class TaskOutputFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class TaskStep(BaseModel):
+ actions: List[str]
+
+ evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
+
+ memory: str
+
+ next_goal: str = FieldInfo(alias="nextGoal")
+
+ number: int
+
+ url: str
+
+ screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
+
+
+class TaskUserUploadedFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class Task(BaseModel):
+ id: str
+
+ is_scheduled: bool = FieldInfo(alias="isScheduled")
+
+ llm: LlmModel
+
+ session_id: str = FieldInfo(alias="sessionId")
+
+ started_at: datetime = FieldInfo(alias="startedAt")
+
+ status: TaskStatus
+ """Enumeration of possible task execution states
+
+ Attributes: STARTED: Task has been started and is currently running PAUSED: Task
+ execution has been temporarily paused (can be resumed) STOPPED: Task execution
+ has been stopped (cannot be resumed) FINISHED: Task has completed successfully
+ """
+
+ task: str
+
+ browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
+
+ done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
+
+ finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
+
+ is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
+
+ metadata: Optional[Dict[str, object]] = None
+
+ output_files: Optional[List[TaskOutputFile]] = FieldInfo(alias="outputFiles", default=None)
+
+ session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
+
+ steps: Optional[List[TaskStep]] = None
+
+ user_uploaded_files: Optional[List[TaskUserUploadedFile]] = FieldInfo(alias="userUploadedFiles", default=None)
class SessionView(BaseModel):
@@ -20,9 +89,8 @@ class SessionView(BaseModel):
status: SessionStatus
"""Enumeration of possible (browser) session states
- Attributes: ACTIVE: Session is currently active and running (aka browser is
- running) STOPPED: Session has been stopped and is no longer active (aka browser
- is stopped)
+ Attributes: ACTIVE: Session is currently active and running (browser is running)
+ STOPPED: Session has been stopped and is no longer active (browser is stopped)
"""
finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
@@ -33,4 +101,4 @@ class SessionView(BaseModel):
record_url: Optional[str] = FieldInfo(alias="recordUrl", default=None)
- tasks: Optional[List[TaskView]] = None
+ tasks: Optional[List[Task]] = None
diff --git a/src/browser_use_sdk/types/task_create_params.py b/src/browser_use_sdk/types/task_create_params.py
index 5773e37..c970662 100644
--- a/src/browser_use_sdk/types/task_create_params.py
+++ b/src/browser_use_sdk/types/task_create_params.py
@@ -17,18 +17,16 @@ class TaskCreateParams(TypedDict, total=False):
agent_settings: Annotated[AgentSettings, PropertyInfo(alias="agentSettings")]
"""Configuration settings for the AI agent
- Attributes: llm: The LLM model to use for the agent (default: O3 - best
- performance for now) profile_id: ID of the agent profile to use for the task
- (None for default)
+ Attributes: llm: The LLM model to use for the agent profile_id: Unique
+ identifier of the agent profile to use for the task
"""
browser_settings: Annotated[BrowserSettings, PropertyInfo(alias="browserSettings")]
"""Configuration settings for the browser session
- Attributes: session_id: ID of existing session to continue (None for new
- session) profile_id: ID of browser profile to use (None for default)
- save_browser_data: Whether to save browser state/data for the user to download
- later
+ Attributes: session_id: Unique identifier of existing session to continue
+ profile_id: Unique identifier of browser profile to use save_browser_data:
+ Whether to save browser state/data for the user to download later
"""
included_file_names: Annotated[Optional[List[str]], PropertyInfo(alias="includedFileNames")]
diff --git a/src/browser_use_sdk/types/task_list_params.py b/src/browser_use_sdk/types/task_list_params.py
index f354c46..849b038 100644
--- a/src/browser_use_sdk/types/task_list_params.py
+++ b/src/browser_use_sdk/types/task_list_params.py
@@ -2,7 +2,8 @@
from __future__ import annotations
-from typing_extensions import Annotated, TypedDict
+from typing import Optional
+from typing_extensions import Literal, Annotated, TypedDict
from .._utils import PropertyInfo
@@ -10,6 +11,17 @@
class TaskListParams(TypedDict, total=False):
+ filter_by: Annotated[
+ Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]],
+ PropertyInfo(alias="filterBy"),
+ ]
+ """Enumeration of possible task filters
+
+ Attributes: STARTED: All started tasks PAUSED: All paused tasks STOPPED: All
+ stopped tasks FINISHED: All finished tasks SUCCESSFUL: All successful tasks
+ UNSUCCESSFUL: All unsuccessful tasks
+ """
+
include_output_files: Annotated[bool, PropertyInfo(alias="includeOutputFiles")]
include_steps: Annotated[bool, PropertyInfo(alias="includeSteps")]
@@ -19,3 +31,5 @@ class TaskListParams(TypedDict, total=False):
page_number: Annotated[int, PropertyInfo(alias="pageNumber")]
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
+
+ session_id: Annotated[Optional[str], PropertyInfo(alias="sessionId")]
diff --git a/src/browser_use_sdk/types/task_list_response.py b/src/browser_use_sdk/types/task_list_response.py
index 6237338..6fe357b 100644
--- a/src/browser_use_sdk/types/task_list_response.py
+++ b/src/browser_use_sdk/types/task_list_response.py
@@ -1,17 +1,87 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import Dict, List, Optional
+from datetime import datetime
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .task_view import TaskView
+from .llm_model import LlmModel
+from .task_status import TaskStatus
-__all__ = ["TaskListResponse"]
+__all__ = ["TaskListResponse", "Item", "ItemOutputFile", "ItemStep", "ItemUserUploadedFile"]
+
+
+class ItemOutputFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class ItemStep(BaseModel):
+ actions: List[str]
+
+ evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
+
+ memory: str
+
+ next_goal: str = FieldInfo(alias="nextGoal")
+
+ number: int
+
+ url: str
+
+ screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
+
+
+class ItemUserUploadedFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class Item(BaseModel):
+ id: str
+
+ is_scheduled: bool = FieldInfo(alias="isScheduled")
+
+ llm: LlmModel
+
+ session_id: str = FieldInfo(alias="sessionId")
+
+ started_at: datetime = FieldInfo(alias="startedAt")
+
+ status: TaskStatus
+ """Enumeration of possible task execution states
+
+ Attributes: STARTED: Task has been started and is currently running PAUSED: Task
+ execution has been temporarily paused (can be resumed) STOPPED: Task execution
+ has been stopped (cannot be resumed) FINISHED: Task has completed successfully
+ """
+
+ task: str
+
+ browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
+
+ done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
+
+ finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
+
+ is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
+
+ metadata: Optional[Dict[str, object]] = None
+
+ output_files: Optional[List[ItemOutputFile]] = FieldInfo(alias="outputFiles", default=None)
+
+ session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
+
+ steps: Optional[List[ItemStep]] = None
+
+ user_uploaded_files: Optional[List[ItemUserUploadedFile]] = FieldInfo(alias="userUploadedFiles", default=None)
class TaskListResponse(BaseModel):
- items: List[TaskView]
+ items: List[Item]
page_number: int = FieldInfo(alias="pageNumber")
diff --git a/src/browser_use_sdk/types/task_retrieve_output_file_response.py b/src/browser_use_sdk/types/task_retrieve_output_file_response.py
deleted file mode 100644
index d532e3d..0000000
--- a/src/browser_use_sdk/types/task_retrieve_output_file_response.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from pydantic import Field as FieldInfo
-
-from .._models import BaseModel
-
-__all__ = ["TaskRetrieveOutputFileResponse"]
-
-
-class TaskRetrieveOutputFileResponse(BaseModel):
- download_url: str = FieldInfo(alias="downloadUrl")
diff --git a/src/browser_use_sdk/types/task_retrieve_params.py b/src/browser_use_sdk/types/task_retrieve_params.py
deleted file mode 100644
index dc8e594..0000000
--- a/src/browser_use_sdk/types/task_retrieve_params.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["TaskRetrieveParams"]
-
-
-class TaskRetrieveParams(TypedDict, total=False):
- status_only: Annotated[bool, PropertyInfo(alias="statusOnly")]
diff --git a/src/browser_use_sdk/types/task_retrieve_response.py b/src/browser_use_sdk/types/task_retrieve_response.py
deleted file mode 100644
index fac9792..0000000
--- a/src/browser_use_sdk/types/task_retrieve_response.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Union
-from typing_extensions import TypeAlias
-
-from .._models import BaseModel
-from .task_view import TaskView
-from .task_status import TaskStatus
-
-__all__ = ["TaskRetrieveResponse", "TaskStatusView"]
-
-
-class TaskStatusView(BaseModel):
- status: TaskStatus
- """Enumeration of possible task execution states
-
- Attributes: STARTED: Task has been initiated and is currently running PAUSED:
- Task execution has been temporarily paused STOPPED: Task execution has been
- stopped (not completed) FINISHED: Task has completed successfully
- """
-
-
-TaskRetrieveResponse: TypeAlias = Union[TaskView, TaskStatusView]
diff --git a/src/browser_use_sdk/types/task_view.py b/src/browser_use_sdk/types/task_view.py
index 933ceb5..2fa202c 100644
--- a/src/browser_use_sdk/types/task_view.py
+++ b/src/browser_use_sdk/types/task_view.py
@@ -9,7 +9,13 @@
from .llm_model import LlmModel
from .task_status import TaskStatus
-__all__ = ["TaskView", "Step"]
+__all__ = ["TaskView", "OutputFile", "Step", "UserUploadedFile"]
+
+
+class OutputFile(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
class Step(BaseModel):
@@ -28,15 +34,21 @@ class Step(BaseModel):
screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
-class TaskView(BaseModel):
+class UserUploadedFile(BaseModel):
id: str
- done_output: str = FieldInfo(alias="doneOutput")
+ file_name: str = FieldInfo(alias="fileName")
+
+
+class TaskView(BaseModel):
+ id: str
is_scheduled: bool = FieldInfo(alias="isScheduled")
llm: LlmModel
+ output_files: List[OutputFile] = FieldInfo(alias="outputFiles")
+
session_id: str = FieldInfo(alias="sessionId")
started_at: datetime = FieldInfo(alias="startedAt")
@@ -44,23 +56,25 @@ class TaskView(BaseModel):
status: TaskStatus
"""Enumeration of possible task execution states
- Attributes: STARTED: Task has been initiated and is currently running PAUSED:
- Task execution has been temporarily paused STOPPED: Task execution has been
- stopped (not completed) FINISHED: Task has completed successfully
+ Attributes: STARTED: Task has been started and is currently running PAUSED: Task
+ execution has been temporarily paused (can be resumed) STOPPED: Task execution
+ has been stopped (cannot be resumed) FINISHED: Task has completed successfully
"""
+ steps: List[Step]
+
task: str
+ user_uploaded_files: List[UserUploadedFile] = FieldInfo(alias="userUploadedFiles")
+
browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
+ done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
+
finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
- metadata: Optional[Dict[str, object]] = None
+ is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
- output_files: Optional[List[str]] = FieldInfo(alias="outputFiles", default=None)
+ metadata: Optional[Dict[str, object]] = None
session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
-
- steps: Optional[List[Step]] = None
-
- user_uploaded_files: Optional[List[str]] = FieldInfo(alias="userUploadedFiles", default=None)
diff --git a/tests/api_resources/sessions/test_public_share.py b/tests/api_resources/sessions/test_public_share.py
index 3a83c4e..1b877cb 100644
--- a/tests/api_resources/sessions/test_public_share.py
+++ b/tests/api_resources/sessions/test_public_share.py
@@ -107,7 +107,7 @@ def test_method_delete(self, client: BrowserUse) -> None:
public_share = client.sessions.public_share.delete(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(object, public_share, path=["response"])
+ assert public_share is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -119,7 +119,7 @@ def test_raw_response_delete(self, client: BrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
public_share = response.parse()
- assert_matches_type(object, public_share, path=["response"])
+ assert public_share is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -131,7 +131,7 @@ def test_streaming_response_delete(self, client: BrowserUse) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
public_share = response.parse()
- assert_matches_type(object, public_share, path=["response"])
+ assert public_share is None
assert cast(Any, response.is_closed) is True
@@ -239,7 +239,7 @@ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
public_share = await async_client.sessions.public_share.delete(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(object, public_share, path=["response"])
+ assert public_share is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -251,7 +251,7 @@ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
public_share = await response.parse()
- assert_matches_type(object, public_share, path=["response"])
+ assert public_share is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -263,7 +263,7 @@ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
public_share = await response.parse()
- assert_matches_type(object, public_share, path=["response"])
+ assert public_share is None
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_agent_profiles.py b/tests/api_resources/test_agent_profiles.py
index 2c4af8a..77ee21c 100644
--- a/tests/api_resources/test_agent_profiles.py
+++ b/tests/api_resources/test_agent_profiles.py
@@ -34,11 +34,11 @@ def test_method_create_with_all_params(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.create(
name="x",
allowed_domains=["string"],
+ custom_system_prompt_extension="x",
description="x",
flash_mode=True,
highlight_elements=True,
max_agent_steps=1,
- system_prompt="x",
thinking=True,
vision=True,
)
@@ -126,12 +126,12 @@ def test_method_update_with_all_params(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.update(
profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
allowed_domains=["string"],
+ custom_system_prompt_extension="x",
description="x",
flash_mode=True,
highlight_elements=True,
max_agent_steps=1,
name="x",
- system_prompt="x",
thinking=True,
vision=True,
)
@@ -214,7 +214,7 @@ def test_method_delete(self, client: BrowserUse) -> None:
agent_profile = client.agent_profiles.delete(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(object, agent_profile, path=["response"])
+ assert agent_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -226,7 +226,7 @@ def test_raw_response_delete(self, client: BrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
agent_profile = response.parse()
- assert_matches_type(object, agent_profile, path=["response"])
+ assert agent_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -238,7 +238,7 @@ def test_streaming_response_delete(self, client: BrowserUse) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
agent_profile = response.parse()
- assert_matches_type(object, agent_profile, path=["response"])
+ assert agent_profile is None
assert cast(Any, response.is_closed) is True
@@ -270,11 +270,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse
agent_profile = await async_client.agent_profiles.create(
name="x",
allowed_domains=["string"],
+ custom_system_prompt_extension="x",
description="x",
flash_mode=True,
highlight_elements=True,
max_agent_steps=1,
- system_prompt="x",
thinking=True,
vision=True,
)
@@ -362,12 +362,12 @@ async def test_method_update_with_all_params(self, async_client: AsyncBrowserUse
agent_profile = await async_client.agent_profiles.update(
profile_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
allowed_domains=["string"],
+ custom_system_prompt_extension="x",
description="x",
flash_mode=True,
highlight_elements=True,
max_agent_steps=1,
name="x",
- system_prompt="x",
thinking=True,
vision=True,
)
@@ -450,7 +450,7 @@ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
agent_profile = await async_client.agent_profiles.delete(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(object, agent_profile, path=["response"])
+ assert agent_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -462,7 +462,7 @@ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
agent_profile = await response.parse()
- assert_matches_type(object, agent_profile, path=["response"])
+ assert agent_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -474,7 +474,7 @@ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
agent_profile = await response.parse()
- assert_matches_type(object, agent_profile, path=["response"])
+ assert agent_profile is None
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_browser_profiles.py b/tests/api_resources/test_browser_profiles.py
index 974c2db..d10b16a 100644
--- a/tests/api_resources/test_browser_profiles.py
+++ b/tests/api_resources/test_browser_profiles.py
@@ -216,7 +216,7 @@ def test_method_delete(self, client: BrowserUse) -> None:
browser_profile = client.browser_profiles.delete(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(object, browser_profile, path=["response"])
+ assert browser_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -228,7 +228,7 @@ def test_raw_response_delete(self, client: BrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
browser_profile = response.parse()
- assert_matches_type(object, browser_profile, path=["response"])
+ assert browser_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -240,7 +240,7 @@ def test_streaming_response_delete(self, client: BrowserUse) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
browser_profile = response.parse()
- assert_matches_type(object, browser_profile, path=["response"])
+ assert browser_profile is None
assert cast(Any, response.is_closed) is True
@@ -454,7 +454,7 @@ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
browser_profile = await async_client.browser_profiles.delete(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(object, browser_profile, path=["response"])
+ assert browser_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -466,7 +466,7 @@ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
browser_profile = await response.parse()
- assert_matches_type(object, browser_profile, path=["response"])
+ assert browser_profile is None
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -478,7 +478,7 @@ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
browser_profile = await response.parse()
- assert_matches_type(object, browser_profile, path=["response"])
+ assert browser_profile is None
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index 0012ef2..2e70a65 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -12,9 +12,7 @@
from browser_use_sdk.types import (
TaskView,
TaskListResponse,
- TaskRetrieveResponse,
TaskRetrieveLogsResponse,
- TaskRetrieveOutputFileResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -82,42 +80,33 @@ def test_streaming_response_create(self, client: BrowserUse) -> None:
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
task = client.tasks.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
- task = client.tasks.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- status_only=True,
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
+ assert_matches_type(TaskView, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.tasks.with_raw_response.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = response.parse()
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
+ assert_matches_type(TaskView, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.tasks.with_streaming_response.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = response.parse()
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
+ assert_matches_type(TaskView, task, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -126,7 +115,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
client.tasks.with_raw_response.retrieve(
- task_id="",
+ "",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@@ -185,11 +174,13 @@ def test_method_list(self, client: BrowserUse) -> None:
@parametrize
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
task = client.tasks.list(
+ filter_by="started",
include_output_files=True,
include_steps=True,
include_user_uploaded_files=True,
page_number=1,
page_size=1,
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(TaskListResponse, task, path=["response"])
@@ -257,58 +248,6 @@ def test_path_params_retrieve_logs(self, client: BrowserUse) -> None:
"",
)
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_method_retrieve_output_file(self, client: BrowserUse) -> None:
- task = client.tasks.retrieve_output_file(
- file_name="file_name",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_raw_response_retrieve_output_file(self, client: BrowserUse) -> None:
- response = client.tasks.with_raw_response.retrieve_output_file(
- file_name="file_name",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- task = response.parse()
- assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_streaming_response_retrieve_output_file(self, client: BrowserUse) -> None:
- with client.tasks.with_streaming_response.retrieve_output_file(
- file_name="file_name",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- task = response.parse()
- assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_path_params_retrieve_output_file(self, client: BrowserUse) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
- client.tasks.with_raw_response.retrieve_output_file(
- file_name="file_name",
- task_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_name` but received ''"):
- client.tasks.with_raw_response.retrieve_output_file(
- file_name="",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
class TestAsyncTasks:
parametrize = pytest.mark.parametrize(
@@ -374,42 +313,33 @@ async def test_streaming_response_create(self, async_client: AsyncBrowserUse) ->
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserUse) -> None:
- task = await async_client.tasks.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- status_only=True,
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
+ assert_matches_type(TaskView, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.tasks.with_raw_response.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = await response.parse()
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
+ assert_matches_type(TaskView, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.tasks.with_streaming_response.retrieve(
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = await response.parse()
- assert_matches_type(TaskRetrieveResponse, task, path=["response"])
+ assert_matches_type(TaskView, task, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -418,7 +348,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
await async_client.tasks.with_raw_response.retrieve(
- task_id="",
+ "",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@@ -477,11 +407,13 @@ async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.list(
+ filter_by="started",
include_output_files=True,
include_steps=True,
include_user_uploaded_files=True,
page_number=1,
page_size=1,
+ session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(TaskListResponse, task, path=["response"])
@@ -548,55 +480,3 @@ async def test_path_params_retrieve_logs(self, async_client: AsyncBrowserUse) ->
await async_client.tasks.with_raw_response.retrieve_logs(
"",
)
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_method_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
- task = await async_client.tasks.retrieve_output_file(
- file_name="file_name",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_raw_response_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
- response = await async_client.tasks.with_raw_response.retrieve_output_file(
- file_name="file_name",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- task = await response.parse()
- assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_streaming_response_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
- async with async_client.tasks.with_streaming_response.retrieve_output_file(
- file_name="file_name",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- task = await response.parse()
- assert_matches_type(TaskRetrieveOutputFileResponse, task, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_path_params_retrieve_output_file(self, async_client: AsyncBrowserUse) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
- await async_client.tasks.with_raw_response.retrieve_output_file(
- file_name="file_name",
- task_id="",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_name` but received ''"):
- await async_client.tasks.with_raw_response.retrieve_output_file(
- file_name="",
- task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
diff --git a/tests/test_client.py b/tests/test_client.py
index 44034c9..6cf0f80 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -24,7 +24,7 @@
from browser_use_sdk import BrowserUse, AsyncBrowserUse, APIResponseValidationError
from browser_use_sdk._types import Omit
from browser_use_sdk._models import BaseModel, FinalRequestOptions
-from browser_use_sdk._exceptions import APIStatusError, APITimeoutError, BrowserUseError, APIResponseValidationError
+from browser_use_sdk._exceptions import APIStatusError, APITimeoutError, APIResponseValidationError
from browser_use_sdk._base_client import (
DEFAULT_TIMEOUT,
HTTPX_DEFAULT_TIMEOUT,
@@ -336,16 +336,6 @@ def test_default_headers_option(self) -> None:
assert request.headers.get("x-foo") == "stainless"
assert request.headers.get("x-stainless-lang") == "my-overriding-header"
- def test_validate_headers(self) -> None:
- client = BrowserUse(base_url=base_url, api_key=api_key, _strict_response_validation=True)
- request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
- assert request.headers.get("X-Browser-Use-API-Key") == api_key
-
- with pytest.raises(BrowserUseError):
- with update_env(**{"BROWSER_USE_API_KEY": Omit()}):
- client2 = BrowserUse(base_url=base_url, api_key=None, _strict_response_validation=True)
- _ = client2
-
def test_default_query_option(self) -> None:
client = BrowserUse(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"}
@@ -1145,16 +1135,6 @@ def test_default_headers_option(self) -> None:
assert request.headers.get("x-foo") == "stainless"
assert request.headers.get("x-stainless-lang") == "my-overriding-header"
- def test_validate_headers(self) -> None:
- client = AsyncBrowserUse(base_url=base_url, api_key=api_key, _strict_response_validation=True)
- request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
- assert request.headers.get("X-Browser-Use-API-Key") == api_key
-
- with pytest.raises(BrowserUseError):
- with update_env(**{"BROWSER_USE_API_KEY": Omit()}):
- client2 = AsyncBrowserUse(base_url=base_url, api_key=None, _strict_response_validation=True)
- _ = client2
-
def test_default_query_option(self) -> None:
client = AsyncBrowserUse(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"}
From 78727c02cefa53fd0dd877e137b7b6f92e14fce8 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 Aug 2025 12:18:16 +0000
Subject: [PATCH 05/10] feat(api): manual updates
---
.stats.yml | 4 +-
README.md | 57 ++--
api.md | 38 ++-
src/browser_use_sdk/_client.py | 21 ++
src/browser_use_sdk/resources/__init__.py | 14 +
.../resources/sessions/sessions.py | 106 ++++++-
src/browser_use_sdk/resources/tasks.py | 290 +++++++++++++++++-
.../resources/users/__init__.py | 33 ++
.../resources/users/me/__init__.py | 33 ++
.../resources/users/me/files.py | 269 ++++++++++++++++
src/browser_use_sdk/resources/users/me/me.py | 207 +++++++++++++
src/browser_use_sdk/resources/users/users.py | 102 ++++++
src/browser_use_sdk/types/__init__.py | 7 +-
src/browser_use_sdk/types/file_view.py | 13 +
.../types/session_list_response.py | 77 +----
src/browser_use_sdk/types/session_view.py | 77 +----
..._response.py => task_get_logs_response.py} | 4 +-
.../types/task_get_output_file_response.py | 11 +
.../task_get_user_uploaded_file_response.py | 11 +
src/browser_use_sdk/types/task_item_view.py | 54 ++++
.../types/task_list_response.py | 78 +----
src/browser_use_sdk/types/task_step_view.py | 25 ++
src/browser_use_sdk/types/task_view.py | 38 +--
src/browser_use_sdk/types/users/__init__.py | 5 +
.../types/users/me/__init__.py | 6 +
.../me/file_create_presigned_url_params.py | 37 +++
.../me/file_create_presigned_url_response.py | 22 ++
.../types/users/me_retrieve_response.py | 22 ++
tests/api_resources/test_sessions.py | 84 +++++
tests/api_resources/test_tasks.py | 256 ++++++++++++++--
tests/api_resources/users/__init__.py | 1 +
tests/api_resources/users/me/__init__.py | 1 +
tests/api_resources/users/me/test_files.py | 104 +++++++
tests/api_resources/users/test_me.py | 80 +++++
tests/test_client.py | 62 ++--
35 files changed, 1899 insertions(+), 350 deletions(-)
create mode 100644 src/browser_use_sdk/resources/users/__init__.py
create mode 100644 src/browser_use_sdk/resources/users/me/__init__.py
create mode 100644 src/browser_use_sdk/resources/users/me/files.py
create mode 100644 src/browser_use_sdk/resources/users/me/me.py
create mode 100644 src/browser_use_sdk/resources/users/users.py
create mode 100644 src/browser_use_sdk/types/file_view.py
rename src/browser_use_sdk/types/{task_retrieve_logs_response.py => task_get_logs_response.py} (72%)
create mode 100644 src/browser_use_sdk/types/task_get_output_file_response.py
create mode 100644 src/browser_use_sdk/types/task_get_user_uploaded_file_response.py
create mode 100644 src/browser_use_sdk/types/task_item_view.py
create mode 100644 src/browser_use_sdk/types/task_step_view.py
create mode 100644 src/browser_use_sdk/types/users/__init__.py
create mode 100644 src/browser_use_sdk/types/users/me/__init__.py
create mode 100644 src/browser_use_sdk/types/users/me/file_create_presigned_url_params.py
create mode 100644 src/browser_use_sdk/types/users/me/file_create_presigned_url_response.py
create mode 100644 src/browser_use_sdk/types/users/me_retrieve_response.py
create mode 100644 tests/api_resources/users/__init__.py
create mode 100644 tests/api_resources/users/me/__init__.py
create mode 100644 tests/api_resources/users/me/test_files.py
create mode 100644 tests/api_resources/users/test_me.py
diff --git a/.stats.yml b/.stats.yml
index 1126772..1c0836f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 21
+configured_endpoints: 26
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-9ff5409663c58ae9e3ecc9ac764956189e3a70600f5ba1b961bb1dedf0208271.yml
openapi_spec_hash: 9865acb75430d9b799502acbae860df0
-config_hash: 99e0e445bc20c5723030c315bab52940
+config_hash: 9d52be5177b2ede4cb0633c04f4cc4ef
diff --git a/README.md b/README.md
index a0a310f..039a95b 100644
--- a/README.md
+++ b/README.md
@@ -25,32 +25,39 @@ pip install browser-use-sdk
The full API of this library can be found in [api.md](api.md).
```python
+import os
from browser_use_sdk import BrowserUse
client = BrowserUse(
- api_key="My API Key",
+ api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
)
-tasks = client.tasks.list()
-print(tasks.items)
+me = client.users.me.retrieve()
+print(me.additional_credits_balance_usd)
```
+While you can provide an `api_key` keyword argument,
+we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
+to add `BROWSER_USE_API_KEY="My API Key"` to your `.env` file
+so that your API Key is not stored in source control.
+
## Async usage
Simply import `AsyncBrowserUse` instead of `BrowserUse` and use `await` with each API call:
```python
+import os
import asyncio
from browser_use_sdk import AsyncBrowserUse
client = AsyncBrowserUse(
- api_key="My API Key",
+ api_key=os.environ.get("BROWSER_USE_API_KEY"), # This is the default and can be omitted
)
async def main() -> None:
- tasks = await client.tasks.list()
- print(tasks.items)
+ me = await client.users.me.retrieve()
+ print(me.additional_credits_balance_usd)
asyncio.run(main())
@@ -82,8 +89,8 @@ async def main() -> None:
api_key="My API Key",
http_client=DefaultAioHttpClient(),
) as client:
- tasks = await client.tasks.list()
- print(tasks.items)
+ me = await client.users.me.retrieve()
+ print(me.additional_credits_balance_usd)
asyncio.run(main())
@@ -105,9 +112,7 @@ Nested parameters are dictionaries, typed using `TypedDict`, for example:
```python
from browser_use_sdk import BrowserUse
-client = BrowserUse(
- api_key="My API Key",
-)
+client = BrowserUse()
task_view = client.tasks.create(
task="x",
@@ -129,12 +134,10 @@ All errors inherit from `browser_use_sdk.APIError`.
import browser_use_sdk
from browser_use_sdk import BrowserUse
-client = BrowserUse(
- api_key="My API Key",
-)
+client = BrowserUse()
try:
- client.tasks.list()
+ client.users.me.retrieve()
except browser_use_sdk.APIConnectionError as e:
print("The server could not be reached")
print(e.__cause__) # an underlying Exception, likely raised within httpx.
@@ -172,13 +175,12 @@ from browser_use_sdk import BrowserUse
# Configure the default for all requests:
client = BrowserUse(
- api_key="My API Key",
# default is 2
max_retries=0,
)
# Or, configure per-request:
-client.with_options(max_retries=5).tasks.list()
+client.with_options(max_retries=5).users.me.retrieve()
```
### Timeouts
@@ -191,19 +193,17 @@ from browser_use_sdk import BrowserUse
# Configure the default for all requests:
client = BrowserUse(
- api_key="My API Key",
# 20 seconds (default is 1 minute)
timeout=20.0,
)
# More granular control:
client = BrowserUse(
- api_key="My API Key",
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
)
# Override per-request:
-client.with_options(timeout=5.0).tasks.list()
+client.with_options(timeout=5.0).users.me.retrieve()
```
On timeout, an `APITimeoutError` is thrown.
@@ -243,14 +243,12 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
```py
from browser_use_sdk import BrowserUse
-client = BrowserUse(
- api_key="My API Key",
-)
-response = client.tasks.with_raw_response.list()
+client = BrowserUse()
+response = client.users.me.with_raw_response.retrieve()
print(response.headers.get('X-My-Header'))
-task = response.parse() # get the object that `tasks.list()` would have returned
-print(task.items)
+me = response.parse() # get the object that `users.me.retrieve()` would have returned
+print(me.additional_credits_balance_usd)
```
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
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.
```python
-with client.tasks.with_streaming_response.list() as response:
+with client.users.me.with_streaming_response.retrieve() as response:
print(response.headers.get("X-My-Header"))
for line in response.iter_lines():
@@ -320,7 +318,6 @@ import httpx
from browser_use_sdk import BrowserUse, DefaultHttpxClient
client = BrowserUse(
- api_key="My API Key",
# Or use the `BROWSER_USE_BASE_URL` env var
base_url="http://my.test.server.example.com:8083",
http_client=DefaultHttpxClient(
@@ -343,9 +340,7 @@ By default the library closes underlying HTTP connections whenever the client is
```py
from browser_use_sdk import BrowserUse
-with BrowserUse(
- api_key="My API Key",
-) as client:
+with BrowserUse() as client:
# make requests here
...
diff --git a/api.md b/api.md
index 22f0b35..bc9f11c 100644
--- a/api.md
+++ b/api.md
@@ -1,14 +1,45 @@
+# Users
+
+## Me
+
+Types:
+
+```python
+from browser_use_sdk.types.users import MeRetrieveResponse
+```
+
+Methods:
+
+- client.users.me.retrieve() -> MeRetrieveResponse
+
+### Files
+
+Types:
+
+```python
+from browser_use_sdk.types.users.me import FileCreatePresignedURLResponse
+```
+
+Methods:
+
+- client.users.me.files.create_presigned_url(\*\*params) -> FileCreatePresignedURLResponse
+
# Tasks
Types:
```python
from browser_use_sdk.types import (
+ FileView,
LlmModel,
+ TaskItemView,
TaskStatus,
+ TaskStepView,
TaskView,
TaskListResponse,
- TaskRetrieveLogsResponse,
+ TaskGetLogsResponse,
+ TaskGetOutputFileResponse,
+ TaskGetUserUploadedFileResponse,
)
```
@@ -18,7 +49,9 @@ Methods:
- client.tasks.retrieve(task_id) -> TaskView
- client.tasks.update(task_id, \*\*params) -> TaskView
- client.tasks.list(\*\*params) -> TaskListResponse
-- client.tasks.retrieve_logs(task_id) -> TaskRetrieveLogsResponse
+- client.tasks.get_logs(task_id) -> TaskGetLogsResponse
+- client.tasks.get_output_file(file_id, \*, task_id) -> TaskGetOutputFileResponse
+- client.tasks.get_user_uploaded_file(file_id, \*, task_id) -> TaskGetUserUploadedFileResponse
# Sessions
@@ -33,6 +66,7 @@ Methods:
- client.sessions.retrieve(session_id, \*\*params) -> SessionView
- client.sessions.update(session_id, \*\*params) -> SessionView
- client.sessions.list(\*\*params) -> SessionListResponse
+- client.sessions.delete(session_id) -> None
## PublicShare
diff --git a/src/browser_use_sdk/_client.py b/src/browser_use_sdk/_client.py
index fc2fd46..13ad53e 100644
--- a/src/browser_use_sdk/_client.py
+++ b/src/browser_use_sdk/_client.py
@@ -29,6 +29,7 @@
SyncAPIClient,
AsyncAPIClient,
)
+from .resources.users import users
from .resources.sessions import sessions
__all__ = [
@@ -44,6 +45,7 @@
class BrowserUse(SyncAPIClient):
+ users: users.UsersResource
tasks: tasks.TasksResource
sessions: sessions.SessionsResource
browser_profiles: browser_profiles.BrowserProfilesResource
@@ -105,6 +107,7 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
+ self.users = users.UsersResource(self)
self.tasks = tasks.TasksResource(self)
self.sessions = sessions.SessionsResource(self)
self.browser_profiles = browser_profiles.BrowserProfilesResource(self)
@@ -117,6 +120,12 @@ def __init__(
def qs(self) -> Querystring:
return Querystring(array_format="comma")
+ @property
+ @override
+ def auth_headers(self) -> dict[str, str]:
+ api_key = self.api_key
+ return {"X-Browser-Use-API-Key": api_key}
+
@property
@override
def default_headers(self) -> dict[str, str | Omit]:
@@ -212,6 +221,7 @@ def _make_status_error(
class AsyncBrowserUse(AsyncAPIClient):
+ users: users.AsyncUsersResource
tasks: tasks.AsyncTasksResource
sessions: sessions.AsyncSessionsResource
browser_profiles: browser_profiles.AsyncBrowserProfilesResource
@@ -273,6 +283,7 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
+ self.users = users.AsyncUsersResource(self)
self.tasks = tasks.AsyncTasksResource(self)
self.sessions = sessions.AsyncSessionsResource(self)
self.browser_profiles = browser_profiles.AsyncBrowserProfilesResource(self)
@@ -285,6 +296,12 @@ def __init__(
def qs(self) -> Querystring:
return Querystring(array_format="comma")
+ @property
+ @override
+ def auth_headers(self) -> dict[str, str]:
+ api_key = self.api_key
+ return {"X-Browser-Use-API-Key": api_key}
+
@property
@override
def default_headers(self) -> dict[str, str | Omit]:
@@ -381,6 +398,7 @@ def _make_status_error(
class BrowserUseWithRawResponse:
def __init__(self, client: BrowserUse) -> None:
+ self.users = users.UsersResourceWithRawResponse(client.users)
self.tasks = tasks.TasksResourceWithRawResponse(client.tasks)
self.sessions = sessions.SessionsResourceWithRawResponse(client.sessions)
self.browser_profiles = browser_profiles.BrowserProfilesResourceWithRawResponse(client.browser_profiles)
@@ -389,6 +407,7 @@ def __init__(self, client: BrowserUse) -> None:
class AsyncBrowserUseWithRawResponse:
def __init__(self, client: AsyncBrowserUse) -> None:
+ self.users = users.AsyncUsersResourceWithRawResponse(client.users)
self.tasks = tasks.AsyncTasksResourceWithRawResponse(client.tasks)
self.sessions = sessions.AsyncSessionsResourceWithRawResponse(client.sessions)
self.browser_profiles = browser_profiles.AsyncBrowserProfilesResourceWithRawResponse(client.browser_profiles)
@@ -397,6 +416,7 @@ def __init__(self, client: AsyncBrowserUse) -> None:
class BrowserUseWithStreamedResponse:
def __init__(self, client: BrowserUse) -> None:
+ self.users = users.UsersResourceWithStreamingResponse(client.users)
self.tasks = tasks.TasksResourceWithStreamingResponse(client.tasks)
self.sessions = sessions.SessionsResourceWithStreamingResponse(client.sessions)
self.browser_profiles = browser_profiles.BrowserProfilesResourceWithStreamingResponse(client.browser_profiles)
@@ -405,6 +425,7 @@ def __init__(self, client: BrowserUse) -> None:
class AsyncBrowserUseWithStreamedResponse:
def __init__(self, client: AsyncBrowserUse) -> None:
+ self.users = users.AsyncUsersResourceWithStreamingResponse(client.users)
self.tasks = tasks.AsyncTasksResourceWithStreamingResponse(client.tasks)
self.sessions = sessions.AsyncSessionsResourceWithStreamingResponse(client.sessions)
self.browser_profiles = browser_profiles.AsyncBrowserProfilesResourceWithStreamingResponse(
diff --git a/src/browser_use_sdk/resources/__init__.py b/src/browser_use_sdk/resources/__init__.py
index 02bbbb2..c8d13bb 100644
--- a/src/browser_use_sdk/resources/__init__.py
+++ b/src/browser_use_sdk/resources/__init__.py
@@ -8,6 +8,14 @@
TasksResourceWithStreamingResponse,
AsyncTasksResourceWithStreamingResponse,
)
+from .users import (
+ UsersResource,
+ AsyncUsersResource,
+ UsersResourceWithRawResponse,
+ AsyncUsersResourceWithRawResponse,
+ UsersResourceWithStreamingResponse,
+ AsyncUsersResourceWithStreamingResponse,
+)
from .sessions import (
SessionsResource,
AsyncSessionsResource,
@@ -34,6 +42,12 @@
)
__all__ = [
+ "UsersResource",
+ "AsyncUsersResource",
+ "UsersResourceWithRawResponse",
+ "AsyncUsersResourceWithRawResponse",
+ "UsersResourceWithStreamingResponse",
+ "AsyncUsersResourceWithStreamingResponse",
"TasksResource",
"AsyncTasksResource",
"TasksResourceWithRawResponse",
diff --git a/src/browser_use_sdk/resources/sessions/sessions.py b/src/browser_use_sdk/resources/sessions/sessions.py
index eb99bba..5919f7f 100644
--- a/src/browser_use_sdk/resources/sessions/sessions.py
+++ b/src/browser_use_sdk/resources/sessions/sessions.py
@@ -8,7 +8,7 @@
import httpx
from ...types import SessionStatus, session_list_params, session_update_params, session_retrieve_params
-from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
@@ -242,6 +242,52 @@ def list(
cast_to=SessionListResponse,
)
+ def delete(
+ self,
+ session_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Delete a session and all its associated data.
+
+ Permanently removes a session and all its tasks, browser data, and public
+ shares. This action cannot be undone. Use this endpoint to clean up old sessions
+ and free up storage space.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session to delete
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not session_id:
+ raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ f"/sessions/{session_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class AsyncSessionsResource(AsyncAPIResource):
@cached_property
@@ -453,6 +499,52 @@ async def list(
cast_to=SessionListResponse,
)
+ async def delete(
+ self,
+ session_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> None:
+ """
+ Delete a session and all its associated data.
+
+ Permanently removes a session and all its tasks, browser data, and public
+ shares. This action cannot be undone. Use this endpoint to clean up old sessions
+ and free up storage space.
+
+ Args:
+
+ - session_id: The unique identifier of the agent session to delete
+
+ Returns:
+
+ - 204 No Content on successful deletion (idempotent)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not session_id:
+ raise ValueError(f"Expected a non-empty value for `session_id` but received {session_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ f"/sessions/{session_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class SessionsResourceWithRawResponse:
def __init__(self, sessions: SessionsResource) -> None:
@@ -467,6 +559,9 @@ def __init__(self, sessions: SessionsResource) -> None:
self.list = to_raw_response_wrapper(
sessions.list,
)
+ self.delete = to_raw_response_wrapper(
+ sessions.delete,
+ )
@cached_property
def public_share(self) -> PublicShareResourceWithRawResponse:
@@ -486,6 +581,9 @@ def __init__(self, sessions: AsyncSessionsResource) -> None:
self.list = async_to_raw_response_wrapper(
sessions.list,
)
+ self.delete = async_to_raw_response_wrapper(
+ sessions.delete,
+ )
@cached_property
def public_share(self) -> AsyncPublicShareResourceWithRawResponse:
@@ -505,6 +603,9 @@ def __init__(self, sessions: SessionsResource) -> None:
self.list = to_streamed_response_wrapper(
sessions.list,
)
+ self.delete = to_streamed_response_wrapper(
+ sessions.delete,
+ )
@cached_property
def public_share(self) -> PublicShareResourceWithStreamingResponse:
@@ -524,6 +625,9 @@ def __init__(self, sessions: AsyncSessionsResource) -> None:
self.list = async_to_streamed_response_wrapper(
sessions.list,
)
+ self.delete = async_to_streamed_response_wrapper(
+ sessions.delete,
+ )
@cached_property
def public_share(self) -> AsyncPublicShareResourceWithStreamingResponse:
diff --git a/src/browser_use_sdk/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
index 3db6831..cb1644a 100644
--- a/src/browser_use_sdk/resources/tasks.py
+++ b/src/browser_use_sdk/resources/tasks.py
@@ -21,7 +21,9 @@
from .._base_client import make_request_options
from ..types.task_view import TaskView
from ..types.task_list_response import TaskListResponse
-from ..types.task_retrieve_logs_response import TaskRetrieveLogsResponse
+from ..types.task_get_logs_response import TaskGetLogsResponse
+from ..types.task_get_output_file_response import TaskGetOutputFileResponse
+from ..types.task_get_user_uploaded_file_response import TaskGetUserUploadedFileResponse
__all__ = ["TasksResource", "AsyncTasksResource"]
@@ -350,7 +352,7 @@ def list(
cast_to=TaskListResponse,
)
- def retrieve_logs(
+ def get_logs(
self,
task_id: str,
*,
@@ -360,7 +362,7 @@ def retrieve_logs(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskRetrieveLogsResponse:
+ ) -> TaskGetLogsResponse:
"""
Get a download URL for the execution logs of an AI agent task.
@@ -408,7 +410,124 @@ def retrieve_logs(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TaskRetrieveLogsResponse,
+ cast_to=TaskGetLogsResponse,
+ )
+
+ def get_output_file(
+ self,
+ file_id: str,
+ *,
+ task_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> TaskGetOutputFileResponse:
+ """
+ Get a download URL for a specific output file generated by an AI agent task.
+
+ AI agents can generate various output files during task execution, such as:
+
+ - Screenshots of web pages
+ - Extracted data in CSV/JSON format
+ - Generated reports or documents
+ - Downloaded files from websites
+
+ This endpoint provides a secure, time-limited download URL for accessing these
+ files. The URL expires after a short time for security.
+
+ Args:
+
+ - task_id: The unique identifier of the agent task
+ - file_id: The unique identifier of the output file
+
+ Returns:
+
+ - A presigned download URL for the requested file
+
+ Raises:
+
+ - 404: If the user agent task or output file doesn't exist
+ - 500: If the download URL cannot be generated (should not happen)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not task_id:
+ raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
+ if not file_id:
+ raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
+ return self._get(
+ f"/tasks/{task_id}/output-files/{file_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskGetOutputFileResponse,
+ )
+
+ def get_user_uploaded_file(
+ self,
+ file_id: str,
+ *,
+ task_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> TaskGetUserUploadedFileResponse:
+ """
+ Get a download URL for a specific user uploaded file that was used in the task.
+
+ A user can upload files to their account file bucket and reference the name of
+ the file in a task. These files are then made available for the agent to use
+ during the agent task run.
+
+ This endpoint provides a secure, time-limited download URL for accessing these
+ files. The URL expires after a short time for security.
+
+ Args:
+
+ - task_id: The unique identifier of the agent task
+ - file_id: The unique identifier of the user uploaded file
+
+ Returns:
+
+ - A presigned download URL for the requested file
+
+ Raises:
+
+ - 404: If the user agent task or user uploaded file doesn't exist
+ - 500: If the download URL cannot be generated (should not happen)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not task_id:
+ raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
+ if not file_id:
+ raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
+ return self._get(
+ f"/tasks/{task_id}/user-uploaded-files/{file_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskGetUserUploadedFileResponse,
)
@@ -736,7 +855,7 @@ async def list(
cast_to=TaskListResponse,
)
- async def retrieve_logs(
+ async def get_logs(
self,
task_id: str,
*,
@@ -746,7 +865,7 @@ async def retrieve_logs(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskRetrieveLogsResponse:
+ ) -> TaskGetLogsResponse:
"""
Get a download URL for the execution logs of an AI agent task.
@@ -794,7 +913,124 @@ async def retrieve_logs(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TaskRetrieveLogsResponse,
+ cast_to=TaskGetLogsResponse,
+ )
+
+ async def get_output_file(
+ self,
+ file_id: str,
+ *,
+ task_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> TaskGetOutputFileResponse:
+ """
+ Get a download URL for a specific output file generated by an AI agent task.
+
+ AI agents can generate various output files during task execution, such as:
+
+ - Screenshots of web pages
+ - Extracted data in CSV/JSON format
+ - Generated reports or documents
+ - Downloaded files from websites
+
+ This endpoint provides a secure, time-limited download URL for accessing these
+ files. The URL expires after a short time for security.
+
+ Args:
+
+ - task_id: The unique identifier of the agent task
+ - file_id: The unique identifier of the output file
+
+ Returns:
+
+ - A presigned download URL for the requested file
+
+ Raises:
+
+ - 404: If the user agent task or output file doesn't exist
+ - 500: If the download URL cannot be generated (should not happen)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not task_id:
+ raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
+ if not file_id:
+ raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
+ return await self._get(
+ f"/tasks/{task_id}/output-files/{file_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskGetOutputFileResponse,
+ )
+
+ async def get_user_uploaded_file(
+ self,
+ file_id: str,
+ *,
+ task_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> TaskGetUserUploadedFileResponse:
+ """
+ Get a download URL for a specific user uploaded file that was used in the task.
+
+ A user can upload files to their account file bucket and reference the name of
+ the file in a task. These files are then made available for the agent to use
+ during the agent task run.
+
+ This endpoint provides a secure, time-limited download URL for accessing these
+ files. The URL expires after a short time for security.
+
+ Args:
+
+ - task_id: The unique identifier of the agent task
+ - file_id: The unique identifier of the user uploaded file
+
+ Returns:
+
+ - A presigned download URL for the requested file
+
+ Raises:
+
+ - 404: If the user agent task or user uploaded file doesn't exist
+ - 500: If the download URL cannot be generated (should not happen)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not task_id:
+ raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}")
+ if not file_id:
+ raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}")
+ return await self._get(
+ f"/tasks/{task_id}/user-uploaded-files/{file_id}",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=TaskGetUserUploadedFileResponse,
)
@@ -814,8 +1050,14 @@ def __init__(self, tasks: TasksResource) -> None:
self.list = to_raw_response_wrapper(
tasks.list,
)
- self.retrieve_logs = to_raw_response_wrapper(
- tasks.retrieve_logs,
+ self.get_logs = to_raw_response_wrapper(
+ tasks.get_logs,
+ )
+ self.get_output_file = to_raw_response_wrapper(
+ tasks.get_output_file,
+ )
+ self.get_user_uploaded_file = to_raw_response_wrapper(
+ tasks.get_user_uploaded_file,
)
@@ -835,8 +1077,14 @@ def __init__(self, tasks: AsyncTasksResource) -> None:
self.list = async_to_raw_response_wrapper(
tasks.list,
)
- self.retrieve_logs = async_to_raw_response_wrapper(
- tasks.retrieve_logs,
+ self.get_logs = async_to_raw_response_wrapper(
+ tasks.get_logs,
+ )
+ self.get_output_file = async_to_raw_response_wrapper(
+ tasks.get_output_file,
+ )
+ self.get_user_uploaded_file = async_to_raw_response_wrapper(
+ tasks.get_user_uploaded_file,
)
@@ -856,8 +1104,14 @@ def __init__(self, tasks: TasksResource) -> None:
self.list = to_streamed_response_wrapper(
tasks.list,
)
- self.retrieve_logs = to_streamed_response_wrapper(
- tasks.retrieve_logs,
+ self.get_logs = to_streamed_response_wrapper(
+ tasks.get_logs,
+ )
+ self.get_output_file = to_streamed_response_wrapper(
+ tasks.get_output_file,
+ )
+ self.get_user_uploaded_file = to_streamed_response_wrapper(
+ tasks.get_user_uploaded_file,
)
@@ -877,6 +1131,12 @@ def __init__(self, tasks: AsyncTasksResource) -> None:
self.list = async_to_streamed_response_wrapper(
tasks.list,
)
- self.retrieve_logs = async_to_streamed_response_wrapper(
- tasks.retrieve_logs,
+ self.get_logs = async_to_streamed_response_wrapper(
+ tasks.get_logs,
+ )
+ self.get_output_file = async_to_streamed_response_wrapper(
+ tasks.get_output_file,
+ )
+ self.get_user_uploaded_file = async_to_streamed_response_wrapper(
+ tasks.get_user_uploaded_file,
)
diff --git a/src/browser_use_sdk/resources/users/__init__.py b/src/browser_use_sdk/resources/users/__init__.py
new file mode 100644
index 0000000..8b1ed20
--- /dev/null
+++ b/src/browser_use_sdk/resources/users/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .me import (
+ MeResource,
+ AsyncMeResource,
+ MeResourceWithRawResponse,
+ AsyncMeResourceWithRawResponse,
+ MeResourceWithStreamingResponse,
+ AsyncMeResourceWithStreamingResponse,
+)
+from .users import (
+ UsersResource,
+ AsyncUsersResource,
+ UsersResourceWithRawResponse,
+ AsyncUsersResourceWithRawResponse,
+ UsersResourceWithStreamingResponse,
+ AsyncUsersResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "MeResource",
+ "AsyncMeResource",
+ "MeResourceWithRawResponse",
+ "AsyncMeResourceWithRawResponse",
+ "MeResourceWithStreamingResponse",
+ "AsyncMeResourceWithStreamingResponse",
+ "UsersResource",
+ "AsyncUsersResource",
+ "UsersResourceWithRawResponse",
+ "AsyncUsersResourceWithRawResponse",
+ "UsersResourceWithStreamingResponse",
+ "AsyncUsersResourceWithStreamingResponse",
+]
diff --git a/src/browser_use_sdk/resources/users/me/__init__.py b/src/browser_use_sdk/resources/users/me/__init__.py
new file mode 100644
index 0000000..4409f6d
--- /dev/null
+++ b/src/browser_use_sdk/resources/users/me/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .me import (
+ MeResource,
+ AsyncMeResource,
+ MeResourceWithRawResponse,
+ AsyncMeResourceWithRawResponse,
+ MeResourceWithStreamingResponse,
+ AsyncMeResourceWithStreamingResponse,
+)
+from .files import (
+ FilesResource,
+ AsyncFilesResource,
+ FilesResourceWithRawResponse,
+ AsyncFilesResourceWithRawResponse,
+ FilesResourceWithStreamingResponse,
+ AsyncFilesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "FilesResource",
+ "AsyncFilesResource",
+ "FilesResourceWithRawResponse",
+ "AsyncFilesResourceWithRawResponse",
+ "FilesResourceWithStreamingResponse",
+ "AsyncFilesResourceWithStreamingResponse",
+ "MeResource",
+ "AsyncMeResource",
+ "MeResourceWithRawResponse",
+ "AsyncMeResourceWithRawResponse",
+ "MeResourceWithStreamingResponse",
+ "AsyncMeResourceWithStreamingResponse",
+]
diff --git a/src/browser_use_sdk/resources/users/me/files.py b/src/browser_use_sdk/resources/users/me/files.py
new file mode 100644
index 0000000..1468254
--- /dev/null
+++ b/src/browser_use_sdk/resources/users/me/files.py
@@ -0,0 +1,269 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal
+
+import httpx
+
+from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ...._utils import maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._base_client import make_request_options
+from ....types.users.me import file_create_presigned_url_params
+from ....types.users.me.file_create_presigned_url_response import FileCreatePresignedURLResponse
+
+__all__ = ["FilesResource", "AsyncFilesResource"]
+
+
+class FilesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> FilesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#accessing-raw-response-data-eg-headers
+ """
+ return FilesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> FilesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#with_streaming_response
+ """
+ return FilesResourceWithStreamingResponse(self)
+
+ def create_presigned_url(
+ self,
+ *,
+ content_type: Literal[
+ "image/jpg",
+ "image/jpeg",
+ "image/png",
+ "image/gif",
+ "image/webp",
+ "image/svg+xml",
+ "application/pdf",
+ "application/msword",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.ms-excel",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "text/plain",
+ "text/csv",
+ "text/markdown",
+ ],
+ file_name: str,
+ size_bytes: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> FileCreatePresignedURLResponse:
+ """
+ Get a presigned URL for uploading files that AI agents can use during tasks.
+
+ This endpoint generates a secure, time-limited upload URL that allows you to
+ upload files directly to our storage system. These files can then be referenced
+ in AI agent tasks for the agent to work with.
+
+ Supported use cases:
+
+ - Uploading documents for data extraction tasks
+ - Providing reference materials for agents
+ - Sharing files that agents need to process
+ - Including images or PDFs for analysis
+
+ The upload URL expires after 2 minutes for security. Files are automatically
+ organized by user ID and can be referenced in task creation using the returned
+ file name.
+
+ Args:
+
+ - request: File upload details including name, content type, and size
+
+ Returns:
+
+ - Presigned upload URL and form fields for direct file upload
+
+ Raises:
+
+ - 400: If the content type is unsupported
+ - 500: If the upload URL generation fails (should not happen)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._post(
+ "/users/me/files/presigned-url",
+ body=maybe_transform(
+ {
+ "content_type": content_type,
+ "file_name": file_name,
+ "size_bytes": size_bytes,
+ },
+ file_create_presigned_url_params.FileCreatePresignedURLParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=FileCreatePresignedURLResponse,
+ )
+
+
+class AsyncFilesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncFilesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncFilesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncFilesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#with_streaming_response
+ """
+ return AsyncFilesResourceWithStreamingResponse(self)
+
+ async def create_presigned_url(
+ self,
+ *,
+ content_type: Literal[
+ "image/jpg",
+ "image/jpeg",
+ "image/png",
+ "image/gif",
+ "image/webp",
+ "image/svg+xml",
+ "application/pdf",
+ "application/msword",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.ms-excel",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "text/plain",
+ "text/csv",
+ "text/markdown",
+ ],
+ file_name: str,
+ size_bytes: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> FileCreatePresignedURLResponse:
+ """
+ Get a presigned URL for uploading files that AI agents can use during tasks.
+
+ This endpoint generates a secure, time-limited upload URL that allows you to
+ upload files directly to our storage system. These files can then be referenced
+ in AI agent tasks for the agent to work with.
+
+ Supported use cases:
+
+ - Uploading documents for data extraction tasks
+ - Providing reference materials for agents
+ - Sharing files that agents need to process
+ - Including images or PDFs for analysis
+
+ The upload URL expires after 2 minutes for security. Files are automatically
+ organized by user ID and can be referenced in task creation using the returned
+ file name.
+
+ Args:
+
+ - request: File upload details including name, content type, and size
+
+ Returns:
+
+ - Presigned upload URL and form fields for direct file upload
+
+ Raises:
+
+ - 400: If the content type is unsupported
+ - 500: If the upload URL generation fails (should not happen)
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._post(
+ "/users/me/files/presigned-url",
+ body=await async_maybe_transform(
+ {
+ "content_type": content_type,
+ "file_name": file_name,
+ "size_bytes": size_bytes,
+ },
+ file_create_presigned_url_params.FileCreatePresignedURLParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=FileCreatePresignedURLResponse,
+ )
+
+
+class FilesResourceWithRawResponse:
+ def __init__(self, files: FilesResource) -> None:
+ self._files = files
+
+ self.create_presigned_url = to_raw_response_wrapper(
+ files.create_presigned_url,
+ )
+
+
+class AsyncFilesResourceWithRawResponse:
+ def __init__(self, files: AsyncFilesResource) -> None:
+ self._files = files
+
+ self.create_presigned_url = async_to_raw_response_wrapper(
+ files.create_presigned_url,
+ )
+
+
+class FilesResourceWithStreamingResponse:
+ def __init__(self, files: FilesResource) -> None:
+ self._files = files
+
+ self.create_presigned_url = to_streamed_response_wrapper(
+ files.create_presigned_url,
+ )
+
+
+class AsyncFilesResourceWithStreamingResponse:
+ def __init__(self, files: AsyncFilesResource) -> None:
+ self._files = files
+
+ self.create_presigned_url = async_to_streamed_response_wrapper(
+ files.create_presigned_url,
+ )
diff --git a/src/browser_use_sdk/resources/users/me/me.py b/src/browser_use_sdk/resources/users/me/me.py
new file mode 100644
index 0000000..b63585c
--- /dev/null
+++ b/src/browser_use_sdk/resources/users/me/me.py
@@ -0,0 +1,207 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from .files import (
+ FilesResource,
+ AsyncFilesResource,
+ FilesResourceWithRawResponse,
+ AsyncFilesResourceWithRawResponse,
+ FilesResourceWithStreamingResponse,
+ AsyncFilesResourceWithStreamingResponse,
+)
+from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._base_client import make_request_options
+from ....types.users.me_retrieve_response import MeRetrieveResponse
+
+__all__ = ["MeResource", "AsyncMeResource"]
+
+
+class MeResource(SyncAPIResource):
+ @cached_property
+ def files(self) -> FilesResource:
+ return FilesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> MeResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#accessing-raw-response-data-eg-headers
+ """
+ return MeResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> MeResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#with_streaming_response
+ """
+ return MeResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MeRetrieveResponse:
+ """
+ Get information about the currently authenticated user.
+
+ Retrieves your user profile information including:
+
+ - Credit balances (monthly and additional credits in USD)
+ - Account details (email, name, signup date)
+
+ This endpoint is useful for:
+
+ - Checking your remaining credits before running tasks
+ - Displaying user information in your application
+
+ Returns:
+
+ - Complete user profile information including credits and account details
+
+ Raises:
+
+ - 404: If the user profile cannot be found
+ """
+ return self._get(
+ "/users/me",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MeRetrieveResponse,
+ )
+
+
+class AsyncMeResource(AsyncAPIResource):
+ @cached_property
+ def files(self) -> AsyncFilesResource:
+ return AsyncFilesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncMeResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncMeResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncMeResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#with_streaming_response
+ """
+ return AsyncMeResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> MeRetrieveResponse:
+ """
+ Get information about the currently authenticated user.
+
+ Retrieves your user profile information including:
+
+ - Credit balances (monthly and additional credits in USD)
+ - Account details (email, name, signup date)
+
+ This endpoint is useful for:
+
+ - Checking your remaining credits before running tasks
+ - Displaying user information in your application
+
+ Returns:
+
+ - Complete user profile information including credits and account details
+
+ Raises:
+
+ - 404: If the user profile cannot be found
+ """
+ return await self._get(
+ "/users/me",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MeRetrieveResponse,
+ )
+
+
+class MeResourceWithRawResponse:
+ def __init__(self, me: MeResource) -> None:
+ self._me = me
+
+ self.retrieve = to_raw_response_wrapper(
+ me.retrieve,
+ )
+
+ @cached_property
+ def files(self) -> FilesResourceWithRawResponse:
+ return FilesResourceWithRawResponse(self._me.files)
+
+
+class AsyncMeResourceWithRawResponse:
+ def __init__(self, me: AsyncMeResource) -> None:
+ self._me = me
+
+ self.retrieve = async_to_raw_response_wrapper(
+ me.retrieve,
+ )
+
+ @cached_property
+ def files(self) -> AsyncFilesResourceWithRawResponse:
+ return AsyncFilesResourceWithRawResponse(self._me.files)
+
+
+class MeResourceWithStreamingResponse:
+ def __init__(self, me: MeResource) -> None:
+ self._me = me
+
+ self.retrieve = to_streamed_response_wrapper(
+ me.retrieve,
+ )
+
+ @cached_property
+ def files(self) -> FilesResourceWithStreamingResponse:
+ return FilesResourceWithStreamingResponse(self._me.files)
+
+
+class AsyncMeResourceWithStreamingResponse:
+ def __init__(self, me: AsyncMeResource) -> None:
+ self._me = me
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ me.retrieve,
+ )
+
+ @cached_property
+ def files(self) -> AsyncFilesResourceWithStreamingResponse:
+ return AsyncFilesResourceWithStreamingResponse(self._me.files)
diff --git a/src/browser_use_sdk/resources/users/users.py b/src/browser_use_sdk/resources/users/users.py
new file mode 100644
index 0000000..95dfc93
--- /dev/null
+++ b/src/browser_use_sdk/resources/users/users.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .me.me import (
+ MeResource,
+ AsyncMeResource,
+ MeResourceWithRawResponse,
+ AsyncMeResourceWithRawResponse,
+ MeResourceWithStreamingResponse,
+ AsyncMeResourceWithStreamingResponse,
+)
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["UsersResource", "AsyncUsersResource"]
+
+
+class UsersResource(SyncAPIResource):
+ @cached_property
+ def me(self) -> MeResource:
+ return MeResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> UsersResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#accessing-raw-response-data-eg-headers
+ """
+ return UsersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> UsersResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#with_streaming_response
+ """
+ return UsersResourceWithStreamingResponse(self)
+
+
+class AsyncUsersResource(AsyncAPIResource):
+ @cached_property
+ def me(self) -> AsyncMeResource:
+ return AsyncMeResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncUsersResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncUsersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncUsersResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browser-use/browser-use-python#with_streaming_response
+ """
+ return AsyncUsersResourceWithStreamingResponse(self)
+
+
+class UsersResourceWithRawResponse:
+ def __init__(self, users: UsersResource) -> None:
+ self._users = users
+
+ @cached_property
+ def me(self) -> MeResourceWithRawResponse:
+ return MeResourceWithRawResponse(self._users.me)
+
+
+class AsyncUsersResourceWithRawResponse:
+ def __init__(self, users: AsyncUsersResource) -> None:
+ self._users = users
+
+ @cached_property
+ def me(self) -> AsyncMeResourceWithRawResponse:
+ return AsyncMeResourceWithRawResponse(self._users.me)
+
+
+class UsersResourceWithStreamingResponse:
+ def __init__(self, users: UsersResource) -> None:
+ self._users = users
+
+ @cached_property
+ def me(self) -> MeResourceWithStreamingResponse:
+ return MeResourceWithStreamingResponse(self._users.me)
+
+
+class AsyncUsersResourceWithStreamingResponse:
+ def __init__(self, users: AsyncUsersResource) -> None:
+ self._users = users
+
+ @cached_property
+ def me(self) -> AsyncMeResourceWithStreamingResponse:
+ return AsyncMeResourceWithStreamingResponse(self._users.me)
diff --git a/src/browser_use_sdk/types/__init__.py b/src/browser_use_sdk/types/__init__.py
index cd963cf..74d4a7c 100644
--- a/src/browser_use_sdk/types/__init__.py
+++ b/src/browser_use_sdk/types/__init__.py
@@ -2,11 +2,14 @@
from __future__ import annotations
+from .file_view import FileView as FileView
from .llm_model import LlmModel as LlmModel
from .task_view import TaskView as TaskView
from .task_status import TaskStatus as TaskStatus
from .session_view import SessionView as SessionView
from .session_status import SessionStatus as SessionStatus
+from .task_item_view import TaskItemView as TaskItemView
+from .task_step_view import TaskStepView as TaskStepView
from .task_list_params import TaskListParams as TaskListParams
from .agent_profile_view import AgentProfileView as AgentProfileView
from .proxy_country_code import ProxyCountryCode as ProxyCountryCode
@@ -17,13 +20,15 @@
from .browser_profile_view import BrowserProfileView as BrowserProfileView
from .session_list_response import SessionListResponse as SessionListResponse
from .session_update_params import SessionUpdateParams as SessionUpdateParams
+from .task_get_logs_response import TaskGetLogsResponse as TaskGetLogsResponse
from .session_retrieve_params import SessionRetrieveParams as SessionRetrieveParams
from .agent_profile_list_params import AgentProfileListParams as AgentProfileListParams
from .agent_profile_create_params import AgentProfileCreateParams as AgentProfileCreateParams
from .agent_profile_list_response import AgentProfileListResponse as AgentProfileListResponse
from .agent_profile_update_params import AgentProfileUpdateParams as AgentProfileUpdateParams
from .browser_profile_list_params import BrowserProfileListParams as BrowserProfileListParams
-from .task_retrieve_logs_response import TaskRetrieveLogsResponse as TaskRetrieveLogsResponse
from .browser_profile_create_params import BrowserProfileCreateParams as BrowserProfileCreateParams
from .browser_profile_list_response import BrowserProfileListResponse as BrowserProfileListResponse
from .browser_profile_update_params import BrowserProfileUpdateParams as BrowserProfileUpdateParams
+from .task_get_output_file_response import TaskGetOutputFileResponse as TaskGetOutputFileResponse
+from .task_get_user_uploaded_file_response import TaskGetUserUploadedFileResponse as TaskGetUserUploadedFileResponse
diff --git a/src/browser_use_sdk/types/file_view.py b/src/browser_use_sdk/types/file_view.py
new file mode 100644
index 0000000..620c57c
--- /dev/null
+++ b/src/browser_use_sdk/types/file_view.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["FileView"]
+
+
+class FileView(BaseModel):
+ id: str
+
+ file_name: str = FieldInfo(alias="fileName")
diff --git a/src/browser_use_sdk/types/session_list_response.py b/src/browser_use_sdk/types/session_list_response.py
index 7fae531..4b89459 100644
--- a/src/browser_use_sdk/types/session_list_response.py
+++ b/src/browser_use_sdk/types/session_list_response.py
@@ -1,84 +1,15 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Optional
+from typing import List, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .llm_model import LlmModel
-from .task_status import TaskStatus
from .session_status import SessionStatus
+from .task_item_view import TaskItemView
-__all__ = ["SessionListResponse", "Item", "ItemTask", "ItemTaskOutputFile", "ItemTaskStep", "ItemTaskUserUploadedFile"]
-
-
-class ItemTaskOutputFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class ItemTaskStep(BaseModel):
- actions: List[str]
-
- evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
-
- memory: str
-
- next_goal: str = FieldInfo(alias="nextGoal")
-
- number: int
-
- url: str
-
- screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
-
-
-class ItemTaskUserUploadedFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class ItemTask(BaseModel):
- id: str
-
- is_scheduled: bool = FieldInfo(alias="isScheduled")
-
- llm: LlmModel
-
- session_id: str = FieldInfo(alias="sessionId")
-
- started_at: datetime = FieldInfo(alias="startedAt")
-
- status: TaskStatus
- """Enumeration of possible task execution states
-
- Attributes: STARTED: Task has been started and is currently running PAUSED: Task
- execution has been temporarily paused (can be resumed) STOPPED: Task execution
- has been stopped (cannot be resumed) FINISHED: Task has completed successfully
- """
-
- task: str
-
- browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
-
- done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
-
- finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
-
- is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
-
- metadata: Optional[Dict[str, object]] = None
-
- output_files: Optional[List[ItemTaskOutputFile]] = FieldInfo(alias="outputFiles", default=None)
-
- session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
-
- steps: Optional[List[ItemTaskStep]] = None
-
- user_uploaded_files: Optional[List[ItemTaskUserUploadedFile]] = FieldInfo(alias="userUploadedFiles", default=None)
+__all__ = ["SessionListResponse", "Item"]
class Item(BaseModel):
@@ -97,7 +28,7 @@ class Item(BaseModel):
live_url: Optional[str] = FieldInfo(alias="liveUrl", default=None)
- tasks: Optional[List[ItemTask]] = None
+ tasks: Optional[List[TaskItemView]] = None
class SessionListResponse(BaseModel):
diff --git a/src/browser_use_sdk/types/session_view.py b/src/browser_use_sdk/types/session_view.py
index 9d00083..492e4aa 100644
--- a/src/browser_use_sdk/types/session_view.py
+++ b/src/browser_use_sdk/types/session_view.py
@@ -1,84 +1,15 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Optional
+from typing import List, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .llm_model import LlmModel
-from .task_status import TaskStatus
from .session_status import SessionStatus
+from .task_item_view import TaskItemView
-__all__ = ["SessionView", "Task", "TaskOutputFile", "TaskStep", "TaskUserUploadedFile"]
-
-
-class TaskOutputFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class TaskStep(BaseModel):
- actions: List[str]
-
- evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
-
- memory: str
-
- next_goal: str = FieldInfo(alias="nextGoal")
-
- number: int
-
- url: str
-
- screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
-
-
-class TaskUserUploadedFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class Task(BaseModel):
- id: str
-
- is_scheduled: bool = FieldInfo(alias="isScheduled")
-
- llm: LlmModel
-
- session_id: str = FieldInfo(alias="sessionId")
-
- started_at: datetime = FieldInfo(alias="startedAt")
-
- status: TaskStatus
- """Enumeration of possible task execution states
-
- Attributes: STARTED: Task has been started and is currently running PAUSED: Task
- execution has been temporarily paused (can be resumed) STOPPED: Task execution
- has been stopped (cannot be resumed) FINISHED: Task has completed successfully
- """
-
- task: str
-
- browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
-
- done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
-
- finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
-
- is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
-
- metadata: Optional[Dict[str, object]] = None
-
- output_files: Optional[List[TaskOutputFile]] = FieldInfo(alias="outputFiles", default=None)
-
- session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
-
- steps: Optional[List[TaskStep]] = None
-
- user_uploaded_files: Optional[List[TaskUserUploadedFile]] = FieldInfo(alias="userUploadedFiles", default=None)
+__all__ = ["SessionView"]
class SessionView(BaseModel):
@@ -101,4 +32,4 @@ class SessionView(BaseModel):
record_url: Optional[str] = FieldInfo(alias="recordUrl", default=None)
- tasks: Optional[List[Task]] = None
+ tasks: Optional[List[TaskItemView]] = None
diff --git a/src/browser_use_sdk/types/task_retrieve_logs_response.py b/src/browser_use_sdk/types/task_get_logs_response.py
similarity index 72%
rename from src/browser_use_sdk/types/task_retrieve_logs_response.py
rename to src/browser_use_sdk/types/task_get_logs_response.py
index cdee450..5bc035c 100644
--- a/src/browser_use_sdk/types/task_retrieve_logs_response.py
+++ b/src/browser_use_sdk/types/task_get_logs_response.py
@@ -4,8 +4,8 @@
from .._models import BaseModel
-__all__ = ["TaskRetrieveLogsResponse"]
+__all__ = ["TaskGetLogsResponse"]
-class TaskRetrieveLogsResponse(BaseModel):
+class TaskGetLogsResponse(BaseModel):
download_url: str = FieldInfo(alias="downloadUrl")
diff --git a/src/browser_use_sdk/types/task_get_output_file_response.py b/src/browser_use_sdk/types/task_get_output_file_response.py
new file mode 100644
index 0000000..bd32595
--- /dev/null
+++ b/src/browser_use_sdk/types/task_get_output_file_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["TaskGetOutputFileResponse"]
+
+
+class TaskGetOutputFileResponse(BaseModel):
+ download_url: str = FieldInfo(alias="downloadUrl")
diff --git a/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py b/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py
new file mode 100644
index 0000000..60376c1
--- /dev/null
+++ b/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["TaskGetUserUploadedFileResponse"]
+
+
+class TaskGetUserUploadedFileResponse(BaseModel):
+ download_url: str = FieldInfo(alias="downloadUrl")
diff --git a/src/browser_use_sdk/types/task_item_view.py b/src/browser_use_sdk/types/task_item_view.py
new file mode 100644
index 0000000..38abbb8
--- /dev/null
+++ b/src/browser_use_sdk/types/task_item_view.py
@@ -0,0 +1,54 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Optional
+from datetime import datetime
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+from .file_view import FileView
+from .llm_model import LlmModel
+from .task_status import TaskStatus
+from .task_step_view import TaskStepView
+
+__all__ = ["TaskItemView"]
+
+
+class TaskItemView(BaseModel):
+ id: str
+
+ is_scheduled: bool = FieldInfo(alias="isScheduled")
+
+ llm: LlmModel
+
+ session_id: str = FieldInfo(alias="sessionId")
+
+ started_at: datetime = FieldInfo(alias="startedAt")
+
+ status: TaskStatus
+ """Enumeration of possible task execution states
+
+ Attributes: STARTED: Task has been started and is currently running PAUSED: Task
+ execution has been temporarily paused (can be resumed) STOPPED: Task execution
+ has been stopped (cannot be resumed) FINISHED: Task has completed successfully
+ """
+
+ task: str
+
+ browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
+
+ done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
+
+ finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
+
+ is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
+
+ metadata: Optional[Dict[str, object]] = None
+
+ output_files: Optional[List[FileView]] = FieldInfo(alias="outputFiles", default=None)
+
+ session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
+
+ steps: Optional[List[TaskStepView]] = None
+
+ user_uploaded_files: Optional[List[FileView]] = FieldInfo(alias="userUploadedFiles", default=None)
diff --git a/src/browser_use_sdk/types/task_list_response.py b/src/browser_use_sdk/types/task_list_response.py
index 6fe357b..de14f6e 100644
--- a/src/browser_use_sdk/types/task_list_response.py
+++ b/src/browser_use_sdk/types/task_list_response.py
@@ -1,87 +1,17 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Optional
-from datetime import datetime
+from typing import List
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .llm_model import LlmModel
-from .task_status import TaskStatus
+from .task_item_view import TaskItemView
-__all__ = ["TaskListResponse", "Item", "ItemOutputFile", "ItemStep", "ItemUserUploadedFile"]
-
-
-class ItemOutputFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class ItemStep(BaseModel):
- actions: List[str]
-
- evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
-
- memory: str
-
- next_goal: str = FieldInfo(alias="nextGoal")
-
- number: int
-
- url: str
-
- screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
-
-
-class ItemUserUploadedFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class Item(BaseModel):
- id: str
-
- is_scheduled: bool = FieldInfo(alias="isScheduled")
-
- llm: LlmModel
-
- session_id: str = FieldInfo(alias="sessionId")
-
- started_at: datetime = FieldInfo(alias="startedAt")
-
- status: TaskStatus
- """Enumeration of possible task execution states
-
- Attributes: STARTED: Task has been started and is currently running PAUSED: Task
- execution has been temporarily paused (can be resumed) STOPPED: Task execution
- has been stopped (cannot be resumed) FINISHED: Task has completed successfully
- """
-
- task: str
-
- browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
-
- done_output: Optional[str] = FieldInfo(alias="doneOutput", default=None)
-
- finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
-
- is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
-
- metadata: Optional[Dict[str, object]] = None
-
- output_files: Optional[List[ItemOutputFile]] = FieldInfo(alias="outputFiles", default=None)
-
- session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
-
- steps: Optional[List[ItemStep]] = None
-
- user_uploaded_files: Optional[List[ItemUserUploadedFile]] = FieldInfo(alias="userUploadedFiles", default=None)
+__all__ = ["TaskListResponse"]
class TaskListResponse(BaseModel):
- items: List[Item]
+ items: List[TaskItemView]
page_number: int = FieldInfo(alias="pageNumber")
diff --git a/src/browser_use_sdk/types/task_step_view.py b/src/browser_use_sdk/types/task_step_view.py
new file mode 100644
index 0000000..b32e08c
--- /dev/null
+++ b/src/browser_use_sdk/types/task_step_view.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["TaskStepView"]
+
+
+class TaskStepView(BaseModel):
+ actions: List[str]
+
+ evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
+
+ memory: str
+
+ next_goal: str = FieldInfo(alias="nextGoal")
+
+ number: int
+
+ url: str
+
+ screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
diff --git a/src/browser_use_sdk/types/task_view.py b/src/browser_use_sdk/types/task_view.py
index 2fa202c..263b90a 100644
--- a/src/browser_use_sdk/types/task_view.py
+++ b/src/browser_use_sdk/types/task_view.py
@@ -6,38 +6,12 @@
from pydantic import Field as FieldInfo
from .._models import BaseModel
+from .file_view import FileView
from .llm_model import LlmModel
from .task_status import TaskStatus
+from .task_step_view import TaskStepView
-__all__ = ["TaskView", "OutputFile", "Step", "UserUploadedFile"]
-
-
-class OutputFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
-
-
-class Step(BaseModel):
- actions: List[str]
-
- evaluation_previous_goal: str = FieldInfo(alias="evaluationPreviousGoal")
-
- memory: str
-
- next_goal: str = FieldInfo(alias="nextGoal")
-
- number: int
-
- url: str
-
- screenshot_url: Optional[str] = FieldInfo(alias="screenshotUrl", default=None)
-
-
-class UserUploadedFile(BaseModel):
- id: str
-
- file_name: str = FieldInfo(alias="fileName")
+__all__ = ["TaskView"]
class TaskView(BaseModel):
@@ -47,7 +21,7 @@ class TaskView(BaseModel):
llm: LlmModel
- output_files: List[OutputFile] = FieldInfo(alias="outputFiles")
+ output_files: List[FileView] = FieldInfo(alias="outputFiles")
session_id: str = FieldInfo(alias="sessionId")
@@ -61,11 +35,11 @@ class TaskView(BaseModel):
has been stopped (cannot be resumed) FINISHED: Task has completed successfully
"""
- steps: List[Step]
+ steps: List[TaskStepView]
task: str
- user_uploaded_files: List[UserUploadedFile] = FieldInfo(alias="userUploadedFiles")
+ user_uploaded_files: List[FileView] = FieldInfo(alias="userUploadedFiles")
browser_use_version: Optional[str] = FieldInfo(alias="browserUseVersion", default=None)
diff --git a/src/browser_use_sdk/types/users/__init__.py b/src/browser_use_sdk/types/users/__init__.py
new file mode 100644
index 0000000..de5007b
--- /dev/null
+++ b/src/browser_use_sdk/types/users/__init__.py
@@ -0,0 +1,5 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .me_retrieve_response import MeRetrieveResponse as MeRetrieveResponse
diff --git a/src/browser_use_sdk/types/users/me/__init__.py b/src/browser_use_sdk/types/users/me/__init__.py
new file mode 100644
index 0000000..27f2334
--- /dev/null
+++ b/src/browser_use_sdk/types/users/me/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .file_create_presigned_url_params import FileCreatePresignedURLParams as FileCreatePresignedURLParams
+from .file_create_presigned_url_response import FileCreatePresignedURLResponse as FileCreatePresignedURLResponse
diff --git a/src/browser_use_sdk/types/users/me/file_create_presigned_url_params.py b/src/browser_use_sdk/types/users/me/file_create_presigned_url_params.py
new file mode 100644
index 0000000..368b0c9
--- /dev/null
+++ b/src/browser_use_sdk/types/users/me/file_create_presigned_url_params.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["FileCreatePresignedURLParams"]
+
+
+class FileCreatePresignedURLParams(TypedDict, total=False):
+ content_type: Required[
+ Annotated[
+ Literal[
+ "image/jpg",
+ "image/jpeg",
+ "image/png",
+ "image/gif",
+ "image/webp",
+ "image/svg+xml",
+ "application/pdf",
+ "application/msword",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.ms-excel",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "text/plain",
+ "text/csv",
+ "text/markdown",
+ ],
+ PropertyInfo(alias="contentType"),
+ ]
+ ]
+
+ file_name: Required[Annotated[str, PropertyInfo(alias="fileName")]]
+
+ size_bytes: Required[Annotated[int, PropertyInfo(alias="sizeBytes")]]
diff --git a/src/browser_use_sdk/types/users/me/file_create_presigned_url_response.py b/src/browser_use_sdk/types/users/me/file_create_presigned_url_response.py
new file mode 100644
index 0000000..f3dc32f
--- /dev/null
+++ b/src/browser_use_sdk/types/users/me/file_create_presigned_url_response.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from ...._models import BaseModel
+
+__all__ = ["FileCreatePresignedURLResponse"]
+
+
+class FileCreatePresignedURLResponse(BaseModel):
+ expires_in: int = FieldInfo(alias="expiresIn")
+
+ fields: Dict[str, str]
+
+ file_name: str = FieldInfo(alias="fileName")
+
+ method: Literal["POST"]
+
+ url: str
diff --git a/src/browser_use_sdk/types/users/me_retrieve_response.py b/src/browser_use_sdk/types/users/me_retrieve_response.py
new file mode 100644
index 0000000..75d83b0
--- /dev/null
+++ b/src/browser_use_sdk/types/users/me_retrieve_response.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["MeRetrieveResponse"]
+
+
+class MeRetrieveResponse(BaseModel):
+ additional_credits_balance_usd: float = FieldInfo(alias="additionalCreditsBalanceUsd")
+
+ monthly_credits_balance_usd: float = FieldInfo(alias="monthlyCreditsBalanceUsd")
+
+ signed_up_at: datetime = FieldInfo(alias="signedUpAt")
+
+ email: Optional[str] = None
+
+ name: Optional[str] = None
diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py
index 52fb550..03b334d 100644
--- a/tests/api_resources/test_sessions.py
+++ b/tests/api_resources/test_sessions.py
@@ -156,6 +156,48 @@ def test_streaming_response_list(self, client: BrowserUse) -> None:
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_delete(self, client: BrowserUse) -> None:
+ session = client.sessions.delete(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert session is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_delete(self, client: BrowserUse) -> None:
+ response = client.sessions.with_raw_response.delete(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = response.parse()
+ assert session is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_delete(self, client: BrowserUse) -> None:
+ with client.sessions.with_streaming_response.delete(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_delete(self, client: BrowserUse) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ client.sessions.with_raw_response.delete(
+ "",
+ )
+
class TestAsyncSessions:
parametrize = pytest.mark.parametrize(
@@ -297,3 +339,45 @@ async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> N
assert_matches_type(SessionListResponse, session, path=["response"])
assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncBrowserUse) -> None:
+ session = await async_client.sessions.delete(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert session is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncBrowserUse) -> None:
+ response = await async_client.sessions.with_raw_response.delete(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ session = await response.parse()
+ assert session is None
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncBrowserUse) -> None:
+ async with async_client.sessions.with_streaming_response.delete(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ session = await response.parse()
+ assert session is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncBrowserUse) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
+ await async_client.sessions.with_raw_response.delete(
+ "",
+ )
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index 2e70a65..35737d6 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -12,7 +12,9 @@
from browser_use_sdk.types import (
TaskView,
TaskListResponse,
- TaskRetrieveLogsResponse,
+ TaskGetLogsResponse,
+ TaskGetOutputFileResponse,
+ TaskGetUserUploadedFileResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -208,46 +210,150 @@ def test_streaming_response_list(self, client: BrowserUse) -> None:
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- def test_method_retrieve_logs(self, client: BrowserUse) -> None:
- task = client.tasks.retrieve_logs(
+ def test_method_get_logs(self, client: BrowserUse) -> None:
+ task = client.tasks.get_logs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
+ assert_matches_type(TaskGetLogsResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- def test_raw_response_retrieve_logs(self, client: BrowserUse) -> None:
- response = client.tasks.with_raw_response.retrieve_logs(
+ def test_raw_response_get_logs(self, client: BrowserUse) -> None:
+ response = client.tasks.with_raw_response.get_logs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = response.parse()
- assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
+ assert_matches_type(TaskGetLogsResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- def test_streaming_response_retrieve_logs(self, client: BrowserUse) -> None:
- with client.tasks.with_streaming_response.retrieve_logs(
+ def test_streaming_response_get_logs(self, client: BrowserUse) -> None:
+ with client.tasks.with_streaming_response.get_logs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = response.parse()
- assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
+ assert_matches_type(TaskGetLogsResponse, task, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- def test_path_params_retrieve_logs(self, client: BrowserUse) -> None:
+ def test_path_params_get_logs(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
- client.tasks.with_raw_response.retrieve_logs(
+ client.tasks.with_raw_response.get_logs(
"",
)
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_get_output_file(self, client: BrowserUse) -> None:
+ task = client.tasks.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(TaskGetOutputFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_get_output_file(self, client: BrowserUse) -> None:
+ response = client.tasks.with_raw_response.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ task = response.parse()
+ assert_matches_type(TaskGetOutputFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_get_output_file(self, client: BrowserUse) -> None:
+ with client.tasks.with_streaming_response.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ task = response.parse()
+ assert_matches_type(TaskGetOutputFileResponse, task, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_get_output_file(self, client: BrowserUse) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
+ client.tasks.with_raw_response.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
+ client.tasks.with_raw_response.get_output_file(
+ file_id="",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_get_user_uploaded_file(self, client: BrowserUse) -> None:
+ task = client.tasks.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(TaskGetUserUploadedFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_get_user_uploaded_file(self, client: BrowserUse) -> None:
+ response = client.tasks.with_raw_response.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ task = response.parse()
+ assert_matches_type(TaskGetUserUploadedFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_get_user_uploaded_file(self, client: BrowserUse) -> None:
+ with client.tasks.with_streaming_response.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ task = response.parse()
+ assert_matches_type(TaskGetUserUploadedFileResponse, task, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_path_params_get_user_uploaded_file(self, client: BrowserUse) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
+ client.tasks.with_raw_response.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
+ client.tasks.with_raw_response.get_user_uploaded_file(
+ file_id="",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
class TestAsyncTasks:
parametrize = pytest.mark.parametrize(
@@ -441,42 +547,146 @@ async def test_streaming_response_list(self, async_client: AsyncBrowserUse) -> N
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- async def test_method_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
- task = await async_client.tasks.retrieve_logs(
+ async def test_method_get_logs(self, async_client: AsyncBrowserUse) -> None:
+ task = await async_client.tasks.get_logs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
- assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
+ assert_matches_type(TaskGetLogsResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- async def test_raw_response_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
- response = await async_client.tasks.with_raw_response.retrieve_logs(
+ async def test_raw_response_get_logs(self, async_client: AsyncBrowserUse) -> None:
+ response = await async_client.tasks.with_raw_response.get_logs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = await response.parse()
- assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
+ assert_matches_type(TaskGetLogsResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- async def test_streaming_response_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
- async with async_client.tasks.with_streaming_response.retrieve_logs(
+ async def test_streaming_response_get_logs(self, async_client: AsyncBrowserUse) -> None:
+ async with async_client.tasks.with_streaming_response.get_logs(
"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = await response.parse()
- assert_matches_type(TaskRetrieveLogsResponse, task, path=["response"])
+ assert_matches_type(TaskGetLogsResponse, task, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
- async def test_path_params_retrieve_logs(self, async_client: AsyncBrowserUse) -> None:
+ async def test_path_params_get_logs(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
- await async_client.tasks.with_raw_response.retrieve_logs(
+ await async_client.tasks.with_raw_response.get_logs(
"",
)
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_get_output_file(self, async_client: AsyncBrowserUse) -> None:
+ task = await async_client.tasks.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(TaskGetOutputFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_get_output_file(self, async_client: AsyncBrowserUse) -> None:
+ response = await async_client.tasks.with_raw_response.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ task = await response.parse()
+ assert_matches_type(TaskGetOutputFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_get_output_file(self, async_client: AsyncBrowserUse) -> None:
+ async with async_client.tasks.with_streaming_response.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ task = await response.parse()
+ assert_matches_type(TaskGetOutputFileResponse, task, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_get_output_file(self, async_client: AsyncBrowserUse) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
+ await async_client.tasks.with_raw_response.get_output_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
+ await async_client.tasks.with_raw_response.get_output_file(
+ file_id="",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_get_user_uploaded_file(self, async_client: AsyncBrowserUse) -> None:
+ task = await async_client.tasks.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(TaskGetUserUploadedFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_get_user_uploaded_file(self, async_client: AsyncBrowserUse) -> None:
+ response = await async_client.tasks.with_raw_response.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ task = await response.parse()
+ assert_matches_type(TaskGetUserUploadedFileResponse, task, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_get_user_uploaded_file(self, async_client: AsyncBrowserUse) -> None:
+ async with async_client.tasks.with_streaming_response.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ task = await response.parse()
+ assert_matches_type(TaskGetUserUploadedFileResponse, task, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_path_params_get_user_uploaded_file(self, async_client: AsyncBrowserUse) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `task_id` but received ''"):
+ await async_client.tasks.with_raw_response.get_user_uploaded_file(
+ file_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ task_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `file_id` but received ''"):
+ await async_client.tasks.with_raw_response.get_user_uploaded_file(
+ file_id="",
+ task_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
diff --git a/tests/api_resources/users/__init__.py b/tests/api_resources/users/__init__.py
new file mode 100644
index 0000000..fd8019a
--- /dev/null
+++ b/tests/api_resources/users/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/users/me/__init__.py b/tests/api_resources/users/me/__init__.py
new file mode 100644
index 0000000..fd8019a
--- /dev/null
+++ b/tests/api_resources/users/me/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/users/me/test_files.py b/tests/api_resources/users/me/test_files.py
new file mode 100644
index 0000000..974f05a
--- /dev/null
+++ b/tests/api_resources/users/me/test_files.py
@@ -0,0 +1,104 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from tests.utils import assert_matches_type
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types.users.me import FileCreatePresignedURLResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestFiles:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_create_presigned_url(self, client: BrowserUse) -> None:
+ file = client.users.me.files.create_presigned_url(
+ content_type="image/jpg",
+ file_name="x",
+ size_bytes=1,
+ )
+ assert_matches_type(FileCreatePresignedURLResponse, file, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_create_presigned_url(self, client: BrowserUse) -> None:
+ response = client.users.me.files.with_raw_response.create_presigned_url(
+ content_type="image/jpg",
+ file_name="x",
+ size_bytes=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ file = response.parse()
+ assert_matches_type(FileCreatePresignedURLResponse, file, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_create_presigned_url(self, client: BrowserUse) -> None:
+ with client.users.me.files.with_streaming_response.create_presigned_url(
+ content_type="image/jpg",
+ file_name="x",
+ size_bytes=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ file = response.parse()
+ assert_matches_type(FileCreatePresignedURLResponse, file, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncFiles:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_create_presigned_url(self, async_client: AsyncBrowserUse) -> None:
+ file = await async_client.users.me.files.create_presigned_url(
+ content_type="image/jpg",
+ file_name="x",
+ size_bytes=1,
+ )
+ assert_matches_type(FileCreatePresignedURLResponse, file, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_create_presigned_url(self, async_client: AsyncBrowserUse) -> None:
+ response = await async_client.users.me.files.with_raw_response.create_presigned_url(
+ content_type="image/jpg",
+ file_name="x",
+ size_bytes=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ file = await response.parse()
+ assert_matches_type(FileCreatePresignedURLResponse, file, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_presigned_url(self, async_client: AsyncBrowserUse) -> None:
+ async with async_client.users.me.files.with_streaming_response.create_presigned_url(
+ content_type="image/jpg",
+ file_name="x",
+ size_bytes=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ file = await response.parse()
+ assert_matches_type(FileCreatePresignedURLResponse, file, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/users/test_me.py b/tests/api_resources/users/test_me.py
new file mode 100644
index 0000000..20e7981
--- /dev/null
+++ b/tests/api_resources/users/test_me.py
@@ -0,0 +1,80 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from tests.utils import assert_matches_type
+from browser_use_sdk import BrowserUse, AsyncBrowserUse
+from browser_use_sdk.types.users import MeRetrieveResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestMe:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_retrieve(self, client: BrowserUse) -> None:
+ me = client.users.me.retrieve()
+ assert_matches_type(MeRetrieveResponse, me, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
+ response = client.users.me.with_raw_response.retrieve()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ me = response.parse()
+ assert_matches_type(MeRetrieveResponse, me, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
+ with client.users.me.with_streaming_response.retrieve() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ me = response.parse()
+ assert_matches_type(MeRetrieveResponse, me, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncMe:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
+ me = await async_client.users.me.retrieve()
+ assert_matches_type(MeRetrieveResponse, me, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
+ response = await async_client.users.me.with_raw_response.retrieve()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ me = await response.parse()
+ assert_matches_type(MeRetrieveResponse, me, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
+ async with async_client.users.me.with_streaming_response.retrieve() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ me = await response.parse()
+ assert_matches_type(MeRetrieveResponse, me, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/test_client.py b/tests/test_client.py
index 6cf0f80..8f044e4 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -24,7 +24,7 @@
from browser_use_sdk import BrowserUse, AsyncBrowserUse, APIResponseValidationError
from browser_use_sdk._types import Omit
from browser_use_sdk._models import BaseModel, FinalRequestOptions
-from browser_use_sdk._exceptions import APIStatusError, APITimeoutError, APIResponseValidationError
+from browser_use_sdk._exceptions import APIStatusError, APITimeoutError, BrowserUseError, APIResponseValidationError
from browser_use_sdk._base_client import (
DEFAULT_TIMEOUT,
HTTPX_DEFAULT_TIMEOUT,
@@ -336,6 +336,16 @@ def test_default_headers_option(self) -> None:
assert request.headers.get("x-foo") == "stainless"
assert request.headers.get("x-stainless-lang") == "my-overriding-header"
+ def test_validate_headers(self) -> None:
+ client = BrowserUse(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
+ assert request.headers.get("X-Browser-Use-API-Key") == api_key
+
+ with pytest.raises(BrowserUseError):
+ with update_env(**{"BROWSER_USE_API_KEY": Omit()}):
+ client2 = BrowserUse(base_url=base_url, api_key=None, _strict_response_validation=True)
+ _ = client2
+
def test_default_query_option(self) -> None:
client = BrowserUse(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"}
@@ -712,20 +722,20 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str
@mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: BrowserUse) -> None:
- respx_mock.get("/tasks").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.get("/users/me").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.tasks.with_streaming_response.list().__enter__()
+ client.users.me.with_streaming_response.retrieve().__enter__()
assert _get_open_connections(self.client) == 0
@mock.patch("browser_use_sdk._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: BrowserUse) -> None:
- respx_mock.get("/tasks").mock(return_value=httpx.Response(500))
+ respx_mock.get("/users/me").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.tasks.with_streaming_response.list().__enter__()
+ client.users.me.with_streaming_response.retrieve().__enter__()
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -752,9 +762,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/tasks").mock(side_effect=retry_handler)
+ respx_mock.get("/users/me").mock(side_effect=retry_handler)
- response = client.tasks.with_raw_response.list()
+ response = client.users.me.with_raw_response.retrieve()
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -776,9 +786,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/tasks").mock(side_effect=retry_handler)
+ respx_mock.get("/users/me").mock(side_effect=retry_handler)
- response = client.tasks.with_raw_response.list(extra_headers={"x-stainless-retry-count": Omit()})
+ response = client.users.me.with_raw_response.retrieve(extra_headers={"x-stainless-retry-count": Omit()})
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -799,9 +809,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/tasks").mock(side_effect=retry_handler)
+ respx_mock.get("/users/me").mock(side_effect=retry_handler)
- response = client.tasks.with_raw_response.list(extra_headers={"x-stainless-retry-count": "42"})
+ response = client.users.me.with_raw_response.retrieve(extra_headers={"x-stainless-retry-count": "42"})
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1135,6 +1145,16 @@ def test_default_headers_option(self) -> None:
assert request.headers.get("x-foo") == "stainless"
assert request.headers.get("x-stainless-lang") == "my-overriding-header"
+ def test_validate_headers(self) -> None:
+ client = AsyncBrowserUse(base_url=base_url, api_key=api_key, _strict_response_validation=True)
+ request = client._build_request(FinalRequestOptions(method="get", url="/foo"))
+ assert request.headers.get("X-Browser-Use-API-Key") == api_key
+
+ with pytest.raises(BrowserUseError):
+ with update_env(**{"BROWSER_USE_API_KEY": Omit()}):
+ client2 = AsyncBrowserUse(base_url=base_url, api_key=None, _strict_response_validation=True)
+ _ = client2
+
def test_default_query_option(self) -> None:
client = AsyncBrowserUse(
base_url=base_url, api_key=api_key, _strict_response_validation=True, default_query={"query_param": "bar"}
@@ -1519,10 +1539,10 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte
async def test_retrying_timeout_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncBrowserUse
) -> None:
- respx_mock.get("/tasks").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.get("/users/me").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.tasks.with_streaming_response.list().__aenter__()
+ await async_client.users.me.with_streaming_response.retrieve().__aenter__()
assert _get_open_connections(self.client) == 0
@@ -1531,10 +1551,10 @@ async def test_retrying_timeout_errors_doesnt_leak(
async def test_retrying_status_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncBrowserUse
) -> None:
- respx_mock.get("/tasks").mock(return_value=httpx.Response(500))
+ respx_mock.get("/users/me").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.tasks.with_streaming_response.list().__aenter__()
+ await async_client.users.me.with_streaming_response.retrieve().__aenter__()
assert _get_open_connections(self.client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1562,9 +1582,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/tasks").mock(side_effect=retry_handler)
+ respx_mock.get("/users/me").mock(side_effect=retry_handler)
- response = await client.tasks.with_raw_response.list()
+ response = await client.users.me.with_raw_response.retrieve()
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1587,9 +1607,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/tasks").mock(side_effect=retry_handler)
+ respx_mock.get("/users/me").mock(side_effect=retry_handler)
- response = await client.tasks.with_raw_response.list(extra_headers={"x-stainless-retry-count": Omit()})
+ response = await client.users.me.with_raw_response.retrieve(extra_headers={"x-stainless-retry-count": Omit()})
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1611,9 +1631,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/tasks").mock(side_effect=retry_handler)
+ respx_mock.get("/users/me").mock(side_effect=retry_handler)
- response = await client.tasks.with_raw_response.list(extra_headers={"x-stainless-retry-count": "42"})
+ response = await client.users.me.with_raw_response.retrieve(extra_headers={"x-stainless-retry-count": "42"})
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From 5dcf360ccfe40f45962ecaa64b8a5aacf55778d4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 Aug 2025 19:32:48 +0000
Subject: [PATCH 06/10] feat: Fix Stainless GitHub Action
---
.stats.yml | 4 ++--
README.md | 4 ++--
api.md | 3 ++-
src/browser_use_sdk/resources/tasks.py | 13 +++++++------
src/browser_use_sdk/types/__init__.py | 1 +
.../types/task_create_response.py | 13 +++++++++++++
tests/api_resources/test_tasks.py | 17 +++++++++--------
7 files changed, 36 insertions(+), 19 deletions(-)
create mode 100644 src/browser_use_sdk/types/task_create_response.py
diff --git a/.stats.yml b/.stats.yml
index 1c0836f..4189f1a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 26
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-9ff5409663c58ae9e3ecc9ac764956189e3a70600f5ba1b961bb1dedf0208271.yml
-openapi_spec_hash: 9865acb75430d9b799502acbae860df0
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-d20f308ac3a63b1ea5749dac763fd846481c9723156a5653c1d03669e73d5b5e.yml
+openapi_spec_hash: ccf5babfe92a776213a3e5097a7cd546
config_hash: 9d52be5177b2ede4cb0633c04f4cc4ef
diff --git a/README.md b/README.md
index 039a95b..6a1320b 100644
--- a/README.md
+++ b/README.md
@@ -114,11 +114,11 @@ from browser_use_sdk import BrowserUse
client = BrowserUse()
-task_view = client.tasks.create(
+task = client.tasks.create(
task="x",
agent_settings={},
)
-print(task_view.agent_settings)
+print(task.agent_settings)
```
## Handling errors
diff --git a/api.md b/api.md
index bc9f11c..16ef2b9 100644
--- a/api.md
+++ b/api.md
@@ -36,6 +36,7 @@ from browser_use_sdk.types import (
TaskStatus,
TaskStepView,
TaskView,
+ TaskCreateResponse,
TaskListResponse,
TaskGetLogsResponse,
TaskGetOutputFileResponse,
@@ -45,7 +46,7 @@ from browser_use_sdk.types import (
Methods:
-- client.tasks.create(\*\*params) -> TaskView
+- client.tasks.create(\*\*params) -> TaskCreateResponse
- client.tasks.retrieve(task_id) -> TaskView
- client.tasks.update(task_id, \*\*params) -> TaskView
- client.tasks.list(\*\*params) -> TaskListResponse
diff --git a/src/browser_use_sdk/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
index cb1644a..6211a36 100644
--- a/src/browser_use_sdk/resources/tasks.py
+++ b/src/browser_use_sdk/resources/tasks.py
@@ -21,6 +21,7 @@
from .._base_client import make_request_options
from ..types.task_view import TaskView
from ..types.task_list_response import TaskListResponse
+from ..types.task_create_response import TaskCreateResponse
from ..types.task_get_logs_response import TaskGetLogsResponse
from ..types.task_get_output_file_response import TaskGetOutputFileResponse
from ..types.task_get_user_uploaded_file_response import TaskGetUserUploadedFileResponse
@@ -64,7 +65,7 @@ def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskView:
+ ) -> TaskCreateResponse:
"""
Create and start a new AI agent task.
@@ -103,7 +104,7 @@ def create(
Returns:
- - The created task with its initial details
+ - The created task ID together with the task's session ID
Raises:
@@ -148,7 +149,7 @@ def create(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TaskView,
+ cast_to=TaskCreateResponse,
)
def retrieve(
@@ -567,7 +568,7 @@ async def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
- ) -> TaskView:
+ ) -> TaskCreateResponse:
"""
Create and start a new AI agent task.
@@ -606,7 +607,7 @@ async def create(
Returns:
- - The created task with its initial details
+ - The created task ID together with the task's session ID
Raises:
@@ -651,7 +652,7 @@ async def create(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TaskView,
+ cast_to=TaskCreateResponse,
)
async def retrieve(
diff --git a/src/browser_use_sdk/types/__init__.py b/src/browser_use_sdk/types/__init__.py
index 74d4a7c..12cbaaf 100644
--- a/src/browser_use_sdk/types/__init__.py
+++ b/src/browser_use_sdk/types/__init__.py
@@ -18,6 +18,7 @@
from .task_update_params import TaskUpdateParams as TaskUpdateParams
from .session_list_params import SessionListParams as SessionListParams
from .browser_profile_view import BrowserProfileView as BrowserProfileView
+from .task_create_response import TaskCreateResponse as TaskCreateResponse
from .session_list_response import SessionListResponse as SessionListResponse
from .session_update_params import SessionUpdateParams as SessionUpdateParams
from .task_get_logs_response import TaskGetLogsResponse as TaskGetLogsResponse
diff --git a/src/browser_use_sdk/types/task_create_response.py b/src/browser_use_sdk/types/task_create_response.py
new file mode 100644
index 0000000..b17ab00
--- /dev/null
+++ b/src/browser_use_sdk/types/task_create_response.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["TaskCreateResponse"]
+
+
+class TaskCreateResponse(BaseModel):
+ id: str
+
+ session_id: str = FieldInfo(alias="sessionId")
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index 35737d6..d30211d 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -12,6 +12,7 @@
from browser_use_sdk.types import (
TaskView,
TaskListResponse,
+ TaskCreateResponse,
TaskGetLogsResponse,
TaskGetOutputFileResponse,
TaskGetUserUploadedFileResponse,
@@ -29,7 +30,7 @@ def test_method_create(self, client: BrowserUse) -> None:
task = client.tasks.create(
task="x",
)
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -50,7 +51,7 @@ def test_method_create_with_all_params(self, client: BrowserUse) -> None:
secrets={"foo": "string"},
structured_output_json="structuredOutputJson",
)
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -62,7 +63,7 @@ def test_raw_response_create(self, client: BrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = response.parse()
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -74,7 +75,7 @@ def test_streaming_response_create(self, client: BrowserUse) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = response.parse()
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -366,7 +367,7 @@ async def test_method_create(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.create(
task="x",
)
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -387,7 +388,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse
secrets={"foo": "string"},
structured_output_json="structuredOutputJson",
)
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -399,7 +400,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserUse) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = await response.parse()
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
@pytest.mark.skip(reason="Prism tests are disabled")
@parametrize
@@ -411,7 +412,7 @@ async def test_streaming_response_create(self, async_client: AsyncBrowserUse) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
task = await response.parse()
- assert_matches_type(TaskView, task, path=["response"])
+ assert_matches_type(TaskCreateResponse, task, path=["response"])
assert cast(Any, response.is_closed) is True
From 44b4c5d7ed416f9f5c37afb3287cdaa6f22a30cd Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sun, 17 Aug 2025 18:06:38 +0000
Subject: [PATCH 07/10] feat: Update param and response views
---
.stats.yml | 4 +--
api.md | 2 +-
.../resources/sessions/sessions.py | 22 ++----------
src/browser_use_sdk/resources/tasks.py | 12 -------
src/browser_use_sdk/types/__init__.py | 1 -
.../types/session_list_params.py | 2 --
.../types/session_list_response.py | 3 --
.../types/session_retrieve_params.py | 13 -------
.../types/task_get_output_file_response.py | 4 +++
.../task_get_user_uploaded_file_response.py | 4 +++
src/browser_use_sdk/types/task_item_view.py | 12 +------
src/browser_use_sdk/types/task_list_params.py | 6 ----
src/browser_use_sdk/types/task_view.py | 31 ++++++++++++++--
tests/api_resources/test_sessions.py | 36 +++++--------------
tests/api_resources/test_tasks.py | 6 ----
15 files changed, 51 insertions(+), 107 deletions(-)
delete mode 100644 src/browser_use_sdk/types/session_retrieve_params.py
diff --git a/.stats.yml b/.stats.yml
index 4189f1a..1091c47 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 26
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-d20f308ac3a63b1ea5749dac763fd846481c9723156a5653c1d03669e73d5b5e.yml
-openapi_spec_hash: ccf5babfe92a776213a3e5097a7cd546
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-758a1c052b93e7e478fa650c1748f4b466653f44cb26f97fef1314c7a96924df.yml
+openapi_spec_hash: 9e0e99b613f2b9bf3993ac36aa0c7911
config_hash: 9d52be5177b2ede4cb0633c04f4cc4ef
diff --git a/api.md b/api.md
index 16ef2b9..bddad6f 100644
--- a/api.md
+++ b/api.md
@@ -64,7 +64,7 @@ from browser_use_sdk.types import SessionStatus, SessionView, SessionListRespons
Methods:
-- client.sessions.retrieve(session_id, \*\*params) -> SessionView
+- client.sessions.retrieve(session_id) -> SessionView
- client.sessions.update(session_id, \*\*params) -> SessionView
- client.sessions.list(\*\*params) -> SessionListResponse
- client.sessions.delete(session_id) -> None
diff --git a/src/browser_use_sdk/resources/sessions/sessions.py b/src/browser_use_sdk/resources/sessions/sessions.py
index 5919f7f..4fc67dd 100644
--- a/src/browser_use_sdk/resources/sessions/sessions.py
+++ b/src/browser_use_sdk/resources/sessions/sessions.py
@@ -7,7 +7,7 @@
import httpx
-from ...types import SessionStatus, session_list_params, session_update_params, session_retrieve_params
+from ...types import SessionStatus, session_list_params, session_update_params
from ..._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
@@ -62,7 +62,6 @@ def retrieve(
self,
session_id: str,
*,
- include_tasks: bool | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -105,11 +104,7 @@ def retrieve(
return self._get(
f"/sessions/{session_id}",
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"include_tasks": include_tasks}, session_retrieve_params.SessionRetrieveParams),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=SessionView,
)
@@ -181,7 +176,6 @@ def list(
self,
*,
filter_by: Optional[SessionStatus] | NotGiven = NOT_GIVEN,
- include_tasks: bool | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -232,7 +226,6 @@ def list(
query=maybe_transform(
{
"filter_by": filter_by,
- "include_tasks": include_tasks,
"page_number": page_number,
"page_size": page_size,
},
@@ -317,7 +310,6 @@ async def retrieve(
self,
session_id: str,
*,
- include_tasks: bool | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -360,13 +352,7 @@ async def retrieve(
return await self._get(
f"/sessions/{session_id}",
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {"include_tasks": include_tasks}, session_retrieve_params.SessionRetrieveParams
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
cast_to=SessionView,
)
@@ -438,7 +424,6 @@ async def list(
self,
*,
filter_by: Optional[SessionStatus] | NotGiven = NOT_GIVEN,
- include_tasks: bool | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -489,7 +474,6 @@ async def list(
query=await async_maybe_transform(
{
"filter_by": filter_by,
- "include_tasks": include_tasks,
"page_number": page_number,
"page_size": page_size,
},
diff --git a/src/browser_use_sdk/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
index 6211a36..9d23e5f 100644
--- a/src/browser_use_sdk/resources/tasks.py
+++ b/src/browser_use_sdk/resources/tasks.py
@@ -281,9 +281,6 @@ def list(
*,
filter_by: Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]]
| NotGiven = NOT_GIVEN,
- include_output_files: bool | NotGiven = NOT_GIVEN,
- include_steps: bool | NotGiven = NOT_GIVEN,
- include_user_uploaded_files: bool | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
session_id: Optional[str] | NotGiven = NOT_GIVEN,
@@ -340,9 +337,6 @@ def list(
query=maybe_transform(
{
"filter_by": filter_by,
- "include_output_files": include_output_files,
- "include_steps": include_steps,
- "include_user_uploaded_files": include_user_uploaded_files,
"page_number": page_number,
"page_size": page_size,
"session_id": session_id,
@@ -784,9 +778,6 @@ async def list(
*,
filter_by: Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]]
| NotGiven = NOT_GIVEN,
- include_output_files: bool | NotGiven = NOT_GIVEN,
- include_steps: bool | NotGiven = NOT_GIVEN,
- include_user_uploaded_files: bool | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
session_id: Optional[str] | NotGiven = NOT_GIVEN,
@@ -843,9 +834,6 @@ async def list(
query=await async_maybe_transform(
{
"filter_by": filter_by,
- "include_output_files": include_output_files,
- "include_steps": include_steps,
- "include_user_uploaded_files": include_user_uploaded_files,
"page_number": page_number,
"page_size": page_size,
"session_id": session_id,
diff --git a/src/browser_use_sdk/types/__init__.py b/src/browser_use_sdk/types/__init__.py
index 12cbaaf..105b042 100644
--- a/src/browser_use_sdk/types/__init__.py
+++ b/src/browser_use_sdk/types/__init__.py
@@ -22,7 +22,6 @@
from .session_list_response import SessionListResponse as SessionListResponse
from .session_update_params import SessionUpdateParams as SessionUpdateParams
from .task_get_logs_response import TaskGetLogsResponse as TaskGetLogsResponse
-from .session_retrieve_params import SessionRetrieveParams as SessionRetrieveParams
from .agent_profile_list_params import AgentProfileListParams as AgentProfileListParams
from .agent_profile_create_params import AgentProfileCreateParams as AgentProfileCreateParams
from .agent_profile_list_response import AgentProfileListResponse as AgentProfileListResponse
diff --git a/src/browser_use_sdk/types/session_list_params.py b/src/browser_use_sdk/types/session_list_params.py
index 70df445..0bd7b72 100644
--- a/src/browser_use_sdk/types/session_list_params.py
+++ b/src/browser_use_sdk/types/session_list_params.py
@@ -19,8 +19,6 @@ class SessionListParams(TypedDict, total=False):
STOPPED: Session has been stopped and is no longer active (browser is stopped)
"""
- include_tasks: Annotated[bool, PropertyInfo(alias="includeTasks")]
-
page_number: Annotated[int, PropertyInfo(alias="pageNumber")]
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
diff --git a/src/browser_use_sdk/types/session_list_response.py b/src/browser_use_sdk/types/session_list_response.py
index 4b89459..0958cfa 100644
--- a/src/browser_use_sdk/types/session_list_response.py
+++ b/src/browser_use_sdk/types/session_list_response.py
@@ -7,7 +7,6 @@
from .._models import BaseModel
from .session_status import SessionStatus
-from .task_item_view import TaskItemView
__all__ = ["SessionListResponse", "Item"]
@@ -28,8 +27,6 @@ class Item(BaseModel):
live_url: Optional[str] = FieldInfo(alias="liveUrl", default=None)
- tasks: Optional[List[TaskItemView]] = None
-
class SessionListResponse(BaseModel):
items: List[Item]
diff --git a/src/browser_use_sdk/types/session_retrieve_params.py b/src/browser_use_sdk/types/session_retrieve_params.py
deleted file mode 100644
index 33db5d3..0000000
--- a/src/browser_use_sdk/types/session_retrieve_params.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["SessionRetrieveParams"]
-
-
-class SessionRetrieveParams(TypedDict, total=False):
- include_tasks: Annotated[bool, PropertyInfo(alias="includeTasks")]
diff --git a/src/browser_use_sdk/types/task_get_output_file_response.py b/src/browser_use_sdk/types/task_get_output_file_response.py
index bd32595..812ac90 100644
--- a/src/browser_use_sdk/types/task_get_output_file_response.py
+++ b/src/browser_use_sdk/types/task_get_output_file_response.py
@@ -8,4 +8,8 @@
class TaskGetOutputFileResponse(BaseModel):
+ id: str
+
download_url: str = FieldInfo(alias="downloadUrl")
+
+ file_name: str = FieldInfo(alias="fileName")
diff --git a/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py b/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py
index 60376c1..f802207 100644
--- a/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py
+++ b/src/browser_use_sdk/types/task_get_user_uploaded_file_response.py
@@ -8,4 +8,8 @@
class TaskGetUserUploadedFileResponse(BaseModel):
+ id: str
+
download_url: str = FieldInfo(alias="downloadUrl")
+
+ file_name: str = FieldInfo(alias="fileName")
diff --git a/src/browser_use_sdk/types/task_item_view.py b/src/browser_use_sdk/types/task_item_view.py
index 38abbb8..b0028da 100644
--- a/src/browser_use_sdk/types/task_item_view.py
+++ b/src/browser_use_sdk/types/task_item_view.py
@@ -1,15 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Optional
+from typing import Dict, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
from .._models import BaseModel
-from .file_view import FileView
from .llm_model import LlmModel
from .task_status import TaskStatus
-from .task_step_view import TaskStepView
__all__ = ["TaskItemView"]
@@ -44,11 +42,3 @@ class TaskItemView(BaseModel):
is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
metadata: Optional[Dict[str, object]] = None
-
- output_files: Optional[List[FileView]] = FieldInfo(alias="outputFiles", default=None)
-
- session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
-
- steps: Optional[List[TaskStepView]] = None
-
- user_uploaded_files: Optional[List[FileView]] = FieldInfo(alias="userUploadedFiles", default=None)
diff --git a/src/browser_use_sdk/types/task_list_params.py b/src/browser_use_sdk/types/task_list_params.py
index 849b038..6a4a3ac 100644
--- a/src/browser_use_sdk/types/task_list_params.py
+++ b/src/browser_use_sdk/types/task_list_params.py
@@ -22,12 +22,6 @@ class TaskListParams(TypedDict, total=False):
UNSUCCESSFUL: All unsuccessful tasks
"""
- include_output_files: Annotated[bool, PropertyInfo(alias="includeOutputFiles")]
-
- include_steps: Annotated[bool, PropertyInfo(alias="includeSteps")]
-
- include_user_uploaded_files: Annotated[bool, PropertyInfo(alias="includeUserUploadedFiles")]
-
page_number: Annotated[int, PropertyInfo(alias="pageNumber")]
page_size: Annotated[int, PropertyInfo(alias="pageSize")]
diff --git a/src/browser_use_sdk/types/task_view.py b/src/browser_use_sdk/types/task_view.py
index 263b90a..a88128c 100644
--- a/src/browser_use_sdk/types/task_view.py
+++ b/src/browser_use_sdk/types/task_view.py
@@ -2,6 +2,7 @@
from typing import Dict, List, Optional
from datetime import datetime
+from typing_extensions import Literal
from pydantic import Field as FieldInfo
@@ -11,7 +12,24 @@
from .task_status import TaskStatus
from .task_step_view import TaskStepView
-__all__ = ["TaskView"]
+__all__ = ["TaskView", "Session"]
+
+
+class Session(BaseModel):
+ id: str
+
+ started_at: datetime = FieldInfo(alias="startedAt")
+
+ status: Literal["active", "stopped"]
+ """Enumeration of possible (browser) session states
+
+ Attributes: ACTIVE: Session is currently active and running (browser is running)
+ STOPPED: Session has been stopped and is no longer active (browser is stopped)
+ """
+
+ finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None)
+
+ live_url: Optional[str] = FieldInfo(alias="liveUrl", default=None)
class TaskView(BaseModel):
@@ -23,6 +41,15 @@ class TaskView(BaseModel):
output_files: List[FileView] = FieldInfo(alias="outputFiles")
+ session: Session
+ """View model for representing a session that a task belongs to
+
+ Attributes: id: Unique identifier for the session status: Current status of the
+ session live_url: URL where the browser can be viewed live in real-time.
+ started_at: Timestamp when the session was created and started. finished_at:
+ Timestamp when the session was stopped (None if still active).
+ """
+
session_id: str = FieldInfo(alias="sessionId")
started_at: datetime = FieldInfo(alias="startedAt")
@@ -50,5 +77,3 @@ class TaskView(BaseModel):
is_success: Optional[bool] = FieldInfo(alias="isSuccess", default=None)
metadata: Optional[Dict[str, object]] = None
-
- session_live_url: Optional[str] = FieldInfo(alias="sessionLiveUrl", default=None)
diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py
index 03b334d..0751000 100644
--- a/tests/api_resources/test_sessions.py
+++ b/tests/api_resources/test_sessions.py
@@ -24,16 +24,7 @@ class TestSessions:
@parametrize
def test_method_retrieve(self, client: BrowserUse) -> None:
session = client.sessions.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(SessionView, session, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
- session = client.sessions.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- include_tasks=True,
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(SessionView, session, path=["response"])
@@ -41,7 +32,7 @@ def test_method_retrieve_with_all_params(self, client: BrowserUse) -> None:
@parametrize
def test_raw_response_retrieve(self, client: BrowserUse) -> None:
response = client.sessions.with_raw_response.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -53,7 +44,7 @@ def test_raw_response_retrieve(self, client: BrowserUse) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
with client.sessions.with_streaming_response.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -68,7 +59,7 @@ def test_streaming_response_retrieve(self, client: BrowserUse) -> None:
def test_path_params_retrieve(self, client: BrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
client.sessions.with_raw_response.retrieve(
- session_id="",
+ "",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@@ -128,7 +119,6 @@ def test_method_list(self, client: BrowserUse) -> None:
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
session = client.sessions.list(
filter_by="active",
- include_tasks=True,
page_number=1,
page_size=1,
)
@@ -208,16 +198,7 @@ class TestAsyncSessions:
@parametrize
async def test_method_retrieve(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- )
- assert_matches_type(SessionView, session, path=["response"])
-
- @pytest.mark.skip(reason="Prism tests are disabled")
- @parametrize
- async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserUse) -> None:
- session = await async_client.sessions.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- include_tasks=True,
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert_matches_type(SessionView, session, path=["response"])
@@ -225,7 +206,7 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncBrowserU
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
response = await async_client.sessions.with_raw_response.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
)
assert response.is_closed is True
@@ -237,7 +218,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncBrowserUse) -> Non
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse) -> None:
async with async_client.sessions.with_streaming_response.retrieve(
- session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -252,7 +233,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrowserUse)
async def test_path_params_retrieve(self, async_client: AsyncBrowserUse) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
await async_client.sessions.with_raw_response.retrieve(
- session_id="",
+ "",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@@ -312,7 +293,6 @@ async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
session = await async_client.sessions.list(
filter_by="active",
- include_tasks=True,
page_number=1,
page_size=1,
)
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index d30211d..ff5a527 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -178,9 +178,6 @@ def test_method_list(self, client: BrowserUse) -> None:
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
task = client.tasks.list(
filter_by="started",
- include_output_files=True,
- include_steps=True,
- include_user_uploaded_files=True,
page_number=1,
page_size=1,
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
@@ -515,9 +512,6 @@ async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.list(
filter_by="started",
- include_output_files=True,
- include_steps=True,
- include_user_uploaded_files=True,
page_number=1,
page_size=1,
session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
From 2ede0a9089bfbba1eca207508a52ee36b4ef18ac Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 18 Aug 2025 09:57:11 +0000
Subject: [PATCH 08/10] feat: Add start_url
---
.stats.yml | 4 ++--
src/browser_use_sdk/resources/tasks.py | 22 ++++++++++---------
.../types/task_create_params.py | 15 +++++++------
src/browser_use_sdk/types/task_view.py | 6 ++---
tests/api_resources/test_tasks.py | 4 ++--
5 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 1091c47..285836b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 26
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-758a1c052b93e7e478fa650c1748f4b466653f44cb26f97fef1314c7a96924df.yml
-openapi_spec_hash: 9e0e99b613f2b9bf3993ac36aa0c7911
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-890b9140b139df6307d175ff31cba0bf14d703887bee2f0a8db9f5bffc78e11d.yml
+openapi_spec_hash: 7131a3daffe4f5b67bc1c7ccec06d961
config_hash: 9d52be5177b2ede4cb0633c04f4cc4ef
diff --git a/src/browser_use_sdk/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
index 9d23e5f..23d3963 100644
--- a/src/browser_use_sdk/resources/tasks.py
+++ b/src/browser_use_sdk/resources/tasks.py
@@ -113,16 +113,17 @@ def create(
- 400: If session is stopped or already has a running task
Args:
- agent_settings: Configuration settings for the AI agent
+ agent_settings: Configuration settings for the agent
- Attributes: llm: The LLM model to use for the agent profile_id: Unique
- identifier of the agent profile to use for the task
+ Attributes: llm: The LLM model to use for the agent start_url: Optional URL to
+ start the agent on (will not be changed as a step) profile_id: Unique identifier
+ of the agent profile to use for the task
browser_settings: Configuration settings for the browser session
Attributes: session_id: Unique identifier of existing session to continue
- profile_id: Unique identifier of browser profile to use save_browser_data:
- Whether to save browser state/data for the user to download later
+ profile_id: Unique identifier of browser profile to use (use if you want to
+ start a new session)
extra_headers: Send extra headers
@@ -610,16 +611,17 @@ async def create(
- 400: If session is stopped or already has a running task
Args:
- agent_settings: Configuration settings for the AI agent
+ agent_settings: Configuration settings for the agent
- Attributes: llm: The LLM model to use for the agent profile_id: Unique
- identifier of the agent profile to use for the task
+ Attributes: llm: The LLM model to use for the agent start_url: Optional URL to
+ start the agent on (will not be changed as a step) profile_id: Unique identifier
+ of the agent profile to use for the task
browser_settings: Configuration settings for the browser session
Attributes: session_id: Unique identifier of existing session to continue
- profile_id: Unique identifier of browser profile to use save_browser_data:
- Whether to save browser state/data for the user to download later
+ profile_id: Unique identifier of browser profile to use (use if you want to
+ start a new session)
extra_headers: Send extra headers
diff --git a/src/browser_use_sdk/types/task_create_params.py b/src/browser_use_sdk/types/task_create_params.py
index c970662..7943846 100644
--- a/src/browser_use_sdk/types/task_create_params.py
+++ b/src/browser_use_sdk/types/task_create_params.py
@@ -15,18 +15,19 @@ class TaskCreateParams(TypedDict, total=False):
task: Required[str]
agent_settings: Annotated[AgentSettings, PropertyInfo(alias="agentSettings")]
- """Configuration settings for the AI agent
+ """Configuration settings for the agent
- Attributes: llm: The LLM model to use for the agent profile_id: Unique
- identifier of the agent profile to use for the task
+ Attributes: llm: The LLM model to use for the agent start_url: Optional URL to
+ start the agent on (will not be changed as a step) profile_id: Unique identifier
+ of the agent profile to use for the task
"""
browser_settings: Annotated[BrowserSettings, PropertyInfo(alias="browserSettings")]
"""Configuration settings for the browser session
Attributes: session_id: Unique identifier of existing session to continue
- profile_id: Unique identifier of browser profile to use save_browser_data:
- Whether to save browser state/data for the user to download later
+ profile_id: Unique identifier of browser profile to use (use if you want to
+ start a new session)
"""
included_file_names: Annotated[Optional[List[str]], PropertyInfo(alias="includedFileNames")]
@@ -43,10 +44,10 @@ class AgentSettings(TypedDict, total=False):
profile_id: Annotated[Optional[str], PropertyInfo(alias="profileId")]
+ start_url: Annotated[Optional[str], PropertyInfo(alias="startUrl")]
+
class BrowserSettings(TypedDict, total=False):
profile_id: Annotated[Optional[str], PropertyInfo(alias="profileId")]
- save_browser_data: Annotated[bool, PropertyInfo(alias="saveBrowserData")]
-
session_id: Annotated[Optional[str], PropertyInfo(alias="sessionId")]
diff --git a/src/browser_use_sdk/types/task_view.py b/src/browser_use_sdk/types/task_view.py
index a88128c..ed102f1 100644
--- a/src/browser_use_sdk/types/task_view.py
+++ b/src/browser_use_sdk/types/task_view.py
@@ -45,9 +45,9 @@ class TaskView(BaseModel):
"""View model for representing a session that a task belongs to
Attributes: id: Unique identifier for the session status: Current status of the
- session live_url: URL where the browser can be viewed live in real-time.
- started_at: Timestamp when the session was created and started. finished_at:
- Timestamp when the session was stopped (None if still active).
+ session (active/stopped) live_url: URL where the browser can be viewed live in
+ real-time. started_at: Timestamp when the session was created and started.
+ finished_at: Timestamp when the session was stopped (None if still active).
"""
session_id: str = FieldInfo(alias="sessionId")
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index ff5a527..fe4ba58 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -40,10 +40,10 @@ def test_method_create_with_all_params(self, client: BrowserUse) -> None:
agent_settings={
"llm": "gpt-4o",
"profile_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "start_url": "startUrl",
},
browser_settings={
"profile_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "save_browser_data": True,
"session_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
},
included_file_names=["string"],
@@ -374,10 +374,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncBrowserUse
agent_settings={
"llm": "gpt-4o",
"profile_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ "start_url": "startUrl",
},
browser_settings={
"profile_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
- "save_browser_data": True,
"session_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
},
included_file_names=["string"],
From 29b4590c69f13fbf7f855888862ef77a9e704172 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:32:47 +0000
Subject: [PATCH 09/10] feat: Align Task Filtering by Status with `status`
Field
---
.stats.yml | 4 +-
src/browser_use_sdk/resources/tasks.py | 72 +++++++++----------
src/browser_use_sdk/types/task_item_view.py | 7 +-
src/browser_use_sdk/types/task_list_params.py | 26 ++++---
src/browser_use_sdk/types/task_status.py | 2 +-
src/browser_use_sdk/types/task_view.py | 7 +-
tests/api_resources/test_tasks.py | 5 ++
7 files changed, 65 insertions(+), 58 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 285836b..8a02f60 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 26
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-890b9140b139df6307d175ff31cba0bf14d703887bee2f0a8db9f5bffc78e11d.yml
-openapi_spec_hash: 7131a3daffe4f5b67bc1c7ccec06d961
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browser-use%2Fbrowser-use-3a9488448292a0736b08b2d6427e702eaf7106d86345ca2e65b64bed4398b036.yml
+openapi_spec_hash: 5ff2781dcc11a0c9aa353f5cb14bcc16
config_hash: 9d52be5177b2ede4cb0633c04f4cc4ef
diff --git a/src/browser_use_sdk/resources/tasks.py b/src/browser_use_sdk/resources/tasks.py
index 23d3963..df75c36 100644
--- a/src/browser_use_sdk/resources/tasks.py
+++ b/src/browser_use_sdk/resources/tasks.py
@@ -2,12 +2,13 @@
from __future__ import annotations
-from typing import Dict, List, Optional
+from typing import Dict, List, Union, Optional
+from datetime import datetime
from typing_extensions import Literal
import httpx
-from ..types import task_list_params, task_create_params, task_update_params
+from ..types import TaskStatus, task_list_params, task_create_params, task_update_params
from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -20,6 +21,7 @@
)
from .._base_client import make_request_options
from ..types.task_view import TaskView
+from ..types.task_status import TaskStatus
from ..types.task_list_response import TaskListResponse
from ..types.task_create_response import TaskCreateResponse
from ..types.task_get_logs_response import TaskGetLogsResponse
@@ -280,8 +282,9 @@ def update(
def list(
self,
*,
- filter_by: Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]]
- | NotGiven = NOT_GIVEN,
+ after: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
+ before: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
+ filter_by: Optional[TaskStatus] | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
session_id: Optional[str] | NotGiven = NOT_GIVEN,
@@ -293,32 +296,26 @@ def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskListResponse:
"""
- Get a paginated list of all AI agent tasks for the authenticated user.
+ Get a paginated list of all Browser Use Agent tasks for the authenticated user.
- AI agent tasks are the individual jobs that your agents perform within a
- session. Each task represents a specific instruction or goal that the agent
+ Browser Use Agent tasks are the individual jobs that your agents perform within
+ a session. Each task represents a specific instruction or goal that the agent
works on, such as filling out a form, extracting data, or navigating to specific
pages.
- You can control what data is included for each task:
-
- - Task steps: Detailed actions the agent took
- - User uploaded files: Files you provided for the task
- - Output files: Files generated by the agent during the task
-
Returns:
- - A paginated list of agent tasks
- - Total count of tasks
+ - A paginated list of Browser Use Agent tasks
+ - Total count of Browser Use Agent tasks
- Page information for navigation
- - Optional detailed data based on your parameters
Args:
- filter_by: Enumeration of possible task filters
+ filter_by: Enumeration of possible task execution states
- Attributes: STARTED: All started tasks PAUSED: All paused tasks STOPPED: All
- stopped tasks FINISHED: All finished tasks SUCCESSFUL: All successful tasks
- UNSUCCESSFUL: All unsuccessful tasks
+ Attributes: STARTED: Task has been started and is currently running. PAUSED:
+ Task execution has been temporarily paused (can be resumed) FINISHED: Task has
+ finished and the agent has completed the task. STOPPED: Task execution has been
+ manually stopped (cannot be resumed).
extra_headers: Send extra headers
@@ -337,6 +334,8 @@ def list(
timeout=timeout,
query=maybe_transform(
{
+ "after": after,
+ "before": before,
"filter_by": filter_by,
"page_number": page_number,
"page_size": page_size,
@@ -778,8 +777,9 @@ async def update(
async def list(
self,
*,
- filter_by: Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]]
- | NotGiven = NOT_GIVEN,
+ after: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
+ before: Union[str, datetime, None] | NotGiven = NOT_GIVEN,
+ filter_by: Optional[TaskStatus] | NotGiven = NOT_GIVEN,
page_number: int | NotGiven = NOT_GIVEN,
page_size: int | NotGiven = NOT_GIVEN,
session_id: Optional[str] | NotGiven = NOT_GIVEN,
@@ -791,32 +791,26 @@ async def list(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> TaskListResponse:
"""
- Get a paginated list of all AI agent tasks for the authenticated user.
+ Get a paginated list of all Browser Use Agent tasks for the authenticated user.
- AI agent tasks are the individual jobs that your agents perform within a
- session. Each task represents a specific instruction or goal that the agent
+ Browser Use Agent tasks are the individual jobs that your agents perform within
+ a session. Each task represents a specific instruction or goal that the agent
works on, such as filling out a form, extracting data, or navigating to specific
pages.
- You can control what data is included for each task:
-
- - Task steps: Detailed actions the agent took
- - User uploaded files: Files you provided for the task
- - Output files: Files generated by the agent during the task
-
Returns:
- - A paginated list of agent tasks
- - Total count of tasks
+ - A paginated list of Browser Use Agent tasks
+ - Total count of Browser Use Agent tasks
- Page information for navigation
- - Optional detailed data based on your parameters
Args:
- filter_by: Enumeration of possible task filters
+ filter_by: Enumeration of possible task execution states
- Attributes: STARTED: All started tasks PAUSED: All paused tasks STOPPED: All
- stopped tasks FINISHED: All finished tasks SUCCESSFUL: All successful tasks
- UNSUCCESSFUL: All unsuccessful tasks
+ Attributes: STARTED: Task has been started and is currently running. PAUSED:
+ Task execution has been temporarily paused (can be resumed) FINISHED: Task has
+ finished and the agent has completed the task. STOPPED: Task execution has been
+ manually stopped (cannot be resumed).
extra_headers: Send extra headers
@@ -835,6 +829,8 @@ async def list(
timeout=timeout,
query=await async_maybe_transform(
{
+ "after": after,
+ "before": before,
"filter_by": filter_by,
"page_number": page_number,
"page_size": page_size,
diff --git a/src/browser_use_sdk/types/task_item_view.py b/src/browser_use_sdk/types/task_item_view.py
index b0028da..ff7c731 100644
--- a/src/browser_use_sdk/types/task_item_view.py
+++ b/src/browser_use_sdk/types/task_item_view.py
@@ -26,9 +26,10 @@ class TaskItemView(BaseModel):
status: TaskStatus
"""Enumeration of possible task execution states
- Attributes: STARTED: Task has been started and is currently running PAUSED: Task
- execution has been temporarily paused (can be resumed) STOPPED: Task execution
- has been stopped (cannot be resumed) FINISHED: Task has completed successfully
+ Attributes: STARTED: Task has been started and is currently running. PAUSED:
+ Task execution has been temporarily paused (can be resumed) FINISHED: Task has
+ finished and the agent has completed the task. STOPPED: Task execution has been
+ manually stopped (cannot be resumed).
"""
task: str
diff --git a/src/browser_use_sdk/types/task_list_params.py b/src/browser_use_sdk/types/task_list_params.py
index 6a4a3ac..0d83aaa 100644
--- a/src/browser_use_sdk/types/task_list_params.py
+++ b/src/browser_use_sdk/types/task_list_params.py
@@ -2,24 +2,28 @@
from __future__ import annotations
-from typing import Optional
-from typing_extensions import Literal, Annotated, TypedDict
+from typing import Union, Optional
+from datetime import datetime
+from typing_extensions import Annotated, TypedDict
from .._utils import PropertyInfo
+from .task_status import TaskStatus
__all__ = ["TaskListParams"]
class TaskListParams(TypedDict, total=False):
- filter_by: Annotated[
- Optional[Literal["started", "paused", "stopped", "finished", "successful", "unsuccessful"]],
- PropertyInfo(alias="filterBy"),
- ]
- """Enumeration of possible task filters
-
- Attributes: STARTED: All started tasks PAUSED: All paused tasks STOPPED: All
- stopped tasks FINISHED: All finished tasks SUCCESSFUL: All successful tasks
- UNSUCCESSFUL: All unsuccessful tasks
+ after: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
+
+ before: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
+
+ filter_by: Annotated[Optional[TaskStatus], PropertyInfo(alias="filterBy")]
+ """Enumeration of possible task execution states
+
+ Attributes: STARTED: Task has been started and is currently running. PAUSED:
+ Task execution has been temporarily paused (can be resumed) FINISHED: Task has
+ finished and the agent has completed the task. STOPPED: Task execution has been
+ manually stopped (cannot be resumed).
"""
page_number: Annotated[int, PropertyInfo(alias="pageNumber")]
diff --git a/src/browser_use_sdk/types/task_status.py b/src/browser_use_sdk/types/task_status.py
index e0bc452..0eabe70 100644
--- a/src/browser_use_sdk/types/task_status.py
+++ b/src/browser_use_sdk/types/task_status.py
@@ -4,4 +4,4 @@
__all__ = ["TaskStatus"]
-TaskStatus: TypeAlias = Literal["started", "paused", "stopped", "finished"]
+TaskStatus: TypeAlias = Literal["started", "paused", "finished", "stopped"]
diff --git a/src/browser_use_sdk/types/task_view.py b/src/browser_use_sdk/types/task_view.py
index ed102f1..2bc4812 100644
--- a/src/browser_use_sdk/types/task_view.py
+++ b/src/browser_use_sdk/types/task_view.py
@@ -57,9 +57,10 @@ class TaskView(BaseModel):
status: TaskStatus
"""Enumeration of possible task execution states
- Attributes: STARTED: Task has been started and is currently running PAUSED: Task
- execution has been temporarily paused (can be resumed) STOPPED: Task execution
- has been stopped (cannot be resumed) FINISHED: Task has completed successfully
+ Attributes: STARTED: Task has been started and is currently running. PAUSED:
+ Task execution has been temporarily paused (can be resumed) FINISHED: Task has
+ finished and the agent has completed the task. STOPPED: Task execution has been
+ manually stopped (cannot be resumed).
"""
steps: List[TaskStepView]
diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py
index fe4ba58..d03ca35 100644
--- a/tests/api_resources/test_tasks.py
+++ b/tests/api_resources/test_tasks.py
@@ -17,6 +17,7 @@
TaskGetOutputFileResponse,
TaskGetUserUploadedFileResponse,
)
+from browser_use_sdk._utils import parse_datetime
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -177,6 +178,8 @@ def test_method_list(self, client: BrowserUse) -> None:
@parametrize
def test_method_list_with_all_params(self, client: BrowserUse) -> None:
task = client.tasks.list(
+ after=parse_datetime("2019-12-27T18:11:19.117Z"),
+ before=parse_datetime("2019-12-27T18:11:19.117Z"),
filter_by="started",
page_number=1,
page_size=1,
@@ -511,6 +514,8 @@ async def test_method_list(self, async_client: AsyncBrowserUse) -> None:
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncBrowserUse) -> None:
task = await async_client.tasks.list(
+ after=parse_datetime("2019-12-27T18:11:19.117Z"),
+ before=parse_datetime("2019-12-27T18:11:19.117Z"),
filter_by="started",
page_number=1,
page_size=1,
From e7f679479dc652f2cdf1cc6e50e9c2e2e08c74cb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:33:05 +0000
Subject: [PATCH 10/10] release: 0.1.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 19 +++++++++++++++++++
pyproject.toml | 2 +-
src/browser_use_sdk/_version.py | 2 +-
4 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index c7159c1..3d2ac0b 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.0.2"
+ ".": "0.1.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2cd7d38..91a872a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
# Changelog
+## 0.1.0 (2025-08-18)
+
+Full Changelog: [v0.0.2...v0.1.0](https://github.com/browser-use/browser-use-python/compare/v0.0.2...v0.1.0)
+
+### Features
+
+* Add start_url ([2ede0a9](https://github.com/browser-use/browser-use-python/commit/2ede0a9089bfbba1eca207508a52ee36b4ef18ac))
+* Align Task Filtering by Status with `status` Field ([29b4590](https://github.com/browser-use/browser-use-python/commit/29b4590c69f13fbf7f855888862ef77a9e704172))
+* **api:** api update ([5867532](https://github.com/browser-use/browser-use-python/commit/58675327b6a0e7ba41f312e4887062a9b6dc2852))
+* **api:** manual updates ([78727c0](https://github.com/browser-use/browser-use-python/commit/78727c02cefa53fd0dd877e137b7b6f92e14fce8))
+* **api:** update via SDK Studio ([b283386](https://github.com/browser-use/browser-use-python/commit/b283386b805435a87114e807f8919185cb6a5b7b))
+* Fix Stainless GitHub Action ([5dcf360](https://github.com/browser-use/browser-use-python/commit/5dcf360ccfe40f45962ecaa64b8a5aacf55778d4))
+* Update param and response views ([44b4c5d](https://github.com/browser-use/browser-use-python/commit/44b4c5d7ed416f9f5c37afb3287cdaa6f22a30cd))
+
+
+### Chores
+
+* **internal:** codegen related update ([151d56b](https://github.com/browser-use/browser-use-python/commit/151d56ba67c2d09970ff415472c0a1d259716bbc))
+
## 0.0.2 (2025-08-09)
Full Changelog: [v0.0.1...v0.0.2](https://github.com/browser-use/browser-use-python/compare/v0.0.1...v0.0.2)
diff --git a/pyproject.toml b/pyproject.toml
index c1a1a97..d50d931 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "browser-use-sdk"
-version = "0.0.2"
+version = "0.1.0"
description = "The official Python library for the browser-use API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/browser_use_sdk/_version.py b/src/browser_use_sdk/_version.py
index 695f607..86ea4c5 100644
--- a/src/browser_use_sdk/_version.py
+++ b/src/browser_use_sdk/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "browser_use_sdk"
-__version__ = "0.0.2" # x-release-please-version
+__version__ = "0.1.0" # x-release-please-version