From b19e21bf4d411face9fd8f252f35bac1981370ef Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 6 Mar 2026 21:44:29 +0000
Subject: [PATCH 1/5] chore(test): do not count install time for mock server
timeout
---
scripts/mock | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/scripts/mock b/scripts/mock
index 0b28f6ea..bcf3b392 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -21,11 +21,22 @@ echo "==> Starting mock server with URL ${URL}"
# Run prism mock on the given spec
if [ "$1" == "--daemon" ]; then
+ # Pre-install the package so the download doesn't eat into the startup timeout
+ npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism --version
+
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
- # Wait for server to come online
+ # Wait for server to come online (max 30s)
echo -n "Waiting for server"
+ attempts=0
while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do
+ attempts=$((attempts + 1))
+ if [ "$attempts" -ge 300 ]; then
+ echo
+ echo "Timed out waiting for Prism server to start"
+ cat .prism.log
+ exit 1
+ fi
echo -n "."
sleep 0.1
done
From 99d0409a98d14dc19359b80a966c30e2aa5d99f0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 7 Mar 2026 21:25:41 +0000
Subject: [PATCH 2/5] chore(ci): skip uploading artifacts on stainless-internal
branches
---
.github/workflows/ci.yml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c77d6d73..0925562d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -61,14 +61,18 @@ jobs:
run: rye build
- name: Get GitHub OIDC Token
- if: github.repository == 'stainless-sdks/browserbase-python'
+ if: |-
+ github.repository == 'stainless-sdks/browserbase-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());
- name: Upload tarball
- if: github.repository == 'stainless-sdks/browserbase-python'
+ if: |-
+ github.repository == 'stainless-sdks/browserbase-python' &&
+ !startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
From 8ff9f32b3d608ea9a2a4e6bd9120c029bd05f6d4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 7 Mar 2026 21:29:18 +0000
Subject: [PATCH 3/5] chore: update placeholder string
---
tests/api_resources/sessions/test_uploads.py | 16 ++++++++--------
tests/api_resources/test_extensions.py | 12 ++++++------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/tests/api_resources/sessions/test_uploads.py b/tests/api_resources/sessions/test_uploads.py
index 748b92e7..b98dc0a5 100644
--- a/tests/api_resources/sessions/test_uploads.py
+++ b/tests/api_resources/sessions/test_uploads.py
@@ -21,7 +21,7 @@ class TestUploads:
def test_method_create(self, client: Browserbase) -> None:
upload = client.sessions.uploads.create(
id="id",
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(UploadCreateResponse, upload, path=["response"])
@@ -29,7 +29,7 @@ def test_method_create(self, client: Browserbase) -> None:
def test_raw_response_create(self, client: Browserbase) -> None:
response = client.sessions.uploads.with_raw_response.create(
id="id",
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -41,7 +41,7 @@ def test_raw_response_create(self, client: Browserbase) -> None:
def test_streaming_response_create(self, client: Browserbase) -> None:
with client.sessions.uploads.with_streaming_response.create(
id="id",
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -56,7 +56,7 @@ def test_path_params_create(self, client: Browserbase) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.sessions.uploads.with_raw_response.create(
id="",
- file=b"raw file contents",
+ file=b"Example data",
)
@@ -69,7 +69,7 @@ class TestAsyncUploads:
async def test_method_create(self, async_client: AsyncBrowserbase) -> None:
upload = await async_client.sessions.uploads.create(
id="id",
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(UploadCreateResponse, upload, path=["response"])
@@ -77,7 +77,7 @@ async def test_method_create(self, async_client: AsyncBrowserbase) -> None:
async def test_raw_response_create(self, async_client: AsyncBrowserbase) -> None:
response = await async_client.sessions.uploads.with_raw_response.create(
id="id",
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -89,7 +89,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserbase) -> None
async def test_streaming_response_create(self, async_client: AsyncBrowserbase) -> None:
async with async_client.sessions.uploads.with_streaming_response.create(
id="id",
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -104,5 +104,5 @@ async def test_path_params_create(self, async_client: AsyncBrowserbase) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.sessions.uploads.with_raw_response.create(
id="",
- file=b"raw file contents",
+ file=b"Example data",
)
diff --git a/tests/api_resources/test_extensions.py b/tests/api_resources/test_extensions.py
index 6b6a0183..b6b6260b 100644
--- a/tests/api_resources/test_extensions.py
+++ b/tests/api_resources/test_extensions.py
@@ -20,14 +20,14 @@ class TestExtensions:
@parametrize
def test_method_create(self, client: Browserbase) -> None:
extension = client.extensions.create(
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(Extension, extension, path=["response"])
@parametrize
def test_raw_response_create(self, client: Browserbase) -> None:
response = client.extensions.with_raw_response.create(
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -38,7 +38,7 @@ def test_raw_response_create(self, client: Browserbase) -> None:
@parametrize
def test_streaming_response_create(self, client: Browserbase) -> None:
with client.extensions.with_streaming_response.create(
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -133,14 +133,14 @@ class TestAsyncExtensions:
@parametrize
async def test_method_create(self, async_client: AsyncBrowserbase) -> None:
extension = await async_client.extensions.create(
- file=b"raw file contents",
+ file=b"Example data",
)
assert_matches_type(Extension, extension, path=["response"])
@parametrize
async def test_raw_response_create(self, async_client: AsyncBrowserbase) -> None:
response = await async_client.extensions.with_raw_response.create(
- file=b"raw file contents",
+ file=b"Example data",
)
assert response.is_closed is True
@@ -151,7 +151,7 @@ async def test_raw_response_create(self, async_client: AsyncBrowserbase) -> None
@parametrize
async def test_streaming_response_create(self, async_client: AsyncBrowserbase) -> None:
async with async_client.extensions.with_streaming_response.create(
- file=b"raw file contents",
+ file=b"Example data",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
From a56673cf002d95b97d855befa64d46bd55559323 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 11 Mar 2026 19:13:39 +0000
Subject: [PATCH 4/5] feat: [CORE-1804][apps/api] Add fetch API schema
---
.stats.yml | 8 +-
api.md | 12 ++
src/browserbase/_client.py | 39 +++-
src/browserbase/resources/__init__.py | 14 ++
src/browserbase/resources/fetch_api.py | 201 ++++++++++++++++++
src/browserbase/types/__init__.py | 2 +
.../types/fetch_api_create_params.py | 23 ++
.../types/fetch_api_create_response.py | 31 +++
tests/api_resources/test_fetch_api.py | 106 +++++++++
9 files changed, 431 insertions(+), 5 deletions(-)
create mode 100644 src/browserbase/resources/fetch_api.py
create mode 100644 src/browserbase/types/fetch_api_create_params.py
create mode 100644 src/browserbase/types/fetch_api_create_response.py
create mode 100644 tests/api_resources/test_fetch_api.py
diff --git a/.stats.yml b/.stats.yml
index 05de0332..3aabff9c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 19
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fbrowserbase-215bc4361122162181eecce83c0dbdda7c45a21801e7addb75102e8011413069.yml
-openapi_spec_hash: c4fadc5bb6b84cd3988c8d864b67bf61
-config_hash: a106b247c7cdf02ac1033077402cfe2d
+configured_endpoints: 20
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fbrowserbase-b20f9fea14d79990ab1af3d276f931e026cd955ac623ec6ace80b2af90de170f.yml
+openapi_spec_hash: 943ff4b3297014503fdc9854544cb9a4
+config_hash: 55c54fdafc9e80be584829b5724b00ab
diff --git a/api.md b/api.md
index d2d26e57..ac45583b 100644
--- a/api.md
+++ b/api.md
@@ -27,6 +27,18 @@ Methods:
- client.extensions.retrieve(id) -> Extension
- client.extensions.delete(id) -> None
+# FetchAPI
+
+Types:
+
+```python
+from browserbase.types import FetchAPICreateResponse
+```
+
+Methods:
+
+- client.fetch_api.create(\*\*params) -> FetchAPICreateResponse
+
# Projects
Types:
diff --git a/src/browserbase/_client.py b/src/browserbase/_client.py
index 5bb997a7..70a7b71d 100644
--- a/src/browserbase/_client.py
+++ b/src/browserbase/_client.py
@@ -31,9 +31,10 @@
)
if TYPE_CHECKING:
- from .resources import contexts, projects, sessions, extensions
+ from .resources import contexts, projects, sessions, fetch_api, extensions
from .resources.contexts import ContextsResource, AsyncContextsResource
from .resources.projects import ProjectsResource, AsyncProjectsResource
+ from .resources.fetch_api import FetchAPIResource, AsyncFetchAPIResource
from .resources.extensions import ExtensionsResource, AsyncExtensionsResource
from .resources.sessions.sessions import SessionsResource, AsyncSessionsResource
@@ -116,6 +117,12 @@ def extensions(self) -> ExtensionsResource:
return ExtensionsResource(self)
+ @cached_property
+ def fetch_api(self) -> FetchAPIResource:
+ from .resources.fetch_api import FetchAPIResource
+
+ return FetchAPIResource(self)
+
@cached_property
def projects(self) -> ProjectsResource:
from .resources.projects import ProjectsResource
@@ -308,6 +315,12 @@ def extensions(self) -> AsyncExtensionsResource:
return AsyncExtensionsResource(self)
+ @cached_property
+ def fetch_api(self) -> AsyncFetchAPIResource:
+ from .resources.fetch_api import AsyncFetchAPIResource
+
+ return AsyncFetchAPIResource(self)
+
@cached_property
def projects(self) -> AsyncProjectsResource:
from .resources.projects import AsyncProjectsResource
@@ -451,6 +464,12 @@ def extensions(self) -> extensions.ExtensionsResourceWithRawResponse:
return ExtensionsResourceWithRawResponse(self._client.extensions)
+ @cached_property
+ def fetch_api(self) -> fetch_api.FetchAPIResourceWithRawResponse:
+ from .resources.fetch_api import FetchAPIResourceWithRawResponse
+
+ return FetchAPIResourceWithRawResponse(self._client.fetch_api)
+
@cached_property
def projects(self) -> projects.ProjectsResourceWithRawResponse:
from .resources.projects import ProjectsResourceWithRawResponse
@@ -482,6 +501,12 @@ def extensions(self) -> extensions.AsyncExtensionsResourceWithRawResponse:
return AsyncExtensionsResourceWithRawResponse(self._client.extensions)
+ @cached_property
+ def fetch_api(self) -> fetch_api.AsyncFetchAPIResourceWithRawResponse:
+ from .resources.fetch_api import AsyncFetchAPIResourceWithRawResponse
+
+ return AsyncFetchAPIResourceWithRawResponse(self._client.fetch_api)
+
@cached_property
def projects(self) -> projects.AsyncProjectsResourceWithRawResponse:
from .resources.projects import AsyncProjectsResourceWithRawResponse
@@ -513,6 +538,12 @@ def extensions(self) -> extensions.ExtensionsResourceWithStreamingResponse:
return ExtensionsResourceWithStreamingResponse(self._client.extensions)
+ @cached_property
+ def fetch_api(self) -> fetch_api.FetchAPIResourceWithStreamingResponse:
+ from .resources.fetch_api import FetchAPIResourceWithStreamingResponse
+
+ return FetchAPIResourceWithStreamingResponse(self._client.fetch_api)
+
@cached_property
def projects(self) -> projects.ProjectsResourceWithStreamingResponse:
from .resources.projects import ProjectsResourceWithStreamingResponse
@@ -544,6 +575,12 @@ def extensions(self) -> extensions.AsyncExtensionsResourceWithStreamingResponse:
return AsyncExtensionsResourceWithStreamingResponse(self._client.extensions)
+ @cached_property
+ def fetch_api(self) -> fetch_api.AsyncFetchAPIResourceWithStreamingResponse:
+ from .resources.fetch_api import AsyncFetchAPIResourceWithStreamingResponse
+
+ return AsyncFetchAPIResourceWithStreamingResponse(self._client.fetch_api)
+
@cached_property
def projects(self) -> projects.AsyncProjectsResourceWithStreamingResponse:
from .resources.projects import AsyncProjectsResourceWithStreamingResponse
diff --git a/src/browserbase/resources/__init__.py b/src/browserbase/resources/__init__.py
index 73451a50..f5a2bf0c 100644
--- a/src/browserbase/resources/__init__.py
+++ b/src/browserbase/resources/__init__.py
@@ -24,6 +24,14 @@
SessionsResourceWithStreamingResponse,
AsyncSessionsResourceWithStreamingResponse,
)
+from .fetch_api import (
+ FetchAPIResource,
+ AsyncFetchAPIResource,
+ FetchAPIResourceWithRawResponse,
+ AsyncFetchAPIResourceWithRawResponse,
+ FetchAPIResourceWithStreamingResponse,
+ AsyncFetchAPIResourceWithStreamingResponse,
+)
from .extensions import (
ExtensionsResource,
AsyncExtensionsResource,
@@ -46,6 +54,12 @@
"AsyncExtensionsResourceWithRawResponse",
"ExtensionsResourceWithStreamingResponse",
"AsyncExtensionsResourceWithStreamingResponse",
+ "FetchAPIResource",
+ "AsyncFetchAPIResource",
+ "FetchAPIResourceWithRawResponse",
+ "AsyncFetchAPIResourceWithRawResponse",
+ "FetchAPIResourceWithStreamingResponse",
+ "AsyncFetchAPIResourceWithStreamingResponse",
"ProjectsResource",
"AsyncProjectsResource",
"ProjectsResourceWithRawResponse",
diff --git a/src/browserbase/resources/fetch_api.py b/src/browserbase/resources/fetch_api.py
new file mode 100644
index 00000000..dc016722
--- /dev/null
+++ b/src/browserbase/resources/fetch_api.py
@@ -0,0 +1,201 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..types import fetch_api_create_params
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+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.fetch_api_create_response import FetchAPICreateResponse
+
+__all__ = ["FetchAPIResource", "AsyncFetchAPIResource"]
+
+
+class FetchAPIResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> FetchAPIResourceWithRawResponse:
+ """
+ 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/browserbase/sdk-python#accessing-raw-response-data-eg-headers
+ """
+ return FetchAPIResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> FetchAPIResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browserbase/sdk-python#with_streaming_response
+ """
+ return FetchAPIResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ url: str,
+ allow_insecure_ssl: bool | Omit = omit,
+ allow_redirects: bool | Omit = omit,
+ proxies: bool | Omit = omit,
+ # 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,
+ ) -> FetchAPICreateResponse:
+ """
+ Fetch a page and return its content, headers, and metadata.
+
+ Args:
+ url: The URL to fetch
+
+ allow_insecure_ssl: Whether to bypass TLS certificate verification
+
+ allow_redirects: Whether to follow HTTP redirects
+
+ proxies: Whether to enable proxy support for the request
+
+ 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(
+ "/v1/fetch",
+ body=maybe_transform(
+ {
+ "url": url,
+ "allow_insecure_ssl": allow_insecure_ssl,
+ "allow_redirects": allow_redirects,
+ "proxies": proxies,
+ },
+ fetch_api_create_params.FetchAPICreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=FetchAPICreateResponse,
+ )
+
+
+class AsyncFetchAPIResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncFetchAPIResourceWithRawResponse:
+ """
+ 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/browserbase/sdk-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncFetchAPIResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncFetchAPIResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/browserbase/sdk-python#with_streaming_response
+ """
+ return AsyncFetchAPIResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ url: str,
+ allow_insecure_ssl: bool | Omit = omit,
+ allow_redirects: bool | Omit = omit,
+ proxies: bool | Omit = omit,
+ # 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,
+ ) -> FetchAPICreateResponse:
+ """
+ Fetch a page and return its content, headers, and metadata.
+
+ Args:
+ url: The URL to fetch
+
+ allow_insecure_ssl: Whether to bypass TLS certificate verification
+
+ allow_redirects: Whether to follow HTTP redirects
+
+ proxies: Whether to enable proxy support for the request
+
+ 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(
+ "/v1/fetch",
+ body=await async_maybe_transform(
+ {
+ "url": url,
+ "allow_insecure_ssl": allow_insecure_ssl,
+ "allow_redirects": allow_redirects,
+ "proxies": proxies,
+ },
+ fetch_api_create_params.FetchAPICreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=FetchAPICreateResponse,
+ )
+
+
+class FetchAPIResourceWithRawResponse:
+ def __init__(self, fetch_api: FetchAPIResource) -> None:
+ self._fetch_api = fetch_api
+
+ self.create = to_raw_response_wrapper(
+ fetch_api.create,
+ )
+
+
+class AsyncFetchAPIResourceWithRawResponse:
+ def __init__(self, fetch_api: AsyncFetchAPIResource) -> None:
+ self._fetch_api = fetch_api
+
+ self.create = async_to_raw_response_wrapper(
+ fetch_api.create,
+ )
+
+
+class FetchAPIResourceWithStreamingResponse:
+ def __init__(self, fetch_api: FetchAPIResource) -> None:
+ self._fetch_api = fetch_api
+
+ self.create = to_streamed_response_wrapper(
+ fetch_api.create,
+ )
+
+
+class AsyncFetchAPIResourceWithStreamingResponse:
+ def __init__(self, fetch_api: AsyncFetchAPIResource) -> None:
+ self._fetch_api = fetch_api
+
+ self.create = async_to_streamed_response_wrapper(
+ fetch_api.create,
+ )
diff --git a/src/browserbase/types/__init__.py b/src/browserbase/types/__init__.py
index 4dd85ddb..52659907 100644
--- a/src/browserbase/types/__init__.py
+++ b/src/browserbase/types/__init__.py
@@ -17,5 +17,7 @@
from .context_create_response import ContextCreateResponse as ContextCreateResponse
from .context_update_response import ContextUpdateResponse as ContextUpdateResponse
from .extension_create_params import ExtensionCreateParams as ExtensionCreateParams
+from .fetch_api_create_params import FetchAPICreateParams as FetchAPICreateParams
from .session_create_response import SessionCreateResponse as SessionCreateResponse
+from .fetch_api_create_response import FetchAPICreateResponse as FetchAPICreateResponse
from .session_retrieve_response import SessionRetrieveResponse as SessionRetrieveResponse
diff --git a/src/browserbase/types/fetch_api_create_params.py b/src/browserbase/types/fetch_api_create_params.py
new file mode 100644
index 00000000..84a8a052
--- /dev/null
+++ b/src/browserbase/types/fetch_api_create_params.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["FetchAPICreateParams"]
+
+
+class FetchAPICreateParams(TypedDict, total=False):
+ url: Required[str]
+ """The URL to fetch"""
+
+ allow_insecure_ssl: Annotated[bool, PropertyInfo(alias="allowInsecureSsl")]
+ """Whether to bypass TLS certificate verification"""
+
+ allow_redirects: Annotated[bool, PropertyInfo(alias="allowRedirects")]
+ """Whether to follow HTTP redirects"""
+
+ proxies: bool
+ """Whether to enable proxy support for the request"""
diff --git a/src/browserbase/types/fetch_api_create_response.py b/src/browserbase/types/fetch_api_create_response.py
new file mode 100644
index 00000000..cfafbba3
--- /dev/null
+++ b/src/browserbase/types/fetch_api_create_response.py
@@ -0,0 +1,31 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["FetchAPICreateResponse"]
+
+
+class FetchAPICreateResponse(BaseModel):
+ """Response body for fetch"""
+
+ id: str
+ """Unique identifier for the fetch request"""
+
+ content: str
+ """The response body content"""
+
+ content_type: str = FieldInfo(alias="contentType")
+ """The MIME type of the response"""
+
+ encoding: str
+ """The character encoding of the response"""
+
+ headers: Dict[str, str]
+ """Response headers as key-value pairs"""
+
+ status_code: int = FieldInfo(alias="statusCode")
+ """HTTP status code of the fetched response"""
diff --git a/tests/api_resources/test_fetch_api.py b/tests/api_resources/test_fetch_api.py
new file mode 100644
index 00000000..b9a0455b
--- /dev/null
+++ b/tests/api_resources/test_fetch_api.py
@@ -0,0 +1,106 @@
+# 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 browserbase import Browserbase, AsyncBrowserbase
+from tests.utils import assert_matches_type
+from browserbase.types import FetchAPICreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestFetchAPI:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Browserbase) -> None:
+ fetch_api = client.fetch_api.create(
+ url="https://example.com",
+ )
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Browserbase) -> None:
+ fetch_api = client.fetch_api.create(
+ url="https://example.com",
+ allow_insecure_ssl=True,
+ allow_redirects=True,
+ proxies=True,
+ )
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Browserbase) -> None:
+ response = client.fetch_api.with_raw_response.create(
+ url="https://example.com",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ fetch_api = response.parse()
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Browserbase) -> None:
+ with client.fetch_api.with_streaming_response.create(
+ url="https://example.com",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ fetch_api = response.parse()
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncFetchAPI:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncBrowserbase) -> None:
+ fetch_api = await async_client.fetch_api.create(
+ url="https://example.com",
+ )
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncBrowserbase) -> None:
+ fetch_api = await async_client.fetch_api.create(
+ url="https://example.com",
+ allow_insecure_ssl=True,
+ allow_redirects=True,
+ proxies=True,
+ )
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncBrowserbase) -> None:
+ response = await async_client.fetch_api.with_raw_response.create(
+ url="https://example.com",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ fetch_api = await response.parse()
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncBrowserbase) -> None:
+ async with async_client.fetch_api.with_streaming_response.create(
+ url="https://example.com",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ fetch_api = await response.parse()
+ assert_matches_type(FetchAPICreateResponse, fetch_api, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
From 3db94f03b79b8d74e29041dd17a3d7b1cf446d27 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 11 Mar 2026 19:14:28 +0000
Subject: [PATCH 5/5] release: 1.6.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++
pyproject.toml | 2 +-
src/browserbase/_version.py | 2 +-
4 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index fbd9082d..7deae338 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.5.0"
+ ".": "1.6.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f38a54f2..a482d7b4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,38 @@
# Changelog
+## 1.6.0 (2026-03-11)
+
+Full Changelog: [v1.5.0...v1.6.0](https://github.com/browserbase/sdk-python/compare/v1.5.0...v1.6.0)
+
+### Features
+
+* [CORE-1804][apps/api] Add fetch API schema ([a56673c](https://github.com/browserbase/sdk-python/commit/a56673cf002d95b97d855befa64d46bd55559323))
+* **api:** api update ([#39](https://github.com/browserbase/sdk-python/issues/39)) ([8c98d9e](https://github.com/browserbase/sdk-python/commit/8c98d9e9da61daba527262aa1b0a1334da22a596))
+* **api:** api update ([#41](https://github.com/browserbase/sdk-python/issues/41)) ([0557ee5](https://github.com/browserbase/sdk-python/commit/0557ee507fc35faa9aabd8d06ce8047bb07843aa))
+* **api:** api update ([#44](https://github.com/browserbase/sdk-python/issues/44)) ([718ef11](https://github.com/browserbase/sdk-python/commit/718ef11db8e865347c24b2205b22f906bccb24e7))
+* **api:** update via SDK Studio ([#10](https://github.com/browserbase/sdk-python/issues/10)) ([712cb9f](https://github.com/browserbase/sdk-python/commit/712cb9f5d36d3f882e36848413fb96f32558b67c))
+* **api:** update via SDK Studio ([#13](https://github.com/browserbase/sdk-python/issues/13)) ([ec90079](https://github.com/browserbase/sdk-python/commit/ec900790bd56f92b174304bb227461a65209cbdb))
+* **api:** update via SDK Studio ([#16](https://github.com/browserbase/sdk-python/issues/16)) ([3739129](https://github.com/browserbase/sdk-python/commit/37391297ef3c3d59105c618ba9026ecae551a77b))
+* **api:** update via SDK Studio ([#18](https://github.com/browserbase/sdk-python/issues/18)) ([c8ff679](https://github.com/browserbase/sdk-python/commit/c8ff67974dbcf8a99dae87aea6e9b18046bf5acd))
+* **api:** update via SDK Studio ([#19](https://github.com/browserbase/sdk-python/issues/19)) ([1556b70](https://github.com/browserbase/sdk-python/commit/1556b7064ad2ec507d74536a1d074e5f464c3d12))
+* **api:** update via SDK Studio ([#20](https://github.com/browserbase/sdk-python/issues/20)) ([8876008](https://github.com/browserbase/sdk-python/commit/887600814fca35fbaf4cb4ddd2a0112a51a3f068))
+* **api:** update via SDK Studio ([#21](https://github.com/browserbase/sdk-python/issues/21)) ([8f22de1](https://github.com/browserbase/sdk-python/commit/8f22de1da97f9157ef52647f20895cabe5ecfd26))
+* **api:** update via SDK Studio ([#27](https://github.com/browserbase/sdk-python/issues/27)) ([b1facb8](https://github.com/browserbase/sdk-python/commit/b1facb8db6d821a2d3c5465dbeb474e0140ed90e))
+* **api:** update via SDK Studio ([#28](https://github.com/browserbase/sdk-python/issues/28)) ([0735db2](https://github.com/browserbase/sdk-python/commit/0735db24fb833dbeb5d09f30b8fd18e67d7a2e5d))
+* **api:** update via SDK Studio ([#29](https://github.com/browserbase/sdk-python/issues/29)) ([c1e0eb9](https://github.com/browserbase/sdk-python/commit/c1e0eb9d84a8b83b30fce673a4c5e6262ce732b2))
+* **api:** update via SDK Studio ([#32](https://github.com/browserbase/sdk-python/issues/32)) ([54a7ed4](https://github.com/browserbase/sdk-python/commit/54a7ed479088a68434961cd92ae225064bf8e8a1))
+* **api:** update via SDK Studio ([#35](https://github.com/browserbase/sdk-python/issues/35)) ([cdc05f9](https://github.com/browserbase/sdk-python/commit/cdc05f947c676bd56bed22e77fcfd48c313f3596))
+* **api:** update via SDK Studio ([#7](https://github.com/browserbase/sdk-python/issues/7)) ([90f80c7](https://github.com/browserbase/sdk-python/commit/90f80c7d8a44b155cac6dc9ed73ac55dbbb9596d))
+* various codegen changes ([a70c78e](https://github.com/browserbase/sdk-python/commit/a70c78ecf5c0f4763c9222a332c164249c1060bc))
+
+
+### Chores
+
+* **ci:** skip uploading artifacts on stainless-internal branches ([99d0409](https://github.com/browserbase/sdk-python/commit/99d0409a98d14dc19359b80a966c30e2aa5d99f0))
+* **test:** do not count install time for mock server timeout ([b19e21b](https://github.com/browserbase/sdk-python/commit/b19e21bf4d411face9fd8f252f35bac1981370ef))
+* update placeholder string ([8ff9f32](https://github.com/browserbase/sdk-python/commit/8ff9f32b3d608ea9a2a4e6bd9120c029bd05f6d4))
+* update SDK settings ([#1](https://github.com/browserbase/sdk-python/issues/1)) ([dc1e229](https://github.com/browserbase/sdk-python/commit/dc1e229189470b0f3df3c5a2e7da4e789fc76279))
+
## 1.5.0-alpha.2 (2026-03-03)
Full Changelog: [v1.5.0-alpha.1...v1.5.0-alpha.2](https://github.com/browserbase/sdk-python/compare/v1.5.0-alpha.1...v1.5.0-alpha.2)
diff --git a/pyproject.toml b/pyproject.toml
index f0fb3526..425bcc4f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "browserbase"
-version = "1.5.0"
+version = "1.6.0"
description = "The official Python library for the Browserbase API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/browserbase/_version.py b/src/browserbase/_version.py
index a4f65d6f..a7f6a7d4 100644
--- a/src/browserbase/_version.py
+++ b/src/browserbase/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "browserbase"
-__version__ = "1.5.0" # x-release-please-version
+__version__ = "1.6.0" # x-release-please-version