From 4caa2bbcdb3e8d7e7860bed91b37f6693a572c98 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 23:38:39 +0000 Subject: [PATCH 1/7] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3b484e3..2aeac55 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-758c3a2fbd5b7be61c8e6e0ad2e6a5ec30695747bb675960d888c497647d13d7.yml -openapi_spec_hash: 00002d90bde02f67e174368ae470c597 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-85694668707cde32f7d8472660bc5760a2f369751d8cf19690778ffad767b0fa.yml +openapi_spec_hash: 5b688312bf5e9a5468a83618ec635ada config_hash: 2bea1743c84d63bd61f8501a6ea63065 From 96f736add9ae63e43ea632a14c8930e1ab4bd488 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 2 Aug 2026 08:32:24 +0000 Subject: [PATCH 2/7] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2aeac55..490472d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-85694668707cde32f7d8472660bc5760a2f369751d8cf19690778ffad767b0fa.yml -openapi_spec_hash: 5b688312bf5e9a5468a83618ec635ada +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-386f0ec51516e1f060c82287c99be4ecdee9eb4753e1375b6c5b27488e63d4c7.yml +openapi_spec_hash: b514ae48cf1c7bcb2ed3a4d7853cbfb5 config_hash: 2bea1743c84d63bd61f8501a6ea63065 From b079b0d241c10462b1d2f0066166bea53a680d83 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 03:23:38 +0000 Subject: [PATCH 3/7] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 490472d..790f64f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-386f0ec51516e1f060c82287c99be4ecdee9eb4753e1375b6c5b27488e63d4c7.yml -openapi_spec_hash: b514ae48cf1c7bcb2ed3a4d7853cbfb5 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-0c273d87106b3f8920d529d9964d7be6a23613c7553f48d67732e24571fbbf7b.yml +openapi_spec_hash: f1fb4082f153c9195fee451ebf5d46ba config_hash: 2bea1743c84d63bd61f8501a6ea63065 From 011cda7203e8533beb84649a098356592b86ae1f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 08:40:57 +0000 Subject: [PATCH 4/7] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 790f64f..29f15de 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-0c273d87106b3f8920d529d9964d7be6a23613c7553f48d67732e24571fbbf7b.yml -openapi_spec_hash: f1fb4082f153c9195fee451ebf5d46ba +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-f2101addc171cf732a879e4bcad5bc6cfe8cec4349c62617c12c09331a883a22.yml +openapi_spec_hash: a143e7e4842279a61807b433ef17e261 config_hash: 2bea1743c84d63bd61f8501a6ea63065 From bee974345bc47c65e8358d9e3ccd1b9b06e8ba6a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 09:40:37 +0000 Subject: [PATCH 5/7] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 29f15de..8e45986 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-f2101addc171cf732a879e4bcad5bc6cfe8cec4349c62617c12c09331a883a22.yml -openapi_spec_hash: a143e7e4842279a61807b433ef17e261 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-eac90d0a78d6166dc64c49ad4cd44883ab0bd357063ff09e60ed78085e2bde3c.yml +openapi_spec_hash: ab91f77e7c9d992400cbc7fc8a9e76c1 config_hash: 2bea1743c84d63bd61f8501a6ea63065 From d26f4e842387b630ba30fcb291bbcdbad610d28c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 10:12:36 +0000 Subject: [PATCH 6/7] feat(api): manual updates --- .stats.yml | 6 +- api.md | 7 +- src/context/dev/resources/brand.py | 125 +++++++++++++++++- src/context/dev/types/__init__.py | 2 + src/context/dev/types/brand_search_params.py | 24 ++++ .../dev/types/brand_search_response.py | 46 +++++++ tests/api_resources/test_brand.py | 87 ++++++++++++ 7 files changed, 292 insertions(+), 5 deletions(-) create mode 100644 src/context/dev/types/brand_search_params.py create mode 100644 src/context/dev/types/brand_search_response.py diff --git a/.stats.yml b/.stats.yml index 8e45986..74e73bc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-eac90d0a78d6166dc64c49ad4cd44883ab0bd357063ff09e60ed78085e2bde3c.yml +configured_endpoints: 38 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-155e4761d62255841349c0f8a01b0a9c463ea1d1f2d6c4fd8d1a75c8bef6f226.yml openapi_spec_hash: ab91f77e7c9d992400cbc7fc8a9e76c1 -config_hash: 2bea1743c84d63bd61f8501a6ea63065 +config_hash: bff282047fafdad771fb7ec685f56944 diff --git a/api.md b/api.md index 7040315..61a5c97 100644 --- a/api.md +++ b/api.md @@ -62,13 +62,18 @@ Methods: Types: ```python -from context.dev.types import BrandRetrieveResponse, BrandRetrieveSimplifiedResponse +from context.dev.types import ( + BrandRetrieveResponse, + BrandRetrieveSimplifiedResponse, + BrandSearchResponse, +) ``` Methods: - client.brand.retrieve(\*\*params) -> BrandRetrieveResponse - client.brand.retrieve_simplified(\*\*params) -> BrandRetrieveSimplifiedResponse +- client.brand.search(\*\*params) -> BrandSearchResponse # Industry diff --git a/src/context/dev/resources/brand.py b/src/context/dev/resources/brand.py index 65cf230..cf8f895 100644 --- a/src/context/dev/resources/brand.py +++ b/src/context/dev/resources/brand.py @@ -7,7 +7,7 @@ import httpx -from ..types import brand_retrieve_params, brand_retrieve_simplified_params +from ..types import brand_search_params, brand_retrieve_params, brand_retrieve_simplified_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from .._utils import required_args, maybe_transform, async_maybe_transform from .._compat import cached_property @@ -19,6 +19,7 @@ async_to_streamed_response_wrapper, ) from .._base_client import make_request_options +from ..types.brand_search_response import BrandSearchResponse from ..types.brand_retrieve_response import BrandRetrieveResponse from ..types.brand_retrieve_simplified_response import BrandRetrieveSimplifiedResponse @@ -1273,6 +1274,61 @@ def retrieve_simplified( cast_to=BrandRetrieveSimplifiedResponse, ) + def search( + self, + *, + query: str, + tags: SequenceNotStr[str] | 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, + ) -> BrandSearchResponse: + """ + Search brands by name or domain and get back up to 10 lightweight matches + (domain, name, logo), most popular first: by Tranco rank, then market cap for + brands outside the Tranco list, with text relevance breaking ties. Matching is + prefix-based with no typo tolerance, so it is suited to autocomplete. Only + brands already in the Context.dev index are returned — use /brand/retrieve to + fetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit + per request on the Free and Starter plans. + + Args: + query: Search term, matched against brand names and domains by prefix (e.g. 'nike', + 'nike.com', 'nik'). + + tags: Optional comma-separated caller-defined tags for tracking this request. Tags are + recorded on the request's usage log and can be used to filter usage on the + dashboard usage page. Up to 20 tags, each 1-50 characters. + + 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._get( + "/brand/search", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "query": query, + "tags": tags, + }, + brand_search_params.BrandSearchParams, + ), + ), + cast_to=BrandSearchResponse, + ) + class AsyncBrandResource(AsyncAPIResource): @cached_property @@ -2522,6 +2578,61 @@ async def retrieve_simplified( cast_to=BrandRetrieveSimplifiedResponse, ) + async def search( + self, + *, + query: str, + tags: SequenceNotStr[str] | 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, + ) -> BrandSearchResponse: + """ + Search brands by name or domain and get back up to 10 lightweight matches + (domain, name, logo), most popular first: by Tranco rank, then market cap for + brands outside the Tranco list, with text relevance breaking ties. Matching is + prefix-based with no typo tolerance, so it is suited to autocomplete. Only + brands already in the Context.dev index are returned — use /brand/retrieve to + fetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit + per request on the Free and Starter plans. + + Args: + query: Search term, matched against brand names and domains by prefix (e.g. 'nike', + 'nike.com', 'nik'). + + tags: Optional comma-separated caller-defined tags for tracking this request. Tags are + recorded on the request's usage log and can be used to filter usage on the + dashboard usage page. Up to 20 tags, each 1-50 characters. + + 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._get( + "/brand/search", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "query": query, + "tags": tags, + }, + brand_search_params.BrandSearchParams, + ), + ), + cast_to=BrandSearchResponse, + ) + class BrandResourceWithRawResponse: def __init__(self, brand: BrandResource) -> None: @@ -2533,6 +2644,9 @@ def __init__(self, brand: BrandResource) -> None: self.retrieve_simplified = to_raw_response_wrapper( brand.retrieve_simplified, ) + self.search = to_raw_response_wrapper( + brand.search, + ) class AsyncBrandResourceWithRawResponse: @@ -2545,6 +2659,9 @@ def __init__(self, brand: AsyncBrandResource) -> None: self.retrieve_simplified = async_to_raw_response_wrapper( brand.retrieve_simplified, ) + self.search = async_to_raw_response_wrapper( + brand.search, + ) class BrandResourceWithStreamingResponse: @@ -2557,6 +2674,9 @@ def __init__(self, brand: BrandResource) -> None: self.retrieve_simplified = to_streamed_response_wrapper( brand.retrieve_simplified, ) + self.search = to_streamed_response_wrapper( + brand.search, + ) class AsyncBrandResourceWithStreamingResponse: @@ -2569,3 +2689,6 @@ def __init__(self, brand: AsyncBrandResource) -> None: self.retrieve_simplified = async_to_streamed_response_wrapper( brand.retrieve_simplified, ) + self.search = async_to_streamed_response_wrapper( + brand.search, + ) diff --git a/src/context/dev/types/__init__.py b/src/context/dev/types/__init__.py index efea4d2..11b8a4a 100644 --- a/src/context/dev/types/__init__.py +++ b/src/context/dev/types/__init__.py @@ -12,6 +12,7 @@ from .web_extract_params import WebExtractParams as WebExtractParams from .batch_list_response import BatchListResponse as BatchListResponse from .batch_submit_params import BatchSubmitParams as BatchSubmitParams +from .brand_search_params import BrandSearchParams as BrandSearchParams from .monitor_list_params import MonitorListParams as MonitorListParams from .parse_handle_params import ParseHandleParams as ParseHandleParams from .web_search_response import WebSearchResponse as WebSearchResponse @@ -20,6 +21,7 @@ from .batch_cancel_response import BatchCancelResponse as BatchCancelResponse from .batch_submit_response import BatchSubmitResponse as BatchSubmitResponse from .brand_retrieve_params import BrandRetrieveParams as BrandRetrieveParams +from .brand_search_response import BrandSearchResponse as BrandSearchResponse from .monitor_create_params import MonitorCreateParams as MonitorCreateParams from .monitor_list_response import MonitorListResponse as MonitorListResponse from .monitor_update_params import MonitorUpdateParams as MonitorUpdateParams diff --git a/src/context/dev/types/brand_search_params.py b/src/context/dev/types/brand_search_params.py new file mode 100644 index 0000000..911d0c5 --- /dev/null +++ b/src/context/dev/types/brand_search_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +from .._types import SequenceNotStr + +__all__ = ["BrandSearchParams"] + + +class BrandSearchParams(TypedDict, total=False): + query: Required[str] + """Search term, matched against brand names and domains by prefix (e.g. + + 'nike', 'nike.com', 'nik'). + """ + + tags: SequenceNotStr[str] + """Optional comma-separated caller-defined tags for tracking this request. + + Tags are recorded on the request's usage log and can be used to filter usage on + the dashboard usage page. Up to 20 tags, each 1-50 characters. + """ diff --git a/src/context/dev/types/brand_search_response.py b/src/context/dev/types/brand_search_response.py new file mode 100644 index 0000000..f2b46ed --- /dev/null +++ b/src/context/dev/types/brand_search_response.py @@ -0,0 +1,46 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from .._models import BaseModel + +__all__ = ["BrandSearchResponse", "Result", "KeyMetadata"] + + +class Result(BaseModel): + domain: str + """The brand's domain.""" + + logo: str + """ + Logo link URL that serves the brand's logo, generated per request for the + calling organization. + """ + + name: str + """The brand's name. Empty string when unknown.""" + + +class KeyMetadata(BaseModel): + """Metadata about the API key used for the request. + + Included in every response whenever a valid API key is provided, even when the response status is not 200. + """ + + credits_consumed: int + """The number of credits consumed by this request.""" + + credits_remaining: int + """The number of credits remaining for your organization after this request.""" + + +class BrandSearchResponse(BaseModel): + results: List[Result] + """Up to 10 matching brands, most popular first. Empty when nothing matches.""" + + key_metadata: Optional[KeyMetadata] = None + """Metadata about the API key used for the request. + + Included in every response whenever a valid API key is provided, even when the + response status is not 200. + """ diff --git a/tests/api_resources/test_brand.py b/tests/api_resources/test_brand.py index 9e921a6..d0912d0 100644 --- a/tests/api_resources/test_brand.py +++ b/tests/api_resources/test_brand.py @@ -10,6 +10,7 @@ from context.dev import ContextDev, AsyncContextDev from tests.utils import assert_matches_type from context.dev.types import ( + BrandSearchResponse, BrandRetrieveResponse, BrandRetrieveSimplifiedResponse, ) @@ -375,6 +376,49 @@ def test_streaming_response_retrieve_simplified(self, client: ContextDev) -> Non assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_search(self, client: ContextDev) -> None: + brand = client.brand.search( + query="x", + ) + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_search_with_all_params(self, client: ContextDev) -> None: + brand = client.brand.search( + query="x", + tags=["production", "team-alpha"], + ) + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_search(self, client: ContextDev) -> None: + response = client.brand.with_raw_response.search( + query="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + brand = response.parse() + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_search(self, client: ContextDev) -> None: + with client.brand.with_streaming_response.search( + query="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + brand = response.parse() + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + assert cast(Any, response.is_closed) is True + class TestAsyncBrand: parametrize = pytest.mark.parametrize( @@ -735,3 +779,46 @@ async def test_streaming_response_retrieve_simplified(self, async_client: AsyncC assert_matches_type(BrandRetrieveSimplifiedResponse, brand, path=["response"]) assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_search(self, async_client: AsyncContextDev) -> None: + brand = await async_client.brand.search( + query="x", + ) + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_search_with_all_params(self, async_client: AsyncContextDev) -> None: + brand = await async_client.brand.search( + query="x", + tags=["production", "team-alpha"], + ) + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_search(self, async_client: AsyncContextDev) -> None: + response = await async_client.brand.with_raw_response.search( + query="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + brand = await response.parse() + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_search(self, async_client: AsyncContextDev) -> None: + async with async_client.brand.with_streaming_response.search( + query="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + brand = await response.parse() + assert_matches_type(BrandSearchResponse, brand, path=["response"]) + + assert cast(Any, response.is_closed) is True From f4e56640bafc0db710f2f9c79ee321671474ab87 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 10:13:00 +0000 Subject: [PATCH 7/7] release: 2.8.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- src/context/dev/_version.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d1328ca..64f9ff4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.0" + ".": "2.8.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 574526f..cabb035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 2.8.0 (2026-08-05) + +Full Changelog: [v2.7.0...v2.8.0](https://github.com/context-dot-dev/context-python-sdk/compare/v2.7.0...v2.8.0) + +### Features + +* **api:** manual updates ([d26f4e8](https://github.com/context-dot-dev/context-python-sdk/commit/d26f4e842387b630ba30fcb291bbcdbad610d28c)) + ## 2.7.0 (2026-08-01) Full Changelog: [v2.6.0...v2.7.0](https://github.com/context-dot-dev/context-python-sdk/compare/v2.6.0...v2.7.0) diff --git a/pyproject.toml b/pyproject.toml index fb0dfb2..ece6698 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "context.dev" -version = "2.7.0" +version = "2.8.0" description = "The official Python library for the context.dev API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/context/dev/_version.py b/src/context/dev/_version.py index 31f9889..c08edfc 100644 --- a/src/context/dev/_version.py +++ b/src/context/dev/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "context.dev" -__version__ = "2.7.0" # x-release-please-version +__version__ = "2.8.0" # x-release-please-version