From c94b95672e4a684f5375f1b48f351c0839be1fdc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 22:52:36 +0000 Subject: [PATCH 1/2] feat(api): api update --- .stats.yml | 4 +-- src/brand/dev/resources/brand.py | 24 ++++++++++++++--- .../dev/types/brand_ai_products_params.py | 17 +++++++++--- tests/api_resources/test_brand.py | 26 ++++++------------- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/.stats.yml b/.stats.yml index 69f3e77..ef7f019 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/brand-dev%2Fbrand.dev-737dbedd830e2c989387e90a9bb5baa3915306ecfef2e46b09d02cb1879f043c.yml -openapi_spec_hash: 7bc21f4c6d5fd39c1a3b22626846ca87 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/brand-dev%2Fbrand.dev-73562e26b663cf10185b9e98966accf5f151c6d3cf99b5e060ce5a847045e383.yml +openapi_spec_hash: bf5994966b84f9dda998ad5059ff8318 config_hash: 6f10592c7d0c3bafefc1271472283217 diff --git a/src/brand/dev/resources/brand.py b/src/brand/dev/resources/brand.py index 16e683f..49cadee 100644 --- a/src/brand/dev/resources/brand.py +++ b/src/brand/dev/resources/brand.py @@ -192,7 +192,8 @@ def retrieve( def ai_products( self, *, - domain: str, + direct_url: str | Omit = omit, + domain: str | Omit = omit, max_products: int | Omit = omit, timeout_ms: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -209,7 +210,13 @@ def ai_products( description, image, pricing, features, and more. Args: - domain: The domain name to analyze + direct_url: A specific URL to use directly as the starting point for extraction without + domain resolution. Useful when you want to extract products from a specific page + rather than discovering the site's product pages automatically. Either 'domain' + or 'directUrl' must be provided, but not both. + + domain: The domain name to analyze. Either 'domain' or 'directUrl' must be provided, but + not both. max_products: Maximum number of products to extract. @@ -229,6 +236,7 @@ def ai_products( "/brand/ai/products", body=maybe_transform( { + "direct_url": direct_url, "domain": domain, "max_products": max_products, "timeout_ms": timeout_ms, @@ -1731,7 +1739,8 @@ async def retrieve( async def ai_products( self, *, - domain: str, + direct_url: str | Omit = omit, + domain: str | Omit = omit, max_products: int | Omit = omit, timeout_ms: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1748,7 +1757,13 @@ async def ai_products( description, image, pricing, features, and more. Args: - domain: The domain name to analyze + direct_url: A specific URL to use directly as the starting point for extraction without + domain resolution. Useful when you want to extract products from a specific page + rather than discovering the site's product pages automatically. Either 'domain' + or 'directUrl' must be provided, but not both. + + domain: The domain name to analyze. Either 'domain' or 'directUrl' must be provided, but + not both. max_products: Maximum number of products to extract. @@ -1768,6 +1783,7 @@ async def ai_products( "/brand/ai/products", body=await async_maybe_transform( { + "direct_url": direct_url, "domain": domain, "max_products": max_products, "timeout_ms": timeout_ms, diff --git a/src/brand/dev/types/brand_ai_products_params.py b/src/brand/dev/types/brand_ai_products_params.py index e9ad4ec..783daa9 100644 --- a/src/brand/dev/types/brand_ai_products_params.py +++ b/src/brand/dev/types/brand_ai_products_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, Annotated, TypedDict +from typing_extensions import Annotated, TypedDict from .._utils import PropertyInfo @@ -10,8 +10,19 @@ class BrandAIProductsParams(TypedDict, total=False): - domain: Required[str] - """The domain name to analyze""" + direct_url: Annotated[str, PropertyInfo(alias="directUrl")] + """ + A specific URL to use directly as the starting point for extraction without + domain resolution. Useful when you want to extract products from a specific page + rather than discovering the site's product pages automatically. Either 'domain' + or 'directUrl' must be provided, but not both. + """ + + domain: str + """The domain name to analyze. + + Either 'domain' or 'directUrl' must be provided, but not both. + """ max_products: Annotated[int, PropertyInfo(alias="maxProducts")] """Maximum number of products to extract.""" diff --git a/tests/api_resources/test_brand.py b/tests/api_resources/test_brand.py index 6216d39..b01bbf2 100644 --- a/tests/api_resources/test_brand.py +++ b/tests/api_resources/test_brand.py @@ -81,15 +81,14 @@ def test_streaming_response_retrieve(self, client: BrandDev) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_ai_products(self, client: BrandDev) -> None: - brand = client.brand.ai_products( - domain="domain", - ) + brand = client.brand.ai_products() assert_matches_type(BrandAIProductsResponse, brand, path=["response"]) @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_method_ai_products_with_all_params(self, client: BrandDev) -> None: brand = client.brand.ai_products( + direct_url="https://example.com", domain="domain", max_products=1, timeout_ms=1, @@ -99,9 +98,7 @@ def test_method_ai_products_with_all_params(self, client: BrandDev) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_raw_response_ai_products(self, client: BrandDev) -> None: - response = client.brand.with_raw_response.ai_products( - domain="domain", - ) + response = client.brand.with_raw_response.ai_products() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -111,9 +108,7 @@ def test_raw_response_ai_products(self, client: BrandDev) -> None: @pytest.mark.skip(reason="Prism tests are disabled") @parametrize def test_streaming_response_ai_products(self, client: BrandDev) -> None: - with client.brand.with_streaming_response.ai_products( - domain="domain", - ) as response: + with client.brand.with_streaming_response.ai_products() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -803,15 +798,14 @@ async def test_streaming_response_retrieve(self, async_client: AsyncBrandDev) -> @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_ai_products(self, async_client: AsyncBrandDev) -> None: - brand = await async_client.brand.ai_products( - domain="domain", - ) + brand = await async_client.brand.ai_products() assert_matches_type(BrandAIProductsResponse, brand, path=["response"]) @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_method_ai_products_with_all_params(self, async_client: AsyncBrandDev) -> None: brand = await async_client.brand.ai_products( + direct_url="https://example.com", domain="domain", max_products=1, timeout_ms=1, @@ -821,9 +815,7 @@ async def test_method_ai_products_with_all_params(self, async_client: AsyncBrand @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_raw_response_ai_products(self, async_client: AsyncBrandDev) -> None: - response = await async_client.brand.with_raw_response.ai_products( - domain="domain", - ) + response = await async_client.brand.with_raw_response.ai_products() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -833,9 +825,7 @@ async def test_raw_response_ai_products(self, async_client: AsyncBrandDev) -> No @pytest.mark.skip(reason="Prism tests are disabled") @parametrize async def test_streaming_response_ai_products(self, async_client: AsyncBrandDev) -> None: - async with async_client.brand.with_streaming_response.ai_products( - domain="domain", - ) as response: + async with async_client.brand.with_streaming_response.ai_products() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" From 5d2492a2dfa5a20c6e8ba6aed6486d8dda8fe7a7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 22:52:52 +0000 Subject: [PATCH 2/2] release: 1.30.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/brand/dev/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b8af36c..35c30ad 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.29.0" + ".": "1.30.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index ce25016..50327f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.30.0 (2026-02-07) + +Full Changelog: [v1.29.0...v1.30.0](https://github.com/brand-dot-dev/python-sdk/compare/v1.29.0...v1.30.0) + +### Features + +* **api:** api update ([c94b956](https://github.com/brand-dot-dev/python-sdk/commit/c94b95672e4a684f5375f1b48f351c0839be1fdc)) + ## 1.29.0 (2026-02-02) Full Changelog: [v1.28.0...v1.29.0](https://github.com/brand-dot-dev/python-sdk/compare/v1.28.0...v1.29.0) diff --git a/pyproject.toml b/pyproject.toml index aa8d74d..8a91b63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "brand.dev" -version = "1.29.0" +version = "1.30.0" description = "The official Python library for the brand.dev API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/brand/dev/_version.py b/src/brand/dev/_version.py index aa85e9d..6b37f6b 100644 --- a/src/brand/dev/_version.py +++ b/src/brand/dev/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "brand.dev" -__version__ = "1.29.0" # x-release-please-version +__version__ = "1.30.0" # x-release-please-version