diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 427b8ec..21f6056 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.0" + ".": "2.10.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 97db86d..4b9b1cb 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 40 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-a0dda03bbb600917cfb9add468cc4c8c84351a8dbbf61644dbc353263ca1748f.yml -openapi_spec_hash: c24264f32a46d9317aac5af9d6a396f7 -config_hash: 920678668dd2da6f8966fbf1b8fde4e2 +configured_endpoints: 41 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-5dbe631ce516ca688273053ddcb58870561bd6dc76fa75df354c954d7af65a3c.yml +openapi_spec_hash: 53a74c4cccbdec8590db38183840a446 +config_hash: 0fb0ceca5946298c416cec0cca5260c7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e5e281..b8cde85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 2.10.0 (2026-08-17) + +Full Changelog: [v2.9.0...v2.10.0](https://github.com/context-dot-dev/context-python-sdk/compare/v2.9.0...v2.10.0) + +### Features + +* **api:** api update ([253db7d](https://github.com/context-dot-dev/context-python-sdk/commit/253db7d8a9129f323b2a56b82bd5e780bcd8bf86)) +* **api:** api update ([740b2d4](https://github.com/context-dot-dev/context-python-sdk/commit/740b2d42d9e897eefd273779ab2a62c285c3b84f)) +* **api:** api update ([07e8016](https://github.com/context-dot-dev/context-python-sdk/commit/07e80168ee24305f42bfac338ee85d676e9601d7)) +* **api:** api update ([499fb3f](https://github.com/context-dot-dev/context-python-sdk/commit/499fb3fdef35838f9c631560b2bc073b73f3a04a)) +* **api:** api update ([853f56b](https://github.com/context-dot-dev/context-python-sdk/commit/853f56b503807b1bb41f4ca26800b56fc41e395c)) +* **api:** manual updates ([4f84467](https://github.com/context-dot-dev/context-python-sdk/commit/4f84467a599b7c80702e95b027e87584ba6d07a7)) + ## 2.9.0 (2026-08-07) Full Changelog: [v2.8.0...v2.9.0](https://github.com/context-dot-dev/context-python-sdk/compare/v2.8.0...v2.9.0) diff --git a/api.md b/api.md index 56ac7f5..2a88eee 100644 --- a/api.md +++ b/api.md @@ -178,3 +178,15 @@ from context.dev.types import PersonEnrichResponse Methods: - client.people.enrich(\*\*params) -> PersonEnrichResponse + +# News + +Types: + +```python +from context.dev.types import NewsSearchResponse +``` + +Methods: + +- client.news.search(\*\*params) -> NewsSearchResponse diff --git a/pyproject.toml b/pyproject.toml index 7c3d73f..5d891ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "context.dev" -version = "2.9.0" +version = "2.10.0" description = "The official Python library for the context.dev API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/context/dev/_client.py b/src/context/dev/_client.py index 63888b2..5b83688 100644 --- a/src/context/dev/_client.py +++ b/src/context/dev/_client.py @@ -35,9 +35,10 @@ ) if TYPE_CHECKING: - from .resources import ai, web, batch, brand, parse, people, utility, industry, monitors + from .resources import ai, web, news, batch, brand, parse, people, utility, industry, monitors from .resources.ai import AIResource, AsyncAIResource from .resources.web import WebResource, AsyncWebResource + from .resources.news import NewsResource, AsyncNewsResource from .resources.batch import BatchResource, AsyncBatchResource from .resources.brand import BrandResource, AsyncBrandResource from .resources.parse import ParseResource, AsyncParseResource @@ -180,6 +181,13 @@ def people(self) -> PeopleResource: return PeopleResource(self) + @cached_property + def news(self) -> NewsResource: + """Search live first-party RSS and free historical news data by company identity.""" + from .resources.news import NewsResource + + return NewsResource(self) + @cached_property def with_raw_response(self) -> ContextDevWithRawResponse: return ContextDevWithRawResponse(self) @@ -415,6 +423,13 @@ def people(self) -> AsyncPeopleResource: return AsyncPeopleResource(self) + @cached_property + def news(self) -> AsyncNewsResource: + """Search live first-party RSS and free historical news data by company identity.""" + from .resources.news import AsyncNewsResource + + return AsyncNewsResource(self) + @cached_property def with_raw_response(self) -> AsyncContextDevWithRawResponse: return AsyncContextDevWithRawResponse(self) @@ -592,6 +607,13 @@ def people(self) -> people.PeopleResourceWithRawResponse: return PeopleResourceWithRawResponse(self._client.people) + @cached_property + def news(self) -> news.NewsResourceWithRawResponse: + """Search live first-party RSS and free historical news data by company identity.""" + from .resources.news import NewsResourceWithRawResponse + + return NewsResourceWithRawResponse(self._client.news) + class AsyncContextDevWithRawResponse: _client: AsyncContextDev @@ -657,6 +679,13 @@ def people(self) -> people.AsyncPeopleResourceWithRawResponse: return AsyncPeopleResourceWithRawResponse(self._client.people) + @cached_property + def news(self) -> news.AsyncNewsResourceWithRawResponse: + """Search live first-party RSS and free historical news data by company identity.""" + from .resources.news import AsyncNewsResourceWithRawResponse + + return AsyncNewsResourceWithRawResponse(self._client.news) + class ContextDevWithStreamedResponse: _client: ContextDev @@ -722,6 +751,13 @@ def people(self) -> people.PeopleResourceWithStreamingResponse: return PeopleResourceWithStreamingResponse(self._client.people) + @cached_property + def news(self) -> news.NewsResourceWithStreamingResponse: + """Search live first-party RSS and free historical news data by company identity.""" + from .resources.news import NewsResourceWithStreamingResponse + + return NewsResourceWithStreamingResponse(self._client.news) + class AsyncContextDevWithStreamedResponse: _client: AsyncContextDev @@ -787,6 +823,13 @@ def people(self) -> people.AsyncPeopleResourceWithStreamingResponse: return AsyncPeopleResourceWithStreamingResponse(self._client.people) + @cached_property + def news(self) -> news.AsyncNewsResourceWithStreamingResponse: + """Search live first-party RSS and free historical news data by company identity.""" + from .resources.news import AsyncNewsResourceWithStreamingResponse + + return AsyncNewsResourceWithStreamingResponse(self._client.news) + Client = ContextDev diff --git a/src/context/dev/_version.py b/src/context/dev/_version.py index 593f642..9acee71 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.9.0" # x-release-please-version +__version__ = "2.10.0" # x-release-please-version diff --git a/src/context/dev/resources/__init__.py b/src/context/dev/resources/__init__.py index 9d68085..03f6108 100644 --- a/src/context/dev/resources/__init__.py +++ b/src/context/dev/resources/__init__.py @@ -16,6 +16,14 @@ WebResourceWithStreamingResponse, AsyncWebResourceWithStreamingResponse, ) +from .news import ( + NewsResource, + AsyncNewsResource, + NewsResourceWithRawResponse, + AsyncNewsResourceWithRawResponse, + NewsResourceWithStreamingResponse, + AsyncNewsResourceWithStreamingResponse, +) from .batch import ( BatchResource, AsyncBatchResource, @@ -128,4 +136,10 @@ "AsyncPeopleResourceWithRawResponse", "PeopleResourceWithStreamingResponse", "AsyncPeopleResourceWithStreamingResponse", + "NewsResource", + "AsyncNewsResource", + "NewsResourceWithRawResponse", + "AsyncNewsResourceWithRawResponse", + "NewsResourceWithStreamingResponse", + "AsyncNewsResourceWithStreamingResponse", ] diff --git a/src/context/dev/resources/brand.py b/src/context/dev/resources/brand.py index b7bb4ca..5a9f7fd 100644 --- a/src/context/dev/resources/brand.py +++ b/src/context/dev/resources/brand.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Union, Optional +from typing import List, Union, Optional from typing_extensions import Literal, overload import httpx @@ -1278,7 +1278,10 @@ def search( self, *, query: str, + autocomplete: bool | Omit = omit, + query_by: List[Literal["name", "domain"]] | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, + typo_tolerance: int | 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, @@ -1287,23 +1290,25 @@ def search( 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). Name matches rank ahead of domain matches; within each - group the most popular brands come 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. + Search indexed brands by name or domain Args: - query: Search term, matched against brand names and domains by prefix (e.g. 'nike', + query: Search term, matched against the fields selected by queryBy (e.g. 'nike', 'nike.com', 'nik'). + autocomplete: Whether the search term matches by prefix, so partial words match as they are + typed (e.g. 'nik' matches Nike). Set to false to match whole words only. + + query_by: Fields to match the search term against, as a comma-separated list or repeated + parameter: 'name', 'domain', or both. Defaults to both. + 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. + typo_tolerance: Maximum number of typos tolerated when matching, from 0 to 2. Defaults to 0 (no + typo tolerance). + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -1322,7 +1327,10 @@ def search( query=maybe_transform( { "query": query, + "autocomplete": autocomplete, + "query_by": query_by, "tags": tags, + "typo_tolerance": typo_tolerance, }, brand_search_params.BrandSearchParams, ), @@ -2583,7 +2591,10 @@ async def search( self, *, query: str, + autocomplete: bool | Omit = omit, + query_by: List[Literal["name", "domain"]] | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, + typo_tolerance: int | 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, @@ -2592,23 +2603,25 @@ async def search( 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). Name matches rank ahead of domain matches; within each - group the most popular brands come 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. + Search indexed brands by name or domain Args: - query: Search term, matched against brand names and domains by prefix (e.g. 'nike', + query: Search term, matched against the fields selected by queryBy (e.g. 'nike', 'nike.com', 'nik'). + autocomplete: Whether the search term matches by prefix, so partial words match as they are + typed (e.g. 'nik' matches Nike). Set to false to match whole words only. + + query_by: Fields to match the search term against, as a comma-separated list or repeated + parameter: 'name', 'domain', or both. Defaults to both. + 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. + typo_tolerance: Maximum number of typos tolerated when matching, from 0 to 2. Defaults to 0 (no + typo tolerance). + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -2627,7 +2640,10 @@ async def search( query=await async_maybe_transform( { "query": query, + "autocomplete": autocomplete, + "query_by": query_by, "tags": tags, + "typo_tolerance": typo_tolerance, }, brand_search_params.BrandSearchParams, ), diff --git a/src/context/dev/resources/news.py b/src/context/dev/resources/news.py new file mode 100644 index 0000000..607b2c2 --- /dev/null +++ b/src/context/dev/resources/news.py @@ -0,0 +1,231 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +import httpx + +from ..types import news_search_params +from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, 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.news_search_response import NewsSearchResponse + +__all__ = ["NewsResource", "AsyncNewsResource"] + + +class NewsResource(SyncAPIResource): + """Search live first-party RSS and free historical news data by company identity.""" + + @cached_property + def with_raw_response(self) -> NewsResourceWithRawResponse: + """ + 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/context-dot-dev/context-python-sdk#accessing-raw-response-data-eg-headers + """ + return NewsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> NewsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/context-dot-dev/context-python-sdk#with_streaming_response + """ + return NewsResourceWithStreamingResponse(self) + + def search( + self, + *, + search_by: news_search_params.SearchBy, + cursor: Optional[str] | Omit = omit, + filter_by: news_search_params.FilterBy | Omit = omit, + limit: int | Omit = omit, + sort_by: news_search_params.SortBy | Omit = omit, + 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, + ) -> NewsSearchResponse: + """ + Searches live and historical company news for one company, identified in + searchBy by name, domain, ticker (optionally disambiguated by exchange), or + ISIN. Results can be filtered by publisher domain, publisher country, article + language, article type, and published-at date, and include stable story IDs, + source metadata, verified entity relevance, and cursor pagination. + + Args: + search_by: What to search for. + + cursor: Opaque next_cursor from the previous response, or null for the first page. + + filter_by: Optional result filters. + + limit: Maximum results to return. Defaults to 10. + + sort_by: Result ordering. Defaults to newest. + + tags: Optional tags for tracking usage. Up to 20 tags, each 1 to 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._post( + "/news/search", + body=maybe_transform( + { + "search_by": search_by, + "cursor": cursor, + "filter_by": filter_by, + "limit": limit, + "sort_by": sort_by, + "tags": tags, + }, + news_search_params.NewsSearchParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NewsSearchResponse, + ) + + +class AsyncNewsResource(AsyncAPIResource): + """Search live first-party RSS and free historical news data by company identity.""" + + @cached_property + def with_raw_response(self) -> AsyncNewsResourceWithRawResponse: + """ + 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/context-dot-dev/context-python-sdk#accessing-raw-response-data-eg-headers + """ + return AsyncNewsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncNewsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/context-dot-dev/context-python-sdk#with_streaming_response + """ + return AsyncNewsResourceWithStreamingResponse(self) + + async def search( + self, + *, + search_by: news_search_params.SearchBy, + cursor: Optional[str] | Omit = omit, + filter_by: news_search_params.FilterBy | Omit = omit, + limit: int | Omit = omit, + sort_by: news_search_params.SortBy | Omit = omit, + 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, + ) -> NewsSearchResponse: + """ + Searches live and historical company news for one company, identified in + searchBy by name, domain, ticker (optionally disambiguated by exchange), or + ISIN. Results can be filtered by publisher domain, publisher country, article + language, article type, and published-at date, and include stable story IDs, + source metadata, verified entity relevance, and cursor pagination. + + Args: + search_by: What to search for. + + cursor: Opaque next_cursor from the previous response, or null for the first page. + + filter_by: Optional result filters. + + limit: Maximum results to return. Defaults to 10. + + sort_by: Result ordering. Defaults to newest. + + tags: Optional tags for tracking usage. Up to 20 tags, each 1 to 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._post( + "/news/search", + body=await async_maybe_transform( + { + "search_by": search_by, + "cursor": cursor, + "filter_by": filter_by, + "limit": limit, + "sort_by": sort_by, + "tags": tags, + }, + news_search_params.NewsSearchParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NewsSearchResponse, + ) + + +class NewsResourceWithRawResponse: + def __init__(self, news: NewsResource) -> None: + self._news = news + + self.search = to_raw_response_wrapper( + news.search, + ) + + +class AsyncNewsResourceWithRawResponse: + def __init__(self, news: AsyncNewsResource) -> None: + self._news = news + + self.search = async_to_raw_response_wrapper( + news.search, + ) + + +class NewsResourceWithStreamingResponse: + def __init__(self, news: NewsResource) -> None: + self._news = news + + self.search = to_streamed_response_wrapper( + news.search, + ) + + +class AsyncNewsResourceWithStreamingResponse: + def __init__(self, news: AsyncNewsResource) -> None: + self._news = news + + self.search = async_to_streamed_response_wrapper( + news.search, + ) diff --git a/src/context/dev/resources/parse.py b/src/context/dev/resources/parse.py index 3c3101a..4a2a75f 100644 --- a/src/context/dev/resources/parse.py +++ b/src/context/dev/resources/parse.py @@ -3,7 +3,6 @@ from __future__ import annotations import os -from typing import Union from typing_extensions import Literal import httpx @@ -136,13 +135,13 @@ def handle( "pnm", ] | Omit = omit, - include_images: Union[bool, Literal["true", "false"]] | Omit = omit, - include_links: Union[bool, Literal["true", "false"]] | Omit = omit, - ocr: Union[bool, Literal["true", "false"]] | Omit = omit, + include_images: bool | Omit = omit, + include_links: bool | Omit = omit, + ocr: bool | Omit = omit, pdf: parse_handle_params.Pdf | Omit = omit, - shorten_base64_images: Union[bool, Literal["true", "false"]] | Omit = omit, + shorten_base64_images: bool | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, - use_main_content_only: Union[bool, Literal["true", "false"]] | Omit = omit, + use_main_content_only: bool | Omit = omit, zdr: Literal["enabled", "disabled"] | 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. @@ -321,13 +320,13 @@ async def handle( "pnm", ] | Omit = omit, - include_images: Union[bool, Literal["true", "false"]] | Omit = omit, - include_links: Union[bool, Literal["true", "false"]] | Omit = omit, - ocr: Union[bool, Literal["true", "false"]] | Omit = omit, + include_images: bool | Omit = omit, + include_links: bool | Omit = omit, + ocr: bool | Omit = omit, pdf: parse_handle_params.Pdf | Omit = omit, - shorten_base64_images: Union[bool, Literal["true", "false"]] | Omit = omit, + shorten_base64_images: bool | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, - use_main_content_only: Union[bool, Literal["true", "false"]] | Omit = omit, + use_main_content_only: bool | Omit = omit, zdr: Literal["enabled", "disabled"] | 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. diff --git a/src/context/dev/resources/utility.py b/src/context/dev/resources/utility.py index d7d10f0..33b230c 100644 --- a/src/context/dev/resources/utility.py +++ b/src/context/dev/resources/utility.py @@ -47,7 +47,7 @@ def prefetch( self, *, identifier: utility_prefetch_params.Identifier, - type: Literal["brand"], + type: Literal["brand", "styleguide"], tags: SequenceNotStr[str] | 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. @@ -57,17 +57,19 @@ def prefetch( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> UtilityPrefetchResponse: - """Signal that you may fetch brand data soon to improve latency. + """Signal that you may fetch data soon to improve latency. - The type field - selects what to prefetch (currently only 'brand') and identifier carries exactly - one lookup key: a domain, or an email whose domain is extracted and validated - (free email providers and disposable email addresses are not allowed). + The type field selects + what to prefetch ('brand' queues a brand data fetch, 'styleguide' queues a + styleguide extraction) and identifier carries exactly one lookup key: a domain, + or an email whose domain is extracted and validated (free email providers and + disposable email addresses are not allowed). Args: - identifier: Identifier of the brand to prefetch. Provide exactly one of domain or email. + identifier: Identifier of the target to prefetch. Provide exactly one of domain or email. - type: What to prefetch. Currently only 'brand' is supported. + type: What to prefetch: 'brand' warms the brand data cache, 'styleguide' warms the + styleguide cache. tags: Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. @@ -125,7 +127,7 @@ async def prefetch( self, *, identifier: utility_prefetch_params.Identifier, - type: Literal["brand"], + type: Literal["brand", "styleguide"], tags: SequenceNotStr[str] | 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. @@ -135,17 +137,19 @@ async def prefetch( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> UtilityPrefetchResponse: - """Signal that you may fetch brand data soon to improve latency. + """Signal that you may fetch data soon to improve latency. - The type field - selects what to prefetch (currently only 'brand') and identifier carries exactly - one lookup key: a domain, or an email whose domain is extracted and validated - (free email providers and disposable email addresses are not allowed). + The type field selects + what to prefetch ('brand' queues a brand data fetch, 'styleguide' queues a + styleguide extraction) and identifier carries exactly one lookup key: a domain, + or an email whose domain is extracted and validated (free email providers and + disposable email addresses are not allowed). Args: - identifier: Identifier of the brand to prefetch. Provide exactly one of domain or email. + identifier: Identifier of the target to prefetch. Provide exactly one of domain or email. - type: What to prefetch. Currently only 'brand' is supported. + type: What to prefetch: 'brand' warms the brand data cache, 'styleguide' warms the + styleguide cache. tags: Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. diff --git a/src/context/dev/resources/web.py b/src/context/dev/resources/web.py index efe42f7..a058849 100644 --- a/src/context/dev/resources/web.py +++ b/src/context/dev/resources/web.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Dict, Union, Iterable, Optional +from typing import Dict, Iterable, Optional from typing_extensions import Literal import httpx @@ -597,7 +597,7 @@ def screenshot( direct_url: str | Omit = omit, domain: str | Omit = omit, full_screenshot: Literal["true", "false"] | Omit = omit, - handle_cookie_popup: Union[bool, Literal["true", "false"]] | Omit = omit, + handle_cookie_popup: bool | Omit = omit, max_age_ms: Optional[int] | Omit = omit, page: Literal["login", "signup", "blog", "careers", "pricing", "terms", "privacy", "contact"] | Omit = omit, scroll_offset: Optional[int] | Omit = omit, @@ -1599,14 +1599,14 @@ def web_scrape_html( | Omit = omit, exclude_selectors: Optional[SequenceNotStr[str]] | Omit = omit, headers: Dict[str, str] | Omit = omit, - include_frames: Union[bool, Literal["true", "false"]] | Omit = omit, + include_frames: bool | Omit = omit, include_selectors: Optional[SequenceNotStr[str]] | Omit = omit, max_age_ms: Optional[int] | Omit = omit, pdf: web_web_scrape_html_params.Pdf | Omit = omit, - settle_animations: Union[bool, Literal["true", "false"]] | Omit = omit, + settle_animations: bool | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, timeout_ms: int | Omit = omit, - use_main_content_only: Union[bool, Literal["true", "false"]] | Omit = omit, + use_main_content_only: bool | Omit = omit, wait_for_ms: Optional[int] | Omit = omit, zdr: Literal["enabled", "disabled"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1720,7 +1720,7 @@ def web_scrape_images( *, url: str, actions: Optional[Iterable[web_web_scrape_images_params.Action]] | Omit = omit, - dedupe: Union[bool, Literal["true", "false"]] | Omit = omit, + dedupe: bool | Omit = omit, enrichment: Optional[web_web_scrape_images_params.Enrichment] | Omit = omit, headers: Dict[str, str] | Omit = omit, max_age_ms: Optional[int] | Omit = omit, @@ -2021,17 +2021,18 @@ def web_scrape_md( | Omit = omit, exclude_selectors: Optional[SequenceNotStr[str]] | Omit = omit, headers: Dict[str, str] | Omit = omit, - include_frames: Union[bool, Literal["true", "false"]] | Omit = omit, - include_images: Union[bool, Literal["true", "false"]] | Omit = omit, - include_links: Union[bool, Literal["true", "false"]] | Omit = omit, + include_frames: bool | Omit = omit, + include_html: bool | Omit = omit, + include_images: bool | Omit = omit, + include_links: bool | Omit = omit, include_selectors: Optional[SequenceNotStr[str]] | Omit = omit, max_age_ms: Optional[int] | Omit = omit, pdf: web_web_scrape_md_params.Pdf | Omit = omit, - settle_animations: Union[bool, Literal["true", "false"]] | Omit = omit, - shorten_base64_images: Union[bool, Literal["true", "false"]] | Omit = omit, + settle_animations: bool | Omit = omit, + shorten_base64_images: bool | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, timeout_ms: int | Omit = omit, - use_main_content_only: Union[bool, Literal["true", "false"]] | Omit = omit, + use_main_content_only: bool | Omit = omit, wait_for_ms: Optional[int] | Omit = omit, zdr: Literal["enabled", "disabled"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -2061,17 +2062,17 @@ def web_scrape_md( ### Billing & errors - | HTTP status | Billed? | Meaning | - | ----------- | ----------------------------------------- | ---------------------------------------------------------------------------------------- | - | 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing | - | 400 | No | Invalid input, skipped PDF, or the page could not be scraped | - | 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code | - | 404 | No | Target page returned or fingerprinted as not found | - | 408 | No | Request timed out | - | 413 | No | Target content exceeds the maximum supported size (20 MB) | - | 415 | No | Unsupported content type | - | 429 | No | Per-minute rate limit exceeded; honor Retry-After | - | 500 | No | Internal error | + | HTTP status | Billed? | Meaning | + | ----------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing | + | 400 | No | Invalid input, skipped PDF, or the page could not be scraped. error_code WEBSITE_BLOCKED specifically means the site answered with an anti-bot challenge, CAPTCHA wall, or login shell instead of the page (even when the site returned HTTP 200) — retrying later or from another country sometimes succeeds | + | 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code | + | 404 | No | Target page returned or fingerprinted as not found | + | 408 | No | Request timed out | + | 413 | No | Target content exceeds the maximum supported size (20 MB) | + | 415 | No | Unsupported content type | + | 429 | No | Per-minute rate limit exceeded; honor Retry-After | + | 500 | No | Internal error | Args: url: Full URL to scrape into LLM usable Markdown (must include http:// or https:// @@ -2094,6 +2095,10 @@ def web_scrape_md( include_frames: When true, the contents of iframes are rendered to Markdown. + include_html: When true, the response also includes an `html` field with the page HTML the + Markdown was converted from — the same body the Scrape HTML endpoint returns for + the equivalent request. + include_images: Include image references in Markdown output include_links: Preserve hyperlinks in Markdown output @@ -2157,6 +2162,7 @@ def web_scrape_md( "exclude_selectors": exclude_selectors, "headers": headers, "include_frames": include_frames, + "include_html": include_html, "include_images": include_images, "include_links": include_links, "include_selectors": include_selectors, @@ -2821,7 +2827,7 @@ async def screenshot( direct_url: str | Omit = omit, domain: str | Omit = omit, full_screenshot: Literal["true", "false"] | Omit = omit, - handle_cookie_popup: Union[bool, Literal["true", "false"]] | Omit = omit, + handle_cookie_popup: bool | Omit = omit, max_age_ms: Optional[int] | Omit = omit, page: Literal["login", "signup", "blog", "careers", "pricing", "terms", "privacy", "contact"] | Omit = omit, scroll_offset: Optional[int] | Omit = omit, @@ -3823,14 +3829,14 @@ async def web_scrape_html( | Omit = omit, exclude_selectors: Optional[SequenceNotStr[str]] | Omit = omit, headers: Dict[str, str] | Omit = omit, - include_frames: Union[bool, Literal["true", "false"]] | Omit = omit, + include_frames: bool | Omit = omit, include_selectors: Optional[SequenceNotStr[str]] | Omit = omit, max_age_ms: Optional[int] | Omit = omit, pdf: web_web_scrape_html_params.Pdf | Omit = omit, - settle_animations: Union[bool, Literal["true", "false"]] | Omit = omit, + settle_animations: bool | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, timeout_ms: int | Omit = omit, - use_main_content_only: Union[bool, Literal["true", "false"]] | Omit = omit, + use_main_content_only: bool | Omit = omit, wait_for_ms: Optional[int] | Omit = omit, zdr: Literal["enabled", "disabled"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -3944,7 +3950,7 @@ async def web_scrape_images( *, url: str, actions: Optional[Iterable[web_web_scrape_images_params.Action]] | Omit = omit, - dedupe: Union[bool, Literal["true", "false"]] | Omit = omit, + dedupe: bool | Omit = omit, enrichment: Optional[web_web_scrape_images_params.Enrichment] | Omit = omit, headers: Dict[str, str] | Omit = omit, max_age_ms: Optional[int] | Omit = omit, @@ -4245,17 +4251,18 @@ async def web_scrape_md( | Omit = omit, exclude_selectors: Optional[SequenceNotStr[str]] | Omit = omit, headers: Dict[str, str] | Omit = omit, - include_frames: Union[bool, Literal["true", "false"]] | Omit = omit, - include_images: Union[bool, Literal["true", "false"]] | Omit = omit, - include_links: Union[bool, Literal["true", "false"]] | Omit = omit, + include_frames: bool | Omit = omit, + include_html: bool | Omit = omit, + include_images: bool | Omit = omit, + include_links: bool | Omit = omit, include_selectors: Optional[SequenceNotStr[str]] | Omit = omit, max_age_ms: Optional[int] | Omit = omit, pdf: web_web_scrape_md_params.Pdf | Omit = omit, - settle_animations: Union[bool, Literal["true", "false"]] | Omit = omit, - shorten_base64_images: Union[bool, Literal["true", "false"]] | Omit = omit, + settle_animations: bool | Omit = omit, + shorten_base64_images: bool | Omit = omit, tags: SequenceNotStr[str] | Omit = omit, timeout_ms: int | Omit = omit, - use_main_content_only: Union[bool, Literal["true", "false"]] | Omit = omit, + use_main_content_only: bool | Omit = omit, wait_for_ms: Optional[int] | Omit = omit, zdr: Literal["enabled", "disabled"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -4285,17 +4292,17 @@ async def web_scrape_md( ### Billing & errors - | HTTP status | Billed? | Meaning | - | ----------- | ----------------------------------------- | ---------------------------------------------------------------------------------------- | - | 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing | - | 400 | No | Invalid input, skipped PDF, or the page could not be scraped | - | 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code | - | 404 | No | Target page returned or fingerprinted as not found | - | 408 | No | Request timed out | - | 413 | No | Target content exceeds the maximum supported size (20 MB) | - | 415 | No | Unsupported content type | - | 429 | No | Per-minute rate limit exceeded; honor Retry-After | - | 500 | No | Internal error | + | HTTP status | Billed? | Meaning | + | ----------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing | + | 400 | No | Invalid input, skipped PDF, or the page could not be scraped. error_code WEBSITE_BLOCKED specifically means the site answered with an anti-bot challenge, CAPTCHA wall, or login shell instead of the page (even when the site returned HTTP 200) — retrying later or from another country sometimes succeeds | + | 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code | + | 404 | No | Target page returned or fingerprinted as not found | + | 408 | No | Request timed out | + | 413 | No | Target content exceeds the maximum supported size (20 MB) | + | 415 | No | Unsupported content type | + | 429 | No | Per-minute rate limit exceeded; honor Retry-After | + | 500 | No | Internal error | Args: url: Full URL to scrape into LLM usable Markdown (must include http:// or https:// @@ -4318,6 +4325,10 @@ async def web_scrape_md( include_frames: When true, the contents of iframes are rendered to Markdown. + include_html: When true, the response also includes an `html` field with the page HTML the + Markdown was converted from — the same body the Scrape HTML endpoint returns for + the equivalent request. + include_images: Include image references in Markdown output include_links: Preserve hyperlinks in Markdown output @@ -4381,6 +4392,7 @@ async def web_scrape_md( "exclude_selectors": exclude_selectors, "headers": headers, "include_frames": include_frames, + "include_html": include_html, "include_images": include_images, "include_links": include_links, "include_selectors": include_selectors, diff --git a/src/context/dev/types/__init__.py b/src/context/dev/types/__init__.py index ca25937..139c5e1 100644 --- a/src/context/dev/types/__init__.py +++ b/src/context/dev/types/__init__.py @@ -9,6 +9,7 @@ from .webhook_delivery import WebhookDelivery as WebhookDelivery from .batch_list_params import BatchListParams as BatchListParams from .web_search_params import WebSearchParams as WebSearchParams +from .news_search_params import NewsSearchParams as NewsSearchParams from .web_extract_params import WebExtractParams as WebExtractParams from .batch_list_response import BatchListResponse as BatchListResponse from .batch_submit_params import BatchSubmitParams as BatchSubmitParams @@ -17,6 +18,7 @@ from .parse_handle_params import ParseHandleParams as ParseHandleParams from .web_search_response import WebSearchResponse as WebSearchResponse from .monitor_run_response import MonitorRunResponse as MonitorRunResponse +from .news_search_response import NewsSearchResponse as NewsSearchResponse from .person_enrich_params import PersonEnrichParams as PersonEnrichParams from .web_extract_response import WebExtractResponse as WebExtractResponse from .batch_cancel_response import BatchCancelResponse as BatchCancelResponse diff --git a/src/context/dev/types/batch_get_results_response.py b/src/context/dev/types/batch_get_results_response.py index dfb4d62..b8e6905 100644 --- a/src/context/dev/types/batch_get_results_response.py +++ b/src/context/dev/types/batch_get_results_response.py @@ -14,6 +14,7 @@ "DataOk", "DataOkMetadata", "DataOkMetadataAlternate", + "DataOkMetadataHeading", "DataError", "KeyMetadata", ] @@ -33,6 +34,14 @@ class DataOkMetadataAlternate(BaseModel): """Alternate resource MIME type, when present.""" +class DataOkMetadataHeading(BaseModel): + level: int + """Heading level, 1–6 (from h1–h6).""" + + text: str + """Heading text with whitespace collapsed, truncated to 1000 characters.""" + + class DataOkMetadata(BaseModel): """Metadata extracted from the scraped page HTML.""" @@ -63,6 +72,12 @@ class DataOkMetadata(BaseModel): favicon: Optional[str] = None """Resolved favicon URL, when present.""" + headings: Optional[List[DataOkMetadataHeading]] = None + """Page headings (h1–h6) in document order, extracted from the unfiltered document. + + Capped at the first 500 headings. Omitted when the page has none. + """ + image: Optional[str] = None """Primary resolved preview image from Open Graph, Twitter, or image metadata.""" @@ -116,7 +131,11 @@ class DataOk(BaseModel): """URL as submitted, or as discovered by the crawl.""" html: Optional[str] = None - """Raw page HTML. Present on html batches.""" + """Page HTML. + + Present on html batches, and on markdown batches submitted with + `options.includeHTML`. + """ item_id: Optional[str] = FieldInfo(alias="itemId", default=None) """Caller-supplied identifier echoed from submission.""" diff --git a/src/context/dev/types/batch_submit_params.py b/src/context/dev/types/batch_submit_params.py index d52a6d1..ec7335b 100644 --- a/src/context/dev/types/batch_submit_params.py +++ b/src/context/dev/types/batch_submit_params.py @@ -88,7 +88,7 @@ class InputScrapeDataMarkdownOptionsPdf(TypedDict, total=False): start when both are provided. """ - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real @@ -96,7 +96,7 @@ class InputScrapeDataMarkdownOptionsPdf(TypedDict, total=False): of the base request cost. When false, no OCR runs. """ - should_parse: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shouldParse")] + should_parse: Annotated[bool, PropertyInfo(alias="shouldParse")] """When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned. @@ -329,6 +329,12 @@ class InputScrapeDataMarkdownOptions(TypedDict, total=False): Applied after `includeSelectors`, so an element matching both is removed. """ + include_html: Annotated[bool, PropertyInfo(alias="includeHTML")] + """ + Also include each page's HTML in its result record, as an `html` field alongside + the Markdown. + """ + include_images: Annotated[bool, PropertyInfo(alias="includeImages")] """Include image references in the Markdown.""" @@ -413,7 +419,7 @@ class InputScrapeDataHTMLOptionsPdf(TypedDict, total=False): start when both are provided. """ - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real @@ -421,7 +427,7 @@ class InputScrapeDataHTMLOptionsPdf(TypedDict, total=False): of the base request cost. When false, no OCR runs. """ - should_parse: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shouldParse")] + should_parse: Annotated[bool, PropertyInfo(alias="shouldParse")] """When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned. @@ -796,7 +802,7 @@ class InputCrawlDataMarkdownOptionsPdf(TypedDict, total=False): start when both are provided. """ - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real @@ -804,7 +810,7 @@ class InputCrawlDataMarkdownOptionsPdf(TypedDict, total=False): of the base request cost. When false, no OCR runs. """ - should_parse: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shouldParse")] + should_parse: Annotated[bool, PropertyInfo(alias="shouldParse")] """When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned. @@ -1037,6 +1043,12 @@ class InputCrawlDataMarkdownOptions(TypedDict, total=False): Applied after `includeSelectors`, so an element matching both is removed. """ + include_html: Annotated[bool, PropertyInfo(alias="includeHTML")] + """ + Also include each page's HTML in its result record, as an `html` field alongside + the Markdown. + """ + include_images: Annotated[bool, PropertyInfo(alias="includeImages")] """Include image references in the Markdown.""" @@ -1173,7 +1185,7 @@ class InputCrawlDataHTMLOptionsPdf(TypedDict, total=False): start when both are provided. """ - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real @@ -1181,7 +1193,7 @@ class InputCrawlDataHTMLOptionsPdf(TypedDict, total=False): of the base request cost. When false, no OCR runs. """ - should_parse: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shouldParse")] + should_parse: Annotated[bool, PropertyInfo(alias="shouldParse")] """When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned. diff --git a/src/context/dev/types/brand_search_params.py b/src/context/dev/types/brand_search_params.py index 911d0c5..720c66c 100644 --- a/src/context/dev/types/brand_search_params.py +++ b/src/context/dev/types/brand_search_params.py @@ -2,23 +2,43 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing import List +from typing_extensions import Literal, Required, Annotated, TypedDict from .._types import SequenceNotStr +from .._utils import PropertyInfo __all__ = ["BrandSearchParams"] class BrandSearchParams(TypedDict, total=False): query: Required[str] - """Search term, matched against brand names and domains by prefix (e.g. + """Search term, matched against the fields selected by queryBy (e.g. 'nike', 'nike.com', 'nik'). """ + autocomplete: bool + """ + Whether the search term matches by prefix, so partial words match as they are + typed (e.g. 'nik' matches Nike). Set to false to match whole words only. + """ + + query_by: Annotated[List[Literal["name", "domain"]], PropertyInfo(alias="queryBy")] + """ + Fields to match the search term against, as a comma-separated list or repeated + parameter: 'name', 'domain', or both. Defaults to both. + """ + 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. """ + + typo_tolerance: Annotated[int, PropertyInfo(alias="typoTolerance")] + """Maximum number of typos tolerated when matching, from 0 to 2. + + Defaults to 0 (no typo tolerance). + """ diff --git a/src/context/dev/types/news_search_params.py b/src/context/dev/types/news_search_params.py new file mode 100644 index 0000000..a7136e6 --- /dev/null +++ b/src/context/dev/types/news_search_params.py @@ -0,0 +1,253 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Union, Optional +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = [ + "NewsSearchParams", + "SearchBy", + "SearchByEntity", + "SearchByEntityNewsSearchEntityByName", + "SearchByEntityNewsSearchEntityByDomain", + "SearchByEntityNewsSearchEntityByTicker", + "SearchByEntityNewsSearchEntityByIsin", + "FilterBy", + "FilterByDate", + "SortBy", +] + + +class NewsSearchParams(TypedDict, total=False): + search_by: Required[Annotated[SearchBy, PropertyInfo(alias="searchBy")]] + """What to search for.""" + + cursor: Optional[str] + """Opaque next_cursor from the previous response, or null for the first page.""" + + filter_by: Annotated[FilterBy, PropertyInfo(alias="filterBy")] + """Optional result filters.""" + + limit: int + """Maximum results to return. Defaults to 10.""" + + sort_by: Annotated[SortBy, PropertyInfo(alias="sortBy")] + """Result ordering. Defaults to newest.""" + + tags: SequenceNotStr[str] + """Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.""" + + +class SearchByEntityNewsSearchEntityByName(TypedDict, total=False): + """Identify the company by name.""" + + name: Required[str] + """Company name.""" + + type: Required[Literal["name"]] + + +class SearchByEntityNewsSearchEntityByDomain(TypedDict, total=False): + """Identify the company by website domain.""" + + domain: Required[str] + """Company website domain, such as apple.com.""" + + type: Required[Literal["domain"]] + + +class SearchByEntityNewsSearchEntityByTicker(TypedDict, total=False): + """Identify the company by stock ticker, optionally scoped to an exchange.""" + + ticker: Required[str] + """Public-company ticker.""" + + type: Required[Literal["ticker"]] + + exchange: Literal[ + "AMEX", + "AMS", + "AQS", + "ASX", + "ATH", + "BER", + "BME", + "BRU", + "BSE", + "BUD", + "BUE", + "BVC", + "CBOE", + "CNQ", + "CPH", + "DFM", + "DOH", + "DUB", + "DUS", + "DXE", + "EGX", + "FSX", + "HAM", + "HEL", + "HKSE", + "HOSE", + "ICE", + "IOB", + "IST", + "JKT", + "JNB", + "JPX", + "KLS", + "KOE", + "KSC", + "KUW", + "LIS", + "LSE", + "MCX", + "MEX", + "MIL", + "MUN", + "NASDAQ", + "NEO", + "NSE", + "NYSE", + "NZE", + "OSL", + "OTC", + "PAR", + "PNK", + "PRA", + "RIS", + "SAO", + "SAU", + "SES", + "SET", + "SGO", + "SHH", + "SHZ", + "SIX", + "STO", + "STU", + "TAI", + "TAL", + "TLV", + "TSX", + "TSXV", + "TWO", + "VIE", + "WSE", + "XETRA", + ] + """ + Stock exchange the ticker trades on, used to disambiguate tickers listed on + multiple exchanges. + """ + + +class SearchByEntityNewsSearchEntityByIsin(TypedDict, total=False): + """Identify the company by International Securities Identification Number.""" + + isin: Required[str] + """International Securities Identification Number.""" + + type: Required[Literal["isin"]] + + +SearchByEntity: TypeAlias = Union[ + SearchByEntityNewsSearchEntityByName, + SearchByEntityNewsSearchEntityByDomain, + SearchByEntityNewsSearchEntityByTicker, + SearchByEntityNewsSearchEntityByIsin, +] + + +class SearchBy(TypedDict, total=False): + """What to search for.""" + + entity: Required[SearchByEntity] + """The company to search news for, identified by name, domain, ticker, or ISIN.""" + + type: Required[Literal["entity"]] + """How to search. Only entity search is supported.""" + + +_FilterByDateReservedKeywords = TypedDict( + "_FilterByDateReservedKeywords", + { + "from": int, + }, + total=False, +) + + +class FilterByDate(_FilterByDateReservedKeywords, total=False): + """Published-at window in epoch milliseconds.""" + + to: int + """Inclusive end of the published-at window, in epoch milliseconds.""" + + +class FilterBy(TypedDict, total=False): + """Optional result filters.""" + + article_language: Annotated[ + List[Literal["ar", "de", "en", "es", "fr", "hi", "it", "ja", "ko", "nl", "pt", "ru", "zh"]], + PropertyInfo(alias="articleLanguage"), + ] + """Article languages to include. Up to 3.""" + + article_type: Annotated[ + List[Literal["editorial", "press_release", "regulatory_filing", "advisory"]], PropertyInfo(alias="articleType") + ] + """Article types to include. Up to 3.""" + + date: FilterByDate + """Published-at window in epoch milliseconds.""" + + source_country: Annotated[ + List[ + Literal[ + "ae", + "ar", + "au", + "ca", + "cg", + "ch", + "cl", + "de", + "fi", + "fr", + "gb", + "hk", + "il", + "in", + "jp", + "kr", + "mx", + "ng", + "nl", + "qa", + "sa", + "se", + "sg", + "us", + "za", + ] + ], + PropertyInfo(alias="sourceCountry"), + ] + """Publisher countries to include, as lowercase ISO 3166-1 alpha-2 codes. Up to 3.""" + + source_domain: Annotated[SequenceNotStr[str], PropertyInfo(alias="sourceDomain")] + """Publisher domains to include. Up to 3.""" + + +class SortBy(TypedDict, total=False): + """Result ordering. Defaults to newest.""" + + type: Required[Literal["relevance", "newest"]] + """Result ordering.""" diff --git a/src/context/dev/types/news_search_response.py b/src/context/dev/types/news_search_response.py new file mode 100644 index 0000000..af82932 --- /dev/null +++ b/src/context/dev/types/news_search_response.py @@ -0,0 +1,85 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["NewsSearchResponse", "Data", "DataMatch", "DataSource", "Meta", "KeyMetadata"] + + +class DataMatch(BaseModel): + confidence: Optional[float] = None + + level: Literal["primary", "secondary"] + + +class DataSource(BaseModel): + direct: bool + """True when Context observed this article in the publisher-owned feed.""" + + domain: str + + name: str + + +class Data(BaseModel): + id: str + + authors: List[str] + + description: Optional[str] = None + + image_url: Optional[str] = None + + language: Optional[str] = None + + match: DataMatch + + published_at: Optional[datetime] = None + + source: DataSource + + story_id: str + """Groups matching normalized headlines published on the same UTC day.""" + + title: str + + type: Literal["editorial", "press_release", "regulatory_filing", "advisory"] + + url: str + + +class Meta(BaseModel): + count: int + + +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 NewsSearchResponse(BaseModel): + data: List[Data] + + has_more: bool + + meta: Meta + + next_cursor: Optional[str] = None + + 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/src/context/dev/types/parse_handle_params.py b/src/context/dev/types/parse_handle_params.py index 26676e1..7b34545 100644 --- a/src/context/dev/types/parse_handle_params.py +++ b/src/context/dev/types/parse_handle_params.py @@ -2,7 +2,6 @@ from __future__ import annotations -from typing import Union from typing_extensions import Literal, Annotated, TypedDict from .._types import SequenceNotStr @@ -92,13 +91,13 @@ class ParseHandleParams(TypedDict, total=False): md, py, rtf, jpg, png, or txt. """ - include_images: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="includeImages")] + include_images: Annotated[bool, PropertyInfo(alias="includeImages")] """Include image references in Markdown output""" - include_links: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="includeLinks")] + include_links: Annotated[bool, PropertyInfo(alias="includeLinks")] """Preserve hyperlinks in Markdown output""" - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true for PDF inputs, OCR the selected pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages @@ -110,7 +109,7 @@ class ParseHandleParams(TypedDict, total=False): pdf: Pdf """PDF page-range options as a JSON object, e.g. {"start": 2, "end": 5}.""" - shorten_base64_images: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shortenBase64Images")] + shorten_base64_images: Annotated[bool, PropertyInfo(alias="shortenBase64Images")] """Shorten base64-encoded image data in the Markdown output""" tags: SequenceNotStr[str] @@ -120,7 +119,7 @@ class ParseHandleParams(TypedDict, total=False): the dashboard usage page. Up to 20 tags, each 1-50 characters. """ - use_main_content_only: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="useMainContentOnly")] + use_main_content_only: Annotated[bool, PropertyInfo(alias="useMainContentOnly")] """Extract only the main content from HTML-like inputs""" zdr: Literal["enabled", "disabled"] diff --git a/src/context/dev/types/person_enrich_response.py b/src/context/dev/types/person_enrich_response.py index 34cc571..4b13b5a 100644 --- a/src/context/dev/types/person_enrich_response.py +++ b/src/context/dev/types/person_enrich_response.py @@ -163,6 +163,14 @@ class MatchPersonEnrichmentCandidateMatchPersonName(BaseModel): class MatchPersonEnrichmentCandidateMatchPerson(BaseModel): + current_role_status: Literal["present", "none", "unknown"] + """Whether the person's current role is known. + + `present` — current_role is populated. `none` — the work history explicitly + shows every role has ended. `unknown` — our data sources could not confirm + either way; treat a missing current_role as unverified rather than vacant. + """ + education: List[MatchPersonEnrichmentCandidateMatchPersonEducation] experience: List[MatchPersonEnrichmentCandidateMatchPersonExperience] @@ -177,10 +185,19 @@ class MatchPersonEnrichmentCandidateMatchPerson(BaseModel): bio: Optional[str] = None + checked_at: Optional[str] = None + """When we last refreshed this profile from our data sources (ISO 8601).""" + current_role: Optional[MatchPersonEnrichmentCandidateMatchPersonCurrentRole] = None email: Optional[str] = None + last_updated: Optional[str] = None + """When the underlying profile data last changed in our data sources (ISO 8601). + + Omitted when unknown. + """ + location: Optional[MatchPersonEnrichmentCandidateMatchPersonLocation] = None name: Optional[MatchPersonEnrichmentCandidateMatchPersonName] = None diff --git a/src/context/dev/types/utility_prefetch_params.py b/src/context/dev/types/utility_prefetch_params.py index 3e82039..d230252 100644 --- a/src/context/dev/types/utility_prefetch_params.py +++ b/src/context/dev/types/utility_prefetch_params.py @@ -18,10 +18,13 @@ class UtilityPrefetchParams(TypedDict, total=False): identifier: Required[Identifier] - """Identifier of the brand to prefetch. Provide exactly one of domain or email.""" + """Identifier of the target to prefetch. Provide exactly one of domain or email.""" - type: Required[Literal["brand"]] - """What to prefetch. Currently only 'brand' is supported.""" + type: Required[Literal["brand", "styleguide"]] + """ + What to prefetch: 'brand' warms the brand data cache, 'styleguide' warms the + styleguide cache. + """ tags: SequenceNotStr[str] """Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.""" @@ -35,17 +38,17 @@ class UtilityPrefetchParams(TypedDict, total=False): class IdentifierUtilityPrefetchDomainIdentifier(TypedDict, total=False): - """Prefetch brand data by domain.""" + """Prefetch by domain.""" domain: Required[str] - """Domain name to prefetch brand data for""" + """Domain name to prefetch data for""" class IdentifierUtilityPrefetchEmailIdentifier(TypedDict, total=False): - """Prefetch brand data by email. The domain will be extracted and validated.""" + """Prefetch by email. The domain will be extracted and validated.""" email: Required[str] - """Email address to prefetch brand data for. + """Email address to prefetch data for. The domain will be extracted from the email. Free email providers (gmail.com, yahoo.com, etc.) and disposable email addresses are not allowed. diff --git a/src/context/dev/types/utility_prefetch_response.py b/src/context/dev/types/utility_prefetch_response.py index 346abd0..8f9c3bb 100644 --- a/src/context/dev/types/utility_prefetch_response.py +++ b/src/context/dev/types/utility_prefetch_response.py @@ -38,8 +38,5 @@ class UtilityPrefetchResponse(BaseModel): status: Optional[str] = None """Status of the response, e.g., 'ok'""" - type: Optional[Literal["brand"]] = None - """ - The type of prefetch that was queued, echoed from the request (currently always - 'brand') - """ + type: Optional[Literal["brand", "styleguide"]] = None + """The type of prefetch that was queued, echoed from the request""" diff --git a/src/context/dev/types/web_screenshot_params.py b/src/context/dev/types/web_screenshot_params.py index 830e1a7..2442d70 100644 --- a/src/context/dev/types/web_screenshot_params.py +++ b/src/context/dev/types/web_screenshot_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Union, Optional +from typing import Optional from typing_extensions import Literal, Annotated, TypedDict from .._types import SequenceNotStr @@ -250,7 +250,7 @@ class WebScreenshotParams(TypedDict, total=False): provided, takes a viewport screenshot (standard browser view). """ - handle_cookie_popup: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="handleCookiePopup")] + handle_cookie_popup: Annotated[bool, PropertyInfo(alias="handleCookiePopup")] """Optional parameter to control cookie/consent popup handling. If 'true', we dismiss cookie banner before capture. If 'false' or not provided, diff --git a/src/context/dev/types/web_web_crawl_md_response.py b/src/context/dev/types/web_web_crawl_md_response.py index 6c8206d..6218a6c 100644 --- a/src/context/dev/types/web_web_crawl_md_response.py +++ b/src/context/dev/types/web_web_crawl_md_response.py @@ -6,7 +6,15 @@ from .._models import BaseModel -__all__ = ["WebWebCrawlMdResponse", "Metadata", "Result", "ResultMetadata", "ResultMetadataAlternate", "KeyMetadata"] +__all__ = [ + "WebWebCrawlMdResponse", + "Metadata", + "Result", + "ResultMetadata", + "ResultMetadataAlternate", + "ResultMetadataHeading", + "KeyMetadata", +] class Metadata(BaseModel): @@ -43,6 +51,14 @@ class ResultMetadataAlternate(BaseModel): """Alternate resource MIME type, when present.""" +class ResultMetadataHeading(BaseModel): + level: int + """Heading level, 1–6 (from h1–h6).""" + + text: str + """Heading text with whitespace collapsed, truncated to 1000 characters.""" + + class ResultMetadata(BaseModel): crawl_depth: int = FieldInfo(alias="crawlDepth") """Depth relative to the start URL. 0 = start URL, 1 = one link away.""" @@ -86,6 +102,12 @@ class ResultMetadata(BaseModel): favicon: Optional[str] = None """Resolved favicon URL, when present.""" + headings: Optional[List[ResultMetadataHeading]] = None + """Page headings (h1–h6) in document order, extracted from the unfiltered document. + + Capped at the first 500 headings. Omitted when the page has none. + """ + image: Optional[str] = None """Primary resolved preview image from Open Graph, Twitter, or image metadata.""" diff --git a/src/context/dev/types/web_web_scrape_html_params.py b/src/context/dev/types/web_web_scrape_html_params.py index 461974a..df85c86 100644 --- a/src/context/dev/types/web_web_scrape_html_params.py +++ b/src/context/dev/types/web_web_scrape_html_params.py @@ -247,7 +247,7 @@ class WebWebScrapeHTMLParams(TypedDict, total=False): is bypassed: the result is neither read from nor written to cache. """ - include_frames: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="includeFrames")] + include_frames: Annotated[bool, PropertyInfo(alias="includeFrames")] """When true, iframes are rendered inline into the returned HTML.""" include_selectors: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="includeSelectors")] @@ -272,7 +272,7 @@ class WebWebScrapeHTMLParams(TypedDict, total=False): inclusive 1-based page range. """ - settle_animations: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="settleAnimations")] + settle_animations: Annotated[bool, PropertyInfo(alias="settleAnimations")] """ When true, waits briefly for CSS and transition animations to settle before extracting HTML. Defaults to false. This adds a bit of latency in exchange for @@ -293,7 +293,7 @@ class WebWebScrapeHTMLParams(TypedDict, total=False): status code. Maximum allowed value is 300000ms (5 minutes). """ - use_main_content_only: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="useMainContentOnly")] + use_main_content_only: Annotated[bool, PropertyInfo(alias="useMainContentOnly")] """ When true, return only the page's main content in the HTML response, excluding headers, footers, sidebars, and navigation when detectable. @@ -346,7 +346,7 @@ class Pdf(TypedDict, total=False): start when both are provided. """ - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real @@ -354,7 +354,7 @@ class Pdf(TypedDict, total=False): of the base request cost. When false, no OCR runs. """ - should_parse: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shouldParse")] + should_parse: Annotated[bool, PropertyInfo(alias="shouldParse")] """When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned. diff --git a/src/context/dev/types/web_web_scrape_html_response.py b/src/context/dev/types/web_web_scrape_html_response.py index 6ea2dd9..2d92bc7 100644 --- a/src/context/dev/types/web_web_scrape_html_response.py +++ b/src/context/dev/types/web_web_scrape_html_response.py @@ -7,7 +7,14 @@ from .._models import BaseModel -__all__ = ["WebWebScrapeHTMLResponse", "Metadata", "MetadataAlternate", "ActionsApplied", "KeyMetadata"] +__all__ = [ + "WebWebScrapeHTMLResponse", + "Metadata", + "MetadataAlternate", + "MetadataHeading", + "ActionsApplied", + "KeyMetadata", +] class MetadataAlternate(BaseModel): @@ -24,6 +31,14 @@ class MetadataAlternate(BaseModel): """Alternate resource MIME type, when present.""" +class MetadataHeading(BaseModel): + level: int + """Heading level, 1–6 (from h1–h6).""" + + text: str + """Heading text with whitespace collapsed, truncated to 1000 characters.""" + + class Metadata(BaseModel): """Metadata extracted from the scraped page HTML.""" @@ -54,6 +69,12 @@ class Metadata(BaseModel): favicon: Optional[str] = None """Resolved favicon URL, when present.""" + headings: Optional[List[MetadataHeading]] = None + """Page headings (h1–h6) in document order, extracted from the unfiltered document. + + Capped at the first 500 headings. Omitted when the page has none. + """ + image: Optional[str] = None """Primary resolved preview image from Open Graph, Twitter, or image metadata.""" diff --git a/src/context/dev/types/web_web_scrape_images_params.py b/src/context/dev/types/web_web_scrape_images_params.py index b2fb384..952dc76 100644 --- a/src/context/dev/types/web_web_scrape_images_params.py +++ b/src/context/dev/types/web_web_scrape_images_params.py @@ -28,7 +28,7 @@ class WebWebScrapeImagesParams(TypedDict, total=False): parameter. Maximum: 5 actions. """ - dedupe: Union[bool, Literal["true", "false"]] + dedupe: bool """ When true, visually duplicate images are removed: every image is loaded and perceptually hashed, and only the highest-resolution copy of each duplicate @@ -101,10 +101,10 @@ class Enrichment(TypedDict, total=False): Optional per-image processing, sent as deep-object query params such as enrichment[resolution]=true. """ - classification: Union[bool, Literal["true", "false"]] + classification: bool """Classify each image by visual asset type.""" - hosted_url: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="hostedUrl")] + hosted_url: Annotated[bool, PropertyInfo(alias="hostedUrl")] """ Host materializable images on the Brand.dev CDN and return their URL and MIME type. @@ -113,5 +113,5 @@ class Enrichment(TypedDict, total=False): max_time_per_ms: Annotated[int, PropertyInfo(alias="maxTimePerMs")] """Per-image enrichment timeout in milliseconds. Default: 30000. Maximum: 60000.""" - resolution: Union[bool, Literal["true", "false"]] + resolution: bool """Measure image width and height when possible.""" diff --git a/src/context/dev/types/web_web_scrape_md_params.py b/src/context/dev/types/web_web_scrape_md_params.py index 11b56f1..e655fd6 100644 --- a/src/context/dev/types/web_web_scrape_md_params.py +++ b/src/context/dev/types/web_web_scrape_md_params.py @@ -250,13 +250,20 @@ class WebWebScrapeMdParams(TypedDict, total=False): is bypassed: the result is neither read from nor written to cache. """ - include_frames: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="includeFrames")] + include_frames: Annotated[bool, PropertyInfo(alias="includeFrames")] """When true, the contents of iframes are rendered to Markdown.""" - include_images: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="includeImages")] + include_html: Annotated[bool, PropertyInfo(alias="includeHTML")] + """ + When true, the response also includes an `html` field with the page HTML the + Markdown was converted from — the same body the Scrape HTML endpoint returns for + the equivalent request. + """ + + include_images: Annotated[bool, PropertyInfo(alias="includeImages")] """Include image references in Markdown output""" - include_links: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="includeLinks")] + include_links: Annotated[bool, PropertyInfo(alias="includeLinks")] """Preserve hyperlinks in Markdown output""" include_selectors: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="includeSelectors")] @@ -281,14 +288,14 @@ class WebWebScrapeMdParams(TypedDict, total=False): inclusive 1-based page range. """ - settle_animations: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="settleAnimations")] + settle_animations: Annotated[bool, PropertyInfo(alias="settleAnimations")] """ When true, waits briefly for CSS and transition animations to settle before converting to Markdown. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages. """ - shorten_base64_images: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shortenBase64Images")] + shorten_base64_images: Annotated[bool, PropertyInfo(alias="shortenBase64Images")] """Shorten base64-encoded image data in the Markdown output""" tags: SequenceNotStr[str] @@ -305,7 +312,7 @@ class WebWebScrapeMdParams(TypedDict, total=False): status code. Maximum allowed value is 300000ms (5 minutes). """ - use_main_content_only: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="useMainContentOnly")] + use_main_content_only: Annotated[bool, PropertyInfo(alias="useMainContentOnly")] """ Extract only the main content of the page, excluding headers, footers, sidebars, and navigation @@ -358,7 +365,7 @@ class Pdf(TypedDict, total=False): start when both are provided. """ - ocr: Union[bool, Literal["true", "false"]] + ocr: bool """ When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real @@ -366,7 +373,7 @@ class Pdf(TypedDict, total=False): of the base request cost. When false, no OCR runs. """ - should_parse: Annotated[Union[bool, Literal["true", "false"]], PropertyInfo(alias="shouldParse")] + should_parse: Annotated[bool, PropertyInfo(alias="shouldParse")] """When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned. diff --git a/src/context/dev/types/web_web_scrape_md_response.py b/src/context/dev/types/web_web_scrape_md_response.py index e02866b..2ea9747 100644 --- a/src/context/dev/types/web_web_scrape_md_response.py +++ b/src/context/dev/types/web_web_scrape_md_response.py @@ -7,7 +7,14 @@ from .._models import BaseModel -__all__ = ["WebWebScrapeMdResponse", "Metadata", "MetadataAlternate", "ActionsApplied", "KeyMetadata"] +__all__ = [ + "WebWebScrapeMdResponse", + "Metadata", + "MetadataAlternate", + "MetadataHeading", + "ActionsApplied", + "KeyMetadata", +] class MetadataAlternate(BaseModel): @@ -24,6 +31,14 @@ class MetadataAlternate(BaseModel): """Alternate resource MIME type, when present.""" +class MetadataHeading(BaseModel): + level: int + """Heading level, 1–6 (from h1–h6).""" + + text: str + """Heading text with whitespace collapsed, truncated to 1000 characters.""" + + class Metadata(BaseModel): """Metadata extracted from the scraped page HTML.""" @@ -54,6 +69,12 @@ class Metadata(BaseModel): favicon: Optional[str] = None """Resolved favicon URL, when present.""" + headings: Optional[List[MetadataHeading]] = None + """Page headings (h1–h6) in document order, extracted from the unfiltered document. + + Capped at the first 500 headings. Omitted when the page has none. + """ + image: Optional[str] = None """Primary resolved preview image from Open Graph, Twitter, or image metadata.""" @@ -151,6 +172,13 @@ class WebWebScrapeMdResponse(BaseModel): afterward. """ + html: Optional[str] = None + """ + Only present when includeHTML=true: the page HTML the Markdown was converted + from — the same body the Scrape HTML endpoint returns for the equivalent + request. + """ + key_metadata: Optional[KeyMetadata] = None """Metadata about the API key used for the request. diff --git a/tests/api_resources/test_batch.py b/tests/api_resources/test_batch.py index 0691496..9e91446 100644 --- a/tests/api_resources/test_batch.py +++ b/tests/api_resources/test_batch.py @@ -282,14 +282,15 @@ def test_method_submit_with_all_params(self, client: ContextDev) -> None: "options": { "country": "de", "exclude_selectors": ["x"], + "include_html": True, "include_images": True, "include_links": True, "include_selectors": ["x"], "max_age_ms": 0, "pdf": { "end": 1, - "ocr": "true", - "should_parse": "true", + "ocr": True, + "should_parse": True, "start": 1, }, "settle_animations": True, @@ -614,14 +615,15 @@ async def test_method_submit_with_all_params(self, async_client: AsyncContextDev "options": { "country": "de", "exclude_selectors": ["x"], + "include_html": True, "include_images": True, "include_links": True, "include_selectors": ["x"], "max_age_ms": 0, "pdf": { "end": 1, - "ocr": "true", - "should_parse": "true", + "ocr": True, + "should_parse": True, "start": 1, }, "settle_animations": True, diff --git a/tests/api_resources/test_brand.py b/tests/api_resources/test_brand.py index d0912d0..c2321c3 100644 --- a/tests/api_resources/test_brand.py +++ b/tests/api_resources/test_brand.py @@ -389,7 +389,10 @@ def test_method_search(self, client: ContextDev) -> None: def test_method_search_with_all_params(self, client: ContextDev) -> None: brand = client.brand.search( query="x", + autocomplete=True, + query_by=["name"], tags=["production", "team-alpha"], + typo_tolerance=0, ) assert_matches_type(BrandSearchResponse, brand, path=["response"]) @@ -793,7 +796,10 @@ async def test_method_search(self, async_client: AsyncContextDev) -> None: async def test_method_search_with_all_params(self, async_client: AsyncContextDev) -> None: brand = await async_client.brand.search( query="x", + autocomplete=True, + query_by=["name"], tags=["production", "team-alpha"], + typo_tolerance=0, ) assert_matches_type(BrandSearchResponse, brand, path=["response"]) diff --git a/tests/api_resources/test_news.py b/tests/api_resources/test_news.py new file mode 100644 index 0000000..16c0a1d --- /dev/null +++ b/tests/api_resources/test_news.py @@ -0,0 +1,184 @@ +# 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 context.dev import ContextDev, AsyncContextDev +from tests.utils import assert_matches_type +from context.dev.types import NewsSearchResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestNews: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_search(self, client: ContextDev) -> None: + news = client.news.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + ) + assert_matches_type(NewsSearchResponse, news, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_search_with_all_params(self, client: ContextDev) -> None: + news = client.news.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + cursor="cursor", + filter_by={ + "article_language": ["ar"], + "article_type": ["editorial"], + "date": { + "from": 0, + "to": 0, + }, + "source_country": ["ae"], + "source_domain": ["x"], + }, + limit=1, + sort_by={"type": "relevance"}, + tags=["production", "team-alpha"], + ) + assert_matches_type(NewsSearchResponse, news, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_search(self, client: ContextDev) -> None: + response = client.news.with_raw_response.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + news = response.parse() + assert_matches_type(NewsSearchResponse, news, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_search(self, client: ContextDev) -> None: + with client.news.with_streaming_response.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + news = response.parse() + assert_matches_type(NewsSearchResponse, news, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncNews: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_search(self, async_client: AsyncContextDev) -> None: + news = await async_client.news.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + ) + assert_matches_type(NewsSearchResponse, news, 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: + news = await async_client.news.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + cursor="cursor", + filter_by={ + "article_language": ["ar"], + "article_type": ["editorial"], + "date": { + "from": 0, + "to": 0, + }, + "source_country": ["ae"], + "source_domain": ["x"], + }, + limit=1, + sort_by={"type": "relevance"}, + tags=["production", "team-alpha"], + ) + assert_matches_type(NewsSearchResponse, news, 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.news.with_raw_response.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + news = await response.parse() + assert_matches_type(NewsSearchResponse, news, 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.news.with_streaming_response.search( + search_by={ + "entity": { + "name": "xx", + "type": "name", + }, + "type": "entity", + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + news = await response.parse() + assert_matches_type(NewsSearchResponse, news, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_parse.py b/tests/api_resources/test_parse.py index d42c128..006aede 100644 --- a/tests/api_resources/test_parse.py +++ b/tests/api_resources/test_parse.py @@ -32,16 +32,16 @@ def test_method_handle_with_all_params(self, client: ContextDev) -> None: body=b"Example data", client="x", extension="txt", - include_images="true", - include_links="true", - ocr="true", + include_images=True, + include_links=True, + ocr=True, pdf={ "end": 1, "start": 1, }, - shorten_base64_images="true", + shorten_base64_images=True, tags=["production", "team-alpha"], - use_main_content_only="true", + use_main_content_only=True, zdr="enabled", ) assert_matches_type(ParseHandleResponse, parse, path=["response"]) @@ -93,16 +93,16 @@ async def test_method_handle_with_all_params(self, async_client: AsyncContextDev body=b"Example data", client="x", extension="txt", - include_images="true", - include_links="true", - ocr="true", + include_images=True, + include_links=True, + ocr=True, pdf={ "end": 1, "start": 1, }, - shorten_base64_images="true", + shorten_base64_images=True, tags=["production", "team-alpha"], - use_main_content_only="true", + use_main_content_only=True, zdr="enabled", ) assert_matches_type(ParseHandleResponse, parse, path=["response"]) diff --git a/tests/api_resources/test_web.py b/tests/api_resources/test_web.py index b873aab..724e013 100644 --- a/tests/api_resources/test_web.py +++ b/tests/api_resources/test_web.py @@ -253,7 +253,7 @@ def test_method_screenshot_with_all_params(self, client: ContextDev) -> None: direct_url="https://example.com", domain="xxx", full_screenshot="true", - handle_cookie_popup="true", + handle_cookie_popup=True, max_age_ms=0, page="login", scroll_offset=0, @@ -445,19 +445,19 @@ def test_method_web_scrape_html_with_all_params(self, client: ContextDev) -> Non country="de", exclude_selectors=["x"], headers={"foo": "J!"}, - include_frames="true", + include_frames=True, include_selectors=["x"], max_age_ms=0, pdf={ "end": 1, - "ocr": "true", - "should_parse": "true", + "ocr": True, + "should_parse": True, "start": 1, }, - settle_animations="true", + settle_animations=True, tags=["production", "team-alpha"], timeout_ms=1, - use_main_content_only="true", + use_main_content_only=True, wait_for_ms=0, zdr="enabled", ) @@ -508,12 +508,12 @@ def test_method_web_scrape_images_with_all_params(self, client: ContextDev) -> N "time_ms": 0, } ], - dedupe="true", + dedupe=True, enrichment={ - "classification": "true", - "hosted_url": "true", + "classification": True, + "hosted_url": True, "max_time_per_ms": 1, - "resolution": "true", + "resolution": True, }, headers={"foo": "J!"}, max_age_ms=0, @@ -571,22 +571,23 @@ def test_method_web_scrape_md_with_all_params(self, client: ContextDev) -> None: country="de", exclude_selectors=["x"], headers={"foo": "J!"}, - include_frames="true", - include_images="true", - include_links="true", + include_frames=True, + include_html=True, + include_images=True, + include_links=True, include_selectors=["x"], max_age_ms=0, pdf={ "end": 1, - "ocr": "true", - "should_parse": "true", + "ocr": True, + "should_parse": True, "start": 1, }, - settle_animations="true", - shorten_base64_images="true", + settle_animations=True, + shorten_base64_images=True, tags=["production", "team-alpha"], timeout_ms=1, - use_main_content_only="true", + use_main_content_only=True, wait_for_ms=0, zdr="enabled", ) @@ -898,7 +899,7 @@ async def test_method_screenshot_with_all_params(self, async_client: AsyncContex direct_url="https://example.com", domain="xxx", full_screenshot="true", - handle_cookie_popup="true", + handle_cookie_popup=True, max_age_ms=0, page="login", scroll_offset=0, @@ -1090,19 +1091,19 @@ async def test_method_web_scrape_html_with_all_params(self, async_client: AsyncC country="de", exclude_selectors=["x"], headers={"foo": "J!"}, - include_frames="true", + include_frames=True, include_selectors=["x"], max_age_ms=0, pdf={ "end": 1, - "ocr": "true", - "should_parse": "true", + "ocr": True, + "should_parse": True, "start": 1, }, - settle_animations="true", + settle_animations=True, tags=["production", "team-alpha"], timeout_ms=1, - use_main_content_only="true", + use_main_content_only=True, wait_for_ms=0, zdr="enabled", ) @@ -1153,12 +1154,12 @@ async def test_method_web_scrape_images_with_all_params(self, async_client: Asyn "time_ms": 0, } ], - dedupe="true", + dedupe=True, enrichment={ - "classification": "true", - "hosted_url": "true", + "classification": True, + "hosted_url": True, "max_time_per_ms": 1, - "resolution": "true", + "resolution": True, }, headers={"foo": "J!"}, max_age_ms=0, @@ -1216,22 +1217,23 @@ async def test_method_web_scrape_md_with_all_params(self, async_client: AsyncCon country="de", exclude_selectors=["x"], headers={"foo": "J!"}, - include_frames="true", - include_images="true", - include_links="true", + include_frames=True, + include_html=True, + include_images=True, + include_links=True, include_selectors=["x"], max_age_ms=0, pdf={ "end": 1, - "ocr": "true", - "should_parse": "true", + "ocr": True, + "should_parse": True, "start": 1, }, - settle_animations="true", - shorten_base64_images="true", + settle_animations=True, + shorten_base64_images=True, tags=["production", "team-alpha"], timeout_ms=1, - use_main_content_only="true", + use_main_content_only=True, wait_for_ms=0, zdr="enabled", )