From 1c5aeb4aa561ed414ce36dd70455799e8674f04d Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 29 Jun 2026 05:36:21 +0000
Subject: [PATCH 01/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 5bb2078..0a0c76c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 25
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-021b48afe1d6e3f54c4ebe3d0da4beb3fb8b69a6d384a4aeadbc5bab7f967603.yml
-openapi_spec_hash: 2aa5b59d78c708b094acf29cc0d9a68a
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-d04e3c285c2f57723b288ee69b1d78b7bb928aae403203b2cdd524dd195e55b2.yml
+openapi_spec_hash: e33db883d584bc8573897391f3edb105
config_hash: c7b0cdaba3b9797b77efd89e1754d803
From f80c3061d969b6650d9f5a2f9df5ca8f371e14d7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 29 Jun 2026 05:41:56 +0000
Subject: [PATCH 02/18] feat(api): manual updates
---
.stats.yml | 6 +-
api.md | 34 +
src/context/dev/_client.py | 57 +-
src/context/dev/resources/__init__.py | 14 +
src/context/dev/resources/monitors.py | 1633 ++++++++++++++++
src/context/dev/types/__init__.py | 20 +
.../dev/types/monitor_create_params.py | 323 ++++
.../dev/types/monitor_create_response.py | 413 ++++
.../dev/types/monitor_delete_response.py | 11 +
.../monitor_list_account_changes_params.py | 30 +
.../monitor_list_account_changes_response.py | 130 ++
.../types/monitor_list_account_runs_params.py | 15 +
.../monitor_list_account_runs_response.py | 54 +
.../dev/types/monitor_list_changes_params.py | 24 +
.../types/monitor_list_changes_response.py | 130 ++
src/context/dev/types/monitor_list_params.py | 22 +
.../dev/types/monitor_list_response.py | 425 ++++
.../dev/types/monitor_list_runs_params.py | 15 +
.../dev/types/monitor_list_runs_response.py | 54 +
.../types/monitor_retrieve_change_response.py | 159 ++
.../dev/types/monitor_retrieve_response.py | 413 ++++
src/context/dev/types/monitor_run_response.py | 11 +
.../dev/types/monitor_update_params.py | 147 ++
.../dev/types/monitor_update_response.py | 413 ++++
tests/api_resources/test_monitors.py | 1713 +++++++++++++++++
25 files changed, 6262 insertions(+), 4 deletions(-)
create mode 100644 src/context/dev/resources/monitors.py
create mode 100644 src/context/dev/types/monitor_create_params.py
create mode 100644 src/context/dev/types/monitor_create_response.py
create mode 100644 src/context/dev/types/monitor_delete_response.py
create mode 100644 src/context/dev/types/monitor_list_account_changes_params.py
create mode 100644 src/context/dev/types/monitor_list_account_changes_response.py
create mode 100644 src/context/dev/types/monitor_list_account_runs_params.py
create mode 100644 src/context/dev/types/monitor_list_account_runs_response.py
create mode 100644 src/context/dev/types/monitor_list_changes_params.py
create mode 100644 src/context/dev/types/monitor_list_changes_response.py
create mode 100644 src/context/dev/types/monitor_list_params.py
create mode 100644 src/context/dev/types/monitor_list_response.py
create mode 100644 src/context/dev/types/monitor_list_runs_params.py
create mode 100644 src/context/dev/types/monitor_list_runs_response.py
create mode 100644 src/context/dev/types/monitor_retrieve_change_response.py
create mode 100644 src/context/dev/types/monitor_retrieve_response.py
create mode 100644 src/context/dev/types/monitor_run_response.py
create mode 100644 src/context/dev/types/monitor_update_params.py
create mode 100644 src/context/dev/types/monitor_update_response.py
create mode 100644 tests/api_resources/test_monitors.py
diff --git a/.stats.yml b/.stats.yml
index 0a0c76c..2f86aeb 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 25
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-d04e3c285c2f57723b288ee69b1d78b7bb928aae403203b2cdd524dd195e55b2.yml
+configured_endpoints: 36
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-8667763c416101820f5086c97d542bf13bb3bb12b57f5f604da671d9dcea0599.yml
openapi_spec_hash: e33db883d584bc8573897391f3edb105
-config_hash: c7b0cdaba3b9797b77efd89e1754d803
+config_hash: 7ec4851ee8d93177947e95df5ae897b5
diff --git a/api.md b/api.md
index 640d179..f31fb8a 100644
--- a/api.md
+++ b/api.md
@@ -97,3 +97,37 @@ Methods:
- client.utility.prefetch(\*\*params) -> UtilityPrefetchResponse
- client.utility.prefetch_by_email(\*\*params) -> UtilityPrefetchByEmailResponse
+
+# Monitors
+
+Types:
+
+```python
+from context.dev.types import (
+ MonitorCreateResponse,
+ MonitorRetrieveResponse,
+ MonitorUpdateResponse,
+ MonitorListResponse,
+ MonitorDeleteResponse,
+ MonitorListAccountChangesResponse,
+ MonitorListAccountRunsResponse,
+ MonitorListChangesResponse,
+ MonitorListRunsResponse,
+ MonitorRetrieveChangeResponse,
+ MonitorRunResponse,
+)
+```
+
+Methods:
+
+- client.monitors.create(\*\*params) -> MonitorCreateResponse
+- client.monitors.retrieve(monitor_id) -> MonitorRetrieveResponse
+- client.monitors.update(monitor_id, \*\*params) -> MonitorUpdateResponse
+- client.monitors.list(\*\*params) -> MonitorListResponse
+- client.monitors.delete(monitor_id) -> MonitorDeleteResponse
+- client.monitors.list_account_changes(\*\*params) -> MonitorListAccountChangesResponse
+- client.monitors.list_account_runs(\*\*params) -> MonitorListAccountRunsResponse
+- client.monitors.list_changes(monitor_id, \*\*params) -> MonitorListChangesResponse
+- client.monitors.list_runs(monitor_id, \*\*params) -> MonitorListRunsResponse
+- client.monitors.retrieve_change(change_id) -> MonitorRetrieveChangeResponse
+- client.monitors.run(monitor_id) -> MonitorRunResponse
diff --git a/src/context/dev/_client.py b/src/context/dev/_client.py
index 511e025..e0b4af5 100644
--- a/src/context/dev/_client.py
+++ b/src/context/dev/_client.py
@@ -35,12 +35,13 @@
)
if TYPE_CHECKING:
- from .resources import ai, web, brand, utility, industry
+ from .resources import ai, web, brand, utility, industry, monitors
from .resources.ai import AIResource, AsyncAIResource
from .resources.web import WebResource, AsyncWebResource
from .resources.brand import BrandResource, AsyncBrandResource
from .resources.utility import UtilityResource, AsyncUtilityResource
from .resources.industry import IndustryResource, AsyncIndustryResource
+ from .resources.monitors import MonitorsResource, AsyncMonitorsResource
__all__ = [
"Timeout",
@@ -148,6 +149,15 @@ def utility(self) -> UtilityResource:
return UtilityResource(self)
+ @cached_property
+ def monitors(self) -> MonitorsResource:
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+ from .resources.monitors import MonitorsResource
+
+ return MonitorsResource(self)
+
@cached_property
def with_raw_response(self) -> ContextDevWithRawResponse:
return ContextDevWithRawResponse(self)
@@ -355,6 +365,15 @@ def utility(self) -> AsyncUtilityResource:
return AsyncUtilityResource(self)
+ @cached_property
+ def monitors(self) -> AsyncMonitorsResource:
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+ from .resources.monitors import AsyncMonitorsResource
+
+ return AsyncMonitorsResource(self)
+
@cached_property
def with_raw_response(self) -> AsyncContextDevWithRawResponse:
return AsyncContextDevWithRawResponse(self)
@@ -504,6 +523,15 @@ def utility(self) -> utility.UtilityResourceWithRawResponse:
return UtilityResourceWithRawResponse(self._client.utility)
+ @cached_property
+ def monitors(self) -> monitors.MonitorsResourceWithRawResponse:
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+ from .resources.monitors import MonitorsResourceWithRawResponse
+
+ return MonitorsResourceWithRawResponse(self._client.monitors)
+
class AsyncContextDevWithRawResponse:
_client: AsyncContextDev
@@ -541,6 +569,15 @@ def utility(self) -> utility.AsyncUtilityResourceWithRawResponse:
return AsyncUtilityResourceWithRawResponse(self._client.utility)
+ @cached_property
+ def monitors(self) -> monitors.AsyncMonitorsResourceWithRawResponse:
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+ from .resources.monitors import AsyncMonitorsResourceWithRawResponse
+
+ return AsyncMonitorsResourceWithRawResponse(self._client.monitors)
+
class ContextDevWithStreamedResponse:
_client: ContextDev
@@ -578,6 +615,15 @@ def utility(self) -> utility.UtilityResourceWithStreamingResponse:
return UtilityResourceWithStreamingResponse(self._client.utility)
+ @cached_property
+ def monitors(self) -> monitors.MonitorsResourceWithStreamingResponse:
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+ from .resources.monitors import MonitorsResourceWithStreamingResponse
+
+ return MonitorsResourceWithStreamingResponse(self._client.monitors)
+
class AsyncContextDevWithStreamedResponse:
_client: AsyncContextDev
@@ -615,6 +661,15 @@ def utility(self) -> utility.AsyncUtilityResourceWithStreamingResponse:
return AsyncUtilityResourceWithStreamingResponse(self._client.utility)
+ @cached_property
+ def monitors(self) -> monitors.AsyncMonitorsResourceWithStreamingResponse:
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+ from .resources.monitors import AsyncMonitorsResourceWithStreamingResponse
+
+ return AsyncMonitorsResourceWithStreamingResponse(self._client.monitors)
+
Client = ContextDev
diff --git a/src/context/dev/resources/__init__.py b/src/context/dev/resources/__init__.py
index edc5356..b0af419 100644
--- a/src/context/dev/resources/__init__.py
+++ b/src/context/dev/resources/__init__.py
@@ -40,6 +40,14 @@
IndustryResourceWithStreamingResponse,
AsyncIndustryResourceWithStreamingResponse,
)
+from .monitors import (
+ MonitorsResource,
+ AsyncMonitorsResource,
+ MonitorsResourceWithRawResponse,
+ AsyncMonitorsResourceWithRawResponse,
+ MonitorsResourceWithStreamingResponse,
+ AsyncMonitorsResourceWithStreamingResponse,
+)
__all__ = [
"WebResource",
@@ -72,4 +80,10 @@
"AsyncUtilityResourceWithRawResponse",
"UtilityResourceWithStreamingResponse",
"AsyncUtilityResourceWithStreamingResponse",
+ "MonitorsResource",
+ "AsyncMonitorsResource",
+ "MonitorsResourceWithRawResponse",
+ "AsyncMonitorsResourceWithRawResponse",
+ "MonitorsResourceWithStreamingResponse",
+ "AsyncMonitorsResourceWithStreamingResponse",
]
diff --git a/src/context/dev/resources/monitors.py b/src/context/dev/resources/monitors.py
new file mode 100644
index 0000000..1eb37cb
--- /dev/null
+++ b/src/context/dev/resources/monitors.py
@@ -0,0 +1,1633 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Any, Union, Optional, cast
+from datetime import datetime
+from typing_extensions import Literal, overload
+
+import httpx
+
+from ..types import (
+ monitor_list_params,
+ monitor_create_params,
+ monitor_update_params,
+ monitor_list_runs_params,
+ monitor_list_changes_params,
+ monitor_list_account_runs_params,
+ monitor_list_account_changes_params,
+)
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from .._utils import path_template, required_args, 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.monitor_run_response import MonitorRunResponse
+from ..types.monitor_list_response import MonitorListResponse
+from ..types.monitor_create_response import MonitorCreateResponse
+from ..types.monitor_delete_response import MonitorDeleteResponse
+from ..types.monitor_update_response import MonitorUpdateResponse
+from ..types.monitor_retrieve_response import MonitorRetrieveResponse
+from ..types.monitor_list_runs_response import MonitorListRunsResponse
+from ..types.monitor_list_changes_response import MonitorListChangesResponse
+from ..types.monitor_retrieve_change_response import MonitorRetrieveChangeResponse
+from ..types.monitor_list_account_runs_response import MonitorListAccountRunsResponse
+from ..types.monitor_list_account_changes_response import MonitorListAccountChangesResponse
+
+__all__ = ["MonitorsResource", "AsyncMonitorsResource"]
+
+
+class MonitorsResource(SyncAPIResource):
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> MonitorsResourceWithRawResponse:
+ """
+ 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 MonitorsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> MonitorsResourceWithStreamingResponse:
+ """
+ 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 MonitorsResourceWithStreamingResponse(self)
+
+ @overload
+ def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect exact changes. For page targets, this means visible text diffs. For
+ sitemap targets, this means URL additions and removals.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @overload
+ def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect exact changes. For page targets, this means visible text diffs. For
+ sitemap targets, this means URL additions and removals.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @overload
+ def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect meaning-level changes that match a natural language query.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @overload
+ def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect meaning-level changes that match a natural language query.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @required_args(["change_detection", "name", "schedule", "target"])
+ def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection
+ | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection
+ | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection
+ | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule
+ | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule
+ | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule
+ | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget
+ | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget
+ | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget
+ | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook]
+ | Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook]
+ | Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook]
+ | Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook]
+ | 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,
+ ) -> MonitorCreateResponse:
+ return cast(
+ MonitorCreateResponse,
+ self._post(
+ "/monitors",
+ body=maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "target": target,
+ "tags": tags,
+ "webhook": webhook,
+ },
+ monitor_create_params.MonitorCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorCreateResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def retrieve(
+ self,
+ monitor_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorRetrieveResponse:
+ """
+ Get a monitor
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return cast(
+ MonitorRetrieveResponse,
+ self._get(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorRetrieveResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def update(
+ self,
+ monitor_id: str,
+ *,
+ change_detection: monitor_update_params.ChangeDetection | Omit = omit,
+ name: str | Omit = omit,
+ schedule: monitor_update_params.Schedule | Omit = omit,
+ status: Literal["active", "paused"] | Omit = omit,
+ tags: SequenceNotStr[str] | Omit = omit,
+ target: monitor_update_params.Target | Omit = omit,
+ webhook: Optional[monitor_update_params.Webhook] | 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,
+ ) -> MonitorUpdateResponse:
+ """Updates a monitor.
+
+ If `target` or `change_detection` changes, the monitor
+ creates a new baseline. Unsupported target/change detection combinations are
+ rejected.
+
+ Args:
+ change_detection: Discriminated union describing how changes are detected.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ target: Discriminated union describing what the monitor watches.
+
+ webhook: Set to null to remove the webhook.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return cast(
+ MonitorUpdateResponse,
+ self._patch(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ body=maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "status": status,
+ "tags": tags,
+ "target": target,
+ "webhook": webhook,
+ },
+ monitor_update_params.MonitorUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorUpdateResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def list(
+ self,
+ *,
+ change_detection_type: Literal["exact", "semantic"] | Omit = omit,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ status: Literal["active", "paused", "failed"] | Omit = omit,
+ tag: str | Omit = omit,
+ target_type: Literal["page", "sitemap", "extract"] | 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,
+ ) -> MonitorListResponse:
+ """
+ List monitors
+
+ Args:
+ tag: Filter to items that have this tag.
+
+ 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(
+ "/monitors",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "change_detection_type": change_detection_type,
+ "cursor": cursor,
+ "limit": limit,
+ "status": status,
+ "tag": tag,
+ "target_type": target_type,
+ },
+ monitor_list_params.MonitorListParams,
+ ),
+ ),
+ cast_to=MonitorListResponse,
+ )
+
+ def delete(
+ self,
+ monitor_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorDeleteResponse:
+ """
+ Delete a monitor
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return self._delete(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MonitorDeleteResponse,
+ )
+
+ def list_account_changes(
+ self,
+ *,
+ change_detection_type: Literal["exact", "semantic"] | Omit = omit,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ monitor_id: str | Omit = omit,
+ since: Union[str, datetime] | Omit = omit,
+ tag: str | Omit = omit,
+ target_type: Literal["page", "sitemap", "extract"] | Omit = omit,
+ until: Union[str, datetime] | 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,
+ ) -> MonitorListAccountChangesResponse:
+ """
+ Returns an account-wide feed of detected changes across monitors.
+
+ Args:
+ tag: Filter to items that have this tag.
+
+ 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(
+ "/monitors/changes",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "change_detection_type": change_detection_type,
+ "cursor": cursor,
+ "limit": limit,
+ "monitor_id": monitor_id,
+ "since": since,
+ "tag": tag,
+ "target_type": target_type,
+ "until": until,
+ },
+ monitor_list_account_changes_params.MonitorListAccountChangesParams,
+ ),
+ ),
+ cast_to=MonitorListAccountChangesResponse,
+ )
+
+ def list_account_runs(
+ self,
+ *,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed"] | 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,
+ ) -> MonitorListAccountRunsResponse:
+ """
+ Returns an account-wide feed of monitor runs across all monitors.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get(
+ "/monitors/runs",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ "status": status,
+ },
+ monitor_list_account_runs_params.MonitorListAccountRunsParams,
+ ),
+ ),
+ cast_to=MonitorListAccountRunsResponse,
+ )
+
+ def list_changes(
+ self,
+ monitor_id: str,
+ *,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ since: Union[str, datetime] | Omit = omit,
+ tag: str | Omit = omit,
+ until: Union[str, datetime] | 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,
+ ) -> MonitorListChangesResponse:
+ """
+ List changes for a monitor
+
+ Args:
+ tag: Filter to items that have this tag.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return self._get(
+ path_template("/monitors/{monitor_id}/changes", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ "since": since,
+ "tag": tag,
+ "until": until,
+ },
+ monitor_list_changes_params.MonitorListChangesParams,
+ ),
+ ),
+ cast_to=MonitorListChangesResponse,
+ )
+
+ def list_runs(
+ self,
+ monitor_id: str,
+ *,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed"] | 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,
+ ) -> MonitorListRunsResponse:
+ """
+ List monitor runs
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return self._get(
+ path_template("/monitors/{monitor_id}/runs", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ "status": status,
+ },
+ monitor_list_runs_params.MonitorListRunsParams,
+ ),
+ ),
+ cast_to=MonitorListRunsResponse,
+ )
+
+ def retrieve_change(
+ self,
+ change_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorRetrieveChangeResponse:
+ """
+ Get a change
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not change_id:
+ raise ValueError(f"Expected a non-empty value for `change_id` but received {change_id!r}")
+ return cast(
+ MonitorRetrieveChangeResponse,
+ self._get(
+ path_template("/monitors/changes/{change_id}", change_id=change_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorRetrieveChangeResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def run(
+ self,
+ monitor_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorRunResponse:
+ """Triggers an immediate run of the monitor outside its normal schedule.
+
+ The run is
+ queued and processed asynchronously.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return self._post(
+ path_template("/monitors/{monitor_id}/run", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MonitorRunResponse,
+ )
+
+
+class AsyncMonitorsResource(AsyncAPIResource):
+ """
+ Monitor pages, sitemaps, and extracted website data for exact or semantic changes. The change.detected webhook payload is documented by the MonitorsChangeDetectedWebhookPayload schema.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncMonitorsResourceWithRawResponse:
+ """
+ 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 AsyncMonitorsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncMonitorsResourceWithStreamingResponse:
+ """
+ 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 AsyncMonitorsResourceWithStreamingResponse(self)
+
+ @overload
+ async def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect exact changes. For page targets, this means visible text diffs. For
+ sitemap targets, this means URL additions and removals.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @overload
+ async def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect exact changes. For page targets, this means visible text diffs. For
+ sitemap targets, this means URL additions and removals.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @overload
+ async def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect meaning-level changes that match a natural language query.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @overload
+ async def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook] | 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,
+ ) -> MonitorCreateResponse:
+ """Creates a monitor.
+
+ The request body is a union of the supported target/change
+ detection combinations. The monitor runs immediately after creation to create
+ its initial baseline.
+
+ Args:
+ change_detection: Detect meaning-level changes that match a natural language query.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ 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
+ """
+ ...
+
+ @required_args(["change_detection", "name", "schedule", "target"])
+ async def create(
+ self,
+ *,
+ change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection
+ | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection
+ | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection
+ | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
+ name: str,
+ schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule
+ | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule
+ | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule
+ | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
+ target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget
+ | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget
+ | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget
+ | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
+ tags: SequenceNotStr[str] | Omit = omit,
+ webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook]
+ | Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook]
+ | Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook]
+ | Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook]
+ | 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,
+ ) -> MonitorCreateResponse:
+ return cast(
+ MonitorCreateResponse,
+ await self._post(
+ "/monitors",
+ body=await async_maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "target": target,
+ "tags": tags,
+ "webhook": webhook,
+ },
+ monitor_create_params.MonitorCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorCreateResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def retrieve(
+ self,
+ monitor_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorRetrieveResponse:
+ """
+ Get a monitor
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return cast(
+ MonitorRetrieveResponse,
+ await self._get(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorRetrieveResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def update(
+ self,
+ monitor_id: str,
+ *,
+ change_detection: monitor_update_params.ChangeDetection | Omit = omit,
+ name: str | Omit = omit,
+ schedule: monitor_update_params.Schedule | Omit = omit,
+ status: Literal["active", "paused"] | Omit = omit,
+ tags: SequenceNotStr[str] | Omit = omit,
+ target: monitor_update_params.Target | Omit = omit,
+ webhook: Optional[monitor_update_params.Webhook] | 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,
+ ) -> MonitorUpdateResponse:
+ """Updates a monitor.
+
+ If `target` or `change_detection` changes, the monitor
+ creates a new baseline. Unsupported target/change detection combinations are
+ rejected.
+
+ Args:
+ change_detection: Discriminated union describing how changes are detected.
+
+ schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+
+ tags: User-defined tags for grouping and filtering monitors and their changes.
+
+ target: Discriminated union describing what the monitor watches.
+
+ webhook: Set to null to remove the webhook.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return cast(
+ MonitorUpdateResponse,
+ await self._patch(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ body=await async_maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "status": status,
+ "tags": tags,
+ "target": target,
+ "webhook": webhook,
+ },
+ monitor_update_params.MonitorUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorUpdateResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def list(
+ self,
+ *,
+ change_detection_type: Literal["exact", "semantic"] | Omit = omit,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ status: Literal["active", "paused", "failed"] | Omit = omit,
+ tag: str | Omit = omit,
+ target_type: Literal["page", "sitemap", "extract"] | 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,
+ ) -> MonitorListResponse:
+ """
+ List monitors
+
+ Args:
+ tag: Filter to items that have this tag.
+
+ 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(
+ "/monitors",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "change_detection_type": change_detection_type,
+ "cursor": cursor,
+ "limit": limit,
+ "status": status,
+ "tag": tag,
+ "target_type": target_type,
+ },
+ monitor_list_params.MonitorListParams,
+ ),
+ ),
+ cast_to=MonitorListResponse,
+ )
+
+ async def delete(
+ self,
+ monitor_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorDeleteResponse:
+ """
+ Delete a monitor
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return await self._delete(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MonitorDeleteResponse,
+ )
+
+ async def list_account_changes(
+ self,
+ *,
+ change_detection_type: Literal["exact", "semantic"] | Omit = omit,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ monitor_id: str | Omit = omit,
+ since: Union[str, datetime] | Omit = omit,
+ tag: str | Omit = omit,
+ target_type: Literal["page", "sitemap", "extract"] | Omit = omit,
+ until: Union[str, datetime] | 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,
+ ) -> MonitorListAccountChangesResponse:
+ """
+ Returns an account-wide feed of detected changes across monitors.
+
+ Args:
+ tag: Filter to items that have this tag.
+
+ 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(
+ "/monitors/changes",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "change_detection_type": change_detection_type,
+ "cursor": cursor,
+ "limit": limit,
+ "monitor_id": monitor_id,
+ "since": since,
+ "tag": tag,
+ "target_type": target_type,
+ "until": until,
+ },
+ monitor_list_account_changes_params.MonitorListAccountChangesParams,
+ ),
+ ),
+ cast_to=MonitorListAccountChangesResponse,
+ )
+
+ async def list_account_runs(
+ self,
+ *,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed"] | 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,
+ ) -> MonitorListAccountRunsResponse:
+ """
+ Returns an account-wide feed of monitor runs across all monitors.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._get(
+ "/monitors/runs",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ "status": status,
+ },
+ monitor_list_account_runs_params.MonitorListAccountRunsParams,
+ ),
+ ),
+ cast_to=MonitorListAccountRunsResponse,
+ )
+
+ async def list_changes(
+ self,
+ monitor_id: str,
+ *,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ since: Union[str, datetime] | Omit = omit,
+ tag: str | Omit = omit,
+ until: Union[str, datetime] | 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,
+ ) -> MonitorListChangesResponse:
+ """
+ List changes for a monitor
+
+ Args:
+ tag: Filter to items that have this tag.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return await self._get(
+ path_template("/monitors/{monitor_id}/changes", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ "since": since,
+ "tag": tag,
+ "until": until,
+ },
+ monitor_list_changes_params.MonitorListChangesParams,
+ ),
+ ),
+ cast_to=MonitorListChangesResponse,
+ )
+
+ async def list_runs(
+ self,
+ monitor_id: str,
+ *,
+ cursor: str | Omit = omit,
+ limit: int | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed"] | 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,
+ ) -> MonitorListRunsResponse:
+ """
+ List monitor runs
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return await self._get(
+ path_template("/monitors/{monitor_id}/runs", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ "status": status,
+ },
+ monitor_list_runs_params.MonitorListRunsParams,
+ ),
+ ),
+ cast_to=MonitorListRunsResponse,
+ )
+
+ async def retrieve_change(
+ self,
+ change_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorRetrieveChangeResponse:
+ """
+ Get a change
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not change_id:
+ raise ValueError(f"Expected a non-empty value for `change_id` but received {change_id!r}")
+ return cast(
+ MonitorRetrieveChangeResponse,
+ await self._get(
+ path_template("/monitors/changes/{change_id}", change_id=change_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, MonitorRetrieveChangeResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def run(
+ self,
+ monitor_id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> MonitorRunResponse:
+ """Triggers an immediate run of the monitor outside its normal schedule.
+
+ The run is
+ queued and processed asynchronously.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not monitor_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
+ return await self._post(
+ path_template("/monitors/{monitor_id}/run", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MonitorRunResponse,
+ )
+
+
+class MonitorsResourceWithRawResponse:
+ def __init__(self, monitors: MonitorsResource) -> None:
+ self._monitors = monitors
+
+ self.create = to_raw_response_wrapper(
+ monitors.create,
+ )
+ self.retrieve = to_raw_response_wrapper(
+ monitors.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ monitors.update,
+ )
+ self.list = to_raw_response_wrapper(
+ monitors.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ monitors.delete,
+ )
+ self.list_account_changes = to_raw_response_wrapper(
+ monitors.list_account_changes,
+ )
+ self.list_account_runs = to_raw_response_wrapper(
+ monitors.list_account_runs,
+ )
+ self.list_changes = to_raw_response_wrapper(
+ monitors.list_changes,
+ )
+ self.list_runs = to_raw_response_wrapper(
+ monitors.list_runs,
+ )
+ self.retrieve_change = to_raw_response_wrapper(
+ monitors.retrieve_change,
+ )
+ self.run = to_raw_response_wrapper(
+ monitors.run,
+ )
+
+
+class AsyncMonitorsResourceWithRawResponse:
+ def __init__(self, monitors: AsyncMonitorsResource) -> None:
+ self._monitors = monitors
+
+ self.create = async_to_raw_response_wrapper(
+ monitors.create,
+ )
+ self.retrieve = async_to_raw_response_wrapper(
+ monitors.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ monitors.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ monitors.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ monitors.delete,
+ )
+ self.list_account_changes = async_to_raw_response_wrapper(
+ monitors.list_account_changes,
+ )
+ self.list_account_runs = async_to_raw_response_wrapper(
+ monitors.list_account_runs,
+ )
+ self.list_changes = async_to_raw_response_wrapper(
+ monitors.list_changes,
+ )
+ self.list_runs = async_to_raw_response_wrapper(
+ monitors.list_runs,
+ )
+ self.retrieve_change = async_to_raw_response_wrapper(
+ monitors.retrieve_change,
+ )
+ self.run = async_to_raw_response_wrapper(
+ monitors.run,
+ )
+
+
+class MonitorsResourceWithStreamingResponse:
+ def __init__(self, monitors: MonitorsResource) -> None:
+ self._monitors = monitors
+
+ self.create = to_streamed_response_wrapper(
+ monitors.create,
+ )
+ self.retrieve = to_streamed_response_wrapper(
+ monitors.retrieve,
+ )
+ self.update = to_streamed_response_wrapper(
+ monitors.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ monitors.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ monitors.delete,
+ )
+ self.list_account_changes = to_streamed_response_wrapper(
+ monitors.list_account_changes,
+ )
+ self.list_account_runs = to_streamed_response_wrapper(
+ monitors.list_account_runs,
+ )
+ self.list_changes = to_streamed_response_wrapper(
+ monitors.list_changes,
+ )
+ self.list_runs = to_streamed_response_wrapper(
+ monitors.list_runs,
+ )
+ self.retrieve_change = to_streamed_response_wrapper(
+ monitors.retrieve_change,
+ )
+ self.run = to_streamed_response_wrapper(
+ monitors.run,
+ )
+
+
+class AsyncMonitorsResourceWithStreamingResponse:
+ def __init__(self, monitors: AsyncMonitorsResource) -> None:
+ self._monitors = monitors
+
+ self.create = async_to_streamed_response_wrapper(
+ monitors.create,
+ )
+ self.retrieve = async_to_streamed_response_wrapper(
+ monitors.retrieve,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ monitors.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ monitors.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ monitors.delete,
+ )
+ self.list_account_changes = async_to_streamed_response_wrapper(
+ monitors.list_account_changes,
+ )
+ self.list_account_runs = async_to_streamed_response_wrapper(
+ monitors.list_account_runs,
+ )
+ self.list_changes = async_to_streamed_response_wrapper(
+ monitors.list_changes,
+ )
+ self.list_runs = async_to_streamed_response_wrapper(
+ monitors.list_runs,
+ )
+ self.retrieve_change = async_to_streamed_response_wrapper(
+ monitors.retrieve_change,
+ )
+ self.run = async_to_streamed_response_wrapper(
+ monitors.run,
+ )
diff --git a/src/context/dev/types/__init__.py b/src/context/dev/types/__init__.py
index 91d5d38..c60839d 100644
--- a/src/context/dev/types/__init__.py
+++ b/src/context/dev/types/__init__.py
@@ -5,31 +5,44 @@
from .web_search_params import WebSearchParams as WebSearchParams
from .ai_ai_query_params import AIAIQueryParams as AIAIQueryParams
from .web_extract_params import WebExtractParams as WebExtractParams
+from .monitor_list_params import MonitorListParams as MonitorListParams
from .web_search_response import WebSearchResponse as WebSearchResponse
from .ai_ai_query_response import AIAIQueryResponse as AIAIQueryResponse
+from .monitor_run_response import MonitorRunResponse as MonitorRunResponse
from .web_extract_response import WebExtractResponse as WebExtractResponse
from .brand_retrieve_params import BrandRetrieveParams as BrandRetrieveParams
+from .monitor_create_params import MonitorCreateParams as MonitorCreateParams
+from .monitor_list_response import MonitorListResponse as MonitorListResponse
+from .monitor_update_params import MonitorUpdateParams as MonitorUpdateParams
from .web_screenshot_params import WebScreenshotParams as WebScreenshotParams
from .brand_retrieve_response import BrandRetrieveResponse as BrandRetrieveResponse
+from .monitor_create_response import MonitorCreateResponse as MonitorCreateResponse
+from .monitor_delete_response import MonitorDeleteResponse as MonitorDeleteResponse
+from .monitor_update_response import MonitorUpdateResponse as MonitorUpdateResponse
from .utility_prefetch_params import UtilityPrefetchParams as UtilityPrefetchParams
from .web_screenshot_response import WebScreenshotResponse as WebScreenshotResponse
from .web_web_crawl_md_params import WebWebCrawlMdParams as WebWebCrawlMdParams
+from .monitor_list_runs_params import MonitorListRunsParams as MonitorListRunsParams
from .web_extract_fonts_params import WebExtractFontsParams as WebExtractFontsParams
from .web_web_scrape_md_params import WebWebScrapeMdParams as WebWebScrapeMdParams
from .ai_extract_product_params import AIExtractProductParams as AIExtractProductParams
+from .monitor_retrieve_response import MonitorRetrieveResponse as MonitorRetrieveResponse
from .utility_prefetch_response import UtilityPrefetchResponse as UtilityPrefetchResponse
from .web_web_crawl_md_response import WebWebCrawlMdResponse as WebWebCrawlMdResponse
from .ai_extract_products_params import AIExtractProductsParams as AIExtractProductsParams
+from .monitor_list_runs_response import MonitorListRunsResponse as MonitorListRunsResponse
from .web_extract_fonts_response import WebExtractFontsResponse as WebExtractFontsResponse
from .web_web_scrape_html_params import WebWebScrapeHTMLParams as WebWebScrapeHTMLParams
from .web_web_scrape_md_response import WebWebScrapeMdResponse as WebWebScrapeMdResponse
from .ai_extract_product_response import AIExtractProductResponse as AIExtractProductResponse
+from .monitor_list_changes_params import MonitorListChangesParams as MonitorListChangesParams
from .ai_extract_products_response import AIExtractProductsResponse as AIExtractProductsResponse
from .industry_retrieve_sic_params import IndustryRetrieveSicParams as IndustryRetrieveSicParams
from .web_web_scrape_html_response import WebWebScrapeHTMLResponse as WebWebScrapeHTMLResponse
from .web_web_scrape_images_params import WebWebScrapeImagesParams as WebWebScrapeImagesParams
from .brand_retrieve_by_isin_params import BrandRetrieveByIsinParams as BrandRetrieveByIsinParams
from .brand_retrieve_by_name_params import BrandRetrieveByNameParams as BrandRetrieveByNameParams
+from .monitor_list_changes_response import MonitorListChangesResponse as MonitorListChangesResponse
from .web_extract_styleguide_params import WebExtractStyleguideParams as WebExtractStyleguideParams
from .web_web_scrape_sitemap_params import WebWebScrapeSitemapParams as WebWebScrapeSitemapParams
from .brand_retrieve_by_email_params import BrandRetrieveByEmailParams as BrandRetrieveByEmailParams
@@ -45,11 +58,18 @@
from .brand_retrieve_by_email_response import BrandRetrieveByEmailResponse as BrandRetrieveByEmailResponse
from .brand_retrieve_simplified_params import BrandRetrieveSimplifiedParams as BrandRetrieveSimplifiedParams
from .industry_retrieve_naics_response import IndustryRetrieveNaicsResponse as IndustryRetrieveNaicsResponse
+from .monitor_list_account_runs_params import MonitorListAccountRunsParams as MonitorListAccountRunsParams
+from .monitor_retrieve_change_response import MonitorRetrieveChangeResponse as MonitorRetrieveChangeResponse
from .utility_prefetch_by_email_params import UtilityPrefetchByEmailParams as UtilityPrefetchByEmailParams
from .web_extract_competitors_response import WebExtractCompetitorsResponse as WebExtractCompetitorsResponse
from .brand_retrieve_by_ticker_response import BrandRetrieveByTickerResponse as BrandRetrieveByTickerResponse
from .brand_retrieve_simplified_response import BrandRetrieveSimplifiedResponse as BrandRetrieveSimplifiedResponse
+from .monitor_list_account_runs_response import MonitorListAccountRunsResponse as MonitorListAccountRunsResponse
from .utility_prefetch_by_email_response import UtilityPrefetchByEmailResponse as UtilityPrefetchByEmailResponse
+from .monitor_list_account_changes_params import MonitorListAccountChangesParams as MonitorListAccountChangesParams
+from .monitor_list_account_changes_response import (
+ MonitorListAccountChangesResponse as MonitorListAccountChangesResponse,
+)
from .brand_identify_from_transaction_params import (
BrandIdentifyFromTransactionParams as BrandIdentifyFromTransactionParams,
)
diff --git a/src/context/dev/types/monitor_create_params.py b/src/context/dev/types/monitor_create_params.py
new file mode 100644
index 0000000..0d01412
--- /dev/null
+++ b/src/context/dev/types/monitor_create_params.py
@@ -0,0 +1,323 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = [
+ "MonitorCreateParams",
+ "MonitorsCreatePageExactMonitorRequest",
+ "MonitorsCreatePageExactMonitorRequestChangeDetection",
+ "MonitorsCreatePageExactMonitorRequestSchedule",
+ "MonitorsCreatePageExactMonitorRequestTarget",
+ "MonitorsCreatePageExactMonitorRequestWebhook",
+ "MonitorsCreateSitemapExactMonitorRequest",
+ "MonitorsCreateSitemapExactMonitorRequestChangeDetection",
+ "MonitorsCreateSitemapExactMonitorRequestSchedule",
+ "MonitorsCreateSitemapExactMonitorRequestTarget",
+ "MonitorsCreateSitemapExactMonitorRequestWebhook",
+ "MonitorsCreatePageSemanticMonitorRequest",
+ "MonitorsCreatePageSemanticMonitorRequestChangeDetection",
+ "MonitorsCreatePageSemanticMonitorRequestSchedule",
+ "MonitorsCreatePageSemanticMonitorRequestTarget",
+ "MonitorsCreatePageSemanticMonitorRequestWebhook",
+ "MonitorsCreateExtractSemanticMonitorRequest",
+ "MonitorsCreateExtractSemanticMonitorRequestChangeDetection",
+ "MonitorsCreateExtractSemanticMonitorRequestSchedule",
+ "MonitorsCreateExtractSemanticMonitorRequestTarget",
+ "MonitorsCreateExtractSemanticMonitorRequestWebhook",
+]
+
+
+class MonitorsCreatePageExactMonitorRequest(TypedDict, total=False):
+ change_detection: Required[MonitorsCreatePageExactMonitorRequestChangeDetection]
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ name: Required[str]
+
+ schedule: Required[MonitorsCreatePageExactMonitorRequestSchedule]
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ target: Required[MonitorsCreatePageExactMonitorRequestTarget]
+
+ tags: SequenceNotStr[str]
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsCreatePageExactMonitorRequestWebhook]
+
+
+class MonitorsCreatePageExactMonitorRequestChangeDetection(TypedDict, total=False):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Required[Literal["exact"]]
+
+
+class MonitorsCreatePageExactMonitorRequestSchedule(TypedDict, total=False):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: Required[int]
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Required[Literal["interval"]]
+
+ unit: Required[Literal["minutes", "hours", "days"]]
+
+
+class MonitorsCreatePageExactMonitorRequestTarget(TypedDict, total=False):
+ type: Required[Literal["page"]]
+
+ url: Required[str]
+
+ normalize_whitespace: bool
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsCreatePageExactMonitorRequestWebhook(TypedDict, total=False):
+ url: Required[str]
+ """Webhook URL called when a change is detected."""
+
+
+class MonitorsCreateSitemapExactMonitorRequest(TypedDict, total=False):
+ change_detection: Required[MonitorsCreateSitemapExactMonitorRequestChangeDetection]
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ name: Required[str]
+
+ schedule: Required[MonitorsCreateSitemapExactMonitorRequestSchedule]
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ target: Required[MonitorsCreateSitemapExactMonitorRequestTarget]
+
+ tags: SequenceNotStr[str]
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsCreateSitemapExactMonitorRequestWebhook]
+
+
+class MonitorsCreateSitemapExactMonitorRequestChangeDetection(TypedDict, total=False):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Required[Literal["exact"]]
+
+
+class MonitorsCreateSitemapExactMonitorRequestSchedule(TypedDict, total=False):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: Required[int]
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Required[Literal["interval"]]
+
+ unit: Required[Literal["minutes", "hours", "days"]]
+
+
+class MonitorsCreateSitemapExactMonitorRequestTarget(TypedDict, total=False):
+ type: Required[Literal["sitemap"]]
+
+ url: Required[str]
+ """Sitemap URL to monitor."""
+
+ exclude: SequenceNotStr[str]
+ """URL path patterns to exclude."""
+
+ include: SequenceNotStr[str]
+ """URL path patterns to include."""
+
+ max_urls: int
+
+
+class MonitorsCreateSitemapExactMonitorRequestWebhook(TypedDict, total=False):
+ url: Required[str]
+ """Webhook URL called when a change is detected."""
+
+
+class MonitorsCreatePageSemanticMonitorRequest(TypedDict, total=False):
+ change_detection: Required[MonitorsCreatePageSemanticMonitorRequestChangeDetection]
+ """Detect meaning-level changes that match a natural language query."""
+
+ name: Required[str]
+
+ schedule: Required[MonitorsCreatePageSemanticMonitorRequestSchedule]
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ target: Required[MonitorsCreatePageSemanticMonitorRequestTarget]
+
+ tags: SequenceNotStr[str]
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsCreatePageSemanticMonitorRequestWebhook]
+
+
+class MonitorsCreatePageSemanticMonitorRequestChangeDetection(TypedDict, total=False):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: Required[str]
+
+ type: Required[Literal["semantic"]]
+
+ confidence_threshold: float
+
+
+class MonitorsCreatePageSemanticMonitorRequestSchedule(TypedDict, total=False):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: Required[int]
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Required[Literal["interval"]]
+
+ unit: Required[Literal["minutes", "hours", "days"]]
+
+
+class MonitorsCreatePageSemanticMonitorRequestTarget(TypedDict, total=False):
+ type: Required[Literal["page"]]
+
+ url: Required[str]
+
+ normalize_whitespace: bool
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsCreatePageSemanticMonitorRequestWebhook(TypedDict, total=False):
+ url: Required[str]
+ """Webhook URL called when a change is detected."""
+
+
+class MonitorsCreateExtractSemanticMonitorRequest(TypedDict, total=False):
+ change_detection: Required[MonitorsCreateExtractSemanticMonitorRequestChangeDetection]
+ """Detect meaning-level changes that match a natural language query."""
+
+ name: Required[str]
+
+ schedule: Required[MonitorsCreateExtractSemanticMonitorRequestSchedule]
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ target: Required[MonitorsCreateExtractSemanticMonitorRequestTarget]
+
+ tags: SequenceNotStr[str]
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsCreateExtractSemanticMonitorRequestWebhook]
+
+
+class MonitorsCreateExtractSemanticMonitorRequestChangeDetection(TypedDict, total=False):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: Required[str]
+
+ type: Required[Literal["semantic"]]
+
+ confidence_threshold: float
+
+
+class MonitorsCreateExtractSemanticMonitorRequestSchedule(TypedDict, total=False):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: Required[int]
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Required[Literal["interval"]]
+
+ unit: Required[Literal["minutes", "hours", "days"]]
+
+
+class MonitorsCreateExtractSemanticMonitorRequestTarget(TypedDict, total=False):
+ type: Required[Literal["extract"]]
+
+ url: Required[str]
+ """Root URL to extract structured data from."""
+
+ follow_subdomains: bool
+
+ instructions: str
+ """Optional natural-language instructions guiding what to extract."""
+
+ max_depth: int
+ """Optional maximum link depth from the starting URL (0 = only the starting page)."""
+
+ max_pages: int
+ """Maximum number of pages to analyze during extraction."""
+
+ schema: Dict[str, object]
+ """JSON Schema describing the structured data to extract and watch for changes.
+
+ If omitted, a default summary + key-points schema is used.
+ """
+
+
+class MonitorsCreateExtractSemanticMonitorRequestWebhook(TypedDict, total=False):
+ url: Required[str]
+ """Webhook URL called when a change is detected."""
+
+
+MonitorCreateParams: TypeAlias = Union[
+ MonitorsCreatePageExactMonitorRequest,
+ MonitorsCreateSitemapExactMonitorRequest,
+ MonitorsCreatePageSemanticMonitorRequest,
+ MonitorsCreateExtractSemanticMonitorRequest,
+]
diff --git a/src/context/dev/types/monitor_create_response.py b/src/context/dev/types/monitor_create_response.py
new file mode 100644
index 0000000..739efaa
--- /dev/null
+++ b/src/context/dev/types/monitor_create_response.py
@@ -0,0 +1,413 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorCreateResponse",
+ "MonitorsPageExactMonitor",
+ "MonitorsPageExactMonitorChangeDetection",
+ "MonitorsPageExactMonitorSchedule",
+ "MonitorsPageExactMonitorTarget",
+ "MonitorsPageExactMonitorWebhook",
+ "MonitorsSitemapExactMonitor",
+ "MonitorsSitemapExactMonitorChangeDetection",
+ "MonitorsSitemapExactMonitorSchedule",
+ "MonitorsSitemapExactMonitorTarget",
+ "MonitorsSitemapExactMonitorWebhook",
+ "MonitorsPageSemanticMonitor",
+ "MonitorsPageSemanticMonitorChangeDetection",
+ "MonitorsPageSemanticMonitorSchedule",
+ "MonitorsPageSemanticMonitorTarget",
+ "MonitorsPageSemanticMonitorWebhook",
+ "MonitorsExtractSemanticMonitor",
+ "MonitorsExtractSemanticMonitorChangeDetection",
+ "MonitorsExtractSemanticMonitorSchedule",
+ "MonitorsExtractSemanticMonitorTarget",
+ "MonitorsExtractSemanticMonitorWebhook",
+]
+
+
+class MonitorsPageExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class MonitorsPageExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsPageExactMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsPageExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsPageExactMonitor(BaseModel):
+ """A page monitor using exact change detection."""
+
+ id: str
+
+ change_detection: MonitorsPageExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsPageExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsPageExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsPageExactMonitorWebhook] = None
+
+
+class MonitorsSitemapExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class MonitorsSitemapExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsSitemapExactMonitorTarget(BaseModel):
+ type: Literal["sitemap"]
+
+ url: str
+ """Sitemap URL to monitor."""
+
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
+
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
+
+ max_urls: Optional[int] = None
+
+
+class MonitorsSitemapExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsSitemapExactMonitor(BaseModel):
+ """A sitemap monitor using exact change detection."""
+
+ id: str
+
+ change_detection: MonitorsSitemapExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsSitemapExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsSitemapExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsSitemapExactMonitorWebhook] = None
+
+
+class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class MonitorsPageSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsPageSemanticMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsPageSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsPageSemanticMonitor(BaseModel):
+ """A page monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: MonitorsPageSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsPageSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsPageSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsPageSemanticMonitorWebhook] = None
+
+
+class MonitorsExtractSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class MonitorsExtractSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsExtractSemanticMonitorTarget(BaseModel):
+ type: Literal["extract"]
+
+ url: str
+ """Root URL to extract structured data from."""
+
+ follow_subdomains: Optional[bool] = None
+
+ instructions: Optional[str] = None
+ """Optional natural-language instructions guiding what to extract."""
+
+ max_depth: Optional[int] = None
+ """Optional maximum link depth from the starting URL (0 = only the starting page)."""
+
+ max_pages: Optional[int] = None
+ """Maximum number of pages to analyze during extraction."""
+
+ schema_: Optional[Dict[str, object]] = FieldInfo(alias="schema", default=None)
+ """JSON Schema describing the structured data to extract and watch for changes.
+
+ If omitted, a default summary + key-points schema is used.
+ """
+
+
+class MonitorsExtractSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsExtractSemanticMonitor(BaseModel):
+ """An extract monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: MonitorsExtractSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsExtractSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsExtractSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsExtractSemanticMonitorWebhook] = None
+
+
+MonitorCreateResponse: TypeAlias = Union[
+ MonitorsPageExactMonitor, MonitorsSitemapExactMonitor, MonitorsPageSemanticMonitor, MonitorsExtractSemanticMonitor
+]
diff --git a/src/context/dev/types/monitor_delete_response.py b/src/context/dev/types/monitor_delete_response.py
new file mode 100644
index 0000000..be86a03
--- /dev/null
+++ b/src/context/dev/types/monitor_delete_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["MonitorDeleteResponse"]
+
+
+class MonitorDeleteResponse(BaseModel):
+ id: str
+
+ deleted: bool
diff --git a/src/context/dev/types/monitor_list_account_changes_params.py b/src/context/dev/types/monitor_list_account_changes_params.py
new file mode 100644
index 0000000..82e684a
--- /dev/null
+++ b/src/context/dev/types/monitor_list_account_changes_params.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Literal, Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["MonitorListAccountChangesParams"]
+
+
+class MonitorListAccountChangesParams(TypedDict, total=False):
+ change_detection_type: Literal["exact", "semantic"]
+
+ cursor: str
+
+ limit: int
+
+ monitor_id: str
+
+ since: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+
+ tag: str
+ """Filter to items that have this tag."""
+
+ target_type: Literal["page", "sitemap", "extract"]
+
+ until: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
diff --git a/src/context/dev/types/monitor_list_account_changes_response.py b/src/context/dev/types/monitor_list_account_changes_response.py
new file mode 100644
index 0000000..a696740
--- /dev/null
+++ b/src/context/dev/types/monitor_list_account_changes_response.py
@@ -0,0 +1,130 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorListAccountChangesResponse",
+ "Data",
+ "DataMonitorsPageExactChangeSummary",
+ "DataMonitorsSitemapExactChangeSummary",
+ "DataMonitorsPageSemanticChangeSummary",
+ "DataMonitorsExtractSemanticChangeSummary",
+]
+
+
+class DataMonitorsPageExactChangeSummary(BaseModel):
+ id: str
+
+ change_detection_type: Literal["exact"]
+
+ detected_at: datetime
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["page"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class DataMonitorsSitemapExactChangeSummary(BaseModel):
+ id: str
+
+ added_url_count: int
+
+ change_detection_type: Literal["exact"]
+
+ detected_at: datetime
+
+ monitor_id: str
+
+ removed_url_count: int
+
+ summary: str
+
+ target_type: Literal["sitemap"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class DataMonitorsPageSemanticChangeSummary(BaseModel):
+ id: str
+
+ change_detection_type: Literal["semantic"]
+
+ confidence: float
+
+ detected_at: datetime
+
+ importance: Literal["low", "medium", "high"]
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["page"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class DataMonitorsExtractSemanticChangeSummary(BaseModel):
+ id: str
+
+ change_detection_type: Literal["semantic"]
+
+ confidence: float
+
+ detected_at: datetime
+
+ importance: Literal["low", "medium", "high"]
+
+ matched_url_count: int
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["extract"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+Data: TypeAlias = Union[
+ DataMonitorsPageExactChangeSummary,
+ DataMonitorsSitemapExactChangeSummary,
+ DataMonitorsPageSemanticChangeSummary,
+ DataMonitorsExtractSemanticChangeSummary,
+]
+
+
+class MonitorListAccountChangesResponse(BaseModel):
+ data: List[Data]
+
+ has_more: bool
+
+ next_cursor: Optional[str] = None
diff --git a/src/context/dev/types/monitor_list_account_runs_params.py b/src/context/dev/types/monitor_list_account_runs_params.py
new file mode 100644
index 0000000..1a54d7c
--- /dev/null
+++ b/src/context/dev/types/monitor_list_account_runs_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["MonitorListAccountRunsParams"]
+
+
+class MonitorListAccountRunsParams(TypedDict, total=False):
+ cursor: str
+
+ limit: int
+
+ status: Literal["queued", "running", "completed", "failed"]
diff --git a/src/context/dev/types/monitor_list_account_runs_response.py b/src/context/dev/types/monitor_list_account_runs_response.py
new file mode 100644
index 0000000..6359dc1
--- /dev/null
+++ b/src/context/dev/types/monitor_list_account_runs_response.py
@@ -0,0 +1,54 @@
+# 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__ = ["MonitorListAccountRunsResponse", "Data", "DataError"]
+
+
+class DataError(BaseModel):
+ code: str
+
+ message: str
+
+
+class Data(BaseModel):
+ id: str
+
+ baseline_created: bool
+ """
+ True when this run established the monitor's initial baseline; baseline runs
+ perform no change detection.
+ """
+
+ change_detected: bool
+
+ change_detection_type: Literal["exact", "semantic"]
+
+ monitor_id: str
+
+ run_type: Literal["baseline", "scheduled"]
+ """The first run after monitor creation is a baseline run."""
+
+ status: Literal["queued", "running", "completed", "failed"]
+
+ target_type: Literal["page", "sitemap", "extract"]
+
+ change_id: Optional[str] = None
+
+ completed_at: Optional[datetime] = None
+
+ error: Optional[DataError] = None
+
+ started_at: Optional[datetime] = None
+
+
+class MonitorListAccountRunsResponse(BaseModel):
+ data: List[Data]
+
+ has_more: bool
+
+ next_cursor: Optional[str] = None
diff --git a/src/context/dev/types/monitor_list_changes_params.py b/src/context/dev/types/monitor_list_changes_params.py
new file mode 100644
index 0000000..a4f75cd
--- /dev/null
+++ b/src/context/dev/types/monitor_list_changes_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 import Union
+from datetime import datetime
+from typing_extensions import Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["MonitorListChangesParams"]
+
+
+class MonitorListChangesParams(TypedDict, total=False):
+ cursor: str
+
+ limit: int
+
+ since: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+
+ tag: str
+ """Filter to items that have this tag."""
+
+ until: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
diff --git a/src/context/dev/types/monitor_list_changes_response.py b/src/context/dev/types/monitor_list_changes_response.py
new file mode 100644
index 0000000..dffe8b2
--- /dev/null
+++ b/src/context/dev/types/monitor_list_changes_response.py
@@ -0,0 +1,130 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorListChangesResponse",
+ "Data",
+ "DataMonitorsPageExactChangeSummary",
+ "DataMonitorsSitemapExactChangeSummary",
+ "DataMonitorsPageSemanticChangeSummary",
+ "DataMonitorsExtractSemanticChangeSummary",
+]
+
+
+class DataMonitorsPageExactChangeSummary(BaseModel):
+ id: str
+
+ change_detection_type: Literal["exact"]
+
+ detected_at: datetime
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["page"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class DataMonitorsSitemapExactChangeSummary(BaseModel):
+ id: str
+
+ added_url_count: int
+
+ change_detection_type: Literal["exact"]
+
+ detected_at: datetime
+
+ monitor_id: str
+
+ removed_url_count: int
+
+ summary: str
+
+ target_type: Literal["sitemap"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class DataMonitorsPageSemanticChangeSummary(BaseModel):
+ id: str
+
+ change_detection_type: Literal["semantic"]
+
+ confidence: float
+
+ detected_at: datetime
+
+ importance: Literal["low", "medium", "high"]
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["page"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class DataMonitorsExtractSemanticChangeSummary(BaseModel):
+ id: str
+
+ change_detection_type: Literal["semantic"]
+
+ confidence: float
+
+ detected_at: datetime
+
+ importance: Literal["low", "medium", "high"]
+
+ matched_url_count: int
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["extract"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+Data: TypeAlias = Union[
+ DataMonitorsPageExactChangeSummary,
+ DataMonitorsSitemapExactChangeSummary,
+ DataMonitorsPageSemanticChangeSummary,
+ DataMonitorsExtractSemanticChangeSummary,
+]
+
+
+class MonitorListChangesResponse(BaseModel):
+ data: List[Data]
+
+ has_more: bool
+
+ next_cursor: Optional[str] = None
diff --git a/src/context/dev/types/monitor_list_params.py b/src/context/dev/types/monitor_list_params.py
new file mode 100644
index 0000000..817a6de
--- /dev/null
+++ b/src/context/dev/types/monitor_list_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["MonitorListParams"]
+
+
+class MonitorListParams(TypedDict, total=False):
+ change_detection_type: Literal["exact", "semantic"]
+
+ cursor: str
+
+ limit: int
+
+ status: Literal["active", "paused", "failed"]
+
+ tag: str
+ """Filter to items that have this tag."""
+
+ target_type: Literal["page", "sitemap", "extract"]
diff --git a/src/context/dev/types/monitor_list_response.py b/src/context/dev/types/monitor_list_response.py
new file mode 100644
index 0000000..7761032
--- /dev/null
+++ b/src/context/dev/types/monitor_list_response.py
@@ -0,0 +1,425 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorListResponse",
+ "Data",
+ "DataMonitorsPageExactMonitor",
+ "DataMonitorsPageExactMonitorChangeDetection",
+ "DataMonitorsPageExactMonitorSchedule",
+ "DataMonitorsPageExactMonitorTarget",
+ "DataMonitorsPageExactMonitorWebhook",
+ "DataMonitorsSitemapExactMonitor",
+ "DataMonitorsSitemapExactMonitorChangeDetection",
+ "DataMonitorsSitemapExactMonitorSchedule",
+ "DataMonitorsSitemapExactMonitorTarget",
+ "DataMonitorsSitemapExactMonitorWebhook",
+ "DataMonitorsPageSemanticMonitor",
+ "DataMonitorsPageSemanticMonitorChangeDetection",
+ "DataMonitorsPageSemanticMonitorSchedule",
+ "DataMonitorsPageSemanticMonitorTarget",
+ "DataMonitorsPageSemanticMonitorWebhook",
+ "DataMonitorsExtractSemanticMonitor",
+ "DataMonitorsExtractSemanticMonitorChangeDetection",
+ "DataMonitorsExtractSemanticMonitorSchedule",
+ "DataMonitorsExtractSemanticMonitorTarget",
+ "DataMonitorsExtractSemanticMonitorWebhook",
+]
+
+
+class DataMonitorsPageExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class DataMonitorsPageExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class DataMonitorsPageExactMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class DataMonitorsPageExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class DataMonitorsPageExactMonitor(BaseModel):
+ """A page monitor using exact change detection."""
+
+ id: str
+
+ change_detection: DataMonitorsPageExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: DataMonitorsPageExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: DataMonitorsPageExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[DataMonitorsPageExactMonitorWebhook] = None
+
+
+class DataMonitorsSitemapExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class DataMonitorsSitemapExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class DataMonitorsSitemapExactMonitorTarget(BaseModel):
+ type: Literal["sitemap"]
+
+ url: str
+ """Sitemap URL to monitor."""
+
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
+
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
+
+ max_urls: Optional[int] = None
+
+
+class DataMonitorsSitemapExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class DataMonitorsSitemapExactMonitor(BaseModel):
+ """A sitemap monitor using exact change detection."""
+
+ id: str
+
+ change_detection: DataMonitorsSitemapExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: DataMonitorsSitemapExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: DataMonitorsSitemapExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[DataMonitorsSitemapExactMonitorWebhook] = None
+
+
+class DataMonitorsPageSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class DataMonitorsPageSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class DataMonitorsPageSemanticMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class DataMonitorsPageSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class DataMonitorsPageSemanticMonitor(BaseModel):
+ """A page monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: DataMonitorsPageSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: DataMonitorsPageSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: DataMonitorsPageSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[DataMonitorsPageSemanticMonitorWebhook] = None
+
+
+class DataMonitorsExtractSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class DataMonitorsExtractSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class DataMonitorsExtractSemanticMonitorTarget(BaseModel):
+ type: Literal["extract"]
+
+ url: str
+ """Root URL to extract structured data from."""
+
+ follow_subdomains: Optional[bool] = None
+
+ instructions: Optional[str] = None
+ """Optional natural-language instructions guiding what to extract."""
+
+ max_depth: Optional[int] = None
+ """Optional maximum link depth from the starting URL (0 = only the starting page)."""
+
+ max_pages: Optional[int] = None
+ """Maximum number of pages to analyze during extraction."""
+
+ schema_: Optional[Dict[str, object]] = FieldInfo(alias="schema", default=None)
+ """JSON Schema describing the structured data to extract and watch for changes.
+
+ If omitted, a default summary + key-points schema is used.
+ """
+
+
+class DataMonitorsExtractSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class DataMonitorsExtractSemanticMonitor(BaseModel):
+ """An extract monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: DataMonitorsExtractSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: DataMonitorsExtractSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: DataMonitorsExtractSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[DataMonitorsExtractSemanticMonitorWebhook] = None
+
+
+Data: TypeAlias = Union[
+ DataMonitorsPageExactMonitor,
+ DataMonitorsSitemapExactMonitor,
+ DataMonitorsPageSemanticMonitor,
+ DataMonitorsExtractSemanticMonitor,
+]
+
+
+class MonitorListResponse(BaseModel):
+ data: List[Data]
+
+ has_more: bool
+
+ next_cursor: Optional[str] = None
diff --git a/src/context/dev/types/monitor_list_runs_params.py b/src/context/dev/types/monitor_list_runs_params.py
new file mode 100644
index 0000000..86db021
--- /dev/null
+++ b/src/context/dev/types/monitor_list_runs_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["MonitorListRunsParams"]
+
+
+class MonitorListRunsParams(TypedDict, total=False):
+ cursor: str
+
+ limit: int
+
+ status: Literal["queued", "running", "completed", "failed"]
diff --git a/src/context/dev/types/monitor_list_runs_response.py b/src/context/dev/types/monitor_list_runs_response.py
new file mode 100644
index 0000000..c7a075f
--- /dev/null
+++ b/src/context/dev/types/monitor_list_runs_response.py
@@ -0,0 +1,54 @@
+# 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__ = ["MonitorListRunsResponse", "Data", "DataError"]
+
+
+class DataError(BaseModel):
+ code: str
+
+ message: str
+
+
+class Data(BaseModel):
+ id: str
+
+ baseline_created: bool
+ """
+ True when this run established the monitor's initial baseline; baseline runs
+ perform no change detection.
+ """
+
+ change_detected: bool
+
+ change_detection_type: Literal["exact", "semantic"]
+
+ monitor_id: str
+
+ run_type: Literal["baseline", "scheduled"]
+ """The first run after monitor creation is a baseline run."""
+
+ status: Literal["queued", "running", "completed", "failed"]
+
+ target_type: Literal["page", "sitemap", "extract"]
+
+ change_id: Optional[str] = None
+
+ completed_at: Optional[datetime] = None
+
+ error: Optional[DataError] = None
+
+ started_at: Optional[datetime] = None
+
+
+class MonitorListRunsResponse(BaseModel):
+ data: List[Data]
+
+ has_more: bool
+
+ next_cursor: Optional[str] = None
diff --git a/src/context/dev/types/monitor_retrieve_change_response.py b/src/context/dev/types/monitor_retrieve_change_response.py
new file mode 100644
index 0000000..6586e41
--- /dev/null
+++ b/src/context/dev/types/monitor_retrieve_change_response.py
@@ -0,0 +1,159 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorRetrieveChangeResponse",
+ "MonitorsPageExactChange",
+ "MonitorsSitemapExactChange",
+ "MonitorsPageSemanticChange",
+ "MonitorsPageSemanticChangeEvidence",
+ "MonitorsExtractSemanticChange",
+ "MonitorsExtractSemanticChangeEvidence",
+]
+
+
+class MonitorsPageExactChange(BaseModel):
+ id: str
+
+ change_detection_type: Literal["exact"]
+
+ detected_at: datetime
+
+ diff: str
+ """Text diff between the previous and current page baseline."""
+
+ monitor_id: str
+
+ summary: str
+
+ target_type: Literal["page"]
+
+ title: str
+
+ url: str
+
+ after_text_excerpt: Optional[str] = None
+
+ before_text_excerpt: Optional[str] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class MonitorsSitemapExactChange(BaseModel):
+ id: str
+
+ added_url_count: int
+
+ added_urls: List[str]
+
+ change_detection_type: Literal["exact"]
+
+ detected_at: datetime
+
+ monitor_id: str
+
+ removed_url_count: int
+
+ removed_urls: List[str]
+
+ summary: str
+
+ target_type: Literal["sitemap"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class MonitorsPageSemanticChangeEvidence(BaseModel):
+ after: str
+
+ before: str
+
+
+class MonitorsPageSemanticChange(BaseModel):
+ id: str
+
+ change_detection_type: Literal["semantic"]
+
+ confidence: float
+
+ detected_at: datetime
+
+ evidence: List[MonitorsPageSemanticChangeEvidence]
+
+ importance: Literal["low", "medium", "high"]
+
+ monitor_id: str
+
+ query: str
+
+ summary: str
+
+ target_type: Literal["page"]
+
+ title: str
+
+ url: str
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+class MonitorsExtractSemanticChangeEvidence(BaseModel):
+ after: str
+ """Snapshot of the extracted data after the change."""
+
+ before: str
+ """Snapshot of the extracted data before the change."""
+
+ url: Optional[str] = None
+ """Optional URL the evidence relates to. Absent for whole-target extract diffs."""
+
+
+class MonitorsExtractSemanticChange(BaseModel):
+ id: str
+
+ change_detection_type: Literal["semantic"]
+
+ confidence: float
+
+ detected_at: datetime
+
+ evidence: List[MonitorsExtractSemanticChangeEvidence]
+
+ importance: Literal["low", "medium", "high"]
+
+ matched_url_count: int
+
+ matched_urls: List[str]
+
+ monitor_id: str
+
+ query: str
+
+ summary: str
+
+ target_type: Literal["extract"]
+
+ title: str
+
+ url: str
+ """Root URL of the extract target."""
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+
+MonitorRetrieveChangeResponse: TypeAlias = Union[
+ MonitorsPageExactChange, MonitorsSitemapExactChange, MonitorsPageSemanticChange, MonitorsExtractSemanticChange
+]
diff --git a/src/context/dev/types/monitor_retrieve_response.py b/src/context/dev/types/monitor_retrieve_response.py
new file mode 100644
index 0000000..d774f7f
--- /dev/null
+++ b/src/context/dev/types/monitor_retrieve_response.py
@@ -0,0 +1,413 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorRetrieveResponse",
+ "MonitorsPageExactMonitor",
+ "MonitorsPageExactMonitorChangeDetection",
+ "MonitorsPageExactMonitorSchedule",
+ "MonitorsPageExactMonitorTarget",
+ "MonitorsPageExactMonitorWebhook",
+ "MonitorsSitemapExactMonitor",
+ "MonitorsSitemapExactMonitorChangeDetection",
+ "MonitorsSitemapExactMonitorSchedule",
+ "MonitorsSitemapExactMonitorTarget",
+ "MonitorsSitemapExactMonitorWebhook",
+ "MonitorsPageSemanticMonitor",
+ "MonitorsPageSemanticMonitorChangeDetection",
+ "MonitorsPageSemanticMonitorSchedule",
+ "MonitorsPageSemanticMonitorTarget",
+ "MonitorsPageSemanticMonitorWebhook",
+ "MonitorsExtractSemanticMonitor",
+ "MonitorsExtractSemanticMonitorChangeDetection",
+ "MonitorsExtractSemanticMonitorSchedule",
+ "MonitorsExtractSemanticMonitorTarget",
+ "MonitorsExtractSemanticMonitorWebhook",
+]
+
+
+class MonitorsPageExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class MonitorsPageExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsPageExactMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsPageExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsPageExactMonitor(BaseModel):
+ """A page monitor using exact change detection."""
+
+ id: str
+
+ change_detection: MonitorsPageExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsPageExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsPageExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsPageExactMonitorWebhook] = None
+
+
+class MonitorsSitemapExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class MonitorsSitemapExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsSitemapExactMonitorTarget(BaseModel):
+ type: Literal["sitemap"]
+
+ url: str
+ """Sitemap URL to monitor."""
+
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
+
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
+
+ max_urls: Optional[int] = None
+
+
+class MonitorsSitemapExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsSitemapExactMonitor(BaseModel):
+ """A sitemap monitor using exact change detection."""
+
+ id: str
+
+ change_detection: MonitorsSitemapExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsSitemapExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsSitemapExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsSitemapExactMonitorWebhook] = None
+
+
+class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class MonitorsPageSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsPageSemanticMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsPageSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsPageSemanticMonitor(BaseModel):
+ """A page monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: MonitorsPageSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsPageSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsPageSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsPageSemanticMonitorWebhook] = None
+
+
+class MonitorsExtractSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class MonitorsExtractSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsExtractSemanticMonitorTarget(BaseModel):
+ type: Literal["extract"]
+
+ url: str
+ """Root URL to extract structured data from."""
+
+ follow_subdomains: Optional[bool] = None
+
+ instructions: Optional[str] = None
+ """Optional natural-language instructions guiding what to extract."""
+
+ max_depth: Optional[int] = None
+ """Optional maximum link depth from the starting URL (0 = only the starting page)."""
+
+ max_pages: Optional[int] = None
+ """Maximum number of pages to analyze during extraction."""
+
+ schema_: Optional[Dict[str, object]] = FieldInfo(alias="schema", default=None)
+ """JSON Schema describing the structured data to extract and watch for changes.
+
+ If omitted, a default summary + key-points schema is used.
+ """
+
+
+class MonitorsExtractSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsExtractSemanticMonitor(BaseModel):
+ """An extract monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: MonitorsExtractSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsExtractSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsExtractSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsExtractSemanticMonitorWebhook] = None
+
+
+MonitorRetrieveResponse: TypeAlias = Union[
+ MonitorsPageExactMonitor, MonitorsSitemapExactMonitor, MonitorsPageSemanticMonitor, MonitorsExtractSemanticMonitor
+]
diff --git a/src/context/dev/types/monitor_run_response.py b/src/context/dev/types/monitor_run_response.py
new file mode 100644
index 0000000..db2416c
--- /dev/null
+++ b/src/context/dev/types/monitor_run_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+
+__all__ = ["MonitorRunResponse"]
+
+
+class MonitorRunResponse(BaseModel):
+ monitor_id: str
+
+ queued: bool
diff --git a/src/context/dev/types/monitor_update_params.py b/src/context/dev/types/monitor_update_params.py
new file mode 100644
index 0000000..89599e6
--- /dev/null
+++ b/src/context/dev/types/monitor_update_params.py
@@ -0,0 +1,147 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = [
+ "MonitorUpdateParams",
+ "ChangeDetection",
+ "ChangeDetectionMonitorsExactChangeDetection",
+ "ChangeDetectionMonitorsSemanticChangeDetection",
+ "Schedule",
+ "Target",
+ "TargetMonitorsPageTarget",
+ "TargetMonitorsSitemapTarget",
+ "TargetMonitorsExtractTarget",
+ "Webhook",
+]
+
+
+class MonitorUpdateParams(TypedDict, total=False):
+ change_detection: ChangeDetection
+ """Discriminated union describing how changes are detected."""
+
+ name: str
+
+ schedule: Schedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused"]
+
+ tags: SequenceNotStr[str]
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ target: Target
+ """Discriminated union describing what the monitor watches."""
+
+ webhook: Optional[Webhook]
+ """Set to null to remove the webhook."""
+
+
+class ChangeDetectionMonitorsExactChangeDetection(TypedDict, total=False):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Required[Literal["exact"]]
+
+
+class ChangeDetectionMonitorsSemanticChangeDetection(TypedDict, total=False):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: Required[str]
+
+ type: Required[Literal["semantic"]]
+
+ confidence_threshold: float
+
+
+ChangeDetection: TypeAlias = Union[
+ ChangeDetectionMonitorsExactChangeDetection, ChangeDetectionMonitorsSemanticChangeDetection
+]
+
+
+class Schedule(TypedDict, total=False):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: Required[int]
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Required[Literal["interval"]]
+
+ unit: Required[Literal["minutes", "hours", "days"]]
+
+
+class TargetMonitorsPageTarget(TypedDict, total=False):
+ type: Required[Literal["page"]]
+
+ url: Required[str]
+
+ normalize_whitespace: bool
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class TargetMonitorsSitemapTarget(TypedDict, total=False):
+ type: Required[Literal["sitemap"]]
+
+ url: Required[str]
+ """Sitemap URL to monitor."""
+
+ exclude: SequenceNotStr[str]
+ """URL path patterns to exclude."""
+
+ include: SequenceNotStr[str]
+ """URL path patterns to include."""
+
+ max_urls: int
+
+
+class TargetMonitorsExtractTarget(TypedDict, total=False):
+ type: Required[Literal["extract"]]
+
+ url: Required[str]
+ """Root URL to extract structured data from."""
+
+ follow_subdomains: bool
+
+ instructions: str
+ """Optional natural-language instructions guiding what to extract."""
+
+ max_depth: int
+ """Optional maximum link depth from the starting URL (0 = only the starting page)."""
+
+ max_pages: int
+ """Maximum number of pages to analyze during extraction."""
+
+ schema: Dict[str, object]
+ """JSON Schema describing the structured data to extract and watch for changes.
+
+ If omitted, a default summary + key-points schema is used.
+ """
+
+
+Target: TypeAlias = Union[TargetMonitorsPageTarget, TargetMonitorsSitemapTarget, TargetMonitorsExtractTarget]
+
+
+class Webhook(TypedDict, total=False):
+ """Set to null to remove the webhook."""
+
+ url: Required[str]
+ """Webhook URL called when a change is detected."""
diff --git a/src/context/dev/types/monitor_update_response.py b/src/context/dev/types/monitor_update_response.py
new file mode 100644
index 0000000..98b0a69
--- /dev/null
+++ b/src/context/dev/types/monitor_update_response.py
@@ -0,0 +1,413 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = [
+ "MonitorUpdateResponse",
+ "MonitorsPageExactMonitor",
+ "MonitorsPageExactMonitorChangeDetection",
+ "MonitorsPageExactMonitorSchedule",
+ "MonitorsPageExactMonitorTarget",
+ "MonitorsPageExactMonitorWebhook",
+ "MonitorsSitemapExactMonitor",
+ "MonitorsSitemapExactMonitorChangeDetection",
+ "MonitorsSitemapExactMonitorSchedule",
+ "MonitorsSitemapExactMonitorTarget",
+ "MonitorsSitemapExactMonitorWebhook",
+ "MonitorsPageSemanticMonitor",
+ "MonitorsPageSemanticMonitorChangeDetection",
+ "MonitorsPageSemanticMonitorSchedule",
+ "MonitorsPageSemanticMonitorTarget",
+ "MonitorsPageSemanticMonitorWebhook",
+ "MonitorsExtractSemanticMonitor",
+ "MonitorsExtractSemanticMonitorChangeDetection",
+ "MonitorsExtractSemanticMonitorSchedule",
+ "MonitorsExtractSemanticMonitorTarget",
+ "MonitorsExtractSemanticMonitorWebhook",
+]
+
+
+class MonitorsPageExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class MonitorsPageExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsPageExactMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsPageExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsPageExactMonitor(BaseModel):
+ """A page monitor using exact change detection."""
+
+ id: str
+
+ change_detection: MonitorsPageExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsPageExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsPageExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsPageExactMonitorWebhook] = None
+
+
+class MonitorsSitemapExactMonitorChangeDetection(BaseModel):
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
+ """
+
+ type: Literal["exact"]
+
+
+class MonitorsSitemapExactMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsSitemapExactMonitorTarget(BaseModel):
+ type: Literal["sitemap"]
+
+ url: str
+ """Sitemap URL to monitor."""
+
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
+
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
+
+ max_urls: Optional[int] = None
+
+
+class MonitorsSitemapExactMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsSitemapExactMonitor(BaseModel):
+ """A sitemap monitor using exact change detection."""
+
+ id: str
+
+ change_detection: MonitorsSitemapExactMonitorChangeDetection
+ """Detect exact changes.
+
+ For page targets, this means visible text diffs. For sitemap targets, this means
+ URL additions and removals.
+ """
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsSitemapExactMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsSitemapExactMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsSitemapExactMonitorWebhook] = None
+
+
+class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class MonitorsPageSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsPageSemanticMonitorTarget(BaseModel):
+ type: Literal["page"]
+
+ url: str
+
+ normalize_whitespace: Optional[bool] = None
+ """Normalize whitespace before comparing or analyzing text."""
+
+
+class MonitorsPageSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsPageSemanticMonitor(BaseModel):
+ """A page monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: MonitorsPageSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsPageSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsPageSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsPageSemanticMonitorWebhook] = None
+
+
+class MonitorsExtractSemanticMonitorChangeDetection(BaseModel):
+ """Detect meaning-level changes that match a natural language query."""
+
+ query: str
+
+ type: Literal["semantic"]
+
+ confidence_threshold: Optional[float] = None
+
+
+class MonitorsExtractSemanticMonitorSchedule(BaseModel):
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
+ """
+
+ frequency: int
+ """Number of units between runs.
+
+ The resulting interval (frequency × unit) must be at least 10 minutes and at
+ most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
+ days).
+ """
+
+ type: Literal["interval"]
+
+ unit: Literal["minutes", "hours", "days"]
+
+
+class MonitorsExtractSemanticMonitorTarget(BaseModel):
+ type: Literal["extract"]
+
+ url: str
+ """Root URL to extract structured data from."""
+
+ follow_subdomains: Optional[bool] = None
+
+ instructions: Optional[str] = None
+ """Optional natural-language instructions guiding what to extract."""
+
+ max_depth: Optional[int] = None
+ """Optional maximum link depth from the starting URL (0 = only the starting page)."""
+
+ max_pages: Optional[int] = None
+ """Maximum number of pages to analyze during extraction."""
+
+ schema_: Optional[Dict[str, object]] = FieldInfo(alias="schema", default=None)
+ """JSON Schema describing the structured data to extract and watch for changes.
+
+ If omitted, a default summary + key-points schema is used.
+ """
+
+
+class MonitorsExtractSemanticMonitorWebhook(BaseModel):
+ url: str
+ """Webhook URL called when a change is detected."""
+
+ secret: Optional[str] = None
+ """Signing secret used to verify webhook authenticity.
+
+ Each delivery includes an `X-Context-Signature: t=,v1=` header,
+ where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
+ Recompute it with a constant-time compare and reject stale timestamps to prevent
+ replay. Generated by the API; cannot be set by clients.
+ """
+
+
+class MonitorsExtractSemanticMonitor(BaseModel):
+ """An extract monitor using semantic change detection."""
+
+ id: str
+
+ change_detection: MonitorsExtractSemanticMonitorChangeDetection
+ """Detect meaning-level changes that match a natural language query."""
+
+ created_at: datetime
+
+ name: str
+
+ schedule: MonitorsExtractSemanticMonitorSchedule
+ """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+
+ every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ between 10 minutes and 1 year.
+ """
+
+ status: Literal["active", "paused", "failed"]
+
+ target: MonitorsExtractSemanticMonitorTarget
+
+ updated_at: datetime
+
+ last_change_at: Optional[datetime] = None
+
+ last_run_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+ """User-defined tags for grouping and filtering monitors and their changes."""
+
+ webhook: Optional[MonitorsExtractSemanticMonitorWebhook] = None
+
+
+MonitorUpdateResponse: TypeAlias = Union[
+ MonitorsPageExactMonitor, MonitorsSitemapExactMonitor, MonitorsPageSemanticMonitor, MonitorsExtractSemanticMonitor
+]
diff --git a/tests/api_resources/test_monitors.py b/tests/api_resources/test_monitors.py
new file mode 100644
index 0000000..54dd812
--- /dev/null
+++ b/tests/api_resources/test_monitors.py
@@ -0,0 +1,1713 @@
+# 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 (
+ MonitorRunResponse,
+ MonitorListResponse,
+ MonitorCreateResponse,
+ MonitorDeleteResponse,
+ MonitorUpdateResponse,
+ MonitorListRunsResponse,
+ MonitorRetrieveResponse,
+ MonitorListChangesResponse,
+ MonitorRetrieveChangeResponse,
+ MonitorListAccountRunsResponse,
+ MonitorListAccountChangesResponse,
+)
+from context.dev._utils import parse_datetime
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestMonitors:
+ 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_create_overload_1(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_with_all_params_overload_1(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ "normalize_whitespace": True,
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create_overload_1(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create_overload_1(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_overload_2(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_with_all_params_overload_2(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ "exclude": ["/legal/*", "/privacy"],
+ "include": ["/blog/*", "/pricing*"],
+ "max_urls": 1,
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create_overload_2(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create_overload_2(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_overload_3(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_with_all_params_overload_3(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ "confidence_threshold": 0,
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ "normalize_whitespace": True,
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create_overload_3(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create_overload_3(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_overload_4(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_with_all_params_overload_4(self, client: ContextDev) -> None:
+ monitor = client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ "confidence_threshold": 0,
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ "follow_subdomains": True,
+ "instructions": "Extract every pricing plan with its monthly price and included limits.",
+ "max_depth": 0,
+ "max_pages": 1,
+ "schema": {
+ "type": "bar",
+ "properties": "bar",
+ },
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create_overload_4(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create_overload_4(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve(self, client: ContextDev) -> None:
+ monitor = client.monitors.retrieve(
+ "mon_123",
+ )
+ assert_matches_type(MonitorRetrieveResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.retrieve(
+ "mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorRetrieveResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.retrieve(
+ "mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorRetrieveResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ client.monitors.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update(self, client: ContextDev) -> None:
+ monitor = client.monitors.update(
+ monitor_id="mon_123",
+ )
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update_with_all_params(self, client: ContextDev) -> None:
+ monitor = client.monitors.update(
+ monitor_id="mon_123",
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 1,
+ "type": "interval",
+ "unit": "hours",
+ },
+ status="active",
+ tags=["pricing", "competitor"],
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ "normalize_whitespace": True,
+ },
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.update(
+ monitor_id="mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.update(
+ monitor_id="mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_update(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ client.monitors.with_raw_response.update(
+ monitor_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: ContextDev) -> None:
+ monitor = client.monitors.list()
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: ContextDev) -> None:
+ monitor = client.monitors.list(
+ change_detection_type="exact",
+ cursor="cursor",
+ limit=1,
+ status="active",
+ tag="tag",
+ target_type="page",
+ )
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_delete(self, client: ContextDev) -> None:
+ monitor = client.monitors.delete(
+ "mon_123",
+ )
+ assert_matches_type(MonitorDeleteResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_delete(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.delete(
+ "mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorDeleteResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_delete(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.delete(
+ "mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorDeleteResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_delete(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ client.monitors.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_account_changes(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_account_changes()
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_account_changes_with_all_params(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_account_changes(
+ change_detection_type="exact",
+ cursor="cursor",
+ limit=1,
+ monitor_id="monitor_id",
+ since=parse_datetime("2019-12-27T18:11:19.117Z"),
+ tag="tag",
+ target_type="page",
+ until=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list_account_changes(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.list_account_changes()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list_account_changes(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.list_account_changes() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_account_runs(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_account_runs()
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_account_runs_with_all_params(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_account_runs(
+ cursor="cursor",
+ limit=1,
+ status="queued",
+ )
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list_account_runs(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.list_account_runs()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list_account_runs(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.list_account_runs() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_changes(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_changes(
+ monitor_id="mon_123",
+ )
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_changes_with_all_params(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_changes(
+ monitor_id="mon_123",
+ cursor="cursor",
+ limit=1,
+ since=parse_datetime("2019-12-27T18:11:19.117Z"),
+ tag="tag",
+ until=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list_changes(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.list_changes(
+ monitor_id="mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list_changes(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.list_changes(
+ monitor_id="mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_list_changes(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ client.monitors.with_raw_response.list_changes(
+ monitor_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_runs(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_runs(
+ monitor_id="mon_123",
+ )
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_runs_with_all_params(self, client: ContextDev) -> None:
+ monitor = client.monitors.list_runs(
+ monitor_id="mon_123",
+ cursor="cursor",
+ limit=1,
+ status="queued",
+ )
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list_runs(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.list_runs(
+ monitor_id="mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list_runs(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.list_runs(
+ monitor_id="mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_list_runs(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ client.monitors.with_raw_response.list_runs(
+ monitor_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_change(self, client: ContextDev) -> None:
+ monitor = client.monitors.retrieve_change(
+ "chg_123",
+ )
+ assert_matches_type(MonitorRetrieveChangeResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve_change(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.retrieve_change(
+ "chg_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorRetrieveChangeResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve_change(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.retrieve_change(
+ "chg_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorRetrieveChangeResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve_change(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `change_id` but received ''"):
+ client.monitors.with_raw_response.retrieve_change(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_run(self, client: ContextDev) -> None:
+ monitor = client.monitors.run(
+ "mon_123",
+ )
+ assert_matches_type(MonitorRunResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_run(self, client: ContextDev) -> None:
+ response = client.monitors.with_raw_response.run(
+ "mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = response.parse()
+ assert_matches_type(MonitorRunResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_run(self, client: ContextDev) -> None:
+ with client.monitors.with_streaming_response.run(
+ "mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = response.parse()
+ assert_matches_type(MonitorRunResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_run(self, client: ContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ client.monitors.with_raw_response.run(
+ "",
+ )
+
+
+class TestAsyncMonitors:
+ 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_create_overload_1(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_with_all_params_overload_1(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ "normalize_whitespace": True,
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create_overload_1(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_overload_1(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_overload_2(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_with_all_params_overload_2(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ "exclude": ["/legal/*", "/privacy"],
+ "include": ["/blog/*", "/pricing*"],
+ "max_urls": 1,
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create_overload_2(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_overload_2(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.create(
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "sitemap",
+ "url": "https://acme.com/sitemap.xml",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_overload_3(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_with_all_params_overload_3(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ "confidence_threshold": 0,
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ "normalize_whitespace": True,
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create_overload_3(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_overload_3(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_overload_4(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ },
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_with_all_params_overload_4(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ "confidence_threshold": 0,
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ "follow_subdomains": True,
+ "instructions": "Extract every pricing plan with its monthly price and included limits.",
+ "max_depth": 0,
+ "max_pages": 1,
+ "schema": {
+ "type": "bar",
+ "properties": "bar",
+ },
+ },
+ tags=["pricing", "competitor"],
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create_overload_4(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_overload_4(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.create(
+ change_detection={
+ "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
+ "type": "semantic",
+ },
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 6,
+ "type": "interval",
+ "unit": "hours",
+ },
+ target={
+ "type": "extract",
+ "url": "https://acme.com",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.retrieve(
+ "mon_123",
+ )
+ assert_matches_type(MonitorRetrieveResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.retrieve(
+ "mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorRetrieveResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.retrieve(
+ "mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorRetrieveResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ await async_client.monitors.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.update(
+ monitor_id="mon_123",
+ )
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.update(
+ monitor_id="mon_123",
+ change_detection={"type": "exact"},
+ name="Acme pricing monitor",
+ schedule={
+ "frequency": 1,
+ "type": "interval",
+ "unit": "hours",
+ },
+ status="active",
+ tags=["pricing", "competitor"],
+ target={
+ "type": "page",
+ "url": "https://acme.com/pricing",
+ "normalize_whitespace": True,
+ },
+ webhook={"url": "https://example.com/webhook"},
+ )
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.update(
+ monitor_id="mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.update(
+ monitor_id="mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorUpdateResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_update(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ await async_client.monitors.with_raw_response.update(
+ monitor_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list()
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list(
+ change_detection_type="exact",
+ cursor="cursor",
+ limit=1,
+ status="active",
+ tag="tag",
+ target_type="page",
+ )
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorListResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.delete(
+ "mon_123",
+ )
+ assert_matches_type(MonitorDeleteResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.delete(
+ "mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorDeleteResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.delete(
+ "mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorDeleteResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ await async_client.monitors.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_account_changes(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_account_changes()
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_account_changes_with_all_params(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_account_changes(
+ change_detection_type="exact",
+ cursor="cursor",
+ limit=1,
+ monitor_id="monitor_id",
+ since=parse_datetime("2019-12-27T18:11:19.117Z"),
+ tag="tag",
+ target_type="page",
+ until=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list_account_changes(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.list_account_changes()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list_account_changes(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.list_account_changes() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorListAccountChangesResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_account_runs(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_account_runs()
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_account_runs_with_all_params(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_account_runs(
+ cursor="cursor",
+ limit=1,
+ status="queued",
+ )
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list_account_runs(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.list_account_runs()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list_account_runs(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.list_account_runs() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorListAccountRunsResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_changes(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_changes(
+ monitor_id="mon_123",
+ )
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_changes_with_all_params(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_changes(
+ monitor_id="mon_123",
+ cursor="cursor",
+ limit=1,
+ since=parse_datetime("2019-12-27T18:11:19.117Z"),
+ tag="tag",
+ until=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list_changes(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.list_changes(
+ monitor_id="mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list_changes(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.list_changes(
+ monitor_id="mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorListChangesResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_list_changes(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ await async_client.monitors.with_raw_response.list_changes(
+ monitor_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_runs(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_runs(
+ monitor_id="mon_123",
+ )
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_runs_with_all_params(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.list_runs(
+ monitor_id="mon_123",
+ cursor="cursor",
+ limit=1,
+ status="queued",
+ )
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list_runs(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.list_runs(
+ monitor_id="mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list_runs(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.list_runs(
+ monitor_id="mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorListRunsResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_list_runs(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ await async_client.monitors.with_raw_response.list_runs(
+ monitor_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_change(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.retrieve_change(
+ "chg_123",
+ )
+ assert_matches_type(MonitorRetrieveChangeResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve_change(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.retrieve_change(
+ "chg_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorRetrieveChangeResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve_change(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.retrieve_change(
+ "chg_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorRetrieveChangeResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve_change(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `change_id` but received ''"):
+ await async_client.monitors.with_raw_response.retrieve_change(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_run(self, async_client: AsyncContextDev) -> None:
+ monitor = await async_client.monitors.run(
+ "mon_123",
+ )
+ assert_matches_type(MonitorRunResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_run(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.monitors.with_raw_response.run(
+ "mon_123",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ monitor = await response.parse()
+ assert_matches_type(MonitorRunResponse, monitor, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_run(self, async_client: AsyncContextDev) -> None:
+ async with async_client.monitors.with_streaming_response.run(
+ "mon_123",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ monitor = await response.parse()
+ assert_matches_type(MonitorRunResponse, monitor, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_run(self, async_client: AsyncContextDev) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_id` but received ''"):
+ await async_client.monitors.with_raw_response.run(
+ "",
+ )
From 789eb8671cd52aba441a03c0139f6993455b5f4d Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 30 Jun 2026 01:13:39 +0000
Subject: [PATCH 03/18] feat(api): api update
---
.stats.yml | 4 +-
src/context/dev/resources/monitors.py | 616 +++++------------
.../dev/types/monitor_create_params.py | 262 ++------
.../dev/types/monitor_create_response.py | 346 ++--------
.../monitor_list_account_changes_response.py | 108 +--
.../types/monitor_list_changes_response.py | 108 +--
src/context/dev/types/monitor_list_params.py | 23 +
.../dev/types/monitor_list_response.py | 349 ++--------
.../types/monitor_retrieve_change_response.py | 149 +----
.../dev/types/monitor_retrieve_response.py | 346 ++--------
.../dev/types/monitor_update_params.py | 6 +
.../dev/types/monitor_update_response.py | 346 ++--------
tests/api_resources/test_monitors.py | 622 +-----------------
13 files changed, 572 insertions(+), 2713 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 2f86aeb..0115b3b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-8667763c416101820f5086c97d542bf13bb3bb12b57f5f604da671d9dcea0599.yml
-openapi_spec_hash: e33db883d584bc8573897391f3edb105
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-66a3bf68b47ba61c9b61406d36f614a079ff752b8964a8df8062e485391d5598.yml
+openapi_spec_hash: b17d6cfe3710dd0605078f3907a1a419
config_hash: 7ec4851ee8d93177947e95df5ae897b5
diff --git a/src/context/dev/resources/monitors.py b/src/context/dev/resources/monitors.py
index 1eb37cb..9147870 100644
--- a/src/context/dev/resources/monitors.py
+++ b/src/context/dev/resources/monitors.py
@@ -2,9 +2,9 @@
from __future__ import annotations
-from typing import Any, Union, Optional, cast
+from typing import List, Union, Optional
from datetime import datetime
-from typing_extensions import Literal, overload
+from typing_extensions import Literal
import httpx
@@ -18,7 +18,7 @@
monitor_list_account_changes_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import path_template, required_args, maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -67,16 +67,16 @@ def with_streaming_response(self) -> MonitorsResourceWithStreamingResponse:
"""
return MonitorsResourceWithStreamingResponse(self)
- @overload
def create(
self,
*,
- change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection,
+ change_detection: monitor_create_params.ChangeDetection,
name: str,
- schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget,
+ schedule: monitor_create_params.Schedule,
+ target: monitor_create_params.Target,
+ mode: Literal["web"] | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook] | Omit = omit,
+ webhook: Optional[monitor_create_params.Webhook] | 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,
@@ -91,139 +91,16 @@ def create(
its initial baseline.
Args:
- change_detection: Detect exact changes. For page targets, this means visible text diffs. For
- sitemap targets, this means URL additions and removals.
-
- schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
-
- tags: User-defined tags for grouping and filtering monitors and their changes.
-
- 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
- """
- ...
-
- @overload
- def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook] | 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,
- ) -> MonitorCreateResponse:
- """Creates a monitor.
-
- The request body is a union of the supported target/change
- detection combinations. The monitor runs immediately after creation to create
- its initial baseline.
-
- Args:
- change_detection: Detect exact changes. For page targets, this means visible text diffs. For
- sitemap targets, this means URL additions and removals.
-
- schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
-
- tags: User-defined tags for grouping and filtering monitors and their changes.
-
- 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
- """
- ...
-
- @overload
- def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook] | 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,
- ) -> MonitorCreateResponse:
- """Creates a monitor.
-
- The request body is a union of the supported target/change
- detection combinations. The monitor runs immediately after creation to create
- its initial baseline.
-
- Args:
- change_detection: Detect meaning-level changes that match a natural language query.
+ change_detection: Discriminated union describing how changes are detected.
schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
between 10 minutes and 1 year.
- tags: User-defined tags for grouping and filtering monitors and their changes.
-
- 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
- """
- ...
-
- @overload
- def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook] | 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,
- ) -> MonitorCreateResponse:
- """Creates a monitor.
-
- The request body is a union of the supported target/change
- detection combinations. The monitor runs immediately after creation to create
- its initial baseline.
-
- Args:
- change_detection: Detect meaning-level changes that match a natural language query.
+ target: Discriminated union describing what the monitor watches.
- schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
+ mode: Top-level monitor category. Always `web` today; the concrete behavior is
+ described by `target` and `change_detection`.
tags: User-defined tags for grouping and filtering monitors and their changes.
@@ -235,60 +112,24 @@ def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
- ...
-
- @required_args(["change_detection", "name", "schedule", "target"])
- def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection
- | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection
- | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection
- | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule
- | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule
- | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule
- | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget
- | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget
- | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget
- | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook]
- | Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook]
- | Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook]
- | Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook]
- | 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,
- ) -> MonitorCreateResponse:
- return cast(
- MonitorCreateResponse,
- self._post(
- "/monitors",
- body=maybe_transform(
- {
- "change_detection": change_detection,
- "name": name,
- "schedule": schedule,
- "target": target,
- "tags": tags,
- "webhook": webhook,
- },
- monitor_create_params.MonitorCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorCreateResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return self._post(
+ "/monitors",
+ body=maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "target": target,
+ "mode": mode,
+ "tags": tags,
+ "webhook": webhook,
+ },
+ monitor_create_params.MonitorCreateParams,
),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MonitorCreateResponse,
)
def retrieve(
@@ -316,17 +157,12 @@ def retrieve(
"""
if not monitor_id:
raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
- return cast(
- MonitorRetrieveResponse,
- self._get(
- path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorRetrieveResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return self._get(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=MonitorRetrieveResponse,
)
def update(
@@ -376,29 +212,24 @@ def update(
"""
if not monitor_id:
raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
- return cast(
- MonitorUpdateResponse,
- self._patch(
- path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
- body=maybe_transform(
- {
- "change_detection": change_detection,
- "name": name,
- "schedule": schedule,
- "status": status,
- "tags": tags,
- "target": target,
- "webhook": webhook,
- },
- monitor_update_params.MonitorUpdateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorUpdateResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return self._patch(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ body=maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "status": status,
+ "tags": tags,
+ "target": target,
+ "webhook": webhook,
+ },
+ monitor_update_params.MonitorUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=MonitorUpdateResponse,
)
def list(
@@ -407,8 +238,12 @@ def list(
change_detection_type: Literal["exact", "semantic"] | Omit = omit,
cursor: str | Omit = omit,
limit: int | Omit = omit,
+ q: str | Omit = omit,
+ search_by: List[Literal["name", "url", "query", "tags"]] | Omit = omit,
+ search_type: Literal["exact", "prefix"] | Omit = omit,
status: Literal["active", "paused", "failed"] | Omit = omit,
tag: str | Omit = omit,
+ tags: SequenceNotStr[str] | Omit = omit,
target_type: Literal["page", "sitemap", "extract"] | 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.
@@ -417,12 +252,25 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MonitorListResponse:
- """
- List monitors
+ """Lists monitors for the authenticated organization.
+
+ Supports free-text search
+ (`q` over `search_by` fields, `prefix` or `exact` via `search_type`) plus
+ status/type/tag filters. Results are paginated via the opaque `cursor`.
Args:
+ q: Free-text search term, matched against the fields named in `search_by`.
+
+ search_by: Comma-separated fields to search with `q`. Defaults to all of them. Note `query`
+ only exists on semantic monitors.
+
+ search_type: `prefix` for as-you-type prefix matching (default), `exact` for full-token
+ matching.
+
tag: Filter to items that have this tag.
+ tags: Comma-separated list of tags to filter by (matches monitors having any of them).
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -443,8 +291,12 @@ def list(
"change_detection_type": change_detection_type,
"cursor": cursor,
"limit": limit,
+ "q": q,
+ "search_by": search_by,
+ "search_type": search_type,
"status": status,
"tag": tag,
+ "tags": tags,
"target_type": target_type,
},
monitor_list_params.MonitorListParams,
@@ -711,17 +563,12 @@ def retrieve_change(
"""
if not change_id:
raise ValueError(f"Expected a non-empty value for `change_id` but received {change_id!r}")
- return cast(
- MonitorRetrieveChangeResponse,
- self._get(
- path_template("/monitors/changes/{change_id}", change_id=change_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorRetrieveChangeResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return self._get(
+ path_template("/monitors/changes/{change_id}", change_id=change_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=MonitorRetrieveChangeResponse,
)
def run(
@@ -784,16 +631,16 @@ def with_streaming_response(self) -> AsyncMonitorsResourceWithStreamingResponse:
"""
return AsyncMonitorsResourceWithStreamingResponse(self)
- @overload
async def create(
self,
*,
- change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection,
+ change_detection: monitor_create_params.ChangeDetection,
name: str,
- schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget,
+ schedule: monitor_create_params.Schedule,
+ target: monitor_create_params.Target,
+ mode: Literal["web"] | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook] | Omit = omit,
+ webhook: Optional[monitor_create_params.Webhook] | 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,
@@ -808,139 +655,16 @@ async def create(
its initial baseline.
Args:
- change_detection: Detect exact changes. For page targets, this means visible text diffs. For
- sitemap targets, this means URL additions and removals.
-
- schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
-
- tags: User-defined tags for grouping and filtering monitors and their changes.
-
- 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
- """
- ...
-
- @overload
- async def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook] | 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,
- ) -> MonitorCreateResponse:
- """Creates a monitor.
-
- The request body is a union of the supported target/change
- detection combinations. The monitor runs immediately after creation to create
- its initial baseline.
-
- Args:
- change_detection: Detect exact changes. For page targets, this means visible text diffs. For
- sitemap targets, this means URL additions and removals.
-
- schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
-
- tags: User-defined tags for grouping and filtering monitors and their changes.
-
- 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
- """
- ...
-
- @overload
- async def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook] | 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,
- ) -> MonitorCreateResponse:
- """Creates a monitor.
-
- The request body is a union of the supported target/change
- detection combinations. The monitor runs immediately after creation to create
- its initial baseline.
-
- Args:
- change_detection: Detect meaning-level changes that match a natural language query.
+ change_detection: Discriminated union describing how changes are detected.
schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
between 10 minutes and 1 year.
- tags: User-defined tags for grouping and filtering monitors and their changes.
-
- 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
- """
- ...
-
- @overload
- async def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook] | 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,
- ) -> MonitorCreateResponse:
- """Creates a monitor.
-
- The request body is a union of the supported target/change
- detection combinations. The monitor runs immediately after creation to create
- its initial baseline.
-
- Args:
- change_detection: Detect meaning-level changes that match a natural language query.
+ target: Discriminated union describing what the monitor watches.
- schedule: Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
+ mode: Top-level monitor category. Always `web` today; the concrete behavior is
+ described by `target` and `change_detection`.
tags: User-defined tags for grouping and filtering monitors and their changes.
@@ -952,60 +676,24 @@ async def create(
timeout: Override the client-level default timeout for this request, in seconds
"""
- ...
-
- @required_args(["change_detection", "name", "schedule", "target"])
- async def create(
- self,
- *,
- change_detection: monitor_create_params.MonitorsCreatePageExactMonitorRequestChangeDetection
- | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestChangeDetection
- | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestChangeDetection
- | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestChangeDetection,
- name: str,
- schedule: monitor_create_params.MonitorsCreatePageExactMonitorRequestSchedule
- | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestSchedule
- | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestSchedule
- | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestSchedule,
- target: monitor_create_params.MonitorsCreatePageExactMonitorRequestTarget
- | monitor_create_params.MonitorsCreateSitemapExactMonitorRequestTarget
- | monitor_create_params.MonitorsCreatePageSemanticMonitorRequestTarget
- | monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestTarget,
- tags: SequenceNotStr[str] | Omit = omit,
- webhook: Optional[monitor_create_params.MonitorsCreatePageExactMonitorRequestWebhook]
- | Optional[monitor_create_params.MonitorsCreateSitemapExactMonitorRequestWebhook]
- | Optional[monitor_create_params.MonitorsCreatePageSemanticMonitorRequestWebhook]
- | Optional[monitor_create_params.MonitorsCreateExtractSemanticMonitorRequestWebhook]
- | 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,
- ) -> MonitorCreateResponse:
- return cast(
- MonitorCreateResponse,
- await self._post(
- "/monitors",
- body=await async_maybe_transform(
- {
- "change_detection": change_detection,
- "name": name,
- "schedule": schedule,
- "target": target,
- "tags": tags,
- "webhook": webhook,
- },
- monitor_create_params.MonitorCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorCreateResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return await self._post(
+ "/monitors",
+ body=await async_maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "target": target,
+ "mode": mode,
+ "tags": tags,
+ "webhook": webhook,
+ },
+ monitor_create_params.MonitorCreateParams,
),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=MonitorCreateResponse,
)
async def retrieve(
@@ -1033,17 +721,12 @@ async def retrieve(
"""
if not monitor_id:
raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
- return cast(
- MonitorRetrieveResponse,
- await self._get(
- path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorRetrieveResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return await self._get(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=MonitorRetrieveResponse,
)
async def update(
@@ -1093,29 +776,24 @@ async def update(
"""
if not monitor_id:
raise ValueError(f"Expected a non-empty value for `monitor_id` but received {monitor_id!r}")
- return cast(
- MonitorUpdateResponse,
- await self._patch(
- path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
- body=await async_maybe_transform(
- {
- "change_detection": change_detection,
- "name": name,
- "schedule": schedule,
- "status": status,
- "tags": tags,
- "target": target,
- "webhook": webhook,
- },
- monitor_update_params.MonitorUpdateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorUpdateResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return await self._patch(
+ path_template("/monitors/{monitor_id}", monitor_id=monitor_id),
+ body=await async_maybe_transform(
+ {
+ "change_detection": change_detection,
+ "name": name,
+ "schedule": schedule,
+ "status": status,
+ "tags": tags,
+ "target": target,
+ "webhook": webhook,
+ },
+ monitor_update_params.MonitorUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=MonitorUpdateResponse,
)
async def list(
@@ -1124,8 +802,12 @@ async def list(
change_detection_type: Literal["exact", "semantic"] | Omit = omit,
cursor: str | Omit = omit,
limit: int | Omit = omit,
+ q: str | Omit = omit,
+ search_by: List[Literal["name", "url", "query", "tags"]] | Omit = omit,
+ search_type: Literal["exact", "prefix"] | Omit = omit,
status: Literal["active", "paused", "failed"] | Omit = omit,
tag: str | Omit = omit,
+ tags: SequenceNotStr[str] | Omit = omit,
target_type: Literal["page", "sitemap", "extract"] | 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.
@@ -1134,12 +816,25 @@ async def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MonitorListResponse:
- """
- List monitors
+ """Lists monitors for the authenticated organization.
+
+ Supports free-text search
+ (`q` over `search_by` fields, `prefix` or `exact` via `search_type`) plus
+ status/type/tag filters. Results are paginated via the opaque `cursor`.
Args:
+ q: Free-text search term, matched against the fields named in `search_by`.
+
+ search_by: Comma-separated fields to search with `q`. Defaults to all of them. Note `query`
+ only exists on semantic monitors.
+
+ search_type: `prefix` for as-you-type prefix matching (default), `exact` for full-token
+ matching.
+
tag: Filter to items that have this tag.
+ tags: Comma-separated list of tags to filter by (matches monitors having any of them).
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1160,8 +855,12 @@ async def list(
"change_detection_type": change_detection_type,
"cursor": cursor,
"limit": limit,
+ "q": q,
+ "search_by": search_by,
+ "search_type": search_type,
"status": status,
"tag": tag,
+ "tags": tags,
"target_type": target_type,
},
monitor_list_params.MonitorListParams,
@@ -1428,17 +1127,12 @@ async def retrieve_change(
"""
if not change_id:
raise ValueError(f"Expected a non-empty value for `change_id` but received {change_id!r}")
- return cast(
- MonitorRetrieveChangeResponse,
- await self._get(
- path_template("/monitors/changes/{change_id}", change_id=change_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=cast(
- Any, MonitorRetrieveChangeResponse
- ), # Union types cannot be passed in as arguments in the type system
+ return await self._get(
+ path_template("/monitors/changes/{change_id}", change_id=change_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
+ cast_to=MonitorRetrieveChangeResponse,
)
async def run(
diff --git a/src/context/dev/types/monitor_create_params.py b/src/context/dev/types/monitor_create_params.py
index 0d01412..93a333c 100644
--- a/src/context/dev/types/monitor_create_params.py
+++ b/src/context/dev/types/monitor_create_params.py
@@ -9,122 +9,48 @@
__all__ = [
"MonitorCreateParams",
- "MonitorsCreatePageExactMonitorRequest",
- "MonitorsCreatePageExactMonitorRequestChangeDetection",
- "MonitorsCreatePageExactMonitorRequestSchedule",
- "MonitorsCreatePageExactMonitorRequestTarget",
- "MonitorsCreatePageExactMonitorRequestWebhook",
- "MonitorsCreateSitemapExactMonitorRequest",
- "MonitorsCreateSitemapExactMonitorRequestChangeDetection",
- "MonitorsCreateSitemapExactMonitorRequestSchedule",
- "MonitorsCreateSitemapExactMonitorRequestTarget",
- "MonitorsCreateSitemapExactMonitorRequestWebhook",
- "MonitorsCreatePageSemanticMonitorRequest",
- "MonitorsCreatePageSemanticMonitorRequestChangeDetection",
- "MonitorsCreatePageSemanticMonitorRequestSchedule",
- "MonitorsCreatePageSemanticMonitorRequestTarget",
- "MonitorsCreatePageSemanticMonitorRequestWebhook",
- "MonitorsCreateExtractSemanticMonitorRequest",
- "MonitorsCreateExtractSemanticMonitorRequestChangeDetection",
- "MonitorsCreateExtractSemanticMonitorRequestSchedule",
- "MonitorsCreateExtractSemanticMonitorRequestTarget",
- "MonitorsCreateExtractSemanticMonitorRequestWebhook",
+ "ChangeDetection",
+ "ChangeDetectionMonitorsExactChangeDetection",
+ "ChangeDetectionMonitorsSemanticChangeDetection",
+ "Schedule",
+ "Target",
+ "TargetMonitorsPageTarget",
+ "TargetMonitorsSitemapTarget",
+ "TargetMonitorsExtractTarget",
+ "Webhook",
]
-class MonitorsCreatePageExactMonitorRequest(TypedDict, total=False):
- change_detection: Required[MonitorsCreatePageExactMonitorRequestChangeDetection]
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
+class MonitorCreateParams(TypedDict, total=False):
+ change_detection: Required[ChangeDetection]
+ """Discriminated union describing how changes are detected."""
name: Required[str]
- schedule: Required[MonitorsCreatePageExactMonitorRequestSchedule]
+ schedule: Required[Schedule]
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
between 10 minutes and 1 year.
"""
- target: Required[MonitorsCreatePageExactMonitorRequestTarget]
-
- tags: SequenceNotStr[str]
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsCreatePageExactMonitorRequestWebhook]
-
-
-class MonitorsCreatePageExactMonitorRequestChangeDetection(TypedDict, total=False):
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
- """
-
- type: Required[Literal["exact"]]
-
-
-class MonitorsCreatePageExactMonitorRequestSchedule(TypedDict, total=False):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: Required[int]
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Required[Literal["interval"]]
-
- unit: Required[Literal["minutes", "hours", "days"]]
-
-
-class MonitorsCreatePageExactMonitorRequestTarget(TypedDict, total=False):
- type: Required[Literal["page"]]
-
- url: Required[str]
-
- normalize_whitespace: bool
- """Normalize whitespace before comparing or analyzing text."""
-
-
-class MonitorsCreatePageExactMonitorRequestWebhook(TypedDict, total=False):
- url: Required[str]
- """Webhook URL called when a change is detected."""
-
-
-class MonitorsCreateSitemapExactMonitorRequest(TypedDict, total=False):
- change_detection: Required[MonitorsCreateSitemapExactMonitorRequestChangeDetection]
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- name: Required[str]
+ target: Required[Target]
+ """Discriminated union describing what the monitor watches."""
- schedule: Required[MonitorsCreateSitemapExactMonitorRequestSchedule]
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ mode: Literal["web"]
+ """Top-level monitor category.
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
"""
- target: Required[MonitorsCreateSitemapExactMonitorRequestTarget]
-
tags: SequenceNotStr[str]
"""User-defined tags for grouping and filtering monitors and their changes."""
- webhook: Optional[MonitorsCreateSitemapExactMonitorRequestWebhook]
+ webhook: Optional[Webhook]
-class MonitorsCreateSitemapExactMonitorRequestChangeDetection(TypedDict, total=False):
+class ChangeDetectionMonitorsExactChangeDetection(TypedDict, total=False):
"""Detect exact changes.
For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
@@ -133,67 +59,7 @@ class MonitorsCreateSitemapExactMonitorRequestChangeDetection(TypedDict, total=F
type: Required[Literal["exact"]]
-class MonitorsCreateSitemapExactMonitorRequestSchedule(TypedDict, total=False):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: Required[int]
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Required[Literal["interval"]]
-
- unit: Required[Literal["minutes", "hours", "days"]]
-
-
-class MonitorsCreateSitemapExactMonitorRequestTarget(TypedDict, total=False):
- type: Required[Literal["sitemap"]]
-
- url: Required[str]
- """Sitemap URL to monitor."""
-
- exclude: SequenceNotStr[str]
- """URL path patterns to exclude."""
-
- include: SequenceNotStr[str]
- """URL path patterns to include."""
-
- max_urls: int
-
-
-class MonitorsCreateSitemapExactMonitorRequestWebhook(TypedDict, total=False):
- url: Required[str]
- """Webhook URL called when a change is detected."""
-
-
-class MonitorsCreatePageSemanticMonitorRequest(TypedDict, total=False):
- change_detection: Required[MonitorsCreatePageSemanticMonitorRequestChangeDetection]
- """Detect meaning-level changes that match a natural language query."""
-
- name: Required[str]
-
- schedule: Required[MonitorsCreatePageSemanticMonitorRequestSchedule]
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- target: Required[MonitorsCreatePageSemanticMonitorRequestTarget]
-
- tags: SequenceNotStr[str]
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsCreatePageSemanticMonitorRequestWebhook]
-
-
-class MonitorsCreatePageSemanticMonitorRequestChangeDetection(TypedDict, total=False):
+class ChangeDetectionMonitorsSemanticChangeDetection(TypedDict, total=False):
"""Detect meaning-level changes that match a natural language query."""
query: Required[str]
@@ -203,7 +69,12 @@ class MonitorsCreatePageSemanticMonitorRequestChangeDetection(TypedDict, total=F
confidence_threshold: float
-class MonitorsCreatePageSemanticMonitorRequestSchedule(TypedDict, total=False):
+ChangeDetection: TypeAlias = Union[
+ ChangeDetectionMonitorsExactChangeDetection, ChangeDetectionMonitorsSemanticChangeDetection
+]
+
+
+class Schedule(TypedDict, total=False):
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
@@ -222,7 +93,9 @@ class MonitorsCreatePageSemanticMonitorRequestSchedule(TypedDict, total=False):
unit: Required[Literal["minutes", "hours", "days"]]
-class MonitorsCreatePageSemanticMonitorRequestTarget(TypedDict, total=False):
+class TargetMonitorsPageTarget(TypedDict, total=False):
+ """Watch a single web page."""
+
type: Required[Literal["page"]]
url: Required[str]
@@ -231,62 +104,26 @@ class MonitorsCreatePageSemanticMonitorRequestTarget(TypedDict, total=False):
"""Normalize whitespace before comparing or analyzing text."""
-class MonitorsCreatePageSemanticMonitorRequestWebhook(TypedDict, total=False):
- url: Required[str]
- """Webhook URL called when a change is detected."""
-
-
-class MonitorsCreateExtractSemanticMonitorRequest(TypedDict, total=False):
- change_detection: Required[MonitorsCreateExtractSemanticMonitorRequestChangeDetection]
- """Detect meaning-level changes that match a natural language query."""
-
- name: Required[str]
-
- schedule: Required[MonitorsCreateExtractSemanticMonitorRequestSchedule]
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- target: Required[MonitorsCreateExtractSemanticMonitorRequestTarget]
-
- tags: SequenceNotStr[str]
- """User-defined tags for grouping and filtering monitors and their changes."""
+class TargetMonitorsSitemapTarget(TypedDict, total=False):
+ """Watch a sitemap for URL additions and removals."""
- webhook: Optional[MonitorsCreateExtractSemanticMonitorRequestWebhook]
-
-
-class MonitorsCreateExtractSemanticMonitorRequestChangeDetection(TypedDict, total=False):
- """Detect meaning-level changes that match a natural language query."""
-
- query: Required[str]
-
- type: Required[Literal["semantic"]]
-
- confidence_threshold: float
-
-
-class MonitorsCreateExtractSemanticMonitorRequestSchedule(TypedDict, total=False):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ type: Required[Literal["sitemap"]]
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
+ url: Required[str]
+ """Sitemap URL to monitor."""
- frequency: Required[int]
- """Number of units between runs.
+ exclude: SequenceNotStr[str]
+ """URL path patterns to exclude."""
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
+ include: SequenceNotStr[str]
+ """URL path patterns to include."""
- type: Required[Literal["interval"]]
+ max_urls: int
- unit: Required[Literal["minutes", "hours", "days"]]
+class TargetMonitorsExtractTarget(TypedDict, total=False):
+ """Watch a site's extracted structured data."""
-class MonitorsCreateExtractSemanticMonitorRequestTarget(TypedDict, total=False):
type: Required[Literal["extract"]]
url: Required[str]
@@ -310,14 +147,9 @@ class MonitorsCreateExtractSemanticMonitorRequestTarget(TypedDict, total=False):
"""
-class MonitorsCreateExtractSemanticMonitorRequestWebhook(TypedDict, total=False):
- url: Required[str]
- """Webhook URL called when a change is detected."""
+Target: TypeAlias = Union[TargetMonitorsPageTarget, TargetMonitorsSitemapTarget, TargetMonitorsExtractTarget]
-MonitorCreateParams: TypeAlias = Union[
- MonitorsCreatePageExactMonitorRequest,
- MonitorsCreateSitemapExactMonitorRequest,
- MonitorsCreatePageSemanticMonitorRequest,
- MonitorsCreateExtractSemanticMonitorRequest,
-]
+class Webhook(TypedDict, total=False):
+ url: Required[str]
+ """Webhook URL called when a change is detected."""
diff --git a/src/context/dev/types/monitor_create_response.py b/src/context/dev/types/monitor_create_response.py
index 739efaa..f085273 100644
--- a/src/context/dev/types/monitor_create_response.py
+++ b/src/context/dev/types/monitor_create_response.py
@@ -2,38 +2,28 @@
from typing import Dict, List, Union, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal, Annotated, TypeAlias
from pydantic import Field as FieldInfo
+from .._utils import PropertyInfo
from .._models import BaseModel
__all__ = [
"MonitorCreateResponse",
- "MonitorsPageExactMonitor",
- "MonitorsPageExactMonitorChangeDetection",
- "MonitorsPageExactMonitorSchedule",
- "MonitorsPageExactMonitorTarget",
- "MonitorsPageExactMonitorWebhook",
- "MonitorsSitemapExactMonitor",
- "MonitorsSitemapExactMonitorChangeDetection",
- "MonitorsSitemapExactMonitorSchedule",
- "MonitorsSitemapExactMonitorTarget",
- "MonitorsSitemapExactMonitorWebhook",
- "MonitorsPageSemanticMonitor",
- "MonitorsPageSemanticMonitorChangeDetection",
- "MonitorsPageSemanticMonitorSchedule",
- "MonitorsPageSemanticMonitorTarget",
- "MonitorsPageSemanticMonitorWebhook",
- "MonitorsExtractSemanticMonitor",
- "MonitorsExtractSemanticMonitorChangeDetection",
- "MonitorsExtractSemanticMonitorSchedule",
- "MonitorsExtractSemanticMonitorTarget",
- "MonitorsExtractSemanticMonitorWebhook",
+ "ChangeDetection",
+ "ChangeDetectionMonitorsExactChangeDetection",
+ "ChangeDetectionMonitorsSemanticChangeDetection",
+ "Schedule",
+ "Target",
+ "TargetMonitorsPageTarget",
+ "TargetMonitorsSitemapTarget",
+ "TargetMonitorsExtractTarget",
+ "Webhook",
]
-class MonitorsPageExactMonitorChangeDetection(BaseModel):
+class ChangeDetectionMonitorsExactChangeDetection(BaseModel):
"""Detect exact changes.
For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
@@ -42,184 +32,7 @@ class MonitorsPageExactMonitorChangeDetection(BaseModel):
type: Literal["exact"]
-class MonitorsPageExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class MonitorsPageExactMonitorTarget(BaseModel):
- type: Literal["page"]
-
- url: str
-
- normalize_whitespace: Optional[bool] = None
- """Normalize whitespace before comparing or analyzing text."""
-
-
-class MonitorsPageExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsPageExactMonitor(BaseModel):
- """A page monitor using exact change detection."""
-
- id: str
-
- change_detection: MonitorsPageExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsPageExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsPageExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsPageExactMonitorWebhook] = None
-
-
-class MonitorsSitemapExactMonitorChangeDetection(BaseModel):
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
- """
-
- type: Literal["exact"]
-
-
-class MonitorsSitemapExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class MonitorsSitemapExactMonitorTarget(BaseModel):
- type: Literal["sitemap"]
-
- url: str
- """Sitemap URL to monitor."""
-
- exclude: Optional[List[str]] = None
- """URL path patterns to exclude."""
-
- include: Optional[List[str]] = None
- """URL path patterns to include."""
-
- max_urls: Optional[int] = None
-
-
-class MonitorsSitemapExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsSitemapExactMonitor(BaseModel):
- """A sitemap monitor using exact change detection."""
-
- id: str
-
- change_detection: MonitorsSitemapExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsSitemapExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsSitemapExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsSitemapExactMonitorWebhook] = None
-
-
-class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
+class ChangeDetectionMonitorsSemanticChangeDetection(BaseModel):
"""Detect meaning-level changes that match a natural language query."""
query: str
@@ -229,7 +42,13 @@ class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
confidence_threshold: Optional[float] = None
-class MonitorsPageSemanticMonitorSchedule(BaseModel):
+ChangeDetection: TypeAlias = Annotated[
+ Union[ChangeDetectionMonitorsExactChangeDetection, ChangeDetectionMonitorsSemanticChangeDetection],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class Schedule(BaseModel):
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
@@ -248,7 +67,9 @@ class MonitorsPageSemanticMonitorSchedule(BaseModel):
unit: Literal["minutes", "hours", "days"]
-class MonitorsPageSemanticMonitorTarget(BaseModel):
+class TargetMonitorsPageTarget(BaseModel):
+ """Watch a single web page."""
+
type: Literal["page"]
url: str
@@ -257,85 +78,26 @@ class MonitorsPageSemanticMonitorTarget(BaseModel):
"""Normalize whitespace before comparing or analyzing text."""
-class MonitorsPageSemanticMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsPageSemanticMonitor(BaseModel):
- """A page monitor using semantic change detection."""
-
- id: str
+class TargetMonitorsSitemapTarget(BaseModel):
+ """Watch a sitemap for URL additions and removals."""
- change_detection: MonitorsPageSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsPageSemanticMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsPageSemanticMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsPageSemanticMonitorWebhook] = None
-
-
-class MonitorsExtractSemanticMonitorChangeDetection(BaseModel):
- """Detect meaning-level changes that match a natural language query."""
-
- query: str
-
- type: Literal["semantic"]
-
- confidence_threshold: Optional[float] = None
-
-
-class MonitorsExtractSemanticMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ type: Literal["sitemap"]
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
+ url: str
+ """Sitemap URL to monitor."""
- frequency: int
- """Number of units between runs.
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
- type: Literal["interval"]
+ max_urls: Optional[int] = None
- unit: Literal["minutes", "hours", "days"]
+class TargetMonitorsExtractTarget(BaseModel):
+ """Watch a site's extracted structured data."""
-class MonitorsExtractSemanticMonitorTarget(BaseModel):
type: Literal["extract"]
url: str
@@ -359,7 +121,13 @@ class MonitorsExtractSemanticMonitorTarget(BaseModel):
"""
-class MonitorsExtractSemanticMonitorWebhook(BaseModel):
+Target: TypeAlias = Annotated[
+ Union[TargetMonitorsPageTarget, TargetMonitorsSitemapTarget, TargetMonitorsExtractTarget],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class Webhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -373,19 +141,29 @@ class MonitorsExtractSemanticMonitorWebhook(BaseModel):
"""
-class MonitorsExtractSemanticMonitor(BaseModel):
- """An extract monitor using semantic change detection."""
+class MonitorCreateResponse(BaseModel):
+ """A web monitor.
+
+ `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).
+ """
id: str
- change_detection: MonitorsExtractSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
+ change_detection: ChangeDetection
+ """Discriminated union describing how changes are detected."""
created_at: datetime
+ mode: Literal["web"]
+ """Top-level monitor category.
+
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
+
name: str
- schedule: MonitorsExtractSemanticMonitorSchedule
+ schedule: Schedule
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
@@ -394,7 +172,8 @@ class MonitorsExtractSemanticMonitor(BaseModel):
status: Literal["active", "paused", "failed"]
- target: MonitorsExtractSemanticMonitorTarget
+ target: Target
+ """Discriminated union describing what the monitor watches."""
updated_at: datetime
@@ -405,9 +184,4 @@ class MonitorsExtractSemanticMonitor(BaseModel):
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
- webhook: Optional[MonitorsExtractSemanticMonitorWebhook] = None
-
-
-MonitorCreateResponse: TypeAlias = Union[
- MonitorsPageExactMonitor, MonitorsSitemapExactMonitor, MonitorsPageSemanticMonitor, MonitorsExtractSemanticMonitor
-]
+ webhook: Optional[Webhook] = None
diff --git a/src/context/dev/types/monitor_list_account_changes_response.py b/src/context/dev/types/monitor_list_account_changes_response.py
index a696740..f3c3d50 100644
--- a/src/context/dev/types/monitor_list_account_changes_response.py
+++ b/src/context/dev/types/monitor_list_account_changes_response.py
@@ -1,127 +1,57 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Union, Optional
+from typing import List, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal
from .._models import BaseModel
-__all__ = [
- "MonitorListAccountChangesResponse",
- "Data",
- "DataMonitorsPageExactChangeSummary",
- "DataMonitorsSitemapExactChangeSummary",
- "DataMonitorsPageSemanticChangeSummary",
- "DataMonitorsExtractSemanticChangeSummary",
-]
+__all__ = ["MonitorListAccountChangesResponse", "Data"]
-class DataMonitorsPageExactChangeSummary(BaseModel):
- id: str
-
- change_detection_type: Literal["exact"]
-
- detected_at: datetime
-
- monitor_id: str
-
- summary: str
-
- target_type: Literal["page"]
+class Data(BaseModel):
+ """A lightweight change summary.
- title: str
+ `mode` is the constant `web`; `target_type` and `change_detection_type` describe the change, and which optional fields are present depends on them (e.g. sitemap changes include `added_url_count`/`removed_url_count`; semantic changes include `confidence`/`importance`).
+ """
- url: str
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
-
-class DataMonitorsSitemapExactChangeSummary(BaseModel):
id: str
- added_url_count: int
-
- change_detection_type: Literal["exact"]
+ change_detection_type: Literal["exact", "semantic"]
detected_at: datetime
- monitor_id: str
-
- removed_url_count: int
-
- summary: str
-
- target_type: Literal["sitemap"]
-
- title: str
-
- url: str
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
-
-class DataMonitorsPageSemanticChangeSummary(BaseModel):
- id: str
-
- change_detection_type: Literal["semantic"]
-
- confidence: float
+ mode: Literal["web"]
+ """Top-level monitor category.
- detected_at: datetime
-
- importance: Literal["low", "medium", "high"]
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
monitor_id: str
summary: str
- target_type: Literal["page"]
+ target_type: Literal["page", "sitemap", "extract"]
title: str
url: str
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
+ added_url_count: Optional[int] = None
+ confidence: Optional[float] = None
-class DataMonitorsExtractSemanticChangeSummary(BaseModel):
- id: str
-
- change_detection_type: Literal["semantic"]
+ importance: Optional[Literal["low", "medium", "high"]] = None
- confidence: float
+ matched_url_count: Optional[int] = None
- detected_at: datetime
-
- importance: Literal["low", "medium", "high"]
-
- matched_url_count: int
-
- monitor_id: str
-
- summary: str
-
- target_type: Literal["extract"]
-
- title: str
-
- url: str
+ removed_url_count: Optional[int] = None
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
-Data: TypeAlias = Union[
- DataMonitorsPageExactChangeSummary,
- DataMonitorsSitemapExactChangeSummary,
- DataMonitorsPageSemanticChangeSummary,
- DataMonitorsExtractSemanticChangeSummary,
-]
-
-
class MonitorListAccountChangesResponse(BaseModel):
data: List[Data]
diff --git a/src/context/dev/types/monitor_list_changes_response.py b/src/context/dev/types/monitor_list_changes_response.py
index dffe8b2..b9ed3fe 100644
--- a/src/context/dev/types/monitor_list_changes_response.py
+++ b/src/context/dev/types/monitor_list_changes_response.py
@@ -1,127 +1,57 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Union, Optional
+from typing import List, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal
from .._models import BaseModel
-__all__ = [
- "MonitorListChangesResponse",
- "Data",
- "DataMonitorsPageExactChangeSummary",
- "DataMonitorsSitemapExactChangeSummary",
- "DataMonitorsPageSemanticChangeSummary",
- "DataMonitorsExtractSemanticChangeSummary",
-]
+__all__ = ["MonitorListChangesResponse", "Data"]
-class DataMonitorsPageExactChangeSummary(BaseModel):
- id: str
-
- change_detection_type: Literal["exact"]
-
- detected_at: datetime
-
- monitor_id: str
-
- summary: str
-
- target_type: Literal["page"]
+class Data(BaseModel):
+ """A lightweight change summary.
- title: str
+ `mode` is the constant `web`; `target_type` and `change_detection_type` describe the change, and which optional fields are present depends on them (e.g. sitemap changes include `added_url_count`/`removed_url_count`; semantic changes include `confidence`/`importance`).
+ """
- url: str
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
-
-class DataMonitorsSitemapExactChangeSummary(BaseModel):
id: str
- added_url_count: int
-
- change_detection_type: Literal["exact"]
+ change_detection_type: Literal["exact", "semantic"]
detected_at: datetime
- monitor_id: str
-
- removed_url_count: int
-
- summary: str
-
- target_type: Literal["sitemap"]
-
- title: str
-
- url: str
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
-
-class DataMonitorsPageSemanticChangeSummary(BaseModel):
- id: str
-
- change_detection_type: Literal["semantic"]
-
- confidence: float
+ mode: Literal["web"]
+ """Top-level monitor category.
- detected_at: datetime
-
- importance: Literal["low", "medium", "high"]
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
monitor_id: str
summary: str
- target_type: Literal["page"]
+ target_type: Literal["page", "sitemap", "extract"]
title: str
url: str
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
+ added_url_count: Optional[int] = None
+ confidence: Optional[float] = None
-class DataMonitorsExtractSemanticChangeSummary(BaseModel):
- id: str
-
- change_detection_type: Literal["semantic"]
+ importance: Optional[Literal["low", "medium", "high"]] = None
- confidence: float
+ matched_url_count: Optional[int] = None
- detected_at: datetime
-
- importance: Literal["low", "medium", "high"]
-
- matched_url_count: int
-
- monitor_id: str
-
- summary: str
-
- target_type: Literal["extract"]
-
- title: str
-
- url: str
+ removed_url_count: Optional[int] = None
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
-Data: TypeAlias = Union[
- DataMonitorsPageExactChangeSummary,
- DataMonitorsSitemapExactChangeSummary,
- DataMonitorsPageSemanticChangeSummary,
- DataMonitorsExtractSemanticChangeSummary,
-]
-
-
class MonitorListChangesResponse(BaseModel):
data: List[Data]
diff --git a/src/context/dev/types/monitor_list_params.py b/src/context/dev/types/monitor_list_params.py
index 817a6de..40bfd1a 100644
--- a/src/context/dev/types/monitor_list_params.py
+++ b/src/context/dev/types/monitor_list_params.py
@@ -2,8 +2,11 @@
from __future__ import annotations
+from typing import List
from typing_extensions import Literal, TypedDict
+from .._types import SequenceNotStr
+
__all__ = ["MonitorListParams"]
@@ -14,9 +17,29 @@ class MonitorListParams(TypedDict, total=False):
limit: int
+ q: str
+ """Free-text search term, matched against the fields named in `search_by`."""
+
+ search_by: List[Literal["name", "url", "query", "tags"]]
+ """Comma-separated fields to search with `q`.
+
+ Defaults to all of them. Note `query` only exists on semantic monitors.
+ """
+
+ search_type: Literal["exact", "prefix"]
+ """
+ `prefix` for as-you-type prefix matching (default), `exact` for full-token
+ matching.
+ """
+
status: Literal["active", "paused", "failed"]
tag: str
"""Filter to items that have this tag."""
+ tags: SequenceNotStr[str]
+ """
+ Comma-separated list of tags to filter by (matches monitors having any of them).
+ """
+
target_type: Literal["page", "sitemap", "extract"]
diff --git a/src/context/dev/types/monitor_list_response.py b/src/context/dev/types/monitor_list_response.py
index 7761032..be26e3b 100644
--- a/src/context/dev/types/monitor_list_response.py
+++ b/src/context/dev/types/monitor_list_response.py
@@ -2,39 +2,29 @@
from typing import Dict, List, Union, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal, Annotated, TypeAlias
from pydantic import Field as FieldInfo
+from .._utils import PropertyInfo
from .._models import BaseModel
__all__ = [
"MonitorListResponse",
"Data",
- "DataMonitorsPageExactMonitor",
- "DataMonitorsPageExactMonitorChangeDetection",
- "DataMonitorsPageExactMonitorSchedule",
- "DataMonitorsPageExactMonitorTarget",
- "DataMonitorsPageExactMonitorWebhook",
- "DataMonitorsSitemapExactMonitor",
- "DataMonitorsSitemapExactMonitorChangeDetection",
- "DataMonitorsSitemapExactMonitorSchedule",
- "DataMonitorsSitemapExactMonitorTarget",
- "DataMonitorsSitemapExactMonitorWebhook",
- "DataMonitorsPageSemanticMonitor",
- "DataMonitorsPageSemanticMonitorChangeDetection",
- "DataMonitorsPageSemanticMonitorSchedule",
- "DataMonitorsPageSemanticMonitorTarget",
- "DataMonitorsPageSemanticMonitorWebhook",
- "DataMonitorsExtractSemanticMonitor",
- "DataMonitorsExtractSemanticMonitorChangeDetection",
- "DataMonitorsExtractSemanticMonitorSchedule",
- "DataMonitorsExtractSemanticMonitorTarget",
- "DataMonitorsExtractSemanticMonitorWebhook",
+ "DataChangeDetection",
+ "DataChangeDetectionMonitorsExactChangeDetection",
+ "DataChangeDetectionMonitorsSemanticChangeDetection",
+ "DataSchedule",
+ "DataTarget",
+ "DataTargetMonitorsPageTarget",
+ "DataTargetMonitorsSitemapTarget",
+ "DataTargetMonitorsExtractTarget",
+ "DataWebhook",
]
-class DataMonitorsPageExactMonitorChangeDetection(BaseModel):
+class DataChangeDetectionMonitorsExactChangeDetection(BaseModel):
"""Detect exact changes.
For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
@@ -43,184 +33,7 @@ class DataMonitorsPageExactMonitorChangeDetection(BaseModel):
type: Literal["exact"]
-class DataMonitorsPageExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class DataMonitorsPageExactMonitorTarget(BaseModel):
- type: Literal["page"]
-
- url: str
-
- normalize_whitespace: Optional[bool] = None
- """Normalize whitespace before comparing or analyzing text."""
-
-
-class DataMonitorsPageExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class DataMonitorsPageExactMonitor(BaseModel):
- """A page monitor using exact change detection."""
-
- id: str
-
- change_detection: DataMonitorsPageExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: DataMonitorsPageExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: DataMonitorsPageExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[DataMonitorsPageExactMonitorWebhook] = None
-
-
-class DataMonitorsSitemapExactMonitorChangeDetection(BaseModel):
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
- """
-
- type: Literal["exact"]
-
-
-class DataMonitorsSitemapExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class DataMonitorsSitemapExactMonitorTarget(BaseModel):
- type: Literal["sitemap"]
-
- url: str
- """Sitemap URL to monitor."""
-
- exclude: Optional[List[str]] = None
- """URL path patterns to exclude."""
-
- include: Optional[List[str]] = None
- """URL path patterns to include."""
-
- max_urls: Optional[int] = None
-
-
-class DataMonitorsSitemapExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class DataMonitorsSitemapExactMonitor(BaseModel):
- """A sitemap monitor using exact change detection."""
-
- id: str
-
- change_detection: DataMonitorsSitemapExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: DataMonitorsSitemapExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: DataMonitorsSitemapExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[DataMonitorsSitemapExactMonitorWebhook] = None
-
-
-class DataMonitorsPageSemanticMonitorChangeDetection(BaseModel):
+class DataChangeDetectionMonitorsSemanticChangeDetection(BaseModel):
"""Detect meaning-level changes that match a natural language query."""
query: str
@@ -230,7 +43,13 @@ class DataMonitorsPageSemanticMonitorChangeDetection(BaseModel):
confidence_threshold: Optional[float] = None
-class DataMonitorsPageSemanticMonitorSchedule(BaseModel):
+DataChangeDetection: TypeAlias = Annotated[
+ Union[DataChangeDetectionMonitorsExactChangeDetection, DataChangeDetectionMonitorsSemanticChangeDetection],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class DataSchedule(BaseModel):
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
@@ -249,7 +68,9 @@ class DataMonitorsPageSemanticMonitorSchedule(BaseModel):
unit: Literal["minutes", "hours", "days"]
-class DataMonitorsPageSemanticMonitorTarget(BaseModel):
+class DataTargetMonitorsPageTarget(BaseModel):
+ """Watch a single web page."""
+
type: Literal["page"]
url: str
@@ -258,85 +79,26 @@ class DataMonitorsPageSemanticMonitorTarget(BaseModel):
"""Normalize whitespace before comparing or analyzing text."""
-class DataMonitorsPageSemanticMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class DataMonitorsPageSemanticMonitor(BaseModel):
- """A page monitor using semantic change detection."""
-
- id: str
+class DataTargetMonitorsSitemapTarget(BaseModel):
+ """Watch a sitemap for URL additions and removals."""
- change_detection: DataMonitorsPageSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
-
- created_at: datetime
-
- name: str
-
- schedule: DataMonitorsPageSemanticMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: DataMonitorsPageSemanticMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[DataMonitorsPageSemanticMonitorWebhook] = None
-
-
-class DataMonitorsExtractSemanticMonitorChangeDetection(BaseModel):
- """Detect meaning-level changes that match a natural language query."""
-
- query: str
-
- type: Literal["semantic"]
-
- confidence_threshold: Optional[float] = None
-
-
-class DataMonitorsExtractSemanticMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ type: Literal["sitemap"]
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
+ url: str
+ """Sitemap URL to monitor."""
- frequency: int
- """Number of units between runs.
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
- type: Literal["interval"]
+ max_urls: Optional[int] = None
- unit: Literal["minutes", "hours", "days"]
+class DataTargetMonitorsExtractTarget(BaseModel):
+ """Watch a site's extracted structured data."""
-class DataMonitorsExtractSemanticMonitorTarget(BaseModel):
type: Literal["extract"]
url: str
@@ -360,7 +122,13 @@ class DataMonitorsExtractSemanticMonitorTarget(BaseModel):
"""
-class DataMonitorsExtractSemanticMonitorWebhook(BaseModel):
+DataTarget: TypeAlias = Annotated[
+ Union[DataTargetMonitorsPageTarget, DataTargetMonitorsSitemapTarget, DataTargetMonitorsExtractTarget],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class DataWebhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -374,19 +142,29 @@ class DataMonitorsExtractSemanticMonitorWebhook(BaseModel):
"""
-class DataMonitorsExtractSemanticMonitor(BaseModel):
- """An extract monitor using semantic change detection."""
+class Data(BaseModel):
+ """A web monitor.
+
+ `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).
+ """
id: str
- change_detection: DataMonitorsExtractSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
+ change_detection: DataChangeDetection
+ """Discriminated union describing how changes are detected."""
created_at: datetime
+ mode: Literal["web"]
+ """Top-level monitor category.
+
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
+
name: str
- schedule: DataMonitorsExtractSemanticMonitorSchedule
+ schedule: DataSchedule
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
@@ -395,7 +173,8 @@ class DataMonitorsExtractSemanticMonitor(BaseModel):
status: Literal["active", "paused", "failed"]
- target: DataMonitorsExtractSemanticMonitorTarget
+ target: DataTarget
+ """Discriminated union describing what the monitor watches."""
updated_at: datetime
@@ -406,15 +185,7 @@ class DataMonitorsExtractSemanticMonitor(BaseModel):
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
- webhook: Optional[DataMonitorsExtractSemanticMonitorWebhook] = None
-
-
-Data: TypeAlias = Union[
- DataMonitorsPageExactMonitor,
- DataMonitorsSitemapExactMonitor,
- DataMonitorsPageSemanticMonitor,
- DataMonitorsExtractSemanticMonitor,
-]
+ webhook: Optional[DataWebhook] = None
class MonitorListResponse(BaseModel):
diff --git a/src/context/dev/types/monitor_retrieve_change_response.py b/src/context/dev/types/monitor_retrieve_change_response.py
index 6586e41..f7cab7a 100644
--- a/src/context/dev/types/monitor_retrieve_change_response.py
+++ b/src/context/dev/types/monitor_retrieve_change_response.py
@@ -1,159 +1,80 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Union, Optional
+from typing import List, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal
from .._models import BaseModel
-__all__ = [
- "MonitorRetrieveChangeResponse",
- "MonitorsPageExactChange",
- "MonitorsSitemapExactChange",
- "MonitorsPageSemanticChange",
- "MonitorsPageSemanticChangeEvidence",
- "MonitorsExtractSemanticChange",
- "MonitorsExtractSemanticChangeEvidence",
-]
+__all__ = ["MonitorRetrieveChangeResponse", "Evidence"]
-class MonitorsPageExactChange(BaseModel):
- id: str
-
- change_detection_type: Literal["exact"]
-
- detected_at: datetime
-
- diff: str
- """Text diff between the previous and current page baseline."""
-
- monitor_id: str
-
- summary: str
-
- target_type: Literal["page"]
-
- title: str
-
- url: str
-
- after_text_excerpt: Optional[str] = None
-
- before_text_excerpt: Optional[str] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
-
-class MonitorsSitemapExactChange(BaseModel):
- id: str
-
- added_url_count: int
-
- added_urls: List[str]
-
- change_detection_type: Literal["exact"]
-
- detected_at: datetime
-
- monitor_id: str
-
- removed_url_count: int
-
- removed_urls: List[str]
-
- summary: str
-
- target_type: Literal["sitemap"]
-
- title: str
-
- url: str
+class Evidence(BaseModel):
+ after: str
+ """Snapshot of the content after the change."""
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
+ before: str
+ """Snapshot of the content before the change."""
+ url: Optional[str] = None
+ """Optional URL the evidence relates to. Absent for whole-target diffs."""
-class MonitorsPageSemanticChangeEvidence(BaseModel):
- after: str
- before: str
+class MonitorRetrieveChangeResponse(BaseModel):
+ """A detected change.
+ `mode` is the constant `web`; `target_type` and `change_detection_type` describe the change, and which optional fields are present depends on them (page: `diff` + excerpts; sitemap: `added_urls`/`removed_urls`; semantic: `query`/`confidence`/`importance`/`evidence`/`matched_urls`).
+ """
-class MonitorsPageSemanticChange(BaseModel):
id: str
- change_detection_type: Literal["semantic"]
-
- confidence: float
+ change_detection_type: Literal["exact", "semantic"]
detected_at: datetime
- evidence: List[MonitorsPageSemanticChangeEvidence]
+ mode: Literal["web"]
+ """Top-level monitor category.
- importance: Literal["low", "medium", "high"]
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
monitor_id: str
- query: str
-
summary: str
- target_type: Literal["page"]
+ target_type: Literal["page", "sitemap", "extract"]
title: str
url: str
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
+ added_url_count: Optional[int] = None
-class MonitorsExtractSemanticChangeEvidence(BaseModel):
- after: str
- """Snapshot of the extracted data after the change."""
+ added_urls: Optional[List[str]] = None
- before: str
- """Snapshot of the extracted data before the change."""
-
- url: Optional[str] = None
- """Optional URL the evidence relates to. Absent for whole-target extract diffs."""
-
-
-class MonitorsExtractSemanticChange(BaseModel):
- id: str
-
- change_detection_type: Literal["semantic"]
-
- confidence: float
-
- detected_at: datetime
+ after_text_excerpt: Optional[str] = None
- evidence: List[MonitorsExtractSemanticChangeEvidence]
+ before_text_excerpt: Optional[str] = None
- importance: Literal["low", "medium", "high"]
+ confidence: Optional[float] = None
- matched_url_count: int
+ diff: Optional[str] = None
+ """Text diff between the previous and current page baseline (page targets)."""
- matched_urls: List[str]
+ evidence: Optional[List[Evidence]] = None
- monitor_id: str
+ importance: Optional[Literal["low", "medium", "high"]] = None
- query: str
+ matched_url_count: Optional[int] = None
- summary: str
+ matched_urls: Optional[List[str]] = None
- target_type: Literal["extract"]
+ query: Optional[str] = None
- title: str
+ removed_url_count: Optional[int] = None
- url: str
- """Root URL of the extract target."""
+ removed_urls: Optional[List[str]] = None
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
-
-
-MonitorRetrieveChangeResponse: TypeAlias = Union[
- MonitorsPageExactChange, MonitorsSitemapExactChange, MonitorsPageSemanticChange, MonitorsExtractSemanticChange
-]
diff --git a/src/context/dev/types/monitor_retrieve_response.py b/src/context/dev/types/monitor_retrieve_response.py
index d774f7f..c0c70bc 100644
--- a/src/context/dev/types/monitor_retrieve_response.py
+++ b/src/context/dev/types/monitor_retrieve_response.py
@@ -2,38 +2,28 @@
from typing import Dict, List, Union, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal, Annotated, TypeAlias
from pydantic import Field as FieldInfo
+from .._utils import PropertyInfo
from .._models import BaseModel
__all__ = [
"MonitorRetrieveResponse",
- "MonitorsPageExactMonitor",
- "MonitorsPageExactMonitorChangeDetection",
- "MonitorsPageExactMonitorSchedule",
- "MonitorsPageExactMonitorTarget",
- "MonitorsPageExactMonitorWebhook",
- "MonitorsSitemapExactMonitor",
- "MonitorsSitemapExactMonitorChangeDetection",
- "MonitorsSitemapExactMonitorSchedule",
- "MonitorsSitemapExactMonitorTarget",
- "MonitorsSitemapExactMonitorWebhook",
- "MonitorsPageSemanticMonitor",
- "MonitorsPageSemanticMonitorChangeDetection",
- "MonitorsPageSemanticMonitorSchedule",
- "MonitorsPageSemanticMonitorTarget",
- "MonitorsPageSemanticMonitorWebhook",
- "MonitorsExtractSemanticMonitor",
- "MonitorsExtractSemanticMonitorChangeDetection",
- "MonitorsExtractSemanticMonitorSchedule",
- "MonitorsExtractSemanticMonitorTarget",
- "MonitorsExtractSemanticMonitorWebhook",
+ "ChangeDetection",
+ "ChangeDetectionMonitorsExactChangeDetection",
+ "ChangeDetectionMonitorsSemanticChangeDetection",
+ "Schedule",
+ "Target",
+ "TargetMonitorsPageTarget",
+ "TargetMonitorsSitemapTarget",
+ "TargetMonitorsExtractTarget",
+ "Webhook",
]
-class MonitorsPageExactMonitorChangeDetection(BaseModel):
+class ChangeDetectionMonitorsExactChangeDetection(BaseModel):
"""Detect exact changes.
For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
@@ -42,184 +32,7 @@ class MonitorsPageExactMonitorChangeDetection(BaseModel):
type: Literal["exact"]
-class MonitorsPageExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class MonitorsPageExactMonitorTarget(BaseModel):
- type: Literal["page"]
-
- url: str
-
- normalize_whitespace: Optional[bool] = None
- """Normalize whitespace before comparing or analyzing text."""
-
-
-class MonitorsPageExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsPageExactMonitor(BaseModel):
- """A page monitor using exact change detection."""
-
- id: str
-
- change_detection: MonitorsPageExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsPageExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsPageExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsPageExactMonitorWebhook] = None
-
-
-class MonitorsSitemapExactMonitorChangeDetection(BaseModel):
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
- """
-
- type: Literal["exact"]
-
-
-class MonitorsSitemapExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class MonitorsSitemapExactMonitorTarget(BaseModel):
- type: Literal["sitemap"]
-
- url: str
- """Sitemap URL to monitor."""
-
- exclude: Optional[List[str]] = None
- """URL path patterns to exclude."""
-
- include: Optional[List[str]] = None
- """URL path patterns to include."""
-
- max_urls: Optional[int] = None
-
-
-class MonitorsSitemapExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsSitemapExactMonitor(BaseModel):
- """A sitemap monitor using exact change detection."""
-
- id: str
-
- change_detection: MonitorsSitemapExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsSitemapExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsSitemapExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsSitemapExactMonitorWebhook] = None
-
-
-class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
+class ChangeDetectionMonitorsSemanticChangeDetection(BaseModel):
"""Detect meaning-level changes that match a natural language query."""
query: str
@@ -229,7 +42,13 @@ class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
confidence_threshold: Optional[float] = None
-class MonitorsPageSemanticMonitorSchedule(BaseModel):
+ChangeDetection: TypeAlias = Annotated[
+ Union[ChangeDetectionMonitorsExactChangeDetection, ChangeDetectionMonitorsSemanticChangeDetection],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class Schedule(BaseModel):
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
@@ -248,7 +67,9 @@ class MonitorsPageSemanticMonitorSchedule(BaseModel):
unit: Literal["minutes", "hours", "days"]
-class MonitorsPageSemanticMonitorTarget(BaseModel):
+class TargetMonitorsPageTarget(BaseModel):
+ """Watch a single web page."""
+
type: Literal["page"]
url: str
@@ -257,85 +78,26 @@ class MonitorsPageSemanticMonitorTarget(BaseModel):
"""Normalize whitespace before comparing or analyzing text."""
-class MonitorsPageSemanticMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsPageSemanticMonitor(BaseModel):
- """A page monitor using semantic change detection."""
-
- id: str
+class TargetMonitorsSitemapTarget(BaseModel):
+ """Watch a sitemap for URL additions and removals."""
- change_detection: MonitorsPageSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsPageSemanticMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsPageSemanticMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsPageSemanticMonitorWebhook] = None
-
-
-class MonitorsExtractSemanticMonitorChangeDetection(BaseModel):
- """Detect meaning-level changes that match a natural language query."""
-
- query: str
-
- type: Literal["semantic"]
-
- confidence_threshold: Optional[float] = None
-
-
-class MonitorsExtractSemanticMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ type: Literal["sitemap"]
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
+ url: str
+ """Sitemap URL to monitor."""
- frequency: int
- """Number of units between runs.
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
- type: Literal["interval"]
+ max_urls: Optional[int] = None
- unit: Literal["minutes", "hours", "days"]
+class TargetMonitorsExtractTarget(BaseModel):
+ """Watch a site's extracted structured data."""
-class MonitorsExtractSemanticMonitorTarget(BaseModel):
type: Literal["extract"]
url: str
@@ -359,7 +121,13 @@ class MonitorsExtractSemanticMonitorTarget(BaseModel):
"""
-class MonitorsExtractSemanticMonitorWebhook(BaseModel):
+Target: TypeAlias = Annotated[
+ Union[TargetMonitorsPageTarget, TargetMonitorsSitemapTarget, TargetMonitorsExtractTarget],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class Webhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -373,19 +141,29 @@ class MonitorsExtractSemanticMonitorWebhook(BaseModel):
"""
-class MonitorsExtractSemanticMonitor(BaseModel):
- """An extract monitor using semantic change detection."""
+class MonitorRetrieveResponse(BaseModel):
+ """A web monitor.
+
+ `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).
+ """
id: str
- change_detection: MonitorsExtractSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
+ change_detection: ChangeDetection
+ """Discriminated union describing how changes are detected."""
created_at: datetime
+ mode: Literal["web"]
+ """Top-level monitor category.
+
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
+
name: str
- schedule: MonitorsExtractSemanticMonitorSchedule
+ schedule: Schedule
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
@@ -394,7 +172,8 @@ class MonitorsExtractSemanticMonitor(BaseModel):
status: Literal["active", "paused", "failed"]
- target: MonitorsExtractSemanticMonitorTarget
+ target: Target
+ """Discriminated union describing what the monitor watches."""
updated_at: datetime
@@ -405,9 +184,4 @@ class MonitorsExtractSemanticMonitor(BaseModel):
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
- webhook: Optional[MonitorsExtractSemanticMonitorWebhook] = None
-
-
-MonitorRetrieveResponse: TypeAlias = Union[
- MonitorsPageExactMonitor, MonitorsSitemapExactMonitor, MonitorsPageSemanticMonitor, MonitorsExtractSemanticMonitor
-]
+ webhook: Optional[Webhook] = None
diff --git a/src/context/dev/types/monitor_update_params.py b/src/context/dev/types/monitor_update_params.py
index 89599e6..373457b 100644
--- a/src/context/dev/types/monitor_update_params.py
+++ b/src/context/dev/types/monitor_update_params.py
@@ -90,6 +90,8 @@ class Schedule(TypedDict, total=False):
class TargetMonitorsPageTarget(TypedDict, total=False):
+ """Watch a single web page."""
+
type: Required[Literal["page"]]
url: Required[str]
@@ -99,6 +101,8 @@ class TargetMonitorsPageTarget(TypedDict, total=False):
class TargetMonitorsSitemapTarget(TypedDict, total=False):
+ """Watch a sitemap for URL additions and removals."""
+
type: Required[Literal["sitemap"]]
url: Required[str]
@@ -114,6 +118,8 @@ class TargetMonitorsSitemapTarget(TypedDict, total=False):
class TargetMonitorsExtractTarget(TypedDict, total=False):
+ """Watch a site's extracted structured data."""
+
type: Required[Literal["extract"]]
url: Required[str]
diff --git a/src/context/dev/types/monitor_update_response.py b/src/context/dev/types/monitor_update_response.py
index 98b0a69..4fc4fcb 100644
--- a/src/context/dev/types/monitor_update_response.py
+++ b/src/context/dev/types/monitor_update_response.py
@@ -2,38 +2,28 @@
from typing import Dict, List, Union, Optional
from datetime import datetime
-from typing_extensions import Literal, TypeAlias
+from typing_extensions import Literal, Annotated, TypeAlias
from pydantic import Field as FieldInfo
+from .._utils import PropertyInfo
from .._models import BaseModel
__all__ = [
"MonitorUpdateResponse",
- "MonitorsPageExactMonitor",
- "MonitorsPageExactMonitorChangeDetection",
- "MonitorsPageExactMonitorSchedule",
- "MonitorsPageExactMonitorTarget",
- "MonitorsPageExactMonitorWebhook",
- "MonitorsSitemapExactMonitor",
- "MonitorsSitemapExactMonitorChangeDetection",
- "MonitorsSitemapExactMonitorSchedule",
- "MonitorsSitemapExactMonitorTarget",
- "MonitorsSitemapExactMonitorWebhook",
- "MonitorsPageSemanticMonitor",
- "MonitorsPageSemanticMonitorChangeDetection",
- "MonitorsPageSemanticMonitorSchedule",
- "MonitorsPageSemanticMonitorTarget",
- "MonitorsPageSemanticMonitorWebhook",
- "MonitorsExtractSemanticMonitor",
- "MonitorsExtractSemanticMonitorChangeDetection",
- "MonitorsExtractSemanticMonitorSchedule",
- "MonitorsExtractSemanticMonitorTarget",
- "MonitorsExtractSemanticMonitorWebhook",
+ "ChangeDetection",
+ "ChangeDetectionMonitorsExactChangeDetection",
+ "ChangeDetectionMonitorsSemanticChangeDetection",
+ "Schedule",
+ "Target",
+ "TargetMonitorsPageTarget",
+ "TargetMonitorsSitemapTarget",
+ "TargetMonitorsExtractTarget",
+ "Webhook",
]
-class MonitorsPageExactMonitorChangeDetection(BaseModel):
+class ChangeDetectionMonitorsExactChangeDetection(BaseModel):
"""Detect exact changes.
For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
@@ -42,184 +32,7 @@ class MonitorsPageExactMonitorChangeDetection(BaseModel):
type: Literal["exact"]
-class MonitorsPageExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class MonitorsPageExactMonitorTarget(BaseModel):
- type: Literal["page"]
-
- url: str
-
- normalize_whitespace: Optional[bool] = None
- """Normalize whitespace before comparing or analyzing text."""
-
-
-class MonitorsPageExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsPageExactMonitor(BaseModel):
- """A page monitor using exact change detection."""
-
- id: str
-
- change_detection: MonitorsPageExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsPageExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsPageExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsPageExactMonitorWebhook] = None
-
-
-class MonitorsSitemapExactMonitorChangeDetection(BaseModel):
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means URL additions and removals.
- """
-
- type: Literal["exact"]
-
-
-class MonitorsSitemapExactMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
-
- frequency: int
- """Number of units between runs.
-
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
-
- type: Literal["interval"]
-
- unit: Literal["minutes", "hours", "days"]
-
-
-class MonitorsSitemapExactMonitorTarget(BaseModel):
- type: Literal["sitemap"]
-
- url: str
- """Sitemap URL to monitor."""
-
- exclude: Optional[List[str]] = None
- """URL path patterns to exclude."""
-
- include: Optional[List[str]] = None
- """URL path patterns to include."""
-
- max_urls: Optional[int] = None
-
-
-class MonitorsSitemapExactMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsSitemapExactMonitor(BaseModel):
- """A sitemap monitor using exact change detection."""
-
- id: str
-
- change_detection: MonitorsSitemapExactMonitorChangeDetection
- """Detect exact changes.
-
- For page targets, this means visible text diffs. For sitemap targets, this means
- URL additions and removals.
- """
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsSitemapExactMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsSitemapExactMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsSitemapExactMonitorWebhook] = None
-
-
-class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
+class ChangeDetectionMonitorsSemanticChangeDetection(BaseModel):
"""Detect meaning-level changes that match a natural language query."""
query: str
@@ -229,7 +42,13 @@ class MonitorsPageSemanticMonitorChangeDetection(BaseModel):
confidence_threshold: Optional[float] = None
-class MonitorsPageSemanticMonitorSchedule(BaseModel):
+ChangeDetection: TypeAlias = Annotated[
+ Union[ChangeDetectionMonitorsExactChangeDetection, ChangeDetectionMonitorsSemanticChangeDetection],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class Schedule(BaseModel):
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
@@ -248,7 +67,9 @@ class MonitorsPageSemanticMonitorSchedule(BaseModel):
unit: Literal["minutes", "hours", "days"]
-class MonitorsPageSemanticMonitorTarget(BaseModel):
+class TargetMonitorsPageTarget(BaseModel):
+ """Watch a single web page."""
+
type: Literal["page"]
url: str
@@ -257,85 +78,26 @@ class MonitorsPageSemanticMonitorTarget(BaseModel):
"""Normalize whitespace before comparing or analyzing text."""
-class MonitorsPageSemanticMonitorWebhook(BaseModel):
- url: str
- """Webhook URL called when a change is detected."""
-
- secret: Optional[str] = None
- """Signing secret used to verify webhook authenticity.
-
- Each delivery includes an `X-Context-Signature: t=,v1=` header,
- where the HMAC is SHA-256 over `"{t}.{rawRequestBody}"` keyed by this secret.
- Recompute it with a constant-time compare and reject stale timestamps to prevent
- replay. Generated by the API; cannot be set by clients.
- """
-
-
-class MonitorsPageSemanticMonitor(BaseModel):
- """A page monitor using semantic change detection."""
-
- id: str
+class TargetMonitorsSitemapTarget(BaseModel):
+ """Watch a sitemap for URL additions and removals."""
- change_detection: MonitorsPageSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
-
- created_at: datetime
-
- name: str
-
- schedule: MonitorsPageSemanticMonitorSchedule
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
-
- every 6 hours or every 2 days. The total interval (frequency × unit) must be
- between 10 minutes and 1 year.
- """
-
- status: Literal["active", "paused", "failed"]
-
- target: MonitorsPageSemanticMonitorTarget
-
- updated_at: datetime
-
- last_change_at: Optional[datetime] = None
-
- last_run_at: Optional[datetime] = None
-
- tags: Optional[List[str]] = None
- """User-defined tags for grouping and filtering monitors and their changes."""
-
- webhook: Optional[MonitorsPageSemanticMonitorWebhook] = None
-
-
-class MonitorsExtractSemanticMonitorChangeDetection(BaseModel):
- """Detect meaning-level changes that match a natural language query."""
-
- query: str
-
- type: Literal["semantic"]
-
- confidence_threshold: Optional[float] = None
-
-
-class MonitorsExtractSemanticMonitorSchedule(BaseModel):
- """Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ type: Literal["sitemap"]
- every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.
- """
+ url: str
+ """Sitemap URL to monitor."""
- frequency: int
- """Number of units between runs.
+ exclude: Optional[List[str]] = None
+ """URL path patterns to exclude."""
- The resulting interval (frequency × unit) must be at least 10 minutes and at
- most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is
- days).
- """
+ include: Optional[List[str]] = None
+ """URL path patterns to include."""
- type: Literal["interval"]
+ max_urls: Optional[int] = None
- unit: Literal["minutes", "hours", "days"]
+class TargetMonitorsExtractTarget(BaseModel):
+ """Watch a site's extracted structured data."""
-class MonitorsExtractSemanticMonitorTarget(BaseModel):
type: Literal["extract"]
url: str
@@ -359,7 +121,13 @@ class MonitorsExtractSemanticMonitorTarget(BaseModel):
"""
-class MonitorsExtractSemanticMonitorWebhook(BaseModel):
+Target: TypeAlias = Annotated[
+ Union[TargetMonitorsPageTarget, TargetMonitorsSitemapTarget, TargetMonitorsExtractTarget],
+ PropertyInfo(discriminator="type"),
+]
+
+
+class Webhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -373,19 +141,29 @@ class MonitorsExtractSemanticMonitorWebhook(BaseModel):
"""
-class MonitorsExtractSemanticMonitor(BaseModel):
- """An extract monitor using semantic change detection."""
+class MonitorUpdateResponse(BaseModel):
+ """A web monitor.
+
+ `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).
+ """
id: str
- change_detection: MonitorsExtractSemanticMonitorChangeDetection
- """Detect meaning-level changes that match a natural language query."""
+ change_detection: ChangeDetection
+ """Discriminated union describing how changes are detected."""
created_at: datetime
+ mode: Literal["web"]
+ """Top-level monitor category.
+
+ Always `web` today; the concrete behavior is described by `target` and
+ `change_detection`.
+ """
+
name: str
- schedule: MonitorsExtractSemanticMonitorSchedule
+ schedule: Schedule
"""Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
every 6 hours or every 2 days. The total interval (frequency × unit) must be
@@ -394,7 +172,8 @@ class MonitorsExtractSemanticMonitor(BaseModel):
status: Literal["active", "paused", "failed"]
- target: MonitorsExtractSemanticMonitorTarget
+ target: Target
+ """Discriminated union describing what the monitor watches."""
updated_at: datetime
@@ -405,9 +184,4 @@ class MonitorsExtractSemanticMonitor(BaseModel):
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
- webhook: Optional[MonitorsExtractSemanticMonitorWebhook] = None
-
-
-MonitorUpdateResponse: TypeAlias = Union[
- MonitorsPageExactMonitor, MonitorsSitemapExactMonitor, MonitorsPageSemanticMonitor, MonitorsExtractSemanticMonitor
-]
+ webhook: Optional[Webhook] = None
diff --git a/tests/api_resources/test_monitors.py b/tests/api_resources/test_monitors.py
index 54dd812..19301c8 100644
--- a/tests/api_resources/test_monitors.py
+++ b/tests/api_resources/test_monitors.py
@@ -32,10 +32,10 @@ class TestMonitors:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_create_overload_1(self, client: ContextDev) -> None:
+ def test_method_create(self, client: ContextDev) -> None:
monitor = client.monitors.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -50,10 +50,10 @@ def test_method_create_overload_1(self, client: ContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_create_with_all_params_overload_1(self, client: ContextDev) -> None:
+ def test_method_create_with_all_params(self, client: ContextDev) -> None:
monitor = client.monitors.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -64,6 +64,7 @@ def test_method_create_with_all_params_overload_1(self, client: ContextDev) -> N
"url": "https://acme.com/pricing",
"normalize_whitespace": True,
},
+ mode="web",
tags=["pricing", "competitor"],
webhook={"url": "https://example.com/webhook"},
)
@@ -71,10 +72,10 @@ def test_method_create_with_all_params_overload_1(self, client: ContextDev) -> N
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_create_overload_1(self, client: ContextDev) -> None:
+ def test_raw_response_create(self, client: ContextDev) -> None:
response = client.monitors.with_raw_response.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -93,10 +94,10 @@ def test_raw_response_create_overload_1(self, client: ContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_create_overload_1(self, client: ContextDev) -> None:
+ def test_streaming_response_create(self, client: ContextDev) -> None:
with client.monitors.with_streaming_response.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -115,296 +116,6 @@ def test_streaming_response_create_overload_1(self, client: ContextDev) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_create_overload_2(self, client: ContextDev) -> None:
- monitor = client.monitors.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- },
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_create_with_all_params_overload_2(self, client: ContextDev) -> None:
- monitor = client.monitors.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- "exclude": ["/legal/*", "/privacy"],
- "include": ["/blog/*", "/pricing*"],
- "max_urls": 1,
- },
- tags=["pricing", "competitor"],
- webhook={"url": "https://example.com/webhook"},
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_raw_response_create_overload_2(self, client: ContextDev) -> None:
- response = client.monitors.with_raw_response.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- },
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- monitor = response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_create_overload_2(self, client: ContextDev) -> None:
- with client.monitors.with_streaming_response.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- },
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- monitor = response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_create_overload_3(self, client: ContextDev) -> None:
- monitor = client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- },
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_create_with_all_params_overload_3(self, client: ContextDev) -> None:
- monitor = client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- "confidence_threshold": 0,
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- "normalize_whitespace": True,
- },
- tags=["pricing", "competitor"],
- webhook={"url": "https://example.com/webhook"},
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_raw_response_create_overload_3(self, client: ContextDev) -> None:
- response = client.monitors.with_raw_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- },
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- monitor = response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_create_overload_3(self, client: ContextDev) -> None:
- with client.monitors.with_streaming_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- },
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- monitor = response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_create_overload_4(self, client: ContextDev) -> None:
- monitor = client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- },
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_create_with_all_params_overload_4(self, client: ContextDev) -> None:
- monitor = client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- "confidence_threshold": 0,
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- "follow_subdomains": True,
- "instructions": "Extract every pricing plan with its monthly price and included limits.",
- "max_depth": 0,
- "max_pages": 1,
- "schema": {
- "type": "bar",
- "properties": "bar",
- },
- },
- tags=["pricing", "competitor"],
- webhook={"url": "https://example.com/webhook"},
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_raw_response_create_overload_4(self, client: ContextDev) -> None:
- response = client.monitors.with_raw_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- },
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- monitor = response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_create_overload_4(self, client: ContextDev) -> None:
- with client.monitors.with_streaming_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- },
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- monitor = response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_retrieve(self, client: ContextDev) -> None:
@@ -525,8 +236,12 @@ def test_method_list_with_all_params(self, client: ContextDev) -> None:
change_detection_type="exact",
cursor="cursor",
limit=1,
+ q="q",
+ search_by=["name"],
+ search_type="exact",
status="active",
tag="tag",
+ tags=["string"],
target_type="page",
)
assert_matches_type(MonitorListResponse, monitor, path=["response"])
@@ -876,10 +591,10 @@ class TestAsyncMonitors:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_create_overload_1(self, async_client: AsyncContextDev) -> None:
+ async def test_method_create(self, async_client: AsyncContextDev) -> None:
monitor = await async_client.monitors.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -894,10 +609,10 @@ async def test_method_create_overload_1(self, async_client: AsyncContextDev) ->
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_create_with_all_params_overload_1(self, async_client: AsyncContextDev) -> None:
+ async def test_method_create_with_all_params(self, async_client: AsyncContextDev) -> None:
monitor = await async_client.monitors.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -908,6 +623,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn
"url": "https://acme.com/pricing",
"normalize_whitespace": True,
},
+ mode="web",
tags=["pricing", "competitor"],
webhook={"url": "https://example.com/webhook"},
)
@@ -915,10 +631,10 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_create_overload_1(self, async_client: AsyncContextDev) -> None:
+ async def test_raw_response_create(self, async_client: AsyncContextDev) -> None:
response = await async_client.monitors.with_raw_response.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -937,10 +653,10 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncContextDe
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_create_overload_1(self, async_client: AsyncContextDev) -> None:
+ async def test_streaming_response_create(self, async_client: AsyncContextDev) -> None:
async with async_client.monitors.with_streaming_response.create(
change_detection={"type": "exact"},
- name="Acme pricing monitor",
+ name="Acme pricing page",
schedule={
"frequency": 6,
"type": "interval",
@@ -959,296 +675,6 @@ async def test_streaming_response_create_overload_1(self, async_client: AsyncCon
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_create_overload_2(self, async_client: AsyncContextDev) -> None:
- monitor = await async_client.monitors.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- },
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_create_with_all_params_overload_2(self, async_client: AsyncContextDev) -> None:
- monitor = await async_client.monitors.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- "exclude": ["/legal/*", "/privacy"],
- "include": ["/blog/*", "/pricing*"],
- "max_urls": 1,
- },
- tags=["pricing", "competitor"],
- webhook={"url": "https://example.com/webhook"},
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_create_overload_2(self, async_client: AsyncContextDev) -> None:
- response = await async_client.monitors.with_raw_response.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- },
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- monitor = await response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_create_overload_2(self, async_client: AsyncContextDev) -> None:
- async with async_client.monitors.with_streaming_response.create(
- change_detection={"type": "exact"},
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "sitemap",
- "url": "https://acme.com/sitemap.xml",
- },
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- monitor = await response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_create_overload_3(self, async_client: AsyncContextDev) -> None:
- monitor = await async_client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- },
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_create_with_all_params_overload_3(self, async_client: AsyncContextDev) -> None:
- monitor = await async_client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- "confidence_threshold": 0,
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- "normalize_whitespace": True,
- },
- tags=["pricing", "competitor"],
- webhook={"url": "https://example.com/webhook"},
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_create_overload_3(self, async_client: AsyncContextDev) -> None:
- response = await async_client.monitors.with_raw_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- },
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- monitor = await response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_create_overload_3(self, async_client: AsyncContextDev) -> None:
- async with async_client.monitors.with_streaming_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "page",
- "url": "https://acme.com/pricing",
- },
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- monitor = await response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_create_overload_4(self, async_client: AsyncContextDev) -> None:
- monitor = await async_client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- },
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_create_with_all_params_overload_4(self, async_client: AsyncContextDev) -> None:
- monitor = await async_client.monitors.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- "confidence_threshold": 0,
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- "follow_subdomains": True,
- "instructions": "Extract every pricing plan with its monthly price and included limits.",
- "max_depth": 0,
- "max_pages": 1,
- "schema": {
- "type": "bar",
- "properties": "bar",
- },
- },
- tags=["pricing", "competitor"],
- webhook={"url": "https://example.com/webhook"},
- )
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_create_overload_4(self, async_client: AsyncContextDev) -> None:
- response = await async_client.monitors.with_raw_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- },
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- monitor = await response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_create_overload_4(self, async_client: AsyncContextDev) -> None:
- async with async_client.monitors.with_streaming_response.create(
- change_detection={
- "query": "Tell me when pricing, packaging, plan limits, or discounts change.",
- "type": "semantic",
- },
- name="Acme pricing monitor",
- schedule={
- "frequency": 6,
- "type": "interval",
- "unit": "hours",
- },
- target={
- "type": "extract",
- "url": "https://acme.com",
- },
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- monitor = await response.parse()
- assert_matches_type(MonitorCreateResponse, monitor, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_retrieve(self, async_client: AsyncContextDev) -> None:
@@ -1369,8 +795,12 @@ async def test_method_list_with_all_params(self, async_client: AsyncContextDev)
change_detection_type="exact",
cursor="cursor",
limit=1,
+ q="q",
+ search_by=["name"],
+ search_type="exact",
status="active",
tag="tag",
+ tags=["string"],
target_type="page",
)
assert_matches_type(MonitorListResponse, monitor, path=["response"])
From fd00858ed8bc9806aebdb5f5c352d119ab2466d1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 30 Jun 2026 03:55:53 +0000
Subject: [PATCH 04/18] feat(api): api update
---
.stats.yml | 4 +--
src/context/dev/resources/web.py | 36 +++++++++++++++++++
.../dev/types/web_web_crawl_md_params.py | 7 ++++
.../dev/types/web_web_scrape_html_params.py | 7 ++++
.../dev/types/web_web_scrape_md_params.py | 7 ++++
tests/api_resources/test_web.py | 6 ++++
6 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0115b3b..f52ab5d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-66a3bf68b47ba61c9b61406d36f614a079ff752b8964a8df8062e485391d5598.yml
-openapi_spec_hash: b17d6cfe3710dd0605078f3907a1a419
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-d71b08e421ccdda9a2754c307e97df0ee7444926306a00624dca2bc7d56548ac.yml
+openapi_spec_hash: ebfbed20b5837ccf8db8bb40ab23baac
config_hash: 7ec4851ee8d93177947e95df5ae897b5
diff --git a/src/context/dev/resources/web.py b/src/context/dev/resources/web.py
index cbaff7d..5f30ccb 100644
--- a/src/context/dev/resources/web.py
+++ b/src/context/dev/resources/web.py
@@ -1211,6 +1211,7 @@ def web_crawl_md(
max_depth: int | Omit = omit,
max_pages: int | Omit = omit,
pdf: web_web_crawl_md_params.Pdf | Omit = omit,
+ settle_animations: bool | Omit = omit,
shorten_base64_images: bool | Omit = omit,
stop_after_ms: int | Omit = omit,
timeout_ms: int | Omit = omit,
@@ -1266,6 +1267,10 @@ def web_crawl_md(
pdf: PDF parsing controls. Use start/end to limit text extraction and OCR to an
inclusive 1-based page range.
+ settle_animations: When true, waits briefly for CSS and transition animations to settle before
+ extracting each crawled page. Defaults to false. This adds a bit of latency in
+ exchange for more stable output on animated pages.
+
shorten_base64_images: Truncate base64-encoded image data in the Markdown output
stop_after_ms: Soft time budget for the crawl in milliseconds. After each scrape, the crawler
@@ -1309,6 +1314,7 @@ def web_crawl_md(
"max_depth": max_depth,
"max_pages": max_pages,
"pdf": pdf,
+ "settle_animations": settle_animations,
"shorten_base64_images": shorten_base64_images,
"stop_after_ms": stop_after_ms,
"timeout_ms": timeout_ms,
@@ -1541,6 +1547,7 @@ def web_scrape_html(
include_selectors: SequenceNotStr[str] | Omit = omit,
max_age_ms: int | Omit = omit,
pdf: web_web_scrape_html_params.Pdf | Omit = omit,
+ settle_animations: bool | Omit = omit,
timeout_ms: int | Omit = omit,
use_main_content_only: bool | Omit = omit,
wait_for_ms: int | Omit = omit,
@@ -1581,6 +1588,10 @@ def web_scrape_html(
pdf: PDF parsing controls. Use start/end to limit text extraction and OCR to an
inclusive 1-based page range.
+ settle_animations: 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
+ more stable output on animated pages.
+
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -1617,6 +1628,7 @@ def web_scrape_html(
"include_selectors": include_selectors,
"max_age_ms": max_age_ms,
"pdf": pdf,
+ "settle_animations": settle_animations,
"timeout_ms": timeout_ms,
"use_main_content_only": use_main_content_only,
"wait_for_ms": wait_for_ms,
@@ -1918,6 +1930,7 @@ def web_scrape_md(
include_selectors: SequenceNotStr[str] | Omit = omit,
max_age_ms: int | Omit = omit,
pdf: web_web_scrape_md_params.Pdf | Omit = omit,
+ settle_animations: bool | Omit = omit,
shorten_base64_images: bool | Omit = omit,
timeout_ms: int | Omit = omit,
use_main_content_only: bool | Omit = omit,
@@ -1964,6 +1977,10 @@ def web_scrape_md(
pdf: PDF parsing controls. Use start/end to limit text extraction and OCR to an
inclusive 1-based page range.
+ settle_animations: 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: Shorten base64-encoded image data in the Markdown output
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
@@ -2003,6 +2020,7 @@ def web_scrape_md(
"include_selectors": include_selectors,
"max_age_ms": max_age_ms,
"pdf": pdf,
+ "settle_animations": settle_animations,
"shorten_base64_images": shorten_base64_images,
"timeout_ms": timeout_ms,
"use_main_content_only": use_main_content_only,
@@ -3244,6 +3262,7 @@ async def web_crawl_md(
max_depth: int | Omit = omit,
max_pages: int | Omit = omit,
pdf: web_web_crawl_md_params.Pdf | Omit = omit,
+ settle_animations: bool | Omit = omit,
shorten_base64_images: bool | Omit = omit,
stop_after_ms: int | Omit = omit,
timeout_ms: int | Omit = omit,
@@ -3299,6 +3318,10 @@ async def web_crawl_md(
pdf: PDF parsing controls. Use start/end to limit text extraction and OCR to an
inclusive 1-based page range.
+ settle_animations: When true, waits briefly for CSS and transition animations to settle before
+ extracting each crawled page. Defaults to false. This adds a bit of latency in
+ exchange for more stable output on animated pages.
+
shorten_base64_images: Truncate base64-encoded image data in the Markdown output
stop_after_ms: Soft time budget for the crawl in milliseconds. After each scrape, the crawler
@@ -3342,6 +3365,7 @@ async def web_crawl_md(
"max_depth": max_depth,
"max_pages": max_pages,
"pdf": pdf,
+ "settle_animations": settle_animations,
"shorten_base64_images": shorten_base64_images,
"stop_after_ms": stop_after_ms,
"timeout_ms": timeout_ms,
@@ -3574,6 +3598,7 @@ async def web_scrape_html(
include_selectors: SequenceNotStr[str] | Omit = omit,
max_age_ms: int | Omit = omit,
pdf: web_web_scrape_html_params.Pdf | Omit = omit,
+ settle_animations: bool | Omit = omit,
timeout_ms: int | Omit = omit,
use_main_content_only: bool | Omit = omit,
wait_for_ms: int | Omit = omit,
@@ -3614,6 +3639,10 @@ async def web_scrape_html(
pdf: PDF parsing controls. Use start/end to limit text extraction and OCR to an
inclusive 1-based page range.
+ settle_animations: 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
+ more stable output on animated pages.
+
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -3650,6 +3679,7 @@ async def web_scrape_html(
"include_selectors": include_selectors,
"max_age_ms": max_age_ms,
"pdf": pdf,
+ "settle_animations": settle_animations,
"timeout_ms": timeout_ms,
"use_main_content_only": use_main_content_only,
"wait_for_ms": wait_for_ms,
@@ -3951,6 +3981,7 @@ async def web_scrape_md(
include_selectors: SequenceNotStr[str] | Omit = omit,
max_age_ms: int | Omit = omit,
pdf: web_web_scrape_md_params.Pdf | Omit = omit,
+ settle_animations: bool | Omit = omit,
shorten_base64_images: bool | Omit = omit,
timeout_ms: int | Omit = omit,
use_main_content_only: bool | Omit = omit,
@@ -3997,6 +4028,10 @@ async def web_scrape_md(
pdf: PDF parsing controls. Use start/end to limit text extraction and OCR to an
inclusive 1-based page range.
+ settle_animations: 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: Shorten base64-encoded image data in the Markdown output
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
@@ -4036,6 +4071,7 @@ async def web_scrape_md(
"include_selectors": include_selectors,
"max_age_ms": max_age_ms,
"pdf": pdf,
+ "settle_animations": settle_animations,
"shorten_base64_images": shorten_base64_images,
"timeout_ms": timeout_ms,
"use_main_content_only": use_main_content_only,
diff --git a/src/context/dev/types/web_web_crawl_md_params.py b/src/context/dev/types/web_web_crawl_md_params.py
index f71309f..c2026e3 100644
--- a/src/context/dev/types/web_web_crawl_md_params.py
+++ b/src/context/dev/types/web_web_crawl_md_params.py
@@ -280,6 +280,13 @@ class WebWebCrawlMdParams(TypedDict, total=False):
range.
"""
+ settle_animations: Annotated[bool, PropertyInfo(alias="settleAnimations")]
+ """
+ When true, waits briefly for CSS and transition animations to settle before
+ extracting each crawled page. Defaults to false. This adds a bit of latency in
+ exchange for more stable output on animated pages.
+ """
+
shorten_base64_images: Annotated[bool, PropertyInfo(alias="shortenBase64Images")]
"""Truncate base64-encoded image data in the Markdown output"""
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 20a6ec9..a7e04d1 100644
--- a/src/context/dev/types/web_web_scrape_html_params.py
+++ b/src/context/dev/types/web_web_scrape_html_params.py
@@ -265,6 +265,13 @@ class WebWebScrapeHTMLParams(TypedDict, total=False):
range.
"""
+ 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
+ more stable output on animated pages.
+ """
+
timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
"""Optional timeout in milliseconds for the request.
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 0bb7b3a..32ad153 100644
--- a/src/context/dev/types/web_web_scrape_md_params.py
+++ b/src/context/dev/types/web_web_scrape_md_params.py
@@ -274,6 +274,13 @@ class WebWebScrapeMdParams(TypedDict, total=False):
range.
"""
+ 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[bool, PropertyInfo(alias="shortenBase64Images")]
"""Shorten base64-encoded image data in the Markdown output"""
diff --git a/tests/api_resources/test_web.py b/tests/api_resources/test_web.py
index 407af5e..8c61691 100644
--- a/tests/api_resources/test_web.py
+++ b/tests/api_resources/test_web.py
@@ -376,6 +376,7 @@ def test_method_web_crawl_md_with_all_params(self, client: ContextDev) -> None:
"should_parse": True,
"start": 1,
},
+ settle_animations=True,
shorten_base64_images=True,
stop_after_ms=10000,
timeout_ms=1000,
@@ -435,6 +436,7 @@ def test_method_web_scrape_html_with_all_params(self, client: ContextDev) -> Non
"should_parse": True,
"start": 1,
},
+ settle_animations=True,
timeout_ms=1000,
use_main_content_only=True,
wait_for_ms=0,
@@ -545,6 +547,7 @@ def test_method_web_scrape_md_with_all_params(self, client: ContextDev) -> None:
"should_parse": True,
"start": 1,
},
+ settle_animations=True,
shorten_base64_images=True,
timeout_ms=1000,
use_main_content_only=True,
@@ -977,6 +980,7 @@ async def test_method_web_crawl_md_with_all_params(self, async_client: AsyncCont
"should_parse": True,
"start": 1,
},
+ settle_animations=True,
shorten_base64_images=True,
stop_after_ms=10000,
timeout_ms=1000,
@@ -1036,6 +1040,7 @@ async def test_method_web_scrape_html_with_all_params(self, async_client: AsyncC
"should_parse": True,
"start": 1,
},
+ settle_animations=True,
timeout_ms=1000,
use_main_content_only=True,
wait_for_ms=0,
@@ -1146,6 +1151,7 @@ async def test_method_web_scrape_md_with_all_params(self, async_client: AsyncCon
"should_parse": True,
"start": 1,
},
+ settle_animations=True,
shorten_base64_images=True,
timeout_ms=1000,
use_main_content_only=True,
From c15ed56b283f8fe464891afda1566b74b120e2d5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 2 Jul 2026 01:46:49 +0000
Subject: [PATCH 05/18] feat(api): api update
---
.stats.yml | 4 ++--
src/context/dev/types/web_extract_response.py | 6 ++++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index f52ab5d..75582f8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-d71b08e421ccdda9a2754c307e97df0ee7444926306a00624dca2bc7d56548ac.yml
-openapi_spec_hash: ebfbed20b5837ccf8db8bb40ab23baac
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-c7625b4a7beb9e7d9827f3b836e6539cbc5f26b6754891d4352716e38cdecd73.yml
+openapi_spec_hash: cbee9cf164cc6704a6febb4d9737e83e
config_hash: 7ec4851ee8d93177947e95df5ae897b5
diff --git a/src/context/dev/types/web_extract_response.py b/src/context/dev/types/web_extract_response.py
index 715ac6e..2230fa2 100644
--- a/src/context/dev/types/web_extract_response.py
+++ b/src/context/dev/types/web_extract_response.py
@@ -12,6 +12,12 @@
class Metadata(BaseModel):
max_crawl_depth: int = FieldInfo(alias="maxCrawlDepth")
+ num_blocked: int = FieldInfo(alias="numBlocked")
+ """
+ Number of crawled pages excluded because they were anti-bot challenges, error
+ pages, or parked-domain placeholders.
+ """
+
num_failed: int = FieldInfo(alias="numFailed")
num_skipped: int = FieldInfo(alias="numSkipped")
From a2650d40a7422733a94b1f2e7e558144230189a0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 2 Jul 2026 05:14:29 +0000
Subject: [PATCH 06/18] feat(api): api update
---
.stats.yml | 4 +-
src/context/dev/resources/monitors.py | 42 +++++++++++++++----
.../dev/types/monitor_create_params.py | 6 ++-
.../dev/types/monitor_create_response.py | 28 ++++++++++++-
.../types/monitor_list_account_runs_params.py | 7 +++-
.../monitor_list_account_runs_response.py | 13 +++++-
src/context/dev/types/monitor_list_params.py | 7 ++++
.../dev/types/monitor_list_response.py | 28 ++++++++++++-
.../dev/types/monitor_list_runs_params.py | 7 +++-
.../dev/types/monitor_list_runs_response.py | 13 +++++-
.../types/monitor_retrieve_change_response.py | 6 +++
.../dev/types/monitor_retrieve_response.py | 28 ++++++++++++-
src/context/dev/types/monitor_run_response.py | 6 +++
.../dev/types/monitor_update_params.py | 6 ++-
.../dev/types/monitor_update_response.py | 28 ++++++++++++-
15 files changed, 209 insertions(+), 20 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 75582f8..3e4f564 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-c7625b4a7beb9e7d9827f3b836e6539cbc5f26b6754891d4352716e38cdecd73.yml
-openapi_spec_hash: cbee9cf164cc6704a6febb4d9737e83e
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-09b6020939995033719a53b988fb00bdb20c42d87070975a8d6b469fa18128fb.yml
+openapi_spec_hash: ba3e471937a679e2c45c0b9a115fca5c
config_hash: 7ec4851ee8d93177947e95df5ae897b5
diff --git a/src/context/dev/resources/monitors.py b/src/context/dev/resources/monitors.py
index 9147870..c5d4768 100644
--- a/src/context/dev/resources/monitors.py
+++ b/src/context/dev/resources/monitors.py
@@ -267,6 +267,12 @@ def list(
search_type: `prefix` for as-you-type prefix matching (default), `exact` for full-token
matching.
+ status: Monitor lifecycle status. `failed` means the most recent run failed (see the
+ monitor's `last_error`); failed monitors keep running on schedule and flip back
+ to `active` on the next successful run. Monitors are auto-`paused` after
+ repeated consecutive failures or insufficient-credit skips; resume by PATCHing
+ status to `active`.
+
tag: Filter to items that have this tag.
tags: Comma-separated list of tags to filter by (matches monitors having any of them).
@@ -399,7 +405,7 @@ def list_account_runs(
*,
cursor: str | Omit = omit,
limit: int | Omit = omit,
- status: Literal["queued", "running", "completed", "failed"] | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed", "skipped"] | 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,
@@ -411,6 +417,9 @@ def list_account_runs(
Returns an account-wide feed of monitor runs across all monitors.
Args:
+ status: Lifecycle status of a run. `skipped` runs never executed — see `skip_reason`
+ (insufficient credits, monitor paused, or superseded by a concurrent run).
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -497,7 +506,7 @@ def list_runs(
*,
cursor: str | Omit = omit,
limit: int | Omit = omit,
- status: Literal["queued", "running", "completed", "failed"] | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed", "skipped"] | 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,
@@ -505,10 +514,14 @@ def list_runs(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MonitorListRunsResponse:
- """
- List monitor runs
+ """List monitor runs
Args:
+ status: Lifecycle status of a run.
+
+ `skipped` runs never executed — see `skip_reason`
+ (insufficient credits, monitor paused, or superseded by a concurrent run).
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -831,6 +844,12 @@ async def list(
search_type: `prefix` for as-you-type prefix matching (default), `exact` for full-token
matching.
+ status: Monitor lifecycle status. `failed` means the most recent run failed (see the
+ monitor's `last_error`); failed monitors keep running on schedule and flip back
+ to `active` on the next successful run. Monitors are auto-`paused` after
+ repeated consecutive failures or insufficient-credit skips; resume by PATCHing
+ status to `active`.
+
tag: Filter to items that have this tag.
tags: Comma-separated list of tags to filter by (matches monitors having any of them).
@@ -963,7 +982,7 @@ async def list_account_runs(
*,
cursor: str | Omit = omit,
limit: int | Omit = omit,
- status: Literal["queued", "running", "completed", "failed"] | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed", "skipped"] | 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,
@@ -975,6 +994,9 @@ async def list_account_runs(
Returns an account-wide feed of monitor runs across all monitors.
Args:
+ status: Lifecycle status of a run. `skipped` runs never executed — see `skip_reason`
+ (insufficient credits, monitor paused, or superseded by a concurrent run).
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1061,7 +1083,7 @@ async def list_runs(
*,
cursor: str | Omit = omit,
limit: int | Omit = omit,
- status: Literal["queued", "running", "completed", "failed"] | Omit = omit,
+ status: Literal["queued", "running", "completed", "failed", "skipped"] | 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,
@@ -1069,10 +1091,14 @@ async def list_runs(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> MonitorListRunsResponse:
- """
- List monitor runs
+ """List monitor runs
Args:
+ status: Lifecycle status of a run.
+
+ `skipped` runs never executed — see `skip_reason`
+ (insufficient credits, monitor paused, or superseded by a concurrent run).
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
diff --git a/src/context/dev/types/monitor_create_params.py b/src/context/dev/types/monitor_create_params.py
index 93a333c..44efe4c 100644
--- a/src/context/dev/types/monitor_create_params.py
+++ b/src/context/dev/types/monitor_create_params.py
@@ -105,7 +105,10 @@ class TargetMonitorsPageTarget(TypedDict, total=False):
class TargetMonitorsSitemapTarget(TypedDict, total=False):
- """Watch a sitemap for URL additions and removals."""
+ """Watch a sitemap for URL additions and removals.
+
+ Crawled URLs are normalized (lowercased host, no trailing slash/fragment) and scoped to the monitored site and its subdomains before comparison. A new URL set must be observed on two consecutive runs before a change is reported, suppressing one-run crawl flaps.
+ """
type: Required[Literal["sitemap"]]
@@ -119,6 +122,7 @@ class TargetMonitorsSitemapTarget(TypedDict, total=False):
"""URL path patterns to include."""
max_urls: int
+ """Maximum number of sitemap URLs to track (capped at 10,000)."""
class TargetMonitorsExtractTarget(TypedDict, total=False):
diff --git a/src/context/dev/types/monitor_create_response.py b/src/context/dev/types/monitor_create_response.py
index f085273..eeff843 100644
--- a/src/context/dev/types/monitor_create_response.py
+++ b/src/context/dev/types/monitor_create_response.py
@@ -19,6 +19,7 @@
"TargetMonitorsPageTarget",
"TargetMonitorsSitemapTarget",
"TargetMonitorsExtractTarget",
+ "LastError",
"Webhook",
]
@@ -79,7 +80,10 @@ class TargetMonitorsPageTarget(BaseModel):
class TargetMonitorsSitemapTarget(BaseModel):
- """Watch a sitemap for URL additions and removals."""
+ """Watch a sitemap for URL additions and removals.
+
+ Crawled URLs are normalized (lowercased host, no trailing slash/fragment) and scoped to the monitored site and its subdomains before comparison. A new URL set must be observed on two consecutive runs before a change is reported, suppressing one-run crawl flaps.
+ """
type: Literal["sitemap"]
@@ -93,6 +97,7 @@ class TargetMonitorsSitemapTarget(BaseModel):
"""URL path patterns to include."""
max_urls: Optional[int] = None
+ """Maximum number of sitemap URLs to track (capped at 10,000)."""
class TargetMonitorsExtractTarget(BaseModel):
@@ -127,6 +132,14 @@ class TargetMonitorsExtractTarget(BaseModel):
]
+class LastError(BaseModel):
+ """Error from the most recent failed run; null when the last run succeeded."""
+
+ code: str
+
+ message: str
+
+
class Webhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -171,6 +184,13 @@ class MonitorCreateResponse(BaseModel):
"""
status: Literal["active", "paused", "failed"]
+ """Monitor lifecycle status.
+
+ `failed` means the most recent run failed (see the monitor's `last_error`);
+ failed monitors keep running on schedule and flip back to `active` on the next
+ successful run. Monitors are auto-`paused` after repeated consecutive failures
+ or insufficient-credit skips; resume by PATCHing status to `active`.
+ """
target: Target
"""Discriminated union describing what the monitor watches."""
@@ -179,8 +199,14 @@ class MonitorCreateResponse(BaseModel):
last_change_at: Optional[datetime] = None
+ last_error: Optional[LastError] = None
+ """Error from the most recent failed run; null when the last run succeeded."""
+
last_run_at: Optional[datetime] = None
+ next_run_at: Optional[datetime] = None
+ """When the next scheduled run is due."""
+
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
diff --git a/src/context/dev/types/monitor_list_account_runs_params.py b/src/context/dev/types/monitor_list_account_runs_params.py
index 1a54d7c..6329e57 100644
--- a/src/context/dev/types/monitor_list_account_runs_params.py
+++ b/src/context/dev/types/monitor_list_account_runs_params.py
@@ -12,4 +12,9 @@ class MonitorListAccountRunsParams(TypedDict, total=False):
limit: int
- status: Literal["queued", "running", "completed", "failed"]
+ status: Literal["queued", "running", "completed", "failed", "skipped"]
+ """Lifecycle status of a run.
+
+ `skipped` runs never executed — see `skip_reason` (insufficient credits, monitor
+ paused, or superseded by a concurrent run).
+ """
diff --git a/src/context/dev/types/monitor_list_account_runs_response.py b/src/context/dev/types/monitor_list_account_runs_response.py
index 6359dc1..a5d4bf0 100644
--- a/src/context/dev/types/monitor_list_account_runs_response.py
+++ b/src/context/dev/types/monitor_list_account_runs_response.py
@@ -28,12 +28,20 @@ class Data(BaseModel):
change_detection_type: Literal["exact", "semantic"]
+ credits_charged: int
+ """Credits charged for this run (0 for skipped/failed runs)."""
+
monitor_id: str
run_type: Literal["baseline", "scheduled"]
"""The first run after monitor creation is a baseline run."""
- status: Literal["queued", "running", "completed", "failed"]
+ status: Literal["queued", "running", "completed", "failed", "skipped"]
+ """Lifecycle status of a run.
+
+ `skipped` runs never executed — see `skip_reason` (insufficient credits, monitor
+ paused, or superseded by a concurrent run).
+ """
target_type: Literal["page", "sitemap", "extract"]
@@ -43,6 +51,9 @@ class Data(BaseModel):
error: Optional[DataError] = None
+ skip_reason: Optional[Literal["insufficient_credits", "monitor_paused", "superseded"]] = None
+ """Why a skipped run never executed; null unless status is `skipped`."""
+
started_at: Optional[datetime] = None
diff --git a/src/context/dev/types/monitor_list_params.py b/src/context/dev/types/monitor_list_params.py
index 40bfd1a..e13f900 100644
--- a/src/context/dev/types/monitor_list_params.py
+++ b/src/context/dev/types/monitor_list_params.py
@@ -33,6 +33,13 @@ class MonitorListParams(TypedDict, total=False):
"""
status: Literal["active", "paused", "failed"]
+ """Monitor lifecycle status.
+
+ `failed` means the most recent run failed (see the monitor's `last_error`);
+ failed monitors keep running on schedule and flip back to `active` on the next
+ successful run. Monitors are auto-`paused` after repeated consecutive failures
+ or insufficient-credit skips; resume by PATCHing status to `active`.
+ """
tag: str
"""Filter to items that have this tag."""
diff --git a/src/context/dev/types/monitor_list_response.py b/src/context/dev/types/monitor_list_response.py
index be26e3b..40277aa 100644
--- a/src/context/dev/types/monitor_list_response.py
+++ b/src/context/dev/types/monitor_list_response.py
@@ -20,6 +20,7 @@
"DataTargetMonitorsPageTarget",
"DataTargetMonitorsSitemapTarget",
"DataTargetMonitorsExtractTarget",
+ "DataLastError",
"DataWebhook",
]
@@ -80,7 +81,10 @@ class DataTargetMonitorsPageTarget(BaseModel):
class DataTargetMonitorsSitemapTarget(BaseModel):
- """Watch a sitemap for URL additions and removals."""
+ """Watch a sitemap for URL additions and removals.
+
+ Crawled URLs are normalized (lowercased host, no trailing slash/fragment) and scoped to the monitored site and its subdomains before comparison. A new URL set must be observed on two consecutive runs before a change is reported, suppressing one-run crawl flaps.
+ """
type: Literal["sitemap"]
@@ -94,6 +98,7 @@ class DataTargetMonitorsSitemapTarget(BaseModel):
"""URL path patterns to include."""
max_urls: Optional[int] = None
+ """Maximum number of sitemap URLs to track (capped at 10,000)."""
class DataTargetMonitorsExtractTarget(BaseModel):
@@ -128,6 +133,14 @@ class DataTargetMonitorsExtractTarget(BaseModel):
]
+class DataLastError(BaseModel):
+ """Error from the most recent failed run; null when the last run succeeded."""
+
+ code: str
+
+ message: str
+
+
class DataWebhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -172,6 +185,13 @@ class Data(BaseModel):
"""
status: Literal["active", "paused", "failed"]
+ """Monitor lifecycle status.
+
+ `failed` means the most recent run failed (see the monitor's `last_error`);
+ failed monitors keep running on schedule and flip back to `active` on the next
+ successful run. Monitors are auto-`paused` after repeated consecutive failures
+ or insufficient-credit skips; resume by PATCHing status to `active`.
+ """
target: DataTarget
"""Discriminated union describing what the monitor watches."""
@@ -180,8 +200,14 @@ class Data(BaseModel):
last_change_at: Optional[datetime] = None
+ last_error: Optional[DataLastError] = None
+ """Error from the most recent failed run; null when the last run succeeded."""
+
last_run_at: Optional[datetime] = None
+ next_run_at: Optional[datetime] = None
+ """When the next scheduled run is due."""
+
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
diff --git a/src/context/dev/types/monitor_list_runs_params.py b/src/context/dev/types/monitor_list_runs_params.py
index 86db021..dbfa379 100644
--- a/src/context/dev/types/monitor_list_runs_params.py
+++ b/src/context/dev/types/monitor_list_runs_params.py
@@ -12,4 +12,9 @@ class MonitorListRunsParams(TypedDict, total=False):
limit: int
- status: Literal["queued", "running", "completed", "failed"]
+ status: Literal["queued", "running", "completed", "failed", "skipped"]
+ """Lifecycle status of a run.
+
+ `skipped` runs never executed — see `skip_reason` (insufficient credits, monitor
+ paused, or superseded by a concurrent run).
+ """
diff --git a/src/context/dev/types/monitor_list_runs_response.py b/src/context/dev/types/monitor_list_runs_response.py
index c7a075f..1e0500a 100644
--- a/src/context/dev/types/monitor_list_runs_response.py
+++ b/src/context/dev/types/monitor_list_runs_response.py
@@ -28,12 +28,20 @@ class Data(BaseModel):
change_detection_type: Literal["exact", "semantic"]
+ credits_charged: int
+ """Credits charged for this run (0 for skipped/failed runs)."""
+
monitor_id: str
run_type: Literal["baseline", "scheduled"]
"""The first run after monitor creation is a baseline run."""
- status: Literal["queued", "running", "completed", "failed"]
+ status: Literal["queued", "running", "completed", "failed", "skipped"]
+ """Lifecycle status of a run.
+
+ `skipped` runs never executed — see `skip_reason` (insufficient credits, monitor
+ paused, or superseded by a concurrent run).
+ """
target_type: Literal["page", "sitemap", "extract"]
@@ -43,6 +51,9 @@ class Data(BaseModel):
error: Optional[DataError] = None
+ skip_reason: Optional[Literal["insufficient_credits", "monitor_paused", "superseded"]] = None
+ """Why a skipped run never executed; null unless status is `skipped`."""
+
started_at: Optional[datetime] = None
diff --git a/src/context/dev/types/monitor_retrieve_change_response.py b/src/context/dev/types/monitor_retrieve_change_response.py
index f7cab7a..dade21a 100644
--- a/src/context/dev/types/monitor_retrieve_change_response.py
+++ b/src/context/dev/types/monitor_retrieve_change_response.py
@@ -41,6 +41,9 @@ class MonitorRetrieveChangeResponse(BaseModel):
monitor_id: str
+ run_id: str
+ """The run that detected this change."""
+
summary: str
target_type: Literal["page", "sitemap", "extract"]
@@ -52,6 +55,7 @@ class MonitorRetrieveChangeResponse(BaseModel):
added_url_count: Optional[int] = None
added_urls: Optional[List[str]] = None
+ """At most 500 URLs are included; the corresponding count field is always exact."""
after_text_excerpt: Optional[str] = None
@@ -69,12 +73,14 @@ class MonitorRetrieveChangeResponse(BaseModel):
matched_url_count: Optional[int] = None
matched_urls: Optional[List[str]] = None
+ """At most 500 URLs are included; the corresponding count field is always exact."""
query: Optional[str] = None
removed_url_count: Optional[int] = None
removed_urls: Optional[List[str]] = None
+ """At most 500 URLs are included; the corresponding count field is always exact."""
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
diff --git a/src/context/dev/types/monitor_retrieve_response.py b/src/context/dev/types/monitor_retrieve_response.py
index c0c70bc..8032a1e 100644
--- a/src/context/dev/types/monitor_retrieve_response.py
+++ b/src/context/dev/types/monitor_retrieve_response.py
@@ -19,6 +19,7 @@
"TargetMonitorsPageTarget",
"TargetMonitorsSitemapTarget",
"TargetMonitorsExtractTarget",
+ "LastError",
"Webhook",
]
@@ -79,7 +80,10 @@ class TargetMonitorsPageTarget(BaseModel):
class TargetMonitorsSitemapTarget(BaseModel):
- """Watch a sitemap for URL additions and removals."""
+ """Watch a sitemap for URL additions and removals.
+
+ Crawled URLs are normalized (lowercased host, no trailing slash/fragment) and scoped to the monitored site and its subdomains before comparison. A new URL set must be observed on two consecutive runs before a change is reported, suppressing one-run crawl flaps.
+ """
type: Literal["sitemap"]
@@ -93,6 +97,7 @@ class TargetMonitorsSitemapTarget(BaseModel):
"""URL path patterns to include."""
max_urls: Optional[int] = None
+ """Maximum number of sitemap URLs to track (capped at 10,000)."""
class TargetMonitorsExtractTarget(BaseModel):
@@ -127,6 +132,14 @@ class TargetMonitorsExtractTarget(BaseModel):
]
+class LastError(BaseModel):
+ """Error from the most recent failed run; null when the last run succeeded."""
+
+ code: str
+
+ message: str
+
+
class Webhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -171,6 +184,13 @@ class MonitorRetrieveResponse(BaseModel):
"""
status: Literal["active", "paused", "failed"]
+ """Monitor lifecycle status.
+
+ `failed` means the most recent run failed (see the monitor's `last_error`);
+ failed monitors keep running on schedule and flip back to `active` on the next
+ successful run. Monitors are auto-`paused` after repeated consecutive failures
+ or insufficient-credit skips; resume by PATCHing status to `active`.
+ """
target: Target
"""Discriminated union describing what the monitor watches."""
@@ -179,8 +199,14 @@ class MonitorRetrieveResponse(BaseModel):
last_change_at: Optional[datetime] = None
+ last_error: Optional[LastError] = None
+ """Error from the most recent failed run; null when the last run succeeded."""
+
last_run_at: Optional[datetime] = None
+ next_run_at: Optional[datetime] = None
+ """When the next scheduled run is due."""
+
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
diff --git a/src/context/dev/types/monitor_run_response.py b/src/context/dev/types/monitor_run_response.py
index db2416c..11a141c 100644
--- a/src/context/dev/types/monitor_run_response.py
+++ b/src/context/dev/types/monitor_run_response.py
@@ -9,3 +9,9 @@ class MonitorRunResponse(BaseModel):
monitor_id: str
queued: bool
+
+ run_id: str
+ """The queued run.
+
+ Poll GET /monitors/{monitor_id}/runs or use it to correlate results.
+ """
diff --git a/src/context/dev/types/monitor_update_params.py b/src/context/dev/types/monitor_update_params.py
index 373457b..7220002 100644
--- a/src/context/dev/types/monitor_update_params.py
+++ b/src/context/dev/types/monitor_update_params.py
@@ -101,7 +101,10 @@ class TargetMonitorsPageTarget(TypedDict, total=False):
class TargetMonitorsSitemapTarget(TypedDict, total=False):
- """Watch a sitemap for URL additions and removals."""
+ """Watch a sitemap for URL additions and removals.
+
+ Crawled URLs are normalized (lowercased host, no trailing slash/fragment) and scoped to the monitored site and its subdomains before comparison. A new URL set must be observed on two consecutive runs before a change is reported, suppressing one-run crawl flaps.
+ """
type: Required[Literal["sitemap"]]
@@ -115,6 +118,7 @@ class TargetMonitorsSitemapTarget(TypedDict, total=False):
"""URL path patterns to include."""
max_urls: int
+ """Maximum number of sitemap URLs to track (capped at 10,000)."""
class TargetMonitorsExtractTarget(TypedDict, total=False):
diff --git a/src/context/dev/types/monitor_update_response.py b/src/context/dev/types/monitor_update_response.py
index 4fc4fcb..a459787 100644
--- a/src/context/dev/types/monitor_update_response.py
+++ b/src/context/dev/types/monitor_update_response.py
@@ -19,6 +19,7 @@
"TargetMonitorsPageTarget",
"TargetMonitorsSitemapTarget",
"TargetMonitorsExtractTarget",
+ "LastError",
"Webhook",
]
@@ -79,7 +80,10 @@ class TargetMonitorsPageTarget(BaseModel):
class TargetMonitorsSitemapTarget(BaseModel):
- """Watch a sitemap for URL additions and removals."""
+ """Watch a sitemap for URL additions and removals.
+
+ Crawled URLs are normalized (lowercased host, no trailing slash/fragment) and scoped to the monitored site and its subdomains before comparison. A new URL set must be observed on two consecutive runs before a change is reported, suppressing one-run crawl flaps.
+ """
type: Literal["sitemap"]
@@ -93,6 +97,7 @@ class TargetMonitorsSitemapTarget(BaseModel):
"""URL path patterns to include."""
max_urls: Optional[int] = None
+ """Maximum number of sitemap URLs to track (capped at 10,000)."""
class TargetMonitorsExtractTarget(BaseModel):
@@ -127,6 +132,14 @@ class TargetMonitorsExtractTarget(BaseModel):
]
+class LastError(BaseModel):
+ """Error from the most recent failed run; null when the last run succeeded."""
+
+ code: str
+
+ message: str
+
+
class Webhook(BaseModel):
url: str
"""Webhook URL called when a change is detected."""
@@ -171,6 +184,13 @@ class MonitorUpdateResponse(BaseModel):
"""
status: Literal["active", "paused", "failed"]
+ """Monitor lifecycle status.
+
+ `failed` means the most recent run failed (see the monitor's `last_error`);
+ failed monitors keep running on schedule and flip back to `active` on the next
+ successful run. Monitors are auto-`paused` after repeated consecutive failures
+ or insufficient-credit skips; resume by PATCHing status to `active`.
+ """
target: Target
"""Discriminated union describing what the monitor watches."""
@@ -179,8 +199,14 @@ class MonitorUpdateResponse(BaseModel):
last_change_at: Optional[datetime] = None
+ last_error: Optional[LastError] = None
+ """Error from the most recent failed run; null when the last run succeeded."""
+
last_run_at: Optional[datetime] = None
+ next_run_at: Optional[datetime] = None
+ """When the next scheduled run is due."""
+
tags: Optional[List[str]] = None
"""User-defined tags for grouping and filtering monitors and their changes."""
From 000bd7c50e673065f0023267aea7457f3bb1f6d9 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 3 Jul 2026 05:13:14 +0000
Subject: [PATCH 07/18] feat(api): api update
---
.stats.yml | 4 ++--
src/context/dev/types/web_web_scrape_html_response.py | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3e4f564..7e51832 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-09b6020939995033719a53b988fb00bdb20c42d87070975a8d6b469fa18128fb.yml
-openapi_spec_hash: ba3e471937a679e2c45c0b9a115fca5c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-6320934d3b42a03cc52429218247595c7119e91a615db570070f71849aaa74de.yml
+openapi_spec_hash: c63aeaa0fdcc422e8ad59c9fb30d2476
config_hash: 7ec4851ee8d93177947e95df5ae897b5
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 09495c6..1628b43 100644
--- a/src/context/dev/types/web_web_scrape_html_response.py
+++ b/src/context/dev/types/web_web_scrape_html_response.py
@@ -116,10 +116,11 @@ class WebWebScrapeHTMLResponse(BaseModel):
success: Literal[True]
"""Indicates success"""
- type: Literal["html", "xml", "json", "text", "csv", "markdown", "svg", "pdf", "docx", "doc"]
+ type: Literal["html", "xml", "json", "text", "csv", "markdown", "svg", "pdf", "docx", "doc", "xlsx", "xls"]
"""Detected content type of the returned `html` field.
- Sitemaps and feeds are surfaced as `xml`; ordinary pages are `html`.
+ Sitemaps and feeds are surfaced as `xml`; ordinary pages are `html`. Excel
+ workbooks are surfaced as `xlsx`/`xls` with the extracted sheets as HTML tables.
"""
url: str
From 41ee2e823e3a91c608861da5fe46b263518c223e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 4 Jul 2026 18:58:48 +0000
Subject: [PATCH 08/18] feat(api): api update
---
.stats.yml | 4 ++--
src/context/dev/types/web_web_scrape_html_response.py | 8 ++++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 7e51832..3840f48 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-6320934d3b42a03cc52429218247595c7119e91a615db570070f71849aaa74de.yml
-openapi_spec_hash: c63aeaa0fdcc422e8ad59c9fb30d2476
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-171b4c39eb26210aad8afd74d63d620bf45f7e0b7f2de3938c7239741ea3f2f4.yml
+openapi_spec_hash: 752c05fc817dc766061bd4357bd327ba
config_hash: 7ec4851ee8d93177947e95df5ae897b5
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 1628b43..a1d07e8 100644
--- a/src/context/dev/types/web_web_scrape_html_response.py
+++ b/src/context/dev/types/web_web_scrape_html_response.py
@@ -116,11 +116,15 @@ class WebWebScrapeHTMLResponse(BaseModel):
success: Literal[True]
"""Indicates success"""
- type: Literal["html", "xml", "json", "text", "csv", "markdown", "svg", "pdf", "docx", "doc", "xlsx", "xls"]
+ type: Literal[
+ "html", "xml", "json", "text", "csv", "markdown", "svg", "pdf", "docx", "doc", "xlsx", "xls", "pptx", "ppt"
+ ]
"""Detected content type of the returned `html` field.
Sitemaps and feeds are surfaced as `xml`; ordinary pages are `html`. Excel
- workbooks are surfaced as `xlsx`/`xls` with the extracted sheets as HTML tables.
+ workbooks are surfaced as `xlsx`/`xls` with the extracted sheets as HTML tables;
+ PowerPoint presentations are surfaced as `pptx`/`ppt` with the extracted slides
+ as HTML.
"""
url: str
From 4bbf3b1ad847353571b27118e0875bb2ff96c0c7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 4 Jul 2026 21:58:58 +0000
Subject: [PATCH 09/18] feat(api): api update
---
.stats.yml | 4 ++--
src/context/dev/resources/web.py | 14 ++++++++++++++
.../dev/types/web_web_scrape_images_params.py | 8 ++++++++
tests/api_resources/test_web.py | 2 ++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3840f48..e7ac969 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-171b4c39eb26210aad8afd74d63d620bf45f7e0b7f2de3938c7239741ea3f2f4.yml
-openapi_spec_hash: 752c05fc817dc766061bd4357bd327ba
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-633097a61ae4e029434e5af07efa3017301fe8b391c27ada3eb68b61d798ef33.yml
+openapi_spec_hash: 051b08a4c6530546d520aa7ec18f8123
config_hash: 7ec4851ee8d93177947e95df5ae897b5
diff --git a/src/context/dev/resources/web.py b/src/context/dev/resources/web.py
index 5f30ccb..00bc95e 100644
--- a/src/context/dev/resources/web.py
+++ b/src/context/dev/resources/web.py
@@ -1643,6 +1643,7 @@ def web_scrape_images(
self,
*,
url: str,
+ dedupe: bool | Omit = omit,
enrichment: web_web_scrape_images_params.Enrichment | Omit = omit,
headers: Dict[str, str] | Omit = omit,
max_age_ms: int | Omit = omit,
@@ -1664,6 +1665,11 @@ def web_scrape_images(
Args:
url: Page URL to inspect. Must include http:// or https://.
+ dedupe: When true, visually duplicate images are removed: every image is loaded and
+ perceptually hashed, and only the highest-resolution copy of each duplicate
+ group is kept. Images that cannot be downloaded or hashed are kept. Default:
+ false.
+
enrichment: Optional per-image processing, sent as deep-object query params such as
enrichment[resolution]=true.
@@ -1699,6 +1705,7 @@ def web_scrape_images(
query=maybe_transform(
{
"url": url,
+ "dedupe": dedupe,
"enrichment": enrichment,
"headers": headers,
"max_age_ms": max_age_ms,
@@ -3694,6 +3701,7 @@ async def web_scrape_images(
self,
*,
url: str,
+ dedupe: bool | Omit = omit,
enrichment: web_web_scrape_images_params.Enrichment | Omit = omit,
headers: Dict[str, str] | Omit = omit,
max_age_ms: int | Omit = omit,
@@ -3715,6 +3723,11 @@ async def web_scrape_images(
Args:
url: Page URL to inspect. Must include http:// or https://.
+ dedupe: When true, visually duplicate images are removed: every image is loaded and
+ perceptually hashed, and only the highest-resolution copy of each duplicate
+ group is kept. Images that cannot be downloaded or hashed are kept. Default:
+ false.
+
enrichment: Optional per-image processing, sent as deep-object query params such as
enrichment[resolution]=true.
@@ -3750,6 +3763,7 @@ async def web_scrape_images(
query=await async_maybe_transform(
{
"url": url,
+ "dedupe": dedupe,
"enrichment": enrichment,
"headers": headers,
"max_age_ms": max_age_ms,
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 06e282a..f745001 100644
--- a/src/context/dev/types/web_web_scrape_images_params.py
+++ b/src/context/dev/types/web_web_scrape_images_params.py
@@ -14,6 +14,14 @@ class WebWebScrapeImagesParams(TypedDict, total=False):
url: Required[str]
"""Page URL to inspect. Must include http:// or https://."""
+ 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
+ group is kept. Images that cannot be downloaded or hashed are kept. Default:
+ false.
+ """
+
enrichment: Enrichment
"""
Optional per-image processing, sent as deep-object query params such as
diff --git a/tests/api_resources/test_web.py b/tests/api_resources/test_web.py
index 8c61691..7e473c5 100644
--- a/tests/api_resources/test_web.py
+++ b/tests/api_resources/test_web.py
@@ -482,6 +482,7 @@ def test_method_web_scrape_images(self, client: ContextDev) -> None:
def test_method_web_scrape_images_with_all_params(self, client: ContextDev) -> None:
web = client.web.web_scrape_images(
url="https://example.com",
+ dedupe=True,
enrichment={
"classification": True,
"hosted_url": True,
@@ -1086,6 +1087,7 @@ async def test_method_web_scrape_images(self, async_client: AsyncContextDev) ->
async def test_method_web_scrape_images_with_all_params(self, async_client: AsyncContextDev) -> None:
web = await async_client.web.web_scrape_images(
url="https://example.com",
+ dedupe=True,
enrichment={
"classification": True,
"hosted_url": True,
From a909702032dd7cd3bcf76b39cad54362fda57bb4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 01:38:58 +0000
Subject: [PATCH 10/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e7ac969..ea3b8ae 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-633097a61ae4e029434e5af07efa3017301fe8b391c27ada3eb68b61d798ef33.yml
-openapi_spec_hash: 051b08a4c6530546d520aa7ec18f8123
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-3bbf1a39f32a13c350bdbc1e8a98ebd3753ec54f70d75cd4656c1773b2d2ecad.yml
+openapi_spec_hash: 69beb23616fa92b1c1f6a2a4f7a36390
config_hash: 7ec4851ee8d93177947e95df5ae897b5
From 006f756aaf642a756f6a3dc14e0a535c1c75e32e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 03:17:35 +0000
Subject: [PATCH 11/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index ea3b8ae..77807ba 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-3bbf1a39f32a13c350bdbc1e8a98ebd3753ec54f70d75cd4656c1773b2d2ecad.yml
-openapi_spec_hash: 69beb23616fa92b1c1f6a2a4f7a36390
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-4b24bfbe3d1371e5ce175d71f9074b6f6aec35d4c3438013af2a54b776f8f126.yml
+openapi_spec_hash: d3b67756889b03f77efaf8571bb09d59
config_hash: 7ec4851ee8d93177947e95df5ae897b5
From 94f3b120b655dc8e8b53e3f6b294bf19646c1ffb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 04:27:57 +0000
Subject: [PATCH 12/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 77807ba..cb8d47f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-4b24bfbe3d1371e5ce175d71f9074b6f6aec35d4c3438013af2a54b776f8f126.yml
-openapi_spec_hash: d3b67756889b03f77efaf8571bb09d59
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-77005ca6ad90dc48689fe056a1dbd63f8eefb0224dc88530dd921a784a7b0185.yml
+openapi_spec_hash: 8f3189c550a36de0ca5e1b032298acfd
config_hash: 7ec4851ee8d93177947e95df5ae897b5
From 95505a7fa6fb35825b688acba49c733fea5b452c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 05:12:23 +0000
Subject: [PATCH 13/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index cb8d47f..a272343 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-77005ca6ad90dc48689fe056a1dbd63f8eefb0224dc88530dd921a784a7b0185.yml
-openapi_spec_hash: 8f3189c550a36de0ca5e1b032298acfd
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-654e47d50a02e8b12f4f035b1a8ec6e864557fed57b744c909ca85127739cc30.yml
+openapi_spec_hash: a44b7d4172c8c7cd395237738867d5cb
config_hash: 7ec4851ee8d93177947e95df5ae897b5
From 63d9bdfc771270ccecff225a339af6ec51dfc1f7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 05:30:55 +0000
Subject: [PATCH 14/18] feat(api): manual updates
---
.stats.yml | 6 +-
README.md | 90 +-
api.md | 25 +-
src/context/dev/resources/ai.py | 128 +-
src/context/dev/resources/brand.py | 1883 ++---------------
src/context/dev/resources/utility.py | 159 +-
src/context/dev/types/__init__.py | 18 -
src/context/dev/types/ai_ai_query_params.py | 86 -
src/context/dev/types/ai_ai_query_response.py | 53 -
.../brand_identify_from_transaction_params.py | 416 ----
...rand_identify_from_transaction_response.py | 682 ------
.../types/brand_retrieve_by_email_params.py | 164 --
.../types/brand_retrieve_by_email_response.py | 682 ------
.../types/brand_retrieve_by_isin_params.py | 164 --
.../types/brand_retrieve_by_isin_response.py | 682 ------
.../types/brand_retrieve_by_name_params.py | 409 ----
.../types/brand_retrieve_by_name_response.py | 682 ------
.../types/brand_retrieve_by_ticker_params.py | 239 ---
.../brand_retrieve_by_ticker_response.py | 682 ------
.../dev/types/brand_retrieve_params.py | 653 +++++-
.../types/utility_prefetch_by_email_params.py | 25 -
.../utility_prefetch_by_email_response.py | 38 -
.../dev/types/utility_prefetch_params.py | 25 +-
.../dev/types/utility_prefetch_response.py | 7 +
tests/api_resources/test_ai.py | 183 --
tests/api_resources/test_brand.py | 397 ++--
tests/api_resources/test_utility.py | 121 +-
tests/test_client.py | 124 +-
28 files changed, 1290 insertions(+), 7533 deletions(-)
delete mode 100644 src/context/dev/types/ai_ai_query_params.py
delete mode 100644 src/context/dev/types/ai_ai_query_response.py
delete mode 100644 src/context/dev/types/brand_identify_from_transaction_params.py
delete mode 100644 src/context/dev/types/brand_identify_from_transaction_response.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_email_params.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_email_response.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_isin_params.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_isin_response.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_name_params.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_name_response.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_ticker_params.py
delete mode 100644 src/context/dev/types/brand_retrieve_by_ticker_response.py
delete mode 100644 src/context/dev/types/utility_prefetch_by_email_params.py
delete mode 100644 src/context/dev/types/utility_prefetch_by_email_response.py
diff --git a/.stats.yml b/.stats.yml
index a272343..151723e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 36
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-654e47d50a02e8b12f4f035b1a8ec6e864557fed57b744c909ca85127739cc30.yml
+configured_endpoints: 29
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-2e40370ce4d7d019b30d43020674bb02aaaf2a67a8916772084815c874f99950.yml
openapi_spec_hash: a44b7d4172c8c7cd395237738867d5cb
-config_hash: 7ec4851ee8d93177947e95df5ae897b5
+config_hash: 472cc1adb51663e5b3d8dce16f6d29d9
diff --git a/README.md b/README.md
index 366323c..d8ce5e8 100644
--- a/README.md
+++ b/README.md
@@ -41,10 +41,16 @@ client = ContextDev(
api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted
)
-brand = client.brand.retrieve(
- domain="REPLACE_ME",
+response = client.web.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
-print(brand.brand)
+print(response.data)
```
While you can provide an `api_key` keyword argument,
@@ -67,10 +73,16 @@ client = AsyncContextDev(
async def main() -> None:
- brand = await client.brand.retrieve(
- domain="REPLACE_ME",
+ response = await client.web.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
- print(brand.brand)
+ print(response.data)
asyncio.run(main())
@@ -103,10 +115,16 @@ async def main() -> None:
api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted
http_client=DefaultAioHttpClient(),
) as client:
- brand = await client.brand.retrieve(
- domain="REPLACE_ME",
+ response = await client.web.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
- print(brand.brand)
+ print(response.data)
asyncio.run(main())
@@ -159,8 +177,14 @@ from context.dev import ContextDev
client = ContextDev()
try:
- client.brand.retrieve(
- domain="REPLACE_ME",
+ client.web.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
except context.dev.APIConnectionError as e:
print("The server could not be reached")
@@ -204,8 +228,14 @@ client = ContextDev(
)
# Or, configure per-request:
-client.with_options(max_retries=5).brand.retrieve(
- domain="REPLACE_ME",
+client.with_options(max_retries=5).web.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
```
@@ -229,8 +259,14 @@ client = ContextDev(
)
# Override per-request:
-client.with_options(timeout=5.0).brand.retrieve(
- domain="REPLACE_ME",
+client.with_options(timeout=5.0).web.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
```
@@ -272,13 +308,19 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
from context.dev import ContextDev
client = ContextDev()
-response = client.brand.with_raw_response.retrieve(
- domain="REPLACE_ME",
+response = client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
)
print(response.headers.get('X-My-Header'))
-brand = response.parse() # get the object that `brand.retrieve()` would have returned
-print(brand.brand)
+web = response.parse() # get the object that `web.extract()` would have returned
+print(web.data)
```
These methods return an [`APIResponse`](https://github.com/context-dot-dev/context-python-sdk/tree/main/src/context/dev/_response.py) object.
@@ -292,8 +334,14 @@ The above interface eagerly reads the full response body when you make the reque
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.
```python
-with client.brand.with_streaming_response.retrieve(
- domain="REPLACE_ME",
+with client.web.with_streaming_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
) as response:
print(response.headers.get("X-My-Header"))
diff --git a/api.md b/api.md
index f31fb8a..1754626 100644
--- a/api.md
+++ b/api.md
@@ -37,12 +37,11 @@ Methods:
Types:
```python
-from context.dev.types import AIAIQueryResponse, AIExtractProductResponse, AIExtractProductsResponse
+from context.dev.types import AIExtractProductResponse, AIExtractProductsResponse
```
Methods:
-- client.ai.ai_query(\*\*params) -> AIAIQueryResponse
- client.ai.extract_product(\*\*params) -> AIExtractProductResponse
- client.ai.extract_products(\*\*params) -> AIExtractProductsResponse
@@ -51,25 +50,12 @@ Methods:
Types:
```python
-from context.dev.types import (
- BrandRetrieveResponse,
- BrandIdentifyFromTransactionResponse,
- BrandRetrieveByEmailResponse,
- BrandRetrieveByIsinResponse,
- BrandRetrieveByNameResponse,
- BrandRetrieveByTickerResponse,
- BrandRetrieveSimplifiedResponse,
-)
+from context.dev.types import BrandRetrieveResponse, BrandRetrieveSimplifiedResponse
```
Methods:
-- client.brand.retrieve(\*\*params) -> BrandRetrieveResponse
-- client.brand.identify_from_transaction(\*\*params) -> BrandIdentifyFromTransactionResponse
-- client.brand.retrieve_by_email(\*\*params) -> BrandRetrieveByEmailResponse
-- client.brand.retrieve_by_isin(\*\*params) -> BrandRetrieveByIsinResponse
-- client.brand.retrieve_by_name(\*\*params) -> BrandRetrieveByNameResponse
-- client.brand.retrieve_by_ticker(\*\*params) -> BrandRetrieveByTickerResponse
+- client.brand.retrieve(\*\*params) -> BrandRetrieveResponse
- client.brand.retrieve_simplified(\*\*params) -> BrandRetrieveSimplifiedResponse
# Industry
@@ -90,13 +76,12 @@ Methods:
Types:
```python
-from context.dev.types import UtilityPrefetchResponse, UtilityPrefetchByEmailResponse
+from context.dev.types import UtilityPrefetchResponse
```
Methods:
-- client.utility.prefetch(\*\*params) -> UtilityPrefetchResponse
-- client.utility.prefetch_by_email(\*\*params) -> UtilityPrefetchByEmailResponse
+- client.utility.prefetch(\*\*params) -> UtilityPrefetchResponse
# Monitors
diff --git a/src/context/dev/resources/ai.py b/src/context/dev/resources/ai.py
index 5e1d231..4bfb82e 100644
--- a/src/context/dev/resources/ai.py
+++ b/src/context/dev/resources/ai.py
@@ -2,12 +2,11 @@
from __future__ import annotations
-from typing import Iterable
from typing_extensions import overload
import httpx
-from ..types import ai_ai_query_params, ai_extract_product_params, ai_extract_products_params
+from ..types import ai_extract_product_params, ai_extract_products_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import required_args, maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -19,7 +18,6 @@
async_to_streamed_response_wrapper,
)
from .._base_client import make_request_options
-from ..types.ai_ai_query_response import AIAIQueryResponse
from ..types.ai_extract_product_response import AIExtractProductResponse
from ..types.ai_extract_products_response import AIExtractProductsResponse
@@ -46,62 +44,6 @@ def with_streaming_response(self) -> AIResourceWithStreamingResponse:
"""
return AIResourceWithStreamingResponse(self)
- def ai_query(
- self,
- *,
- data_to_extract: Iterable[ai_ai_query_params.DataToExtract],
- domain: str,
- specific_pages: ai_ai_query_params.SpecificPages | 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.
- # 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,
- ) -> AIAIQueryResponse:
- """Use AI to extract specific data points from a brand's website.
-
- The AI will crawl
- the website and extract the requested information based on the provided data
- points.
-
- Args:
- data_to_extract: Array of data points to extract from the website
-
- domain: The domain name to analyze
-
- specific_pages: Optional object specifying which pages to analyze
-
- timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
- than this value, it will be aborted with a 408 status code. Maximum allowed
- value is 300000ms (5 minutes).
-
- 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(
- "/brand/ai/query",
- body=maybe_transform(
- {
- "data_to_extract": data_to_extract,
- "domain": domain,
- "specific_pages": specific_pages,
- "timeout_ms": timeout_ms,
- },
- ai_ai_query_params.AIAIQueryParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=AIAIQueryResponse,
- )
-
def extract_product(
self,
*,
@@ -298,62 +240,6 @@ def with_streaming_response(self) -> AsyncAIResourceWithStreamingResponse:
"""
return AsyncAIResourceWithStreamingResponse(self)
- async def ai_query(
- self,
- *,
- data_to_extract: Iterable[ai_ai_query_params.DataToExtract],
- domain: str,
- specific_pages: ai_ai_query_params.SpecificPages | 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.
- # 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,
- ) -> AIAIQueryResponse:
- """Use AI to extract specific data points from a brand's website.
-
- The AI will crawl
- the website and extract the requested information based on the provided data
- points.
-
- Args:
- data_to_extract: Array of data points to extract from the website
-
- domain: The domain name to analyze
-
- specific_pages: Optional object specifying which pages to analyze
-
- timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
- than this value, it will be aborted with a 408 status code. Maximum allowed
- value is 300000ms (5 minutes).
-
- 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(
- "/brand/ai/query",
- body=await async_maybe_transform(
- {
- "data_to_extract": data_to_extract,
- "domain": domain,
- "specific_pages": specific_pages,
- "timeout_ms": timeout_ms,
- },
- ai_ai_query_params.AIAIQueryParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=AIAIQueryResponse,
- )
-
async def extract_product(
self,
*,
@@ -534,9 +420,6 @@ class AIResourceWithRawResponse:
def __init__(self, ai: AIResource) -> None:
self._ai = ai
- self.ai_query = to_raw_response_wrapper(
- ai.ai_query,
- )
self.extract_product = to_raw_response_wrapper(
ai.extract_product,
)
@@ -549,9 +432,6 @@ class AsyncAIResourceWithRawResponse:
def __init__(self, ai: AsyncAIResource) -> None:
self._ai = ai
- self.ai_query = async_to_raw_response_wrapper(
- ai.ai_query,
- )
self.extract_product = async_to_raw_response_wrapper(
ai.extract_product,
)
@@ -564,9 +444,6 @@ class AIResourceWithStreamingResponse:
def __init__(self, ai: AIResource) -> None:
self._ai = ai
- self.ai_query = to_streamed_response_wrapper(
- ai.ai_query,
- )
self.extract_product = to_streamed_response_wrapper(
ai.extract_product,
)
@@ -579,9 +456,6 @@ class AsyncAIResourceWithStreamingResponse:
def __init__(self, ai: AsyncAIResource) -> None:
self._ai = ai
- self.ai_query = async_to_streamed_response_wrapper(
- ai.ai_query,
- )
self.extract_product = async_to_streamed_response_wrapper(
ai.extract_product,
)
diff --git a/src/context/dev/resources/brand.py b/src/context/dev/resources/brand.py
index 0d2aa3e..2c5be6a 100644
--- a/src/context/dev/resources/brand.py
+++ b/src/context/dev/resources/brand.py
@@ -2,21 +2,13 @@
from __future__ import annotations
-from typing_extensions import Literal
+from typing_extensions import Literal, overload
import httpx
-from ..types import (
- brand_retrieve_params,
- brand_retrieve_by_isin_params,
- brand_retrieve_by_name_params,
- brand_retrieve_by_email_params,
- brand_retrieve_by_ticker_params,
- brand_retrieve_simplified_params,
- brand_identify_from_transaction_params,
-)
+from ..types import brand_retrieve_params, brand_retrieve_simplified_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import required_args, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -27,12 +19,7 @@
)
from .._base_client import make_request_options
from ..types.brand_retrieve_response import BrandRetrieveResponse
-from ..types.brand_retrieve_by_isin_response import BrandRetrieveByIsinResponse
-from ..types.brand_retrieve_by_name_response import BrandRetrieveByNameResponse
-from ..types.brand_retrieve_by_email_response import BrandRetrieveByEmailResponse
-from ..types.brand_retrieve_by_ticker_response import BrandRetrieveByTickerResponse
from ..types.brand_retrieve_simplified_response import BrandRetrieveSimplifiedResponse
-from ..types.brand_identify_from_transaction_response import BrandIdentifyFromTransactionResponse
__all__ = ["BrandResource", "AsyncBrandResource"]
@@ -57,6 +44,7 @@ def with_streaming_response(self) -> BrandResourceWithStreamingResponse:
"""
return BrandResourceWithStreamingResponse(self)
+ @overload
def retrieve(
self,
*,
@@ -194,15 +182,14 @@ def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> BrandRetrieveResponse:
- """
- Retrieve logos, backdrops, colors, industry, description, and more from any
- domain
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- Args:
- domain: Domain name to retrieve brand data for (e.g., 'example.com', 'google.com').
- Cannot be used with name or ticker parameters.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ Args:
+ domain: Domain name to retrieve brand data for (e.g., 'stripe.com').
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
@@ -211,7 +198,7 @@ def retrieve(
max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
the API will skip time-consuming operations for faster response at the cost of
- less comprehensive data. Works with all three lookup methods.
+ less comprehensive data.
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
@@ -225,274 +212,14 @@ def retrieve(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/brand/retrieve",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "domain": domain,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_params.BrandRetrieveParams,
- ),
- ),
- cast_to=BrandRetrieveResponse,
- )
+ ...
- def identify_from_transaction(
+ @overload
+ def retrieve(
self,
*,
- transaction_info: str,
- city: str | Omit = omit,
- country_gl: Literal[
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bm",
- "bn",
- "bo",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "gd",
- "ge",
- "gf",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "ht",
- "hu",
- "id",
- "ie",
- "il",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "st",
- "sv",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- ]
- | Omit = omit,
+ name: str,
+ country_gl: str | Omit = omit,
force_language: Literal[
"afrikaans",
"albanian",
@@ -616,10 +343,8 @@ def identify_from_transaction(
"zulu",
]
| Omit = omit,
- high_confidence_only: bool | Omit = omit,
+ max_age_ms: int | Omit = omit,
max_speed: bool | Omit = omit,
- mcc: str | Omit = omit,
- phone: float | 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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -627,33 +352,28 @@ def identify_from_transaction(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandIdentifyFromTransactionResponse:
- """
- Endpoint specially designed for platforms that want to identify transaction data
- by the transaction title.
-
- Args:
- transaction_info: Transaction information to identify the brand
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- city: Optional city name to prioritize when searching for the brand.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- country_gl: Optional country code (GL parameter) to specify the country. This affects the
- geographic location used for search queries.
+ Args:
+ name: Company name to retrieve brand data for (e.g., 'Apple Inc').
- force_language: Optional parameter to force the language of the retrieved brand data.
+ country_gl: Optional country code hint (GL parameter) to specify the country when looking up
+ by company name.
- high_confidence_only: When set to true, the API will perform an additional verification steps to
- ensure the identified brand matches the transaction with high confidence.
+ max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
+ refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
+ are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
+ year.
max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
the API will skip time-consuming operations for faster response at the cost of
less comprehensive data.
- mcc: Optional Merchant Category Code (MCC) to help identify the business
- category/industry.
-
- phone: Optional phone number from the transaction to help verify brand match.
-
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -666,32 +386,10 @@ def identify_from_transaction(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/brand/transaction_identifier",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "transaction_info": transaction_info,
- "city": city,
- "country_gl": country_gl,
- "force_language": force_language,
- "high_confidence_only": high_confidence_only,
- "max_speed": max_speed,
- "mcc": mcc,
- "phone": phone,
- "timeout_ms": timeout_ms,
- },
- brand_identify_from_transaction_params.BrandIdentifyFromTransactionParams,
- ),
- ),
- cast_to=BrandIdentifyFromTransactionResponse,
- )
+ ...
- def retrieve_by_email(
+ @overload
+ def retrieve(
self,
*,
email: str,
@@ -827,18 +525,15 @@ def retrieve_by_email(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandRetrieveByEmailResponse:
- """
- Retrieve brand information using an email address while detecting disposable and
- free email addresses. Disposable and free email addresses (like gmail.com,
- yahoo.com) will throw a 422 error.
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- Args:
- email: Email address to retrieve brand data for (e.g., 'contact@example.com'). The
- domain will be extracted from the email. Free email providers (gmail.com,
- yahoo.com, etc.) and disposable email addresses are not allowed.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ Args:
+ email: Email address to retrieve brand data for (e.g., 'jane@stripe.com').
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
@@ -861,31 +556,13 @@ def retrieve_by_email(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/brand/retrieve-by-email",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "email": email,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_email_params.BrandRetrieveByEmailParams,
- ),
- ),
- cast_to=BrandRetrieveByEmailResponse,
- )
+ ...
- def retrieve_by_isin(
+ @overload
+ def retrieve(
self,
*,
- isin: str,
+ ticker: str,
force_language: Literal[
"afrikaans",
"albanian",
@@ -1011,6 +688,7 @@ def retrieve_by_isin(
| Omit = omit,
max_age_ms: int | Omit = omit,
max_speed: bool | Omit = omit,
+ ticker_exchange: 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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1018,17 +696,15 @@ def retrieve_by_isin(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandRetrieveByIsinResponse:
- """
- Retrieve brand information using an ISIN (International Securities
- Identification Number).
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- Args:
- isin: ISIN (International Securities Identification Number) to retrieve brand data for
- (e.g., 'AU000000IMD5', 'US0378331005'). Must be exactly 12 characters: 2 letters
- followed by 9 alphanumeric characters and ending with a digit.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ Args:
+ ticker: Stock ticker symbol to retrieve brand data for (e.g., 'AAPL').
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
@@ -1039,6 +715,8 @@ def retrieve_by_isin(
the API will skip time-consuming operations for faster response at the cost of
less comprehensive data.
+ ticker_exchange: Optional stock exchange for the ticker. Defaults to NASDAQ if not specified.
+
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -1051,273 +729,15 @@ def retrieve_by_isin(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/brand/retrieve-by-isin",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "isin": isin,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_isin_params.BrandRetrieveByIsinParams,
- ),
- ),
- cast_to=BrandRetrieveByIsinResponse,
- )
+ ...
- def retrieve_by_name(
+ @overload
+ def retrieve(
self,
*,
- name: str,
- country_gl: Literal[
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bm",
- "bn",
- "bo",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "gd",
- "ge",
- "gf",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "ht",
- "hu",
- "id",
- "ie",
- "il",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "st",
- "sv",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- ]
- | Omit = omit,
+ transaction_info: str,
+ city: str | Omit = omit,
+ country_gl: str | Omit = omit,
force_language: Literal[
"afrikaans",
"albanian",
@@ -1441,8 +861,10 @@ def retrieve_by_name(
"zulu",
]
| Omit = omit,
- max_age_ms: int | Omit = omit,
+ high_confidence_only: bool | Omit = omit,
max_speed: bool | Omit = omit,
+ mcc: int | Omit = omit,
+ phone: float | 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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -1450,28 +872,33 @@ def retrieve_by_name(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandRetrieveByNameResponse:
- """
- Retrieve brand information using a company name.
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
+
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
Args:
- name: Company name to retrieve brand data for (e.g., 'Apple Inc', 'Microsoft
- Corporation'). Must be 3-30 characters.
+ transaction_info: Transaction information to identify the brand.
- country_gl: Optional country code hint (GL parameter) to specify the country for the company
- name.
+ city: Optional city name to prioritize when searching for the brand.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ country_gl: Optional country code hint (GL parameter) to specify the country when
+ identifying a transaction.
- max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
+ high_confidence_only: When set to true, the API performs additional verification to ensure the
+ identified brand matches the transaction with high confidence.
max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
the API will skip time-consuming operations for faster response at the cost of
less comprehensive data.
+ mcc: Optional Merchant Category Code (MCC) to help identify the business category or
+ industry.
+
+ phone: Optional phone number from the transaction to help verify brand match.
+
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -1484,32 +911,13 @@ def retrieve_by_name(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/brand/retrieve-by-name",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "name": name,
- "country_gl": country_gl,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_name_params.BrandRetrieveByNameParams,
- ),
- ),
- cast_to=BrandRetrieveByNameResponse,
- )
+ ...
- def retrieve_by_ticker(
+ @required_args(["domain"], ["name"], ["email"], ["ticker"], ["transaction_info"])
+ def retrieve(
self,
*,
- ticker: str,
+ domain: str | Omit = omit,
force_language: Literal[
"afrikaans",
"albanian",
@@ -1635,141 +1043,50 @@ def retrieve_by_ticker(
| Omit = omit,
max_age_ms: int | Omit = omit,
max_speed: bool | Omit = omit,
- 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",
- ]
- | Omit = omit,
timeout_ms: int | Omit = omit,
+ name: str | Omit = omit,
+ country_gl: str | Omit = omit,
+ email: str | Omit = omit,
+ ticker: str | Omit = omit,
+ ticker_exchange: str | Omit = omit,
+ transaction_info: str | Omit = omit,
+ city: str | Omit = omit,
+ high_confidence_only: bool | Omit = omit,
+ mcc: int | Omit = omit,
+ phone: float | 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,
- ) -> BrandRetrieveByTickerResponse:
- """
- Retrieve brand information using a stock ticker symbol.
-
- Args:
- ticker: Stock ticker symbol to retrieve brand data for (e.g., 'AAPL', 'GOOGL', 'BRK.A').
- Must be 1-15 characters, letters/numbers/dots only.
-
- force_language: Optional parameter to force the language of the retrieved brand data.
-
- max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
-
- max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
- the API will skip time-consuming operations for faster response at the cost of
- less comprehensive data.
-
- ticker_exchange: Optional stock exchange for the ticker. Defaults to NASDAQ if not specified.
-
- timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
- than this value, it will be aborted with a 408 status code. Maximum allowed
- value is 300000ms (5 minutes).
-
- 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/retrieve-by-ticker",
+ ) -> BrandRetrieveResponse:
+ return self._post(
+ "/brand/retrieve",
+ body=maybe_transform(
+ {
+ "domain": domain,
+ "force_language": force_language,
+ "max_age_ms": max_age_ms,
+ "max_speed": max_speed,
+ "timeout_ms": timeout_ms,
+ "name": name,
+ "country_gl": country_gl,
+ "email": email,
+ "ticker": ticker,
+ "ticker_exchange": ticker_exchange,
+ "transaction_info": transaction_info,
+ "city": city,
+ "high_confidence_only": high_confidence_only,
+ "mcc": mcc,
+ "phone": phone,
+ },
+ brand_retrieve_params.BrandRetrieveParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "ticker": ticker,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "ticker_exchange": ticker_exchange,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_ticker_params.BrandRetrieveByTickerParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=BrandRetrieveByTickerResponse,
+ cast_to=BrandRetrieveResponse,
)
def retrieve_simplified(
@@ -1850,6 +1167,7 @@ def with_streaming_response(self) -> AsyncBrandResourceWithStreamingResponse:
"""
return AsyncBrandResourceWithStreamingResponse(self)
+ @overload
async def retrieve(
self,
*,
@@ -1987,15 +1305,14 @@ async def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> BrandRetrieveResponse:
- """
- Retrieve logos, backdrops, colors, industry, description, and more from any
- domain
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- Args:
- domain: Domain name to retrieve brand data for (e.g., 'example.com', 'google.com').
- Cannot be used with name or ticker parameters.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ Args:
+ domain: Domain name to retrieve brand data for (e.g., 'stripe.com').
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
@@ -2004,7 +1321,7 @@ async def retrieve(
max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
the API will skip time-consuming operations for faster response at the cost of
- less comprehensive data. Works with all three lookup methods.
+ less comprehensive data.
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
@@ -2018,274 +1335,14 @@ async def retrieve(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/brand/retrieve",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "domain": domain,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_params.BrandRetrieveParams,
- ),
- ),
- cast_to=BrandRetrieveResponse,
- )
+ ...
- async def identify_from_transaction(
+ @overload
+ async def retrieve(
self,
*,
- transaction_info: str,
- city: str | Omit = omit,
- country_gl: Literal[
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bm",
- "bn",
- "bo",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "gd",
- "ge",
- "gf",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "ht",
- "hu",
- "id",
- "ie",
- "il",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "st",
- "sv",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- ]
- | Omit = omit,
+ name: str,
+ country_gl: str | Omit = omit,
force_language: Literal[
"afrikaans",
"albanian",
@@ -2409,10 +1466,8 @@ async def identify_from_transaction(
"zulu",
]
| Omit = omit,
- high_confidence_only: bool | Omit = omit,
+ max_age_ms: int | Omit = omit,
max_speed: bool | Omit = omit,
- mcc: str | Omit = omit,
- phone: float | 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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -2420,33 +1475,28 @@ async def identify_from_transaction(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandIdentifyFromTransactionResponse:
- """
- Endpoint specially designed for platforms that want to identify transaction data
- by the transaction title.
-
- Args:
- transaction_info: Transaction information to identify the brand
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- city: Optional city name to prioritize when searching for the brand.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- country_gl: Optional country code (GL parameter) to specify the country. This affects the
- geographic location used for search queries.
+ Args:
+ name: Company name to retrieve brand data for (e.g., 'Apple Inc').
- force_language: Optional parameter to force the language of the retrieved brand data.
+ country_gl: Optional country code hint (GL parameter) to specify the country when looking up
+ by company name.
- high_confidence_only: When set to true, the API will perform an additional verification steps to
- ensure the identified brand matches the transaction with high confidence.
+ max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
+ refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
+ are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
+ year.
max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
the API will skip time-consuming operations for faster response at the cost of
less comprehensive data.
- mcc: Optional Merchant Category Code (MCC) to help identify the business
- category/industry.
-
- phone: Optional phone number from the transaction to help verify brand match.
-
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -2459,32 +1509,10 @@ async def identify_from_transaction(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/brand/transaction_identifier",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "transaction_info": transaction_info,
- "city": city,
- "country_gl": country_gl,
- "force_language": force_language,
- "high_confidence_only": high_confidence_only,
- "max_speed": max_speed,
- "mcc": mcc,
- "phone": phone,
- "timeout_ms": timeout_ms,
- },
- brand_identify_from_transaction_params.BrandIdentifyFromTransactionParams,
- ),
- ),
- cast_to=BrandIdentifyFromTransactionResponse,
- )
+ ...
- async def retrieve_by_email(
+ @overload
+ async def retrieve(
self,
*,
email: str,
@@ -2620,18 +1648,15 @@ async def retrieve_by_email(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandRetrieveByEmailResponse:
- """
- Retrieve brand information using an email address while detecting disposable and
- free email addresses. Disposable and free email addresses (like gmail.com,
- yahoo.com) will throw a 422 error.
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- Args:
- email: Email address to retrieve brand data for (e.g., 'contact@example.com'). The
- domain will be extracted from the email. Free email providers (gmail.com,
- yahoo.com, etc.) and disposable email addresses are not allowed.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ Args:
+ email: Email address to retrieve brand data for (e.g., 'jane@stripe.com').
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
@@ -2654,31 +1679,13 @@ async def retrieve_by_email(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/brand/retrieve-by-email",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "email": email,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_email_params.BrandRetrieveByEmailParams,
- ),
- ),
- cast_to=BrandRetrieveByEmailResponse,
- )
+ ...
- async def retrieve_by_isin(
+ @overload
+ async def retrieve(
self,
*,
- isin: str,
+ ticker: str,
force_language: Literal[
"afrikaans",
"albanian",
@@ -2804,6 +1811,7 @@ async def retrieve_by_isin(
| Omit = omit,
max_age_ms: int | Omit = omit,
max_speed: bool | Omit = omit,
+ ticker_exchange: 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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -2811,17 +1819,15 @@ async def retrieve_by_isin(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandRetrieveByIsinResponse:
- """
- Retrieve brand information using an ISIN (International Securities
- Identification Number).
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
- Args:
- isin: ISIN (International Securities Identification Number) to retrieve brand data for
- (e.g., 'AU000000IMD5', 'US0378331005'). Must be exactly 12 characters: 2 letters
- followed by 9 alphanumeric characters and ending with a digit.
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ Args:
+ ticker: Stock ticker symbol to retrieve brand data for (e.g., 'AAPL').
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
@@ -2832,6 +1838,8 @@ async def retrieve_by_isin(
the API will skip time-consuming operations for faster response at the cost of
less comprehensive data.
+ ticker_exchange: Optional stock exchange for the ticker. Defaults to NASDAQ if not specified.
+
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -2844,273 +1852,15 @@ async def retrieve_by_isin(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/brand/retrieve-by-isin",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "isin": isin,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_isin_params.BrandRetrieveByIsinParams,
- ),
- ),
- cast_to=BrandRetrieveByIsinResponse,
- )
+ ...
- async def retrieve_by_name(
+ @overload
+ async def retrieve(
self,
*,
- name: str,
- country_gl: Literal[
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bm",
- "bn",
- "bo",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "gd",
- "ge",
- "gf",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "ht",
- "hu",
- "id",
- "ie",
- "il",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "st",
- "sv",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- ]
- | Omit = omit,
+ transaction_info: str,
+ city: str | Omit = omit,
+ country_gl: str | Omit = omit,
force_language: Literal[
"afrikaans",
"albanian",
@@ -3234,8 +1984,10 @@ async def retrieve_by_name(
"zulu",
]
| Omit = omit,
- max_age_ms: int | Omit = omit,
+ high_confidence_only: bool | Omit = omit,
max_speed: bool | Omit = omit,
+ mcc: int | Omit = omit,
+ phone: float | 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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -3243,28 +1995,33 @@ async def retrieve_by_name(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> BrandRetrieveByNameResponse:
- """
- Retrieve brand information using a company name.
+ ) -> BrandRetrieveResponse:
+ """Retrieve logos, backdrops, colors, industry, description, and more.
+
+ Provide
+ exactly one lookup identifier in the request body: a domain, company name, email
+ address, stock ticker, or transaction descriptor.
Args:
- name: Company name to retrieve brand data for (e.g., 'Apple Inc', 'Microsoft
- Corporation'). Must be 3-30 characters.
+ transaction_info: Transaction information to identify the brand.
- country_gl: Optional country code hint (GL parameter) to specify the country for the company
- name.
+ city: Optional city name to prioritize when searching for the brand.
- force_language: Optional parameter to force the language of the retrieved brand data.
+ country_gl: Optional country code hint (GL parameter) to specify the country when
+ identifying a transaction.
- max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
+ high_confidence_only: When set to true, the API performs additional verification to ensure the
+ identified brand matches the transaction with high confidence.
max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
the API will skip time-consuming operations for faster response at the cost of
less comprehensive data.
+ mcc: Optional Merchant Category Code (MCC) to help identify the business category or
+ industry.
+
+ phone: Optional phone number from the transaction to help verify brand match.
+
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
value is 300000ms (5 minutes).
@@ -3277,32 +2034,13 @@ async def retrieve_by_name(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/brand/retrieve-by-name",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "name": name,
- "country_gl": country_gl,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_name_params.BrandRetrieveByNameParams,
- ),
- ),
- cast_to=BrandRetrieveByNameResponse,
- )
+ ...
- async def retrieve_by_ticker(
+ @required_args(["domain"], ["name"], ["email"], ["ticker"], ["transaction_info"])
+ async def retrieve(
self,
*,
- ticker: str,
+ domain: str | Omit = omit,
force_language: Literal[
"afrikaans",
"albanian",
@@ -3428,141 +2166,50 @@ async def retrieve_by_ticker(
| Omit = omit,
max_age_ms: int | Omit = omit,
max_speed: bool | Omit = omit,
- 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",
- ]
- | Omit = omit,
timeout_ms: int | Omit = omit,
+ name: str | Omit = omit,
+ country_gl: str | Omit = omit,
+ email: str | Omit = omit,
+ ticker: str | Omit = omit,
+ ticker_exchange: str | Omit = omit,
+ transaction_info: str | Omit = omit,
+ city: str | Omit = omit,
+ high_confidence_only: bool | Omit = omit,
+ mcc: int | Omit = omit,
+ phone: float | 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,
- ) -> BrandRetrieveByTickerResponse:
- """
- Retrieve brand information using a stock ticker symbol.
-
- Args:
- ticker: Stock ticker symbol to retrieve brand data for (e.g., 'AAPL', 'GOOGL', 'BRK.A').
- Must be 1-15 characters, letters/numbers/dots only.
-
- force_language: Optional parameter to force the language of the retrieved brand data.
-
- max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
-
- max_speed: Optional parameter to optimize the API call for maximum speed. When set to true,
- the API will skip time-consuming operations for faster response at the cost of
- less comprehensive data.
-
- ticker_exchange: Optional stock exchange for the ticker. Defaults to NASDAQ if not specified.
-
- timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
- than this value, it will be aborted with a 408 status code. Maximum allowed
- value is 300000ms (5 minutes).
-
- 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/retrieve-by-ticker",
+ ) -> BrandRetrieveResponse:
+ return await self._post(
+ "/brand/retrieve",
+ body=await async_maybe_transform(
+ {
+ "domain": domain,
+ "force_language": force_language,
+ "max_age_ms": max_age_ms,
+ "max_speed": max_speed,
+ "timeout_ms": timeout_ms,
+ "name": name,
+ "country_gl": country_gl,
+ "email": email,
+ "ticker": ticker,
+ "ticker_exchange": ticker_exchange,
+ "transaction_info": transaction_info,
+ "city": city,
+ "high_confidence_only": high_confidence_only,
+ "mcc": mcc,
+ "phone": phone,
+ },
+ brand_retrieve_params.BrandRetrieveParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "ticker": ticker,
- "force_language": force_language,
- "max_age_ms": max_age_ms,
- "max_speed": max_speed,
- "ticker_exchange": ticker_exchange,
- "timeout_ms": timeout_ms,
- },
- brand_retrieve_by_ticker_params.BrandRetrieveByTickerParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=BrandRetrieveByTickerResponse,
+ cast_to=BrandRetrieveResponse,
)
async def retrieve_simplified(
@@ -3630,21 +2277,6 @@ def __init__(self, brand: BrandResource) -> None:
self.retrieve = to_raw_response_wrapper(
brand.retrieve,
)
- self.identify_from_transaction = to_raw_response_wrapper(
- brand.identify_from_transaction,
- )
- self.retrieve_by_email = to_raw_response_wrapper(
- brand.retrieve_by_email,
- )
- self.retrieve_by_isin = to_raw_response_wrapper(
- brand.retrieve_by_isin,
- )
- self.retrieve_by_name = to_raw_response_wrapper(
- brand.retrieve_by_name,
- )
- self.retrieve_by_ticker = to_raw_response_wrapper(
- brand.retrieve_by_ticker,
- )
self.retrieve_simplified = to_raw_response_wrapper(
brand.retrieve_simplified,
)
@@ -3657,21 +2289,6 @@ def __init__(self, brand: AsyncBrandResource) -> None:
self.retrieve = async_to_raw_response_wrapper(
brand.retrieve,
)
- self.identify_from_transaction = async_to_raw_response_wrapper(
- brand.identify_from_transaction,
- )
- self.retrieve_by_email = async_to_raw_response_wrapper(
- brand.retrieve_by_email,
- )
- self.retrieve_by_isin = async_to_raw_response_wrapper(
- brand.retrieve_by_isin,
- )
- self.retrieve_by_name = async_to_raw_response_wrapper(
- brand.retrieve_by_name,
- )
- self.retrieve_by_ticker = async_to_raw_response_wrapper(
- brand.retrieve_by_ticker,
- )
self.retrieve_simplified = async_to_raw_response_wrapper(
brand.retrieve_simplified,
)
@@ -3684,21 +2301,6 @@ def __init__(self, brand: BrandResource) -> None:
self.retrieve = to_streamed_response_wrapper(
brand.retrieve,
)
- self.identify_from_transaction = to_streamed_response_wrapper(
- brand.identify_from_transaction,
- )
- self.retrieve_by_email = to_streamed_response_wrapper(
- brand.retrieve_by_email,
- )
- self.retrieve_by_isin = to_streamed_response_wrapper(
- brand.retrieve_by_isin,
- )
- self.retrieve_by_name = to_streamed_response_wrapper(
- brand.retrieve_by_name,
- )
- self.retrieve_by_ticker = to_streamed_response_wrapper(
- brand.retrieve_by_ticker,
- )
self.retrieve_simplified = to_streamed_response_wrapper(
brand.retrieve_simplified,
)
@@ -3711,21 +2313,6 @@ def __init__(self, brand: AsyncBrandResource) -> None:
self.retrieve = async_to_streamed_response_wrapper(
brand.retrieve,
)
- self.identify_from_transaction = async_to_streamed_response_wrapper(
- brand.identify_from_transaction,
- )
- self.retrieve_by_email = async_to_streamed_response_wrapper(
- brand.retrieve_by_email,
- )
- self.retrieve_by_isin = async_to_streamed_response_wrapper(
- brand.retrieve_by_isin,
- )
- self.retrieve_by_name = async_to_streamed_response_wrapper(
- brand.retrieve_by_name,
- )
- self.retrieve_by_ticker = async_to_streamed_response_wrapper(
- brand.retrieve_by_ticker,
- )
self.retrieve_simplified = async_to_streamed_response_wrapper(
brand.retrieve_simplified,
)
diff --git a/src/context/dev/resources/utility.py b/src/context/dev/resources/utility.py
index 15328a1..e44220f 100644
--- a/src/context/dev/resources/utility.py
+++ b/src/context/dev/resources/utility.py
@@ -2,9 +2,11 @@
from __future__ import annotations
+from typing_extensions import Literal
+
import httpx
-from ..types import utility_prefetch_params, utility_prefetch_by_email_params
+from ..types import utility_prefetch_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
@@ -17,7 +19,6 @@
)
from .._base_client import make_request_options
from ..types.utility_prefetch_response import UtilityPrefetchResponse
-from ..types.utility_prefetch_by_email_response import UtilityPrefetchByEmailResponse
__all__ = ["UtilityResource", "AsyncUtilityResource"]
@@ -45,7 +46,8 @@ def with_streaming_response(self) -> UtilityResourceWithStreamingResponse:
def prefetch(
self,
*,
- domain: str,
+ identifier: utility_prefetch_params.Identifier,
+ type: Literal["brand"],
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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -54,12 +56,17 @@ def prefetch(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> UtilityPrefetchResponse:
- """
- Signal that you may fetch brand data for a particular domain soon to improve
- latency.
+ """Signal that you may fetch brand 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).
Args:
- domain: Domain name to prefetch brand data for
+ identifier: Identifier of the brand to prefetch. Provide exactly one of domain or email.
+
+ type: What to prefetch. Currently only 'brand' is supported.
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
@@ -74,10 +81,11 @@ def prefetch(
timeout: Override the client-level default timeout for this request, in seconds
"""
return self._post(
- "/brand/prefetch",
+ "/utility/prefetch",
body=maybe_transform(
{
- "domain": domain,
+ "identifier": identifier,
+ "type": type,
"timeout_ms": timeout_ms,
},
utility_prefetch_params.UtilityPrefetchParams,
@@ -88,56 +96,6 @@ def prefetch(
cast_to=UtilityPrefetchResponse,
)
- def prefetch_by_email(
- self,
- *,
- email: str,
- 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.
- # 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,
- ) -> UtilityPrefetchByEmailResponse:
- """
- Signal that you may fetch brand data for a particular domain soon to improve
- latency. This endpoint accepts an email address, extracts the domain from it,
- validates that it's not a disposable or free email provider, and queues the
- domain for prefetching.
-
- Args:
- email: Email address to prefetch brand 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.
-
- timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
- than this value, it will be aborted with a 408 status code. Maximum allowed
- value is 300000ms (5 minutes).
-
- 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(
- "/brand/prefetch-by-email",
- body=maybe_transform(
- {
- "email": email,
- "timeout_ms": timeout_ms,
- },
- utility_prefetch_by_email_params.UtilityPrefetchByEmailParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=UtilityPrefetchByEmailResponse,
- )
-
class AsyncUtilityResource(AsyncAPIResource):
@cached_property
@@ -162,7 +120,8 @@ def with_streaming_response(self) -> AsyncUtilityResourceWithStreamingResponse:
async def prefetch(
self,
*,
- domain: str,
+ identifier: utility_prefetch_params.Identifier,
+ type: Literal["brand"],
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.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -171,12 +130,17 @@ async def prefetch(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> UtilityPrefetchResponse:
- """
- Signal that you may fetch brand data for a particular domain soon to improve
- latency.
+ """Signal that you may fetch brand 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).
Args:
- domain: Domain name to prefetch brand data for
+ identifier: Identifier of the brand to prefetch. Provide exactly one of domain or email.
+
+ type: What to prefetch. Currently only 'brand' is supported.
timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
than this value, it will be aborted with a 408 status code. Maximum allowed
@@ -191,10 +155,11 @@ async def prefetch(
timeout: Override the client-level default timeout for this request, in seconds
"""
return await self._post(
- "/brand/prefetch",
+ "/utility/prefetch",
body=await async_maybe_transform(
{
- "domain": domain,
+ "identifier": identifier,
+ "type": type,
"timeout_ms": timeout_ms,
},
utility_prefetch_params.UtilityPrefetchParams,
@@ -205,56 +170,6 @@ async def prefetch(
cast_to=UtilityPrefetchResponse,
)
- async def prefetch_by_email(
- self,
- *,
- email: str,
- 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.
- # 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,
- ) -> UtilityPrefetchByEmailResponse:
- """
- Signal that you may fetch brand data for a particular domain soon to improve
- latency. This endpoint accepts an email address, extracts the domain from it,
- validates that it's not a disposable or free email provider, and queues the
- domain for prefetching.
-
- Args:
- email: Email address to prefetch brand 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.
-
- timeout_ms: Optional timeout in milliseconds for the request. If the request takes longer
- than this value, it will be aborted with a 408 status code. Maximum allowed
- value is 300000ms (5 minutes).
-
- 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(
- "/brand/prefetch-by-email",
- body=await async_maybe_transform(
- {
- "email": email,
- "timeout_ms": timeout_ms,
- },
- utility_prefetch_by_email_params.UtilityPrefetchByEmailParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=UtilityPrefetchByEmailResponse,
- )
-
class UtilityResourceWithRawResponse:
def __init__(self, utility: UtilityResource) -> None:
@@ -263,9 +178,6 @@ def __init__(self, utility: UtilityResource) -> None:
self.prefetch = to_raw_response_wrapper(
utility.prefetch,
)
- self.prefetch_by_email = to_raw_response_wrapper(
- utility.prefetch_by_email,
- )
class AsyncUtilityResourceWithRawResponse:
@@ -275,9 +187,6 @@ def __init__(self, utility: AsyncUtilityResource) -> None:
self.prefetch = async_to_raw_response_wrapper(
utility.prefetch,
)
- self.prefetch_by_email = async_to_raw_response_wrapper(
- utility.prefetch_by_email,
- )
class UtilityResourceWithStreamingResponse:
@@ -287,9 +196,6 @@ def __init__(self, utility: UtilityResource) -> None:
self.prefetch = to_streamed_response_wrapper(
utility.prefetch,
)
- self.prefetch_by_email = to_streamed_response_wrapper(
- utility.prefetch_by_email,
- )
class AsyncUtilityResourceWithStreamingResponse:
@@ -299,6 +205,3 @@ def __init__(self, utility: AsyncUtilityResource) -> None:
self.prefetch = async_to_streamed_response_wrapper(
utility.prefetch,
)
- self.prefetch_by_email = async_to_streamed_response_wrapper(
- utility.prefetch_by_email,
- )
diff --git a/src/context/dev/types/__init__.py b/src/context/dev/types/__init__.py
index c60839d..654f36e 100644
--- a/src/context/dev/types/__init__.py
+++ b/src/context/dev/types/__init__.py
@@ -3,11 +3,9 @@
from __future__ import annotations
from .web_search_params import WebSearchParams as WebSearchParams
-from .ai_ai_query_params import AIAIQueryParams as AIAIQueryParams
from .web_extract_params import WebExtractParams as WebExtractParams
from .monitor_list_params import MonitorListParams as MonitorListParams
from .web_search_response import WebSearchResponse as WebSearchResponse
-from .ai_ai_query_response import AIAIQueryResponse as AIAIQueryResponse
from .monitor_run_response import MonitorRunResponse as MonitorRunResponse
from .web_extract_response import WebExtractResponse as WebExtractResponse
from .brand_retrieve_params import BrandRetrieveParams as BrandRetrieveParams
@@ -40,39 +38,23 @@
from .industry_retrieve_sic_params import IndustryRetrieveSicParams as IndustryRetrieveSicParams
from .web_web_scrape_html_response import WebWebScrapeHTMLResponse as WebWebScrapeHTMLResponse
from .web_web_scrape_images_params import WebWebScrapeImagesParams as WebWebScrapeImagesParams
-from .brand_retrieve_by_isin_params import BrandRetrieveByIsinParams as BrandRetrieveByIsinParams
-from .brand_retrieve_by_name_params import BrandRetrieveByNameParams as BrandRetrieveByNameParams
from .monitor_list_changes_response import MonitorListChangesResponse as MonitorListChangesResponse
from .web_extract_styleguide_params import WebExtractStyleguideParams as WebExtractStyleguideParams
from .web_web_scrape_sitemap_params import WebWebScrapeSitemapParams as WebWebScrapeSitemapParams
-from .brand_retrieve_by_email_params import BrandRetrieveByEmailParams as BrandRetrieveByEmailParams
from .industry_retrieve_naics_params import IndustryRetrieveNaicsParams as IndustryRetrieveNaicsParams
from .industry_retrieve_sic_response import IndustryRetrieveSicResponse as IndustryRetrieveSicResponse
from .web_extract_competitors_params import WebExtractCompetitorsParams as WebExtractCompetitorsParams
from .web_web_scrape_images_response import WebWebScrapeImagesResponse as WebWebScrapeImagesResponse
-from .brand_retrieve_by_isin_response import BrandRetrieveByIsinResponse as BrandRetrieveByIsinResponse
-from .brand_retrieve_by_name_response import BrandRetrieveByNameResponse as BrandRetrieveByNameResponse
-from .brand_retrieve_by_ticker_params import BrandRetrieveByTickerParams as BrandRetrieveByTickerParams
from .web_extract_styleguide_response import WebExtractStyleguideResponse as WebExtractStyleguideResponse
from .web_web_scrape_sitemap_response import WebWebScrapeSitemapResponse as WebWebScrapeSitemapResponse
-from .brand_retrieve_by_email_response import BrandRetrieveByEmailResponse as BrandRetrieveByEmailResponse
from .brand_retrieve_simplified_params import BrandRetrieveSimplifiedParams as BrandRetrieveSimplifiedParams
from .industry_retrieve_naics_response import IndustryRetrieveNaicsResponse as IndustryRetrieveNaicsResponse
from .monitor_list_account_runs_params import MonitorListAccountRunsParams as MonitorListAccountRunsParams
from .monitor_retrieve_change_response import MonitorRetrieveChangeResponse as MonitorRetrieveChangeResponse
-from .utility_prefetch_by_email_params import UtilityPrefetchByEmailParams as UtilityPrefetchByEmailParams
from .web_extract_competitors_response import WebExtractCompetitorsResponse as WebExtractCompetitorsResponse
-from .brand_retrieve_by_ticker_response import BrandRetrieveByTickerResponse as BrandRetrieveByTickerResponse
from .brand_retrieve_simplified_response import BrandRetrieveSimplifiedResponse as BrandRetrieveSimplifiedResponse
from .monitor_list_account_runs_response import MonitorListAccountRunsResponse as MonitorListAccountRunsResponse
-from .utility_prefetch_by_email_response import UtilityPrefetchByEmailResponse as UtilityPrefetchByEmailResponse
from .monitor_list_account_changes_params import MonitorListAccountChangesParams as MonitorListAccountChangesParams
from .monitor_list_account_changes_response import (
MonitorListAccountChangesResponse as MonitorListAccountChangesResponse,
)
-from .brand_identify_from_transaction_params import (
- BrandIdentifyFromTransactionParams as BrandIdentifyFromTransactionParams,
-)
-from .brand_identify_from_transaction_response import (
- BrandIdentifyFromTransactionResponse as BrandIdentifyFromTransactionResponse,
-)
diff --git a/src/context/dev/types/ai_ai_query_params.py b/src/context/dev/types/ai_ai_query_params.py
deleted file mode 100644
index dd21b8e..0000000
--- a/src/context/dev/types/ai_ai_query_params.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Dict, Iterable
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["AIAIQueryParams", "DataToExtract", "SpecificPages"]
-
-
-class AIAIQueryParams(TypedDict, total=False):
- data_to_extract: Required[Iterable[DataToExtract]]
- """Array of data points to extract from the website"""
-
- domain: Required[str]
- """The domain name to analyze"""
-
- specific_pages: SpecificPages
- """Optional object specifying which pages to analyze"""
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
-
-
-class DataToExtract(TypedDict, total=False):
- datapoint_description: Required[str]
- """Description of what to extract"""
-
- datapoint_example: Required[str]
- """Example of the expected value"""
-
- datapoint_name: Required[str]
- """Name of the data point to extract"""
-
- datapoint_type: Required[Literal["text", "number", "date", "boolean", "list", "url"]]
- """Type of the data point"""
-
- datapoint_list_type: Literal["string", "text", "number", "date", "boolean", "list", "url", "object"]
- """Type of items in the list when datapoint_type is 'list'.
-
- Defaults to 'string'. Use 'object' to extract an array of objects matching a
- schema.
- """
-
- datapoint_object_schema: Dict[str, Literal["string", "number", "date", "boolean"]]
- """Schema definition for objects when datapoint_list_type is 'object'.
-
- Provide a map of field names to their scalar types.
- """
-
-
-class SpecificPages(TypedDict, total=False):
- """Optional object specifying which pages to analyze"""
-
- about_us: bool
- """Whether to analyze the about us page"""
-
- blog: bool
- """Whether to analyze the blog"""
-
- careers: bool
- """Whether to analyze the careers page"""
-
- contact_us: bool
- """Whether to analyze the contact us page"""
-
- faq: bool
- """Whether to analyze the FAQ page"""
-
- home_page: bool
- """Whether to analyze the home page"""
-
- pricing: bool
- """Whether to analyze the pricing page"""
-
- privacy_policy: bool
- """Whether to analyze the privacy policy page"""
-
- terms_and_conditions: bool
- """Whether to analyze the terms and conditions page"""
diff --git a/src/context/dev/types/ai_ai_query_response.py b/src/context/dev/types/ai_ai_query_response.py
deleted file mode 100644
index 634338b..0000000
--- a/src/context/dev/types/ai_ai_query_response.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Union, Optional
-
-from .._models import BaseModel
-
-__all__ = ["AIAIQueryResponse", "DataExtracted", "KeyMetadata"]
-
-
-class DataExtracted(BaseModel):
- datapoint_name: Optional[str] = None
- """Name of the extracted data point"""
-
- datapoint_value: Union[str, float, bool, List[str], List[float], List[object], None] = None
- """Value of the extracted data point.
-
- Can be a primitive type, an array of primitives, or an array of objects when
- datapoint_list_type is 'object'.
- """
-
-
-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 AIAIQueryResponse(BaseModel):
- data_extracted: Optional[List[DataExtracted]] = None
- """Array of extracted data points"""
-
- domain: Optional[str] = None
- """The domain that was analyzed"""
-
- 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.
- """
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
-
- urls_analyzed: Optional[List[str]] = None
- """List of URLs that were analyzed"""
diff --git a/src/context/dev/types/brand_identify_from_transaction_params.py b/src/context/dev/types/brand_identify_from_transaction_params.py
deleted file mode 100644
index e6ecadd..0000000
--- a/src/context/dev/types/brand_identify_from_transaction_params.py
+++ /dev/null
@@ -1,416 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["BrandIdentifyFromTransactionParams"]
-
-
-class BrandIdentifyFromTransactionParams(TypedDict, total=False):
- transaction_info: Required[str]
- """Transaction information to identify the brand"""
-
- city: str
- """Optional city name to prioritize when searching for the brand."""
-
- country_gl: Literal[
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bm",
- "bn",
- "bo",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "gd",
- "ge",
- "gf",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "ht",
- "hu",
- "id",
- "ie",
- "il",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "st",
- "sv",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- ]
- """Optional country code (GL parameter) to specify the country.
-
- This affects the geographic location used for search queries.
- """
-
- force_language: Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- """Optional parameter to force the language of the retrieved brand data."""
-
- high_confidence_only: bool
- """
- When set to true, the API will perform an additional verification steps to
- ensure the identified brand matches the transaction with high confidence.
- """
-
- max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
- """Optional parameter to optimize the API call for maximum speed.
-
- When set to true, the API will skip time-consuming operations for faster
- response at the cost of less comprehensive data.
- """
-
- mcc: str
- """
- Optional Merchant Category Code (MCC) to help identify the business
- category/industry.
- """
-
- phone: float
- """Optional phone number from the transaction to help verify brand match."""
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
diff --git a/src/context/dev/types/brand_identify_from_transaction_response.py b/src/context/dev/types/brand_identify_from_transaction_response.py
deleted file mode 100644
index 6147e92..0000000
--- a/src/context/dev/types/brand_identify_from_transaction_response.py
+++ /dev/null
@@ -1,682 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = [
- "BrandIdentifyFromTransactionResponse",
- "Brand",
- "BrandAddress",
- "BrandBackdrop",
- "BrandBackdropColor",
- "BrandBackdropResolution",
- "BrandColor",
- "BrandIndustries",
- "BrandIndustriesEic",
- "BrandLinks",
- "BrandLogo",
- "BrandLogoColor",
- "BrandLogoResolution",
- "BrandSocial",
- "BrandStock",
- "KeyMetadata",
-]
-
-
-class BrandAddress(BaseModel):
- """Physical address of the brand"""
-
- city: Optional[str] = None
- """City name"""
-
- country: Optional[str] = None
- """Country name"""
-
- country_code: Optional[str] = None
- """Country code"""
-
- postal_code: Optional[str] = None
- """Postal or ZIP code"""
-
- state_code: Optional[str] = None
- """State or province code"""
-
- state_province: Optional[str] = None
- """State or province name"""
-
- street: Optional[str] = None
- """Street address"""
-
-
-class BrandBackdropColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandBackdropResolution(BaseModel):
- """Resolution of the backdrop image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandBackdrop(BaseModel):
- colors: Optional[List[BrandBackdropColor]] = None
- """Array of colors in the backdrop image"""
-
- resolution: Optional[BrandBackdropResolution] = None
- """Resolution of the backdrop image"""
-
- url: Optional[str] = None
- """URL of the backdrop image"""
-
-
-class BrandColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandIndustriesEic(BaseModel):
- industry: Literal[
- "Aerospace & Defense",
- "Technology",
- "Finance",
- "Healthcare",
- "Retail & E-commerce",
- "Entertainment",
- "Education",
- "Government & Nonprofit",
- "Industrial & Energy",
- "Automotive & Transportation",
- "Lifestyle & Leisure",
- "Luxury & Fashion",
- "News & Media",
- "Sports",
- "Real Estate & PropTech",
- "Legal & Compliance",
- "Telecommunications",
- "Agriculture & Food",
- "Professional Services & Agencies",
- "Chemicals & Materials",
- "Logistics & Supply Chain",
- "Hospitality & Tourism",
- "Construction & Built Environment",
- "Consumer Packaged Goods (CPG)",
- ]
- """Industry classification enum"""
-
- subindustry: Literal[
- "Defense Systems & Military Hardware",
- "Aerospace Manufacturing",
- "Avionics & Navigation Technology",
- "Subsea & Naval Defense Systems",
- "Space & Satellite Technology",
- "Defense IT & Systems Integration",
- "Software (B2B)",
- "Software (B2C)",
- "Cloud Infrastructure & DevOps",
- "Cybersecurity",
- "Artificial Intelligence & Machine Learning",
- "Data Infrastructure & Analytics",
- "Hardware & Semiconductors",
- "Fintech Infrastructure",
- "eCommerce & Marketplace Platforms",
- "Developer Tools & APIs",
- "Web3 & Blockchain",
- "XR & Spatial Computing",
- "Banking & Lending",
- "Investment Management & WealthTech",
- "Insurance & InsurTech",
- "Payments & Money Movement",
- "Accounting, Tax & Financial Planning Tools",
- "Capital Markets & Trading Platforms",
- "Financial Infrastructure & APIs",
- "Credit Scoring & Risk Management",
- "Cryptocurrency & Digital Assets",
- "BNPL & Alternative Financing",
- "Healthcare Providers & Services",
- "Pharmaceuticals & Drug Development",
- "Medical Devices & Diagnostics",
- "Biotechnology & Genomics",
- "Digital Health & Telemedicine",
- "Health Insurance & Benefits Tech",
- "Clinical Trials & Research Platforms",
- "Mental Health & Wellness",
- "Healthcare IT & EHR Systems",
- "Consumer Health & Wellness Products",
- "Online Marketplaces",
- "Direct-to-Consumer (DTC) Brands",
- "Retail Tech & Point-of-Sale Systems",
- "Omnichannel & In-Store Retail",
- "E-commerce Enablement & Infrastructure",
- "Subscription & Membership Commerce",
- "Social Commerce & Influencer Platforms",
- "Fashion & Apparel Retail",
- "Food, Beverage & Grocery E-commerce",
- "Streaming Platforms (Video, Music, Audio)",
- "Gaming & Interactive Entertainment",
- "Creator Economy & Influencer Platforms",
- "Advertising, Adtech & Media Buying",
- "Film, TV & Production Studios",
- "Events, Venues & Live Entertainment",
- "Virtual Worlds & Metaverse Experiences",
- "K-12 Education Platforms & Tools",
- "Higher Education & University Tech",
- "Online Learning & MOOCs",
- "Test Prep & Certification",
- "Corporate Training & Upskilling",
- "Tutoring & Supplemental Learning",
- "Education Management Systems (LMS/SIS)",
- "Language Learning",
- "Creator-Led & Cohort-Based Courses",
- "Special Education & Accessibility Tools",
- "Government Technology & Digital Services",
- "Civic Engagement & Policy Platforms",
- "International Development & Humanitarian Aid",
- "Philanthropy & Grantmaking",
- "Nonprofit Operations & Fundraising Tools",
- "Public Health & Social Services",
- "Education & Youth Development Programs",
- "Environmental & Climate Action Organizations",
- "Legal Aid & Social Justice Advocacy",
- "Municipal & Infrastructure Services",
- "Manufacturing & Industrial Automation",
- "Energy Production (Oil, Gas, Nuclear)",
- "Renewable Energy & Cleantech",
- "Utilities & Grid Infrastructure",
- "Industrial IoT & Monitoring Systems",
- "Construction & Heavy Equipment",
- "Mining & Natural Resources",
- "Environmental Engineering & Sustainability",
- "Energy Storage & Battery Technology",
- "Automotive OEMs & Vehicle Manufacturing",
- "Electric Vehicles (EVs) & Charging Infrastructure",
- "Mobility-as-a-Service (MaaS)",
- "Fleet Management",
- "Public Transit & Urban Mobility",
- "Autonomous Vehicles & ADAS",
- "Aftermarket Parts & Services",
- "Telematics & Vehicle Connectivity",
- "Aviation & Aerospace Transport",
- "Maritime Shipping",
- "Fitness & Wellness",
- "Beauty & Personal Care",
- "Home & Living",
- "Dating & Relationships",
- "Hobbies, Crafts & DIY",
- "Outdoor & Recreational Gear",
- "Events, Experiences & Ticketing Platforms",
- "Designer & Luxury Apparel",
- "Accessories, Jewelry & Watches",
- "Footwear & Leather Goods",
- "Beauty, Fragrance & Skincare",
- "Fashion Marketplaces & Retail Platforms",
- "Sustainable & Ethical Fashion",
- "Resale, Vintage & Circular Fashion",
- "Fashion Tech & Virtual Try-Ons",
- "Streetwear & Emerging Luxury",
- "Couture & Made-to-Measure",
- "News Publishing & Journalism",
- "Digital Media & Content Platforms",
- "Broadcasting (TV & Radio)",
- "Podcasting & Audio Media",
- "News Aggregators & Curation Tools",
- "Independent & Creator-Led Media",
- "Newsletters & Substack-Style Platforms",
- "Political & Investigative Media",
- "Trade & Niche Publications",
- "Media Monitoring & Analytics",
- "Professional Teams & Leagues",
- "Sports Media & Broadcasting",
- "Sports Betting & Fantasy Sports",
- "Fitness & Athletic Training Platforms",
- "Sportswear & Equipment",
- "Esports & Competitive Gaming",
- "Sports Venues & Event Management",
- "Athlete Management & Talent Agencies",
- "Sports Tech & Performance Analytics",
- "Youth, Amateur & Collegiate Sports",
- "Real Estate Marketplaces",
- "Property Management Software",
- "Rental Platforms",
- "Mortgage & Lending Tech",
- "Real Estate Investment Platforms",
- "Law Firms & Legal Services",
- "Legal Tech & Automation",
- "Regulatory Compliance",
- "E-Discovery & Litigation Tools",
- "Contract Management",
- "Governance, Risk & Compliance (GRC)",
- "IP & Trademark Management",
- "Legal Research & Intelligence",
- "Compliance Training & Certification",
- "Whistleblower & Ethics Reporting",
- "Mobile & Wireless Networks (3G/4G/5G)",
- "Broadband & Fiber Internet",
- "Satellite & Space-Based Communications",
- "Network Equipment & Infrastructure",
- "Telecom Billing & OSS/BSS Systems",
- "VoIP & Unified Communications",
- "Internet Service Providers (ISPs)",
- "Edge Computing & Network Virtualization",
- "IoT Connectivity Platforms",
- "Precision Agriculture & AgTech",
- "Crop & Livestock Production",
- "Food & Beverage Manufacturing & Processing",
- "Food Distribution",
- "Restaurants & Food Service",
- "Agricultural Inputs & Equipment",
- "Sustainable & Regenerative Agriculture",
- "Seafood & Aquaculture",
- "Management Consulting",
- "Marketing & Advertising Agencies",
- "Design, Branding & Creative Studios",
- "IT Services & Managed Services",
- "Staffing, Recruiting & Talent",
- "Accounting & Tax Firms",
- "Public Relations & Communications",
- "Business Process Outsourcing (BPO)",
- "Professional Training & Coaching",
- "Specialty Chemicals",
- "Commodity & Petrochemicals",
- "Polymers, Plastics & Rubber",
- "Coatings, Adhesives & Sealants",
- "Industrial Gases",
- "Advanced Materials & Composites",
- "Battery Materials & Energy Storage",
- "Electronic Materials & Semiconductor Chemicals",
- "Agrochemicals & Fertilizers",
- "Freight & Transportation Tech",
- "Last-Mile Delivery",
- "Warehouse Automation",
- "Supply Chain Visibility Platforms",
- "Logistics Marketplaces",
- "Shipping & Freight Forwarding",
- "Cold Chain Logistics",
- "Reverse Logistics & Returns",
- "Cross-Border Trade Tech",
- "Transportation Management Systems (TMS)",
- "Hotels & Accommodation",
- "Vacation Rentals & Short-Term Stays",
- "Restaurant Tech & Management",
- "Travel Booking Platforms",
- "Tourism Experiences & Activities",
- "Cruise Lines & Marine Tourism",
- "Hospitality Management Systems",
- "Event & Venue Management",
- "Corporate Travel Management",
- "Travel Insurance & Protection",
- "Construction Management Software",
- "BIM/CAD & Design Tools",
- "Construction Marketplaces",
- "Equipment Rental & Management",
- "Building Materials & Procurement",
- "Construction Workforce Management",
- "Project Estimation & Bidding",
- "Modular & Prefab Construction",
- "Construction Safety & Compliance",
- "Smart Building Technology",
- "Food & Beverage CPG",
- "Home & Personal Care CPG",
- "CPG Analytics & Insights",
- "Direct-to-Consumer CPG Brands",
- "CPG Supply Chain & Distribution",
- "Private Label Manufacturing",
- "CPG Retail Intelligence",
- "Sustainable CPG & Packaging",
- "Beauty & Cosmetics CPG",
- "Health & Wellness CPG",
- ]
- """Subindustry classification enum"""
-
-
-class BrandIndustries(BaseModel):
- """Industry classification information for the brand"""
-
- eic: Optional[List[BrandIndustriesEic]] = None
- """Easy Industry Classification - array of industry and subindustry pairs"""
-
-
-class BrandLinks(BaseModel):
- """Important website links for the brand"""
-
- blog: Optional[str] = None
- """URL to the brand's blog or news page"""
-
- careers: Optional[str] = None
- """URL to the brand's careers or job opportunities page"""
-
- contact: Optional[str] = None
- """URL to the brand's contact or contact us page"""
-
- pricing: Optional[str] = None
- """URL to the brand's pricing or plans page"""
-
- privacy: Optional[str] = None
- """URL to the brand's privacy policy page"""
-
- terms: Optional[str] = None
- """URL to the brand's terms of service or terms and conditions page"""
-
-
-class BrandLogoColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandLogoResolution(BaseModel):
- """Resolution of the logo image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandLogo(BaseModel):
- colors: Optional[List[BrandLogoColor]] = None
- """Array of colors in the logo"""
-
- mode: Optional[Literal["light", "dark", "has_opaque_background"]] = None
- """
- Indicates when this logo is best used: 'light' = best for light mode, 'dark' =
- best for dark mode, 'has_opaque_background' = can be used for either as image
- has its own background
- """
-
- resolution: Optional[BrandLogoResolution] = None
- """Resolution of the logo image"""
-
- type: Optional[Literal["icon", "logo"]] = None
- """Type of the logo based on resolution (e.g., 'icon', 'logo')"""
-
- url: Optional[str] = None
- """CDN hosted url of the logo (ready for display)"""
-
-
-class BrandSocial(BaseModel):
- type: Optional[
- Literal[
- "x",
- "facebook",
- "instagram",
- "linkedin",
- "youtube",
- "pinterest",
- "tiktok",
- "dribbble",
- "github",
- "behance",
- "snapchat",
- "whatsapp",
- "telegram",
- "line",
- "discord",
- "twitch",
- "vimeo",
- "imdb",
- "tumblr",
- "flickr",
- "giphy",
- "medium",
- "spotify",
- "soundcloud",
- "tripadvisor",
- "yelp",
- "producthunt",
- "reddit",
- "crunchbase",
- "appstore",
- "playstore",
- ]
- ] = None
- """Type of social media platform"""
-
- url: Optional[str] = None
- """URL of the social media page"""
-
-
-class BrandStock(BaseModel):
- """
- Stock market information for this brand (will be null if not a publicly traded company)
- """
-
- exchange: Optional[str] = None
- """Stock exchange name"""
-
- ticker: Optional[str] = None
- """Stock ticker symbol"""
-
-
-class Brand(BaseModel):
- """Detailed brand information"""
-
- address: Optional[BrandAddress] = None
- """Physical address of the brand"""
-
- backdrops: Optional[List[BrandBackdrop]] = None
- """An array of backdrop images for the brand"""
-
- colors: Optional[List[BrandColor]] = None
- """An array of brand colors"""
-
- description: Optional[str] = None
- """A brief description of the brand"""
-
- domain: Optional[str] = None
- """The domain name of the brand"""
-
- email: Optional[str] = None
- """Company email address"""
-
- industries: Optional[BrandIndustries] = None
- """Industry classification information for the brand"""
-
- is_nsfw: Optional[bool] = None
- """Indicates whether the brand content is not safe for work (NSFW)"""
-
- links: Optional[BrandLinks] = None
- """Important website links for the brand"""
-
- logos: Optional[List[BrandLogo]] = None
- """An array of logos associated with the brand"""
-
- phone: Optional[str] = None
- """Company phone number"""
-
- primary_language: Optional[
- Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- ] = None
- """The primary language of the brand's website content.
-
- Detected from the HTML lang tag, page content analysis, or social media
- descriptions.
- """
-
- slogan: Optional[str] = None
- """The brand's slogan"""
-
- socials: Optional[List[BrandSocial]] = None
- """An array of social media links for the brand"""
-
- stock: Optional[BrandStock] = None
- """
- Stock market information for this brand (will be null if not a publicly traded
- company)
- """
-
- title: Optional[str] = None
- """The title or name of the brand"""
-
-
-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 BrandIdentifyFromTransactionResponse(BaseModel):
- brand: Optional[Brand] = None
- """Detailed brand information"""
-
- code: Optional[int] = None
- """HTTP status code"""
-
- 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.
- """
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
diff --git a/src/context/dev/types/brand_retrieve_by_email_params.py b/src/context/dev/types/brand_retrieve_by_email_params.py
deleted file mode 100644
index 580b5c1..0000000
--- a/src/context/dev/types/brand_retrieve_by_email_params.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["BrandRetrieveByEmailParams"]
-
-
-class BrandRetrieveByEmailParams(TypedDict, total=False):
- email: Required[str]
- """Email address to retrieve brand data for (e.g., 'contact@example.com').
-
- The domain will be extracted from the email. Free email providers (gmail.com,
- yahoo.com, etc.) and disposable email addresses are not allowed.
- """
-
- force_language: Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- """Optional parameter to force the language of the retrieved brand data."""
-
- max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
- """
- Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
- """
-
- max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
- """Optional parameter to optimize the API call for maximum speed.
-
- When set to true, the API will skip time-consuming operations for faster
- response at the cost of less comprehensive data.
- """
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
diff --git a/src/context/dev/types/brand_retrieve_by_email_response.py b/src/context/dev/types/brand_retrieve_by_email_response.py
deleted file mode 100644
index 6fe6482..0000000
--- a/src/context/dev/types/brand_retrieve_by_email_response.py
+++ /dev/null
@@ -1,682 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = [
- "BrandRetrieveByEmailResponse",
- "Brand",
- "BrandAddress",
- "BrandBackdrop",
- "BrandBackdropColor",
- "BrandBackdropResolution",
- "BrandColor",
- "BrandIndustries",
- "BrandIndustriesEic",
- "BrandLinks",
- "BrandLogo",
- "BrandLogoColor",
- "BrandLogoResolution",
- "BrandSocial",
- "BrandStock",
- "KeyMetadata",
-]
-
-
-class BrandAddress(BaseModel):
- """Physical address of the brand"""
-
- city: Optional[str] = None
- """City name"""
-
- country: Optional[str] = None
- """Country name"""
-
- country_code: Optional[str] = None
- """Country code"""
-
- postal_code: Optional[str] = None
- """Postal or ZIP code"""
-
- state_code: Optional[str] = None
- """State or province code"""
-
- state_province: Optional[str] = None
- """State or province name"""
-
- street: Optional[str] = None
- """Street address"""
-
-
-class BrandBackdropColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandBackdropResolution(BaseModel):
- """Resolution of the backdrop image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandBackdrop(BaseModel):
- colors: Optional[List[BrandBackdropColor]] = None
- """Array of colors in the backdrop image"""
-
- resolution: Optional[BrandBackdropResolution] = None
- """Resolution of the backdrop image"""
-
- url: Optional[str] = None
- """URL of the backdrop image"""
-
-
-class BrandColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandIndustriesEic(BaseModel):
- industry: Literal[
- "Aerospace & Defense",
- "Technology",
- "Finance",
- "Healthcare",
- "Retail & E-commerce",
- "Entertainment",
- "Education",
- "Government & Nonprofit",
- "Industrial & Energy",
- "Automotive & Transportation",
- "Lifestyle & Leisure",
- "Luxury & Fashion",
- "News & Media",
- "Sports",
- "Real Estate & PropTech",
- "Legal & Compliance",
- "Telecommunications",
- "Agriculture & Food",
- "Professional Services & Agencies",
- "Chemicals & Materials",
- "Logistics & Supply Chain",
- "Hospitality & Tourism",
- "Construction & Built Environment",
- "Consumer Packaged Goods (CPG)",
- ]
- """Industry classification enum"""
-
- subindustry: Literal[
- "Defense Systems & Military Hardware",
- "Aerospace Manufacturing",
- "Avionics & Navigation Technology",
- "Subsea & Naval Defense Systems",
- "Space & Satellite Technology",
- "Defense IT & Systems Integration",
- "Software (B2B)",
- "Software (B2C)",
- "Cloud Infrastructure & DevOps",
- "Cybersecurity",
- "Artificial Intelligence & Machine Learning",
- "Data Infrastructure & Analytics",
- "Hardware & Semiconductors",
- "Fintech Infrastructure",
- "eCommerce & Marketplace Platforms",
- "Developer Tools & APIs",
- "Web3 & Blockchain",
- "XR & Spatial Computing",
- "Banking & Lending",
- "Investment Management & WealthTech",
- "Insurance & InsurTech",
- "Payments & Money Movement",
- "Accounting, Tax & Financial Planning Tools",
- "Capital Markets & Trading Platforms",
- "Financial Infrastructure & APIs",
- "Credit Scoring & Risk Management",
- "Cryptocurrency & Digital Assets",
- "BNPL & Alternative Financing",
- "Healthcare Providers & Services",
- "Pharmaceuticals & Drug Development",
- "Medical Devices & Diagnostics",
- "Biotechnology & Genomics",
- "Digital Health & Telemedicine",
- "Health Insurance & Benefits Tech",
- "Clinical Trials & Research Platforms",
- "Mental Health & Wellness",
- "Healthcare IT & EHR Systems",
- "Consumer Health & Wellness Products",
- "Online Marketplaces",
- "Direct-to-Consumer (DTC) Brands",
- "Retail Tech & Point-of-Sale Systems",
- "Omnichannel & In-Store Retail",
- "E-commerce Enablement & Infrastructure",
- "Subscription & Membership Commerce",
- "Social Commerce & Influencer Platforms",
- "Fashion & Apparel Retail",
- "Food, Beverage & Grocery E-commerce",
- "Streaming Platforms (Video, Music, Audio)",
- "Gaming & Interactive Entertainment",
- "Creator Economy & Influencer Platforms",
- "Advertising, Adtech & Media Buying",
- "Film, TV & Production Studios",
- "Events, Venues & Live Entertainment",
- "Virtual Worlds & Metaverse Experiences",
- "K-12 Education Platforms & Tools",
- "Higher Education & University Tech",
- "Online Learning & MOOCs",
- "Test Prep & Certification",
- "Corporate Training & Upskilling",
- "Tutoring & Supplemental Learning",
- "Education Management Systems (LMS/SIS)",
- "Language Learning",
- "Creator-Led & Cohort-Based Courses",
- "Special Education & Accessibility Tools",
- "Government Technology & Digital Services",
- "Civic Engagement & Policy Platforms",
- "International Development & Humanitarian Aid",
- "Philanthropy & Grantmaking",
- "Nonprofit Operations & Fundraising Tools",
- "Public Health & Social Services",
- "Education & Youth Development Programs",
- "Environmental & Climate Action Organizations",
- "Legal Aid & Social Justice Advocacy",
- "Municipal & Infrastructure Services",
- "Manufacturing & Industrial Automation",
- "Energy Production (Oil, Gas, Nuclear)",
- "Renewable Energy & Cleantech",
- "Utilities & Grid Infrastructure",
- "Industrial IoT & Monitoring Systems",
- "Construction & Heavy Equipment",
- "Mining & Natural Resources",
- "Environmental Engineering & Sustainability",
- "Energy Storage & Battery Technology",
- "Automotive OEMs & Vehicle Manufacturing",
- "Electric Vehicles (EVs) & Charging Infrastructure",
- "Mobility-as-a-Service (MaaS)",
- "Fleet Management",
- "Public Transit & Urban Mobility",
- "Autonomous Vehicles & ADAS",
- "Aftermarket Parts & Services",
- "Telematics & Vehicle Connectivity",
- "Aviation & Aerospace Transport",
- "Maritime Shipping",
- "Fitness & Wellness",
- "Beauty & Personal Care",
- "Home & Living",
- "Dating & Relationships",
- "Hobbies, Crafts & DIY",
- "Outdoor & Recreational Gear",
- "Events, Experiences & Ticketing Platforms",
- "Designer & Luxury Apparel",
- "Accessories, Jewelry & Watches",
- "Footwear & Leather Goods",
- "Beauty, Fragrance & Skincare",
- "Fashion Marketplaces & Retail Platforms",
- "Sustainable & Ethical Fashion",
- "Resale, Vintage & Circular Fashion",
- "Fashion Tech & Virtual Try-Ons",
- "Streetwear & Emerging Luxury",
- "Couture & Made-to-Measure",
- "News Publishing & Journalism",
- "Digital Media & Content Platforms",
- "Broadcasting (TV & Radio)",
- "Podcasting & Audio Media",
- "News Aggregators & Curation Tools",
- "Independent & Creator-Led Media",
- "Newsletters & Substack-Style Platforms",
- "Political & Investigative Media",
- "Trade & Niche Publications",
- "Media Monitoring & Analytics",
- "Professional Teams & Leagues",
- "Sports Media & Broadcasting",
- "Sports Betting & Fantasy Sports",
- "Fitness & Athletic Training Platforms",
- "Sportswear & Equipment",
- "Esports & Competitive Gaming",
- "Sports Venues & Event Management",
- "Athlete Management & Talent Agencies",
- "Sports Tech & Performance Analytics",
- "Youth, Amateur & Collegiate Sports",
- "Real Estate Marketplaces",
- "Property Management Software",
- "Rental Platforms",
- "Mortgage & Lending Tech",
- "Real Estate Investment Platforms",
- "Law Firms & Legal Services",
- "Legal Tech & Automation",
- "Regulatory Compliance",
- "E-Discovery & Litigation Tools",
- "Contract Management",
- "Governance, Risk & Compliance (GRC)",
- "IP & Trademark Management",
- "Legal Research & Intelligence",
- "Compliance Training & Certification",
- "Whistleblower & Ethics Reporting",
- "Mobile & Wireless Networks (3G/4G/5G)",
- "Broadband & Fiber Internet",
- "Satellite & Space-Based Communications",
- "Network Equipment & Infrastructure",
- "Telecom Billing & OSS/BSS Systems",
- "VoIP & Unified Communications",
- "Internet Service Providers (ISPs)",
- "Edge Computing & Network Virtualization",
- "IoT Connectivity Platforms",
- "Precision Agriculture & AgTech",
- "Crop & Livestock Production",
- "Food & Beverage Manufacturing & Processing",
- "Food Distribution",
- "Restaurants & Food Service",
- "Agricultural Inputs & Equipment",
- "Sustainable & Regenerative Agriculture",
- "Seafood & Aquaculture",
- "Management Consulting",
- "Marketing & Advertising Agencies",
- "Design, Branding & Creative Studios",
- "IT Services & Managed Services",
- "Staffing, Recruiting & Talent",
- "Accounting & Tax Firms",
- "Public Relations & Communications",
- "Business Process Outsourcing (BPO)",
- "Professional Training & Coaching",
- "Specialty Chemicals",
- "Commodity & Petrochemicals",
- "Polymers, Plastics & Rubber",
- "Coatings, Adhesives & Sealants",
- "Industrial Gases",
- "Advanced Materials & Composites",
- "Battery Materials & Energy Storage",
- "Electronic Materials & Semiconductor Chemicals",
- "Agrochemicals & Fertilizers",
- "Freight & Transportation Tech",
- "Last-Mile Delivery",
- "Warehouse Automation",
- "Supply Chain Visibility Platforms",
- "Logistics Marketplaces",
- "Shipping & Freight Forwarding",
- "Cold Chain Logistics",
- "Reverse Logistics & Returns",
- "Cross-Border Trade Tech",
- "Transportation Management Systems (TMS)",
- "Hotels & Accommodation",
- "Vacation Rentals & Short-Term Stays",
- "Restaurant Tech & Management",
- "Travel Booking Platforms",
- "Tourism Experiences & Activities",
- "Cruise Lines & Marine Tourism",
- "Hospitality Management Systems",
- "Event & Venue Management",
- "Corporate Travel Management",
- "Travel Insurance & Protection",
- "Construction Management Software",
- "BIM/CAD & Design Tools",
- "Construction Marketplaces",
- "Equipment Rental & Management",
- "Building Materials & Procurement",
- "Construction Workforce Management",
- "Project Estimation & Bidding",
- "Modular & Prefab Construction",
- "Construction Safety & Compliance",
- "Smart Building Technology",
- "Food & Beverage CPG",
- "Home & Personal Care CPG",
- "CPG Analytics & Insights",
- "Direct-to-Consumer CPG Brands",
- "CPG Supply Chain & Distribution",
- "Private Label Manufacturing",
- "CPG Retail Intelligence",
- "Sustainable CPG & Packaging",
- "Beauty & Cosmetics CPG",
- "Health & Wellness CPG",
- ]
- """Subindustry classification enum"""
-
-
-class BrandIndustries(BaseModel):
- """Industry classification information for the brand"""
-
- eic: Optional[List[BrandIndustriesEic]] = None
- """Easy Industry Classification - array of industry and subindustry pairs"""
-
-
-class BrandLinks(BaseModel):
- """Important website links for the brand"""
-
- blog: Optional[str] = None
- """URL to the brand's blog or news page"""
-
- careers: Optional[str] = None
- """URL to the brand's careers or job opportunities page"""
-
- contact: Optional[str] = None
- """URL to the brand's contact or contact us page"""
-
- pricing: Optional[str] = None
- """URL to the brand's pricing or plans page"""
-
- privacy: Optional[str] = None
- """URL to the brand's privacy policy page"""
-
- terms: Optional[str] = None
- """URL to the brand's terms of service or terms and conditions page"""
-
-
-class BrandLogoColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandLogoResolution(BaseModel):
- """Resolution of the logo image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandLogo(BaseModel):
- colors: Optional[List[BrandLogoColor]] = None
- """Array of colors in the logo"""
-
- mode: Optional[Literal["light", "dark", "has_opaque_background"]] = None
- """
- Indicates when this logo is best used: 'light' = best for light mode, 'dark' =
- best for dark mode, 'has_opaque_background' = can be used for either as image
- has its own background
- """
-
- resolution: Optional[BrandLogoResolution] = None
- """Resolution of the logo image"""
-
- type: Optional[Literal["icon", "logo"]] = None
- """Type of the logo based on resolution (e.g., 'icon', 'logo')"""
-
- url: Optional[str] = None
- """CDN hosted url of the logo (ready for display)"""
-
-
-class BrandSocial(BaseModel):
- type: Optional[
- Literal[
- "x",
- "facebook",
- "instagram",
- "linkedin",
- "youtube",
- "pinterest",
- "tiktok",
- "dribbble",
- "github",
- "behance",
- "snapchat",
- "whatsapp",
- "telegram",
- "line",
- "discord",
- "twitch",
- "vimeo",
- "imdb",
- "tumblr",
- "flickr",
- "giphy",
- "medium",
- "spotify",
- "soundcloud",
- "tripadvisor",
- "yelp",
- "producthunt",
- "reddit",
- "crunchbase",
- "appstore",
- "playstore",
- ]
- ] = None
- """Type of social media platform"""
-
- url: Optional[str] = None
- """URL of the social media page"""
-
-
-class BrandStock(BaseModel):
- """
- Stock market information for this brand (will be null if not a publicly traded company)
- """
-
- exchange: Optional[str] = None
- """Stock exchange name"""
-
- ticker: Optional[str] = None
- """Stock ticker symbol"""
-
-
-class Brand(BaseModel):
- """Detailed brand information"""
-
- address: Optional[BrandAddress] = None
- """Physical address of the brand"""
-
- backdrops: Optional[List[BrandBackdrop]] = None
- """An array of backdrop images for the brand"""
-
- colors: Optional[List[BrandColor]] = None
- """An array of brand colors"""
-
- description: Optional[str] = None
- """A brief description of the brand"""
-
- domain: Optional[str] = None
- """The domain name of the brand"""
-
- email: Optional[str] = None
- """Company email address"""
-
- industries: Optional[BrandIndustries] = None
- """Industry classification information for the brand"""
-
- is_nsfw: Optional[bool] = None
- """Indicates whether the brand content is not safe for work (NSFW)"""
-
- links: Optional[BrandLinks] = None
- """Important website links for the brand"""
-
- logos: Optional[List[BrandLogo]] = None
- """An array of logos associated with the brand"""
-
- phone: Optional[str] = None
- """Company phone number"""
-
- primary_language: Optional[
- Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- ] = None
- """The primary language of the brand's website content.
-
- Detected from the HTML lang tag, page content analysis, or social media
- descriptions.
- """
-
- slogan: Optional[str] = None
- """The brand's slogan"""
-
- socials: Optional[List[BrandSocial]] = None
- """An array of social media links for the brand"""
-
- stock: Optional[BrandStock] = None
- """
- Stock market information for this brand (will be null if not a publicly traded
- company)
- """
-
- title: Optional[str] = None
- """The title or name of the brand"""
-
-
-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 BrandRetrieveByEmailResponse(BaseModel):
- brand: Optional[Brand] = None
- """Detailed brand information"""
-
- code: Optional[int] = None
- """HTTP status code"""
-
- 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.
- """
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
diff --git a/src/context/dev/types/brand_retrieve_by_isin_params.py b/src/context/dev/types/brand_retrieve_by_isin_params.py
deleted file mode 100644
index 630834f..0000000
--- a/src/context/dev/types/brand_retrieve_by_isin_params.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["BrandRetrieveByIsinParams"]
-
-
-class BrandRetrieveByIsinParams(TypedDict, total=False):
- isin: Required[str]
- """
- ISIN (International Securities Identification Number) to retrieve brand data for
- (e.g., 'AU000000IMD5', 'US0378331005'). Must be exactly 12 characters: 2 letters
- followed by 9 alphanumeric characters and ending with a digit.
- """
-
- force_language: Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- """Optional parameter to force the language of the retrieved brand data."""
-
- max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
- """
- Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
- """
-
- max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
- """Optional parameter to optimize the API call for maximum speed.
-
- When set to true, the API will skip time-consuming operations for faster
- response at the cost of less comprehensive data.
- """
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
diff --git a/src/context/dev/types/brand_retrieve_by_isin_response.py b/src/context/dev/types/brand_retrieve_by_isin_response.py
deleted file mode 100644
index 8934a1f..0000000
--- a/src/context/dev/types/brand_retrieve_by_isin_response.py
+++ /dev/null
@@ -1,682 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = [
- "BrandRetrieveByIsinResponse",
- "Brand",
- "BrandAddress",
- "BrandBackdrop",
- "BrandBackdropColor",
- "BrandBackdropResolution",
- "BrandColor",
- "BrandIndustries",
- "BrandIndustriesEic",
- "BrandLinks",
- "BrandLogo",
- "BrandLogoColor",
- "BrandLogoResolution",
- "BrandSocial",
- "BrandStock",
- "KeyMetadata",
-]
-
-
-class BrandAddress(BaseModel):
- """Physical address of the brand"""
-
- city: Optional[str] = None
- """City name"""
-
- country: Optional[str] = None
- """Country name"""
-
- country_code: Optional[str] = None
- """Country code"""
-
- postal_code: Optional[str] = None
- """Postal or ZIP code"""
-
- state_code: Optional[str] = None
- """State or province code"""
-
- state_province: Optional[str] = None
- """State or province name"""
-
- street: Optional[str] = None
- """Street address"""
-
-
-class BrandBackdropColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandBackdropResolution(BaseModel):
- """Resolution of the backdrop image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandBackdrop(BaseModel):
- colors: Optional[List[BrandBackdropColor]] = None
- """Array of colors in the backdrop image"""
-
- resolution: Optional[BrandBackdropResolution] = None
- """Resolution of the backdrop image"""
-
- url: Optional[str] = None
- """URL of the backdrop image"""
-
-
-class BrandColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandIndustriesEic(BaseModel):
- industry: Literal[
- "Aerospace & Defense",
- "Technology",
- "Finance",
- "Healthcare",
- "Retail & E-commerce",
- "Entertainment",
- "Education",
- "Government & Nonprofit",
- "Industrial & Energy",
- "Automotive & Transportation",
- "Lifestyle & Leisure",
- "Luxury & Fashion",
- "News & Media",
- "Sports",
- "Real Estate & PropTech",
- "Legal & Compliance",
- "Telecommunications",
- "Agriculture & Food",
- "Professional Services & Agencies",
- "Chemicals & Materials",
- "Logistics & Supply Chain",
- "Hospitality & Tourism",
- "Construction & Built Environment",
- "Consumer Packaged Goods (CPG)",
- ]
- """Industry classification enum"""
-
- subindustry: Literal[
- "Defense Systems & Military Hardware",
- "Aerospace Manufacturing",
- "Avionics & Navigation Technology",
- "Subsea & Naval Defense Systems",
- "Space & Satellite Technology",
- "Defense IT & Systems Integration",
- "Software (B2B)",
- "Software (B2C)",
- "Cloud Infrastructure & DevOps",
- "Cybersecurity",
- "Artificial Intelligence & Machine Learning",
- "Data Infrastructure & Analytics",
- "Hardware & Semiconductors",
- "Fintech Infrastructure",
- "eCommerce & Marketplace Platforms",
- "Developer Tools & APIs",
- "Web3 & Blockchain",
- "XR & Spatial Computing",
- "Banking & Lending",
- "Investment Management & WealthTech",
- "Insurance & InsurTech",
- "Payments & Money Movement",
- "Accounting, Tax & Financial Planning Tools",
- "Capital Markets & Trading Platforms",
- "Financial Infrastructure & APIs",
- "Credit Scoring & Risk Management",
- "Cryptocurrency & Digital Assets",
- "BNPL & Alternative Financing",
- "Healthcare Providers & Services",
- "Pharmaceuticals & Drug Development",
- "Medical Devices & Diagnostics",
- "Biotechnology & Genomics",
- "Digital Health & Telemedicine",
- "Health Insurance & Benefits Tech",
- "Clinical Trials & Research Platforms",
- "Mental Health & Wellness",
- "Healthcare IT & EHR Systems",
- "Consumer Health & Wellness Products",
- "Online Marketplaces",
- "Direct-to-Consumer (DTC) Brands",
- "Retail Tech & Point-of-Sale Systems",
- "Omnichannel & In-Store Retail",
- "E-commerce Enablement & Infrastructure",
- "Subscription & Membership Commerce",
- "Social Commerce & Influencer Platforms",
- "Fashion & Apparel Retail",
- "Food, Beverage & Grocery E-commerce",
- "Streaming Platforms (Video, Music, Audio)",
- "Gaming & Interactive Entertainment",
- "Creator Economy & Influencer Platforms",
- "Advertising, Adtech & Media Buying",
- "Film, TV & Production Studios",
- "Events, Venues & Live Entertainment",
- "Virtual Worlds & Metaverse Experiences",
- "K-12 Education Platforms & Tools",
- "Higher Education & University Tech",
- "Online Learning & MOOCs",
- "Test Prep & Certification",
- "Corporate Training & Upskilling",
- "Tutoring & Supplemental Learning",
- "Education Management Systems (LMS/SIS)",
- "Language Learning",
- "Creator-Led & Cohort-Based Courses",
- "Special Education & Accessibility Tools",
- "Government Technology & Digital Services",
- "Civic Engagement & Policy Platforms",
- "International Development & Humanitarian Aid",
- "Philanthropy & Grantmaking",
- "Nonprofit Operations & Fundraising Tools",
- "Public Health & Social Services",
- "Education & Youth Development Programs",
- "Environmental & Climate Action Organizations",
- "Legal Aid & Social Justice Advocacy",
- "Municipal & Infrastructure Services",
- "Manufacturing & Industrial Automation",
- "Energy Production (Oil, Gas, Nuclear)",
- "Renewable Energy & Cleantech",
- "Utilities & Grid Infrastructure",
- "Industrial IoT & Monitoring Systems",
- "Construction & Heavy Equipment",
- "Mining & Natural Resources",
- "Environmental Engineering & Sustainability",
- "Energy Storage & Battery Technology",
- "Automotive OEMs & Vehicle Manufacturing",
- "Electric Vehicles (EVs) & Charging Infrastructure",
- "Mobility-as-a-Service (MaaS)",
- "Fleet Management",
- "Public Transit & Urban Mobility",
- "Autonomous Vehicles & ADAS",
- "Aftermarket Parts & Services",
- "Telematics & Vehicle Connectivity",
- "Aviation & Aerospace Transport",
- "Maritime Shipping",
- "Fitness & Wellness",
- "Beauty & Personal Care",
- "Home & Living",
- "Dating & Relationships",
- "Hobbies, Crafts & DIY",
- "Outdoor & Recreational Gear",
- "Events, Experiences & Ticketing Platforms",
- "Designer & Luxury Apparel",
- "Accessories, Jewelry & Watches",
- "Footwear & Leather Goods",
- "Beauty, Fragrance & Skincare",
- "Fashion Marketplaces & Retail Platforms",
- "Sustainable & Ethical Fashion",
- "Resale, Vintage & Circular Fashion",
- "Fashion Tech & Virtual Try-Ons",
- "Streetwear & Emerging Luxury",
- "Couture & Made-to-Measure",
- "News Publishing & Journalism",
- "Digital Media & Content Platforms",
- "Broadcasting (TV & Radio)",
- "Podcasting & Audio Media",
- "News Aggregators & Curation Tools",
- "Independent & Creator-Led Media",
- "Newsletters & Substack-Style Platforms",
- "Political & Investigative Media",
- "Trade & Niche Publications",
- "Media Monitoring & Analytics",
- "Professional Teams & Leagues",
- "Sports Media & Broadcasting",
- "Sports Betting & Fantasy Sports",
- "Fitness & Athletic Training Platforms",
- "Sportswear & Equipment",
- "Esports & Competitive Gaming",
- "Sports Venues & Event Management",
- "Athlete Management & Talent Agencies",
- "Sports Tech & Performance Analytics",
- "Youth, Amateur & Collegiate Sports",
- "Real Estate Marketplaces",
- "Property Management Software",
- "Rental Platforms",
- "Mortgage & Lending Tech",
- "Real Estate Investment Platforms",
- "Law Firms & Legal Services",
- "Legal Tech & Automation",
- "Regulatory Compliance",
- "E-Discovery & Litigation Tools",
- "Contract Management",
- "Governance, Risk & Compliance (GRC)",
- "IP & Trademark Management",
- "Legal Research & Intelligence",
- "Compliance Training & Certification",
- "Whistleblower & Ethics Reporting",
- "Mobile & Wireless Networks (3G/4G/5G)",
- "Broadband & Fiber Internet",
- "Satellite & Space-Based Communications",
- "Network Equipment & Infrastructure",
- "Telecom Billing & OSS/BSS Systems",
- "VoIP & Unified Communications",
- "Internet Service Providers (ISPs)",
- "Edge Computing & Network Virtualization",
- "IoT Connectivity Platforms",
- "Precision Agriculture & AgTech",
- "Crop & Livestock Production",
- "Food & Beverage Manufacturing & Processing",
- "Food Distribution",
- "Restaurants & Food Service",
- "Agricultural Inputs & Equipment",
- "Sustainable & Regenerative Agriculture",
- "Seafood & Aquaculture",
- "Management Consulting",
- "Marketing & Advertising Agencies",
- "Design, Branding & Creative Studios",
- "IT Services & Managed Services",
- "Staffing, Recruiting & Talent",
- "Accounting & Tax Firms",
- "Public Relations & Communications",
- "Business Process Outsourcing (BPO)",
- "Professional Training & Coaching",
- "Specialty Chemicals",
- "Commodity & Petrochemicals",
- "Polymers, Plastics & Rubber",
- "Coatings, Adhesives & Sealants",
- "Industrial Gases",
- "Advanced Materials & Composites",
- "Battery Materials & Energy Storage",
- "Electronic Materials & Semiconductor Chemicals",
- "Agrochemicals & Fertilizers",
- "Freight & Transportation Tech",
- "Last-Mile Delivery",
- "Warehouse Automation",
- "Supply Chain Visibility Platforms",
- "Logistics Marketplaces",
- "Shipping & Freight Forwarding",
- "Cold Chain Logistics",
- "Reverse Logistics & Returns",
- "Cross-Border Trade Tech",
- "Transportation Management Systems (TMS)",
- "Hotels & Accommodation",
- "Vacation Rentals & Short-Term Stays",
- "Restaurant Tech & Management",
- "Travel Booking Platforms",
- "Tourism Experiences & Activities",
- "Cruise Lines & Marine Tourism",
- "Hospitality Management Systems",
- "Event & Venue Management",
- "Corporate Travel Management",
- "Travel Insurance & Protection",
- "Construction Management Software",
- "BIM/CAD & Design Tools",
- "Construction Marketplaces",
- "Equipment Rental & Management",
- "Building Materials & Procurement",
- "Construction Workforce Management",
- "Project Estimation & Bidding",
- "Modular & Prefab Construction",
- "Construction Safety & Compliance",
- "Smart Building Technology",
- "Food & Beverage CPG",
- "Home & Personal Care CPG",
- "CPG Analytics & Insights",
- "Direct-to-Consumer CPG Brands",
- "CPG Supply Chain & Distribution",
- "Private Label Manufacturing",
- "CPG Retail Intelligence",
- "Sustainable CPG & Packaging",
- "Beauty & Cosmetics CPG",
- "Health & Wellness CPG",
- ]
- """Subindustry classification enum"""
-
-
-class BrandIndustries(BaseModel):
- """Industry classification information for the brand"""
-
- eic: Optional[List[BrandIndustriesEic]] = None
- """Easy Industry Classification - array of industry and subindustry pairs"""
-
-
-class BrandLinks(BaseModel):
- """Important website links for the brand"""
-
- blog: Optional[str] = None
- """URL to the brand's blog or news page"""
-
- careers: Optional[str] = None
- """URL to the brand's careers or job opportunities page"""
-
- contact: Optional[str] = None
- """URL to the brand's contact or contact us page"""
-
- pricing: Optional[str] = None
- """URL to the brand's pricing or plans page"""
-
- privacy: Optional[str] = None
- """URL to the brand's privacy policy page"""
-
- terms: Optional[str] = None
- """URL to the brand's terms of service or terms and conditions page"""
-
-
-class BrandLogoColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandLogoResolution(BaseModel):
- """Resolution of the logo image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandLogo(BaseModel):
- colors: Optional[List[BrandLogoColor]] = None
- """Array of colors in the logo"""
-
- mode: Optional[Literal["light", "dark", "has_opaque_background"]] = None
- """
- Indicates when this logo is best used: 'light' = best for light mode, 'dark' =
- best for dark mode, 'has_opaque_background' = can be used for either as image
- has its own background
- """
-
- resolution: Optional[BrandLogoResolution] = None
- """Resolution of the logo image"""
-
- type: Optional[Literal["icon", "logo"]] = None
- """Type of the logo based on resolution (e.g., 'icon', 'logo')"""
-
- url: Optional[str] = None
- """CDN hosted url of the logo (ready for display)"""
-
-
-class BrandSocial(BaseModel):
- type: Optional[
- Literal[
- "x",
- "facebook",
- "instagram",
- "linkedin",
- "youtube",
- "pinterest",
- "tiktok",
- "dribbble",
- "github",
- "behance",
- "snapchat",
- "whatsapp",
- "telegram",
- "line",
- "discord",
- "twitch",
- "vimeo",
- "imdb",
- "tumblr",
- "flickr",
- "giphy",
- "medium",
- "spotify",
- "soundcloud",
- "tripadvisor",
- "yelp",
- "producthunt",
- "reddit",
- "crunchbase",
- "appstore",
- "playstore",
- ]
- ] = None
- """Type of social media platform"""
-
- url: Optional[str] = None
- """URL of the social media page"""
-
-
-class BrandStock(BaseModel):
- """
- Stock market information for this brand (will be null if not a publicly traded company)
- """
-
- exchange: Optional[str] = None
- """Stock exchange name"""
-
- ticker: Optional[str] = None
- """Stock ticker symbol"""
-
-
-class Brand(BaseModel):
- """Detailed brand information"""
-
- address: Optional[BrandAddress] = None
- """Physical address of the brand"""
-
- backdrops: Optional[List[BrandBackdrop]] = None
- """An array of backdrop images for the brand"""
-
- colors: Optional[List[BrandColor]] = None
- """An array of brand colors"""
-
- description: Optional[str] = None
- """A brief description of the brand"""
-
- domain: Optional[str] = None
- """The domain name of the brand"""
-
- email: Optional[str] = None
- """Company email address"""
-
- industries: Optional[BrandIndustries] = None
- """Industry classification information for the brand"""
-
- is_nsfw: Optional[bool] = None
- """Indicates whether the brand content is not safe for work (NSFW)"""
-
- links: Optional[BrandLinks] = None
- """Important website links for the brand"""
-
- logos: Optional[List[BrandLogo]] = None
- """An array of logos associated with the brand"""
-
- phone: Optional[str] = None
- """Company phone number"""
-
- primary_language: Optional[
- Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- ] = None
- """The primary language of the brand's website content.
-
- Detected from the HTML lang tag, page content analysis, or social media
- descriptions.
- """
-
- slogan: Optional[str] = None
- """The brand's slogan"""
-
- socials: Optional[List[BrandSocial]] = None
- """An array of social media links for the brand"""
-
- stock: Optional[BrandStock] = None
- """
- Stock market information for this brand (will be null if not a publicly traded
- company)
- """
-
- title: Optional[str] = None
- """The title or name of the brand"""
-
-
-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 BrandRetrieveByIsinResponse(BaseModel):
- brand: Optional[Brand] = None
- """Detailed brand information"""
-
- code: Optional[int] = None
- """HTTP status code"""
-
- 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.
- """
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
diff --git a/src/context/dev/types/brand_retrieve_by_name_params.py b/src/context/dev/types/brand_retrieve_by_name_params.py
deleted file mode 100644
index 972fbd0..0000000
--- a/src/context/dev/types/brand_retrieve_by_name_params.py
+++ /dev/null
@@ -1,409 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["BrandRetrieveByNameParams"]
-
-
-class BrandRetrieveByNameParams(TypedDict, total=False):
- name: Required[str]
- """
- Company name to retrieve brand data for (e.g., 'Apple Inc', 'Microsoft
- Corporation'). Must be 3-30 characters.
- """
-
- country_gl: Literal[
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bm",
- "bn",
- "bo",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "gd",
- "ge",
- "gf",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "ht",
- "hu",
- "id",
- "ie",
- "il",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "st",
- "sv",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- ]
- """
- Optional country code hint (GL parameter) to specify the country for the company
- name.
- """
-
- force_language: Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- """Optional parameter to force the language of the retrieved brand data."""
-
- max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
- """
- Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
- """
-
- max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
- """Optional parameter to optimize the API call for maximum speed.
-
- When set to true, the API will skip time-consuming operations for faster
- response at the cost of less comprehensive data.
- """
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
diff --git a/src/context/dev/types/brand_retrieve_by_name_response.py b/src/context/dev/types/brand_retrieve_by_name_response.py
deleted file mode 100644
index 3830c92..0000000
--- a/src/context/dev/types/brand_retrieve_by_name_response.py
+++ /dev/null
@@ -1,682 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = [
- "BrandRetrieveByNameResponse",
- "Brand",
- "BrandAddress",
- "BrandBackdrop",
- "BrandBackdropColor",
- "BrandBackdropResolution",
- "BrandColor",
- "BrandIndustries",
- "BrandIndustriesEic",
- "BrandLinks",
- "BrandLogo",
- "BrandLogoColor",
- "BrandLogoResolution",
- "BrandSocial",
- "BrandStock",
- "KeyMetadata",
-]
-
-
-class BrandAddress(BaseModel):
- """Physical address of the brand"""
-
- city: Optional[str] = None
- """City name"""
-
- country: Optional[str] = None
- """Country name"""
-
- country_code: Optional[str] = None
- """Country code"""
-
- postal_code: Optional[str] = None
- """Postal or ZIP code"""
-
- state_code: Optional[str] = None
- """State or province code"""
-
- state_province: Optional[str] = None
- """State or province name"""
-
- street: Optional[str] = None
- """Street address"""
-
-
-class BrandBackdropColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandBackdropResolution(BaseModel):
- """Resolution of the backdrop image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandBackdrop(BaseModel):
- colors: Optional[List[BrandBackdropColor]] = None
- """Array of colors in the backdrop image"""
-
- resolution: Optional[BrandBackdropResolution] = None
- """Resolution of the backdrop image"""
-
- url: Optional[str] = None
- """URL of the backdrop image"""
-
-
-class BrandColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandIndustriesEic(BaseModel):
- industry: Literal[
- "Aerospace & Defense",
- "Technology",
- "Finance",
- "Healthcare",
- "Retail & E-commerce",
- "Entertainment",
- "Education",
- "Government & Nonprofit",
- "Industrial & Energy",
- "Automotive & Transportation",
- "Lifestyle & Leisure",
- "Luxury & Fashion",
- "News & Media",
- "Sports",
- "Real Estate & PropTech",
- "Legal & Compliance",
- "Telecommunications",
- "Agriculture & Food",
- "Professional Services & Agencies",
- "Chemicals & Materials",
- "Logistics & Supply Chain",
- "Hospitality & Tourism",
- "Construction & Built Environment",
- "Consumer Packaged Goods (CPG)",
- ]
- """Industry classification enum"""
-
- subindustry: Literal[
- "Defense Systems & Military Hardware",
- "Aerospace Manufacturing",
- "Avionics & Navigation Technology",
- "Subsea & Naval Defense Systems",
- "Space & Satellite Technology",
- "Defense IT & Systems Integration",
- "Software (B2B)",
- "Software (B2C)",
- "Cloud Infrastructure & DevOps",
- "Cybersecurity",
- "Artificial Intelligence & Machine Learning",
- "Data Infrastructure & Analytics",
- "Hardware & Semiconductors",
- "Fintech Infrastructure",
- "eCommerce & Marketplace Platforms",
- "Developer Tools & APIs",
- "Web3 & Blockchain",
- "XR & Spatial Computing",
- "Banking & Lending",
- "Investment Management & WealthTech",
- "Insurance & InsurTech",
- "Payments & Money Movement",
- "Accounting, Tax & Financial Planning Tools",
- "Capital Markets & Trading Platforms",
- "Financial Infrastructure & APIs",
- "Credit Scoring & Risk Management",
- "Cryptocurrency & Digital Assets",
- "BNPL & Alternative Financing",
- "Healthcare Providers & Services",
- "Pharmaceuticals & Drug Development",
- "Medical Devices & Diagnostics",
- "Biotechnology & Genomics",
- "Digital Health & Telemedicine",
- "Health Insurance & Benefits Tech",
- "Clinical Trials & Research Platforms",
- "Mental Health & Wellness",
- "Healthcare IT & EHR Systems",
- "Consumer Health & Wellness Products",
- "Online Marketplaces",
- "Direct-to-Consumer (DTC) Brands",
- "Retail Tech & Point-of-Sale Systems",
- "Omnichannel & In-Store Retail",
- "E-commerce Enablement & Infrastructure",
- "Subscription & Membership Commerce",
- "Social Commerce & Influencer Platforms",
- "Fashion & Apparel Retail",
- "Food, Beverage & Grocery E-commerce",
- "Streaming Platforms (Video, Music, Audio)",
- "Gaming & Interactive Entertainment",
- "Creator Economy & Influencer Platforms",
- "Advertising, Adtech & Media Buying",
- "Film, TV & Production Studios",
- "Events, Venues & Live Entertainment",
- "Virtual Worlds & Metaverse Experiences",
- "K-12 Education Platforms & Tools",
- "Higher Education & University Tech",
- "Online Learning & MOOCs",
- "Test Prep & Certification",
- "Corporate Training & Upskilling",
- "Tutoring & Supplemental Learning",
- "Education Management Systems (LMS/SIS)",
- "Language Learning",
- "Creator-Led & Cohort-Based Courses",
- "Special Education & Accessibility Tools",
- "Government Technology & Digital Services",
- "Civic Engagement & Policy Platforms",
- "International Development & Humanitarian Aid",
- "Philanthropy & Grantmaking",
- "Nonprofit Operations & Fundraising Tools",
- "Public Health & Social Services",
- "Education & Youth Development Programs",
- "Environmental & Climate Action Organizations",
- "Legal Aid & Social Justice Advocacy",
- "Municipal & Infrastructure Services",
- "Manufacturing & Industrial Automation",
- "Energy Production (Oil, Gas, Nuclear)",
- "Renewable Energy & Cleantech",
- "Utilities & Grid Infrastructure",
- "Industrial IoT & Monitoring Systems",
- "Construction & Heavy Equipment",
- "Mining & Natural Resources",
- "Environmental Engineering & Sustainability",
- "Energy Storage & Battery Technology",
- "Automotive OEMs & Vehicle Manufacturing",
- "Electric Vehicles (EVs) & Charging Infrastructure",
- "Mobility-as-a-Service (MaaS)",
- "Fleet Management",
- "Public Transit & Urban Mobility",
- "Autonomous Vehicles & ADAS",
- "Aftermarket Parts & Services",
- "Telematics & Vehicle Connectivity",
- "Aviation & Aerospace Transport",
- "Maritime Shipping",
- "Fitness & Wellness",
- "Beauty & Personal Care",
- "Home & Living",
- "Dating & Relationships",
- "Hobbies, Crafts & DIY",
- "Outdoor & Recreational Gear",
- "Events, Experiences & Ticketing Platforms",
- "Designer & Luxury Apparel",
- "Accessories, Jewelry & Watches",
- "Footwear & Leather Goods",
- "Beauty, Fragrance & Skincare",
- "Fashion Marketplaces & Retail Platforms",
- "Sustainable & Ethical Fashion",
- "Resale, Vintage & Circular Fashion",
- "Fashion Tech & Virtual Try-Ons",
- "Streetwear & Emerging Luxury",
- "Couture & Made-to-Measure",
- "News Publishing & Journalism",
- "Digital Media & Content Platforms",
- "Broadcasting (TV & Radio)",
- "Podcasting & Audio Media",
- "News Aggregators & Curation Tools",
- "Independent & Creator-Led Media",
- "Newsletters & Substack-Style Platforms",
- "Political & Investigative Media",
- "Trade & Niche Publications",
- "Media Monitoring & Analytics",
- "Professional Teams & Leagues",
- "Sports Media & Broadcasting",
- "Sports Betting & Fantasy Sports",
- "Fitness & Athletic Training Platforms",
- "Sportswear & Equipment",
- "Esports & Competitive Gaming",
- "Sports Venues & Event Management",
- "Athlete Management & Talent Agencies",
- "Sports Tech & Performance Analytics",
- "Youth, Amateur & Collegiate Sports",
- "Real Estate Marketplaces",
- "Property Management Software",
- "Rental Platforms",
- "Mortgage & Lending Tech",
- "Real Estate Investment Platforms",
- "Law Firms & Legal Services",
- "Legal Tech & Automation",
- "Regulatory Compliance",
- "E-Discovery & Litigation Tools",
- "Contract Management",
- "Governance, Risk & Compliance (GRC)",
- "IP & Trademark Management",
- "Legal Research & Intelligence",
- "Compliance Training & Certification",
- "Whistleblower & Ethics Reporting",
- "Mobile & Wireless Networks (3G/4G/5G)",
- "Broadband & Fiber Internet",
- "Satellite & Space-Based Communications",
- "Network Equipment & Infrastructure",
- "Telecom Billing & OSS/BSS Systems",
- "VoIP & Unified Communications",
- "Internet Service Providers (ISPs)",
- "Edge Computing & Network Virtualization",
- "IoT Connectivity Platforms",
- "Precision Agriculture & AgTech",
- "Crop & Livestock Production",
- "Food & Beverage Manufacturing & Processing",
- "Food Distribution",
- "Restaurants & Food Service",
- "Agricultural Inputs & Equipment",
- "Sustainable & Regenerative Agriculture",
- "Seafood & Aquaculture",
- "Management Consulting",
- "Marketing & Advertising Agencies",
- "Design, Branding & Creative Studios",
- "IT Services & Managed Services",
- "Staffing, Recruiting & Talent",
- "Accounting & Tax Firms",
- "Public Relations & Communications",
- "Business Process Outsourcing (BPO)",
- "Professional Training & Coaching",
- "Specialty Chemicals",
- "Commodity & Petrochemicals",
- "Polymers, Plastics & Rubber",
- "Coatings, Adhesives & Sealants",
- "Industrial Gases",
- "Advanced Materials & Composites",
- "Battery Materials & Energy Storage",
- "Electronic Materials & Semiconductor Chemicals",
- "Agrochemicals & Fertilizers",
- "Freight & Transportation Tech",
- "Last-Mile Delivery",
- "Warehouse Automation",
- "Supply Chain Visibility Platforms",
- "Logistics Marketplaces",
- "Shipping & Freight Forwarding",
- "Cold Chain Logistics",
- "Reverse Logistics & Returns",
- "Cross-Border Trade Tech",
- "Transportation Management Systems (TMS)",
- "Hotels & Accommodation",
- "Vacation Rentals & Short-Term Stays",
- "Restaurant Tech & Management",
- "Travel Booking Platforms",
- "Tourism Experiences & Activities",
- "Cruise Lines & Marine Tourism",
- "Hospitality Management Systems",
- "Event & Venue Management",
- "Corporate Travel Management",
- "Travel Insurance & Protection",
- "Construction Management Software",
- "BIM/CAD & Design Tools",
- "Construction Marketplaces",
- "Equipment Rental & Management",
- "Building Materials & Procurement",
- "Construction Workforce Management",
- "Project Estimation & Bidding",
- "Modular & Prefab Construction",
- "Construction Safety & Compliance",
- "Smart Building Technology",
- "Food & Beverage CPG",
- "Home & Personal Care CPG",
- "CPG Analytics & Insights",
- "Direct-to-Consumer CPG Brands",
- "CPG Supply Chain & Distribution",
- "Private Label Manufacturing",
- "CPG Retail Intelligence",
- "Sustainable CPG & Packaging",
- "Beauty & Cosmetics CPG",
- "Health & Wellness CPG",
- ]
- """Subindustry classification enum"""
-
-
-class BrandIndustries(BaseModel):
- """Industry classification information for the brand"""
-
- eic: Optional[List[BrandIndustriesEic]] = None
- """Easy Industry Classification - array of industry and subindustry pairs"""
-
-
-class BrandLinks(BaseModel):
- """Important website links for the brand"""
-
- blog: Optional[str] = None
- """URL to the brand's blog or news page"""
-
- careers: Optional[str] = None
- """URL to the brand's careers or job opportunities page"""
-
- contact: Optional[str] = None
- """URL to the brand's contact or contact us page"""
-
- pricing: Optional[str] = None
- """URL to the brand's pricing or plans page"""
-
- privacy: Optional[str] = None
- """URL to the brand's privacy policy page"""
-
- terms: Optional[str] = None
- """URL to the brand's terms of service or terms and conditions page"""
-
-
-class BrandLogoColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandLogoResolution(BaseModel):
- """Resolution of the logo image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandLogo(BaseModel):
- colors: Optional[List[BrandLogoColor]] = None
- """Array of colors in the logo"""
-
- mode: Optional[Literal["light", "dark", "has_opaque_background"]] = None
- """
- Indicates when this logo is best used: 'light' = best for light mode, 'dark' =
- best for dark mode, 'has_opaque_background' = can be used for either as image
- has its own background
- """
-
- resolution: Optional[BrandLogoResolution] = None
- """Resolution of the logo image"""
-
- type: Optional[Literal["icon", "logo"]] = None
- """Type of the logo based on resolution (e.g., 'icon', 'logo')"""
-
- url: Optional[str] = None
- """CDN hosted url of the logo (ready for display)"""
-
-
-class BrandSocial(BaseModel):
- type: Optional[
- Literal[
- "x",
- "facebook",
- "instagram",
- "linkedin",
- "youtube",
- "pinterest",
- "tiktok",
- "dribbble",
- "github",
- "behance",
- "snapchat",
- "whatsapp",
- "telegram",
- "line",
- "discord",
- "twitch",
- "vimeo",
- "imdb",
- "tumblr",
- "flickr",
- "giphy",
- "medium",
- "spotify",
- "soundcloud",
- "tripadvisor",
- "yelp",
- "producthunt",
- "reddit",
- "crunchbase",
- "appstore",
- "playstore",
- ]
- ] = None
- """Type of social media platform"""
-
- url: Optional[str] = None
- """URL of the social media page"""
-
-
-class BrandStock(BaseModel):
- """
- Stock market information for this brand (will be null if not a publicly traded company)
- """
-
- exchange: Optional[str] = None
- """Stock exchange name"""
-
- ticker: Optional[str] = None
- """Stock ticker symbol"""
-
-
-class Brand(BaseModel):
- """Detailed brand information"""
-
- address: Optional[BrandAddress] = None
- """Physical address of the brand"""
-
- backdrops: Optional[List[BrandBackdrop]] = None
- """An array of backdrop images for the brand"""
-
- colors: Optional[List[BrandColor]] = None
- """An array of brand colors"""
-
- description: Optional[str] = None
- """A brief description of the brand"""
-
- domain: Optional[str] = None
- """The domain name of the brand"""
-
- email: Optional[str] = None
- """Company email address"""
-
- industries: Optional[BrandIndustries] = None
- """Industry classification information for the brand"""
-
- is_nsfw: Optional[bool] = None
- """Indicates whether the brand content is not safe for work (NSFW)"""
-
- links: Optional[BrandLinks] = None
- """Important website links for the brand"""
-
- logos: Optional[List[BrandLogo]] = None
- """An array of logos associated with the brand"""
-
- phone: Optional[str] = None
- """Company phone number"""
-
- primary_language: Optional[
- Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- ] = None
- """The primary language of the brand's website content.
-
- Detected from the HTML lang tag, page content analysis, or social media
- descriptions.
- """
-
- slogan: Optional[str] = None
- """The brand's slogan"""
-
- socials: Optional[List[BrandSocial]] = None
- """An array of social media links for the brand"""
-
- stock: Optional[BrandStock] = None
- """
- Stock market information for this brand (will be null if not a publicly traded
- company)
- """
-
- title: Optional[str] = None
- """The title or name of the brand"""
-
-
-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 BrandRetrieveByNameResponse(BaseModel):
- brand: Optional[Brand] = None
- """Detailed brand information"""
-
- code: Optional[int] = None
- """HTTP status code"""
-
- 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.
- """
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
diff --git a/src/context/dev/types/brand_retrieve_by_ticker_params.py b/src/context/dev/types/brand_retrieve_by_ticker_params.py
deleted file mode 100644
index 8ba1731..0000000
--- a/src/context/dev/types/brand_retrieve_by_ticker_params.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["BrandRetrieveByTickerParams"]
-
-
-class BrandRetrieveByTickerParams(TypedDict, total=False):
- ticker: Required[str]
- """Stock ticker symbol to retrieve brand data for (e.g., 'AAPL', 'GOOGL', 'BRK.A').
-
- Must be 1-15 characters, letters/numbers/dots only.
- """
-
- force_language: Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- """Optional parameter to force the language of the retrieved brand data."""
-
- max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
- """
- Maximum age in milliseconds for cached brand data before the API performs a hard
- refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
- are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
- year.
- """
-
- max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
- """Optional parameter to optimize the API call for maximum speed.
-
- When set to true, the API will skip time-consuming operations for faster
- response at the cost of less comprehensive data.
- """
-
- 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",
- ]
- """Optional stock exchange for the ticker. Defaults to NASDAQ if not specified."""
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
diff --git a/src/context/dev/types/brand_retrieve_by_ticker_response.py b/src/context/dev/types/brand_retrieve_by_ticker_response.py
deleted file mode 100644
index 63ba9a1..0000000
--- a/src/context/dev/types/brand_retrieve_by_ticker_response.py
+++ /dev/null
@@ -1,682 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = [
- "BrandRetrieveByTickerResponse",
- "Brand",
- "BrandAddress",
- "BrandBackdrop",
- "BrandBackdropColor",
- "BrandBackdropResolution",
- "BrandColor",
- "BrandIndustries",
- "BrandIndustriesEic",
- "BrandLinks",
- "BrandLogo",
- "BrandLogoColor",
- "BrandLogoResolution",
- "BrandSocial",
- "BrandStock",
- "KeyMetadata",
-]
-
-
-class BrandAddress(BaseModel):
- """Physical address of the brand"""
-
- city: Optional[str] = None
- """City name"""
-
- country: Optional[str] = None
- """Country name"""
-
- country_code: Optional[str] = None
- """Country code"""
-
- postal_code: Optional[str] = None
- """Postal or ZIP code"""
-
- state_code: Optional[str] = None
- """State or province code"""
-
- state_province: Optional[str] = None
- """State or province name"""
-
- street: Optional[str] = None
- """Street address"""
-
-
-class BrandBackdropColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandBackdropResolution(BaseModel):
- """Resolution of the backdrop image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandBackdrop(BaseModel):
- colors: Optional[List[BrandBackdropColor]] = None
- """Array of colors in the backdrop image"""
-
- resolution: Optional[BrandBackdropResolution] = None
- """Resolution of the backdrop image"""
-
- url: Optional[str] = None
- """URL of the backdrop image"""
-
-
-class BrandColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandIndustriesEic(BaseModel):
- industry: Literal[
- "Aerospace & Defense",
- "Technology",
- "Finance",
- "Healthcare",
- "Retail & E-commerce",
- "Entertainment",
- "Education",
- "Government & Nonprofit",
- "Industrial & Energy",
- "Automotive & Transportation",
- "Lifestyle & Leisure",
- "Luxury & Fashion",
- "News & Media",
- "Sports",
- "Real Estate & PropTech",
- "Legal & Compliance",
- "Telecommunications",
- "Agriculture & Food",
- "Professional Services & Agencies",
- "Chemicals & Materials",
- "Logistics & Supply Chain",
- "Hospitality & Tourism",
- "Construction & Built Environment",
- "Consumer Packaged Goods (CPG)",
- ]
- """Industry classification enum"""
-
- subindustry: Literal[
- "Defense Systems & Military Hardware",
- "Aerospace Manufacturing",
- "Avionics & Navigation Technology",
- "Subsea & Naval Defense Systems",
- "Space & Satellite Technology",
- "Defense IT & Systems Integration",
- "Software (B2B)",
- "Software (B2C)",
- "Cloud Infrastructure & DevOps",
- "Cybersecurity",
- "Artificial Intelligence & Machine Learning",
- "Data Infrastructure & Analytics",
- "Hardware & Semiconductors",
- "Fintech Infrastructure",
- "eCommerce & Marketplace Platforms",
- "Developer Tools & APIs",
- "Web3 & Blockchain",
- "XR & Spatial Computing",
- "Banking & Lending",
- "Investment Management & WealthTech",
- "Insurance & InsurTech",
- "Payments & Money Movement",
- "Accounting, Tax & Financial Planning Tools",
- "Capital Markets & Trading Platforms",
- "Financial Infrastructure & APIs",
- "Credit Scoring & Risk Management",
- "Cryptocurrency & Digital Assets",
- "BNPL & Alternative Financing",
- "Healthcare Providers & Services",
- "Pharmaceuticals & Drug Development",
- "Medical Devices & Diagnostics",
- "Biotechnology & Genomics",
- "Digital Health & Telemedicine",
- "Health Insurance & Benefits Tech",
- "Clinical Trials & Research Platforms",
- "Mental Health & Wellness",
- "Healthcare IT & EHR Systems",
- "Consumer Health & Wellness Products",
- "Online Marketplaces",
- "Direct-to-Consumer (DTC) Brands",
- "Retail Tech & Point-of-Sale Systems",
- "Omnichannel & In-Store Retail",
- "E-commerce Enablement & Infrastructure",
- "Subscription & Membership Commerce",
- "Social Commerce & Influencer Platforms",
- "Fashion & Apparel Retail",
- "Food, Beverage & Grocery E-commerce",
- "Streaming Platforms (Video, Music, Audio)",
- "Gaming & Interactive Entertainment",
- "Creator Economy & Influencer Platforms",
- "Advertising, Adtech & Media Buying",
- "Film, TV & Production Studios",
- "Events, Venues & Live Entertainment",
- "Virtual Worlds & Metaverse Experiences",
- "K-12 Education Platforms & Tools",
- "Higher Education & University Tech",
- "Online Learning & MOOCs",
- "Test Prep & Certification",
- "Corporate Training & Upskilling",
- "Tutoring & Supplemental Learning",
- "Education Management Systems (LMS/SIS)",
- "Language Learning",
- "Creator-Led & Cohort-Based Courses",
- "Special Education & Accessibility Tools",
- "Government Technology & Digital Services",
- "Civic Engagement & Policy Platforms",
- "International Development & Humanitarian Aid",
- "Philanthropy & Grantmaking",
- "Nonprofit Operations & Fundraising Tools",
- "Public Health & Social Services",
- "Education & Youth Development Programs",
- "Environmental & Climate Action Organizations",
- "Legal Aid & Social Justice Advocacy",
- "Municipal & Infrastructure Services",
- "Manufacturing & Industrial Automation",
- "Energy Production (Oil, Gas, Nuclear)",
- "Renewable Energy & Cleantech",
- "Utilities & Grid Infrastructure",
- "Industrial IoT & Monitoring Systems",
- "Construction & Heavy Equipment",
- "Mining & Natural Resources",
- "Environmental Engineering & Sustainability",
- "Energy Storage & Battery Technology",
- "Automotive OEMs & Vehicle Manufacturing",
- "Electric Vehicles (EVs) & Charging Infrastructure",
- "Mobility-as-a-Service (MaaS)",
- "Fleet Management",
- "Public Transit & Urban Mobility",
- "Autonomous Vehicles & ADAS",
- "Aftermarket Parts & Services",
- "Telematics & Vehicle Connectivity",
- "Aviation & Aerospace Transport",
- "Maritime Shipping",
- "Fitness & Wellness",
- "Beauty & Personal Care",
- "Home & Living",
- "Dating & Relationships",
- "Hobbies, Crafts & DIY",
- "Outdoor & Recreational Gear",
- "Events, Experiences & Ticketing Platforms",
- "Designer & Luxury Apparel",
- "Accessories, Jewelry & Watches",
- "Footwear & Leather Goods",
- "Beauty, Fragrance & Skincare",
- "Fashion Marketplaces & Retail Platforms",
- "Sustainable & Ethical Fashion",
- "Resale, Vintage & Circular Fashion",
- "Fashion Tech & Virtual Try-Ons",
- "Streetwear & Emerging Luxury",
- "Couture & Made-to-Measure",
- "News Publishing & Journalism",
- "Digital Media & Content Platforms",
- "Broadcasting (TV & Radio)",
- "Podcasting & Audio Media",
- "News Aggregators & Curation Tools",
- "Independent & Creator-Led Media",
- "Newsletters & Substack-Style Platforms",
- "Political & Investigative Media",
- "Trade & Niche Publications",
- "Media Monitoring & Analytics",
- "Professional Teams & Leagues",
- "Sports Media & Broadcasting",
- "Sports Betting & Fantasy Sports",
- "Fitness & Athletic Training Platforms",
- "Sportswear & Equipment",
- "Esports & Competitive Gaming",
- "Sports Venues & Event Management",
- "Athlete Management & Talent Agencies",
- "Sports Tech & Performance Analytics",
- "Youth, Amateur & Collegiate Sports",
- "Real Estate Marketplaces",
- "Property Management Software",
- "Rental Platforms",
- "Mortgage & Lending Tech",
- "Real Estate Investment Platforms",
- "Law Firms & Legal Services",
- "Legal Tech & Automation",
- "Regulatory Compliance",
- "E-Discovery & Litigation Tools",
- "Contract Management",
- "Governance, Risk & Compliance (GRC)",
- "IP & Trademark Management",
- "Legal Research & Intelligence",
- "Compliance Training & Certification",
- "Whistleblower & Ethics Reporting",
- "Mobile & Wireless Networks (3G/4G/5G)",
- "Broadband & Fiber Internet",
- "Satellite & Space-Based Communications",
- "Network Equipment & Infrastructure",
- "Telecom Billing & OSS/BSS Systems",
- "VoIP & Unified Communications",
- "Internet Service Providers (ISPs)",
- "Edge Computing & Network Virtualization",
- "IoT Connectivity Platforms",
- "Precision Agriculture & AgTech",
- "Crop & Livestock Production",
- "Food & Beverage Manufacturing & Processing",
- "Food Distribution",
- "Restaurants & Food Service",
- "Agricultural Inputs & Equipment",
- "Sustainable & Regenerative Agriculture",
- "Seafood & Aquaculture",
- "Management Consulting",
- "Marketing & Advertising Agencies",
- "Design, Branding & Creative Studios",
- "IT Services & Managed Services",
- "Staffing, Recruiting & Talent",
- "Accounting & Tax Firms",
- "Public Relations & Communications",
- "Business Process Outsourcing (BPO)",
- "Professional Training & Coaching",
- "Specialty Chemicals",
- "Commodity & Petrochemicals",
- "Polymers, Plastics & Rubber",
- "Coatings, Adhesives & Sealants",
- "Industrial Gases",
- "Advanced Materials & Composites",
- "Battery Materials & Energy Storage",
- "Electronic Materials & Semiconductor Chemicals",
- "Agrochemicals & Fertilizers",
- "Freight & Transportation Tech",
- "Last-Mile Delivery",
- "Warehouse Automation",
- "Supply Chain Visibility Platforms",
- "Logistics Marketplaces",
- "Shipping & Freight Forwarding",
- "Cold Chain Logistics",
- "Reverse Logistics & Returns",
- "Cross-Border Trade Tech",
- "Transportation Management Systems (TMS)",
- "Hotels & Accommodation",
- "Vacation Rentals & Short-Term Stays",
- "Restaurant Tech & Management",
- "Travel Booking Platforms",
- "Tourism Experiences & Activities",
- "Cruise Lines & Marine Tourism",
- "Hospitality Management Systems",
- "Event & Venue Management",
- "Corporate Travel Management",
- "Travel Insurance & Protection",
- "Construction Management Software",
- "BIM/CAD & Design Tools",
- "Construction Marketplaces",
- "Equipment Rental & Management",
- "Building Materials & Procurement",
- "Construction Workforce Management",
- "Project Estimation & Bidding",
- "Modular & Prefab Construction",
- "Construction Safety & Compliance",
- "Smart Building Technology",
- "Food & Beverage CPG",
- "Home & Personal Care CPG",
- "CPG Analytics & Insights",
- "Direct-to-Consumer CPG Brands",
- "CPG Supply Chain & Distribution",
- "Private Label Manufacturing",
- "CPG Retail Intelligence",
- "Sustainable CPG & Packaging",
- "Beauty & Cosmetics CPG",
- "Health & Wellness CPG",
- ]
- """Subindustry classification enum"""
-
-
-class BrandIndustries(BaseModel):
- """Industry classification information for the brand"""
-
- eic: Optional[List[BrandIndustriesEic]] = None
- """Easy Industry Classification - array of industry and subindustry pairs"""
-
-
-class BrandLinks(BaseModel):
- """Important website links for the brand"""
-
- blog: Optional[str] = None
- """URL to the brand's blog or news page"""
-
- careers: Optional[str] = None
- """URL to the brand's careers or job opportunities page"""
-
- contact: Optional[str] = None
- """URL to the brand's contact or contact us page"""
-
- pricing: Optional[str] = None
- """URL to the brand's pricing or plans page"""
-
- privacy: Optional[str] = None
- """URL to the brand's privacy policy page"""
-
- terms: Optional[str] = None
- """URL to the brand's terms of service or terms and conditions page"""
-
-
-class BrandLogoColor(BaseModel):
- hex: Optional[str] = None
- """Color in hexadecimal format"""
-
- name: Optional[str] = None
- """Name of the color"""
-
-
-class BrandLogoResolution(BaseModel):
- """Resolution of the logo image"""
-
- aspect_ratio: Optional[float] = None
- """Aspect ratio of the image (width/height)"""
-
- height: Optional[int] = None
- """Height of the image in pixels"""
-
- width: Optional[int] = None
- """Width of the image in pixels"""
-
-
-class BrandLogo(BaseModel):
- colors: Optional[List[BrandLogoColor]] = None
- """Array of colors in the logo"""
-
- mode: Optional[Literal["light", "dark", "has_opaque_background"]] = None
- """
- Indicates when this logo is best used: 'light' = best for light mode, 'dark' =
- best for dark mode, 'has_opaque_background' = can be used for either as image
- has its own background
- """
-
- resolution: Optional[BrandLogoResolution] = None
- """Resolution of the logo image"""
-
- type: Optional[Literal["icon", "logo"]] = None
- """Type of the logo based on resolution (e.g., 'icon', 'logo')"""
-
- url: Optional[str] = None
- """CDN hosted url of the logo (ready for display)"""
-
-
-class BrandSocial(BaseModel):
- type: Optional[
- Literal[
- "x",
- "facebook",
- "instagram",
- "linkedin",
- "youtube",
- "pinterest",
- "tiktok",
- "dribbble",
- "github",
- "behance",
- "snapchat",
- "whatsapp",
- "telegram",
- "line",
- "discord",
- "twitch",
- "vimeo",
- "imdb",
- "tumblr",
- "flickr",
- "giphy",
- "medium",
- "spotify",
- "soundcloud",
- "tripadvisor",
- "yelp",
- "producthunt",
- "reddit",
- "crunchbase",
- "appstore",
- "playstore",
- ]
- ] = None
- """Type of social media platform"""
-
- url: Optional[str] = None
- """URL of the social media page"""
-
-
-class BrandStock(BaseModel):
- """
- Stock market information for this brand (will be null if not a publicly traded company)
- """
-
- exchange: Optional[str] = None
- """Stock exchange name"""
-
- ticker: Optional[str] = None
- """Stock ticker symbol"""
-
-
-class Brand(BaseModel):
- """Detailed brand information"""
-
- address: Optional[BrandAddress] = None
- """Physical address of the brand"""
-
- backdrops: Optional[List[BrandBackdrop]] = None
- """An array of backdrop images for the brand"""
-
- colors: Optional[List[BrandColor]] = None
- """An array of brand colors"""
-
- description: Optional[str] = None
- """A brief description of the brand"""
-
- domain: Optional[str] = None
- """The domain name of the brand"""
-
- email: Optional[str] = None
- """Company email address"""
-
- industries: Optional[BrandIndustries] = None
- """Industry classification information for the brand"""
-
- is_nsfw: Optional[bool] = None
- """Indicates whether the brand content is not safe for work (NSFW)"""
-
- links: Optional[BrandLinks] = None
- """Important website links for the brand"""
-
- logos: Optional[List[BrandLogo]] = None
- """An array of logos associated with the brand"""
-
- phone: Optional[str] = None
- """Company phone number"""
-
- primary_language: Optional[
- Literal[
- "afrikaans",
- "albanian",
- "amharic",
- "arabic",
- "armenian",
- "assamese",
- "aymara",
- "azeri",
- "basque",
- "belarusian",
- "bengali",
- "bosnian",
- "bulgarian",
- "burmese",
- "cantonese",
- "catalan",
- "cebuano",
- "chinese",
- "corsican",
- "croatian",
- "czech",
- "danish",
- "dutch",
- "english",
- "esperanto",
- "estonian",
- "farsi",
- "fijian",
- "finnish",
- "french",
- "galician",
- "georgian",
- "german",
- "greek",
- "guarani",
- "gujarati",
- "haitian-creole",
- "hausa",
- "hawaiian",
- "hebrew",
- "hindi",
- "hmong",
- "hungarian",
- "icelandic",
- "igbo",
- "indonesian",
- "irish",
- "italian",
- "japanese",
- "javanese",
- "kannada",
- "kazakh",
- "khmer",
- "kinyarwanda",
- "korean",
- "kurdish",
- "kyrgyz",
- "lao",
- "latin",
- "latvian",
- "lingala",
- "lithuanian",
- "luxembourgish",
- "macedonian",
- "malagasy",
- "malay",
- "malayalam",
- "maltese",
- "maori",
- "marathi",
- "mongolian",
- "nepali",
- "norwegian",
- "odia",
- "oromo",
- "pashto",
- "pidgin",
- "polish",
- "portuguese",
- "punjabi",
- "quechua",
- "romanian",
- "russian",
- "samoan",
- "scottish-gaelic",
- "serbian",
- "sesotho",
- "shona",
- "sindhi",
- "sinhala",
- "slovak",
- "slovene",
- "somali",
- "spanish",
- "sundanese",
- "swahili",
- "swedish",
- "tagalog",
- "tajik",
- "tamil",
- "tatar",
- "telugu",
- "thai",
- "tibetan",
- "tigrinya",
- "tongan",
- "tswana",
- "turkish",
- "turkmen",
- "ukrainian",
- "urdu",
- "uyghur",
- "uzbek",
- "vietnamese",
- "welsh",
- "wolof",
- "xhosa",
- "yiddish",
- "yoruba",
- "zulu",
- ]
- ] = None
- """The primary language of the brand's website content.
-
- Detected from the HTML lang tag, page content analysis, or social media
- descriptions.
- """
-
- slogan: Optional[str] = None
- """The brand's slogan"""
-
- socials: Optional[List[BrandSocial]] = None
- """An array of social media links for the brand"""
-
- stock: Optional[BrandStock] = None
- """
- Stock market information for this brand (will be null if not a publicly traded
- company)
- """
-
- title: Optional[str] = None
- """The title or name of the brand"""
-
-
-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 BrandRetrieveByTickerResponse(BaseModel):
- brand: Optional[Brand] = None
- """Detailed brand information"""
-
- code: Optional[int] = None
- """HTTP status code"""
-
- 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.
- """
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
diff --git a/src/context/dev/types/brand_retrieve_params.py b/src/context/dev/types/brand_retrieve_params.py
index 2812ab5..2d1b2e1 100644
--- a/src/context/dev/types/brand_retrieve_params.py
+++ b/src/context/dev/types/brand_retrieve_params.py
@@ -2,20 +2,481 @@
from __future__ import annotations
-from typing_extensions import Literal, Required, Annotated, TypedDict
+from typing import Union
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._utils import PropertyInfo
-__all__ = ["BrandRetrieveParams"]
+__all__ = [
+ "BrandRetrieveParams",
+ "BrandRetrieveByDomainRequest",
+ "BrandRetrieveByNameRequest",
+ "BrandRetrieveByEmailRequest",
+ "BrandRetrieveByTickerRequest",
+ "BrandRetrieveFromTransactionRequest",
+]
-class BrandRetrieveParams(TypedDict, total=False):
+class BrandRetrieveByDomainRequest(TypedDict, total=False):
domain: Required[str]
- """Domain name to retrieve brand data for (e.g., 'example.com', 'google.com').
+ """Domain name to retrieve brand data for (e.g., 'stripe.com')."""
- Cannot be used with name or ticker parameters.
+ force_language: Literal[
+ "afrikaans",
+ "albanian",
+ "amharic",
+ "arabic",
+ "armenian",
+ "assamese",
+ "aymara",
+ "azeri",
+ "basque",
+ "belarusian",
+ "bengali",
+ "bosnian",
+ "bulgarian",
+ "burmese",
+ "cantonese",
+ "catalan",
+ "cebuano",
+ "chinese",
+ "corsican",
+ "croatian",
+ "czech",
+ "danish",
+ "dutch",
+ "english",
+ "esperanto",
+ "estonian",
+ "farsi",
+ "fijian",
+ "finnish",
+ "french",
+ "galician",
+ "georgian",
+ "german",
+ "greek",
+ "guarani",
+ "gujarati",
+ "haitian-creole",
+ "hausa",
+ "hawaiian",
+ "hebrew",
+ "hindi",
+ "hmong",
+ "hungarian",
+ "icelandic",
+ "igbo",
+ "indonesian",
+ "irish",
+ "italian",
+ "japanese",
+ "javanese",
+ "kannada",
+ "kazakh",
+ "khmer",
+ "kinyarwanda",
+ "korean",
+ "kurdish",
+ "kyrgyz",
+ "lao",
+ "latin",
+ "latvian",
+ "lingala",
+ "lithuanian",
+ "luxembourgish",
+ "macedonian",
+ "malagasy",
+ "malay",
+ "malayalam",
+ "maltese",
+ "maori",
+ "marathi",
+ "mongolian",
+ "nepali",
+ "norwegian",
+ "odia",
+ "oromo",
+ "pashto",
+ "pidgin",
+ "polish",
+ "portuguese",
+ "punjabi",
+ "quechua",
+ "romanian",
+ "russian",
+ "samoan",
+ "scottish-gaelic",
+ "serbian",
+ "sesotho",
+ "shona",
+ "sindhi",
+ "sinhala",
+ "slovak",
+ "slovene",
+ "somali",
+ "spanish",
+ "sundanese",
+ "swahili",
+ "swedish",
+ "tagalog",
+ "tajik",
+ "tamil",
+ "tatar",
+ "telugu",
+ "thai",
+ "tibetan",
+ "tigrinya",
+ "tongan",
+ "tswana",
+ "turkish",
+ "turkmen",
+ "ukrainian",
+ "urdu",
+ "uyghur",
+ "uzbek",
+ "vietnamese",
+ "welsh",
+ "wolof",
+ "xhosa",
+ "yiddish",
+ "yoruba",
+ "zulu",
+ ]
+
+ max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
+ """
+ Maximum age in milliseconds for cached brand data before the API performs a hard
+ refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
+ are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
+ year.
+ """
+
+ max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
+ """Optional parameter to optimize the API call for maximum speed.
+
+ When set to true, the API will skip time-consuming operations for faster
+ response at the cost of less comprehensive data.
+ """
+
+ timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
+ """Optional timeout in milliseconds for the request.
+
+ If the request takes longer than this value, it will be aborted with a 408
+ status code. Maximum allowed value is 300000ms (5 minutes).
+ """
+
+
+class BrandRetrieveByNameRequest(TypedDict, total=False):
+ name: Required[str]
+ """Company name to retrieve brand data for (e.g., 'Apple Inc')."""
+
+ country_gl: str
+ """
+ Optional country code hint (GL parameter) to specify the country when looking up
+ by company name.
+ """
+
+ force_language: Literal[
+ "afrikaans",
+ "albanian",
+ "amharic",
+ "arabic",
+ "armenian",
+ "assamese",
+ "aymara",
+ "azeri",
+ "basque",
+ "belarusian",
+ "bengali",
+ "bosnian",
+ "bulgarian",
+ "burmese",
+ "cantonese",
+ "catalan",
+ "cebuano",
+ "chinese",
+ "corsican",
+ "croatian",
+ "czech",
+ "danish",
+ "dutch",
+ "english",
+ "esperanto",
+ "estonian",
+ "farsi",
+ "fijian",
+ "finnish",
+ "french",
+ "galician",
+ "georgian",
+ "german",
+ "greek",
+ "guarani",
+ "gujarati",
+ "haitian-creole",
+ "hausa",
+ "hawaiian",
+ "hebrew",
+ "hindi",
+ "hmong",
+ "hungarian",
+ "icelandic",
+ "igbo",
+ "indonesian",
+ "irish",
+ "italian",
+ "japanese",
+ "javanese",
+ "kannada",
+ "kazakh",
+ "khmer",
+ "kinyarwanda",
+ "korean",
+ "kurdish",
+ "kyrgyz",
+ "lao",
+ "latin",
+ "latvian",
+ "lingala",
+ "lithuanian",
+ "luxembourgish",
+ "macedonian",
+ "malagasy",
+ "malay",
+ "malayalam",
+ "maltese",
+ "maori",
+ "marathi",
+ "mongolian",
+ "nepali",
+ "norwegian",
+ "odia",
+ "oromo",
+ "pashto",
+ "pidgin",
+ "polish",
+ "portuguese",
+ "punjabi",
+ "quechua",
+ "romanian",
+ "russian",
+ "samoan",
+ "scottish-gaelic",
+ "serbian",
+ "sesotho",
+ "shona",
+ "sindhi",
+ "sinhala",
+ "slovak",
+ "slovene",
+ "somali",
+ "spanish",
+ "sundanese",
+ "swahili",
+ "swedish",
+ "tagalog",
+ "tajik",
+ "tamil",
+ "tatar",
+ "telugu",
+ "thai",
+ "tibetan",
+ "tigrinya",
+ "tongan",
+ "tswana",
+ "turkish",
+ "turkmen",
+ "ukrainian",
+ "urdu",
+ "uyghur",
+ "uzbek",
+ "vietnamese",
+ "welsh",
+ "wolof",
+ "xhosa",
+ "yiddish",
+ "yoruba",
+ "zulu",
+ ]
+
+ max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
+ """
+ Maximum age in milliseconds for cached brand data before the API performs a hard
+ refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
+ are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
+ year.
+ """
+
+ max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
+ """Optional parameter to optimize the API call for maximum speed.
+
+ When set to true, the API will skip time-consuming operations for faster
+ response at the cost of less comprehensive data.
+ """
+
+ timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
+ """Optional timeout in milliseconds for the request.
+
+ If the request takes longer than this value, it will be aborted with a 408
+ status code. Maximum allowed value is 300000ms (5 minutes).
+ """
+
+
+class BrandRetrieveByEmailRequest(TypedDict, total=False):
+ email: Required[str]
+ """Email address to retrieve brand data for (e.g., 'jane@stripe.com')."""
+
+ force_language: Literal[
+ "afrikaans",
+ "albanian",
+ "amharic",
+ "arabic",
+ "armenian",
+ "assamese",
+ "aymara",
+ "azeri",
+ "basque",
+ "belarusian",
+ "bengali",
+ "bosnian",
+ "bulgarian",
+ "burmese",
+ "cantonese",
+ "catalan",
+ "cebuano",
+ "chinese",
+ "corsican",
+ "croatian",
+ "czech",
+ "danish",
+ "dutch",
+ "english",
+ "esperanto",
+ "estonian",
+ "farsi",
+ "fijian",
+ "finnish",
+ "french",
+ "galician",
+ "georgian",
+ "german",
+ "greek",
+ "guarani",
+ "gujarati",
+ "haitian-creole",
+ "hausa",
+ "hawaiian",
+ "hebrew",
+ "hindi",
+ "hmong",
+ "hungarian",
+ "icelandic",
+ "igbo",
+ "indonesian",
+ "irish",
+ "italian",
+ "japanese",
+ "javanese",
+ "kannada",
+ "kazakh",
+ "khmer",
+ "kinyarwanda",
+ "korean",
+ "kurdish",
+ "kyrgyz",
+ "lao",
+ "latin",
+ "latvian",
+ "lingala",
+ "lithuanian",
+ "luxembourgish",
+ "macedonian",
+ "malagasy",
+ "malay",
+ "malayalam",
+ "maltese",
+ "maori",
+ "marathi",
+ "mongolian",
+ "nepali",
+ "norwegian",
+ "odia",
+ "oromo",
+ "pashto",
+ "pidgin",
+ "polish",
+ "portuguese",
+ "punjabi",
+ "quechua",
+ "romanian",
+ "russian",
+ "samoan",
+ "scottish-gaelic",
+ "serbian",
+ "sesotho",
+ "shona",
+ "sindhi",
+ "sinhala",
+ "slovak",
+ "slovene",
+ "somali",
+ "spanish",
+ "sundanese",
+ "swahili",
+ "swedish",
+ "tagalog",
+ "tajik",
+ "tamil",
+ "tatar",
+ "telugu",
+ "thai",
+ "tibetan",
+ "tigrinya",
+ "tongan",
+ "tswana",
+ "turkish",
+ "turkmen",
+ "ukrainian",
+ "urdu",
+ "uyghur",
+ "uzbek",
+ "vietnamese",
+ "welsh",
+ "wolof",
+ "xhosa",
+ "yiddish",
+ "yoruba",
+ "zulu",
+ ]
+
+ max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
+ """
+ Maximum age in milliseconds for cached brand data before the API performs a hard
+ refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
+ are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
+ year.
+ """
+
+ max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
+ """Optional parameter to optimize the API call for maximum speed.
+
+ When set to true, the API will skip time-consuming operations for faster
+ response at the cost of less comprehensive data.
+ """
+
+ timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
+ """Optional timeout in milliseconds for the request.
+
+ If the request takes longer than this value, it will be aborted with a 408
+ status code. Maximum allowed value is 300000ms (5 minutes).
"""
+
+class BrandRetrieveByTickerRequest(TypedDict, total=False):
+ ticker: Required[str]
+ """Stock ticker symbol to retrieve brand data for (e.g., 'AAPL')."""
+
force_language: Literal[
"afrikaans",
"albanian",
@@ -138,7 +599,6 @@ class BrandRetrieveParams(TypedDict, total=False):
"yoruba",
"zulu",
]
- """Optional parameter to force the language of the retrieved brand data."""
max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
"""
@@ -152,9 +612,177 @@ class BrandRetrieveParams(TypedDict, total=False):
"""Optional parameter to optimize the API call for maximum speed.
When set to true, the API will skip time-consuming operations for faster
- response at the cost of less comprehensive data. Works with all three lookup
- methods.
+ response at the cost of less comprehensive data.
+ """
+
+ ticker_exchange: str
+ """Optional stock exchange for the ticker. Defaults to NASDAQ if not specified."""
+
+ timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
+ """Optional timeout in milliseconds for the request.
+
+ If the request takes longer than this value, it will be aborted with a 408
+ status code. Maximum allowed value is 300000ms (5 minutes).
+ """
+
+
+class BrandRetrieveFromTransactionRequest(TypedDict, total=False):
+ transaction_info: Required[str]
+ """Transaction information to identify the brand."""
+
+ city: str
+ """Optional city name to prioritize when searching for the brand."""
+
+ country_gl: str
+ """
+ Optional country code hint (GL parameter) to specify the country when
+ identifying a transaction.
+ """
+
+ force_language: Literal[
+ "afrikaans",
+ "albanian",
+ "amharic",
+ "arabic",
+ "armenian",
+ "assamese",
+ "aymara",
+ "azeri",
+ "basque",
+ "belarusian",
+ "bengali",
+ "bosnian",
+ "bulgarian",
+ "burmese",
+ "cantonese",
+ "catalan",
+ "cebuano",
+ "chinese",
+ "corsican",
+ "croatian",
+ "czech",
+ "danish",
+ "dutch",
+ "english",
+ "esperanto",
+ "estonian",
+ "farsi",
+ "fijian",
+ "finnish",
+ "french",
+ "galician",
+ "georgian",
+ "german",
+ "greek",
+ "guarani",
+ "gujarati",
+ "haitian-creole",
+ "hausa",
+ "hawaiian",
+ "hebrew",
+ "hindi",
+ "hmong",
+ "hungarian",
+ "icelandic",
+ "igbo",
+ "indonesian",
+ "irish",
+ "italian",
+ "japanese",
+ "javanese",
+ "kannada",
+ "kazakh",
+ "khmer",
+ "kinyarwanda",
+ "korean",
+ "kurdish",
+ "kyrgyz",
+ "lao",
+ "latin",
+ "latvian",
+ "lingala",
+ "lithuanian",
+ "luxembourgish",
+ "macedonian",
+ "malagasy",
+ "malay",
+ "malayalam",
+ "maltese",
+ "maori",
+ "marathi",
+ "mongolian",
+ "nepali",
+ "norwegian",
+ "odia",
+ "oromo",
+ "pashto",
+ "pidgin",
+ "polish",
+ "portuguese",
+ "punjabi",
+ "quechua",
+ "romanian",
+ "russian",
+ "samoan",
+ "scottish-gaelic",
+ "serbian",
+ "sesotho",
+ "shona",
+ "sindhi",
+ "sinhala",
+ "slovak",
+ "slovene",
+ "somali",
+ "spanish",
+ "sundanese",
+ "swahili",
+ "swedish",
+ "tagalog",
+ "tajik",
+ "tamil",
+ "tatar",
+ "telugu",
+ "thai",
+ "tibetan",
+ "tigrinya",
+ "tongan",
+ "tswana",
+ "turkish",
+ "turkmen",
+ "ukrainian",
+ "urdu",
+ "uyghur",
+ "uzbek",
+ "vietnamese",
+ "welsh",
+ "wolof",
+ "xhosa",
+ "yiddish",
+ "yoruba",
+ "zulu",
+ ]
+
+ high_confidence_only: bool
+ """
+ When set to true, the API performs additional verification to ensure the
+ identified brand matches the transaction with high confidence.
+ """
+
+ max_speed: Annotated[bool, PropertyInfo(alias="maxSpeed")]
+ """Optional parameter to optimize the API call for maximum speed.
+
+ When set to true, the API will skip time-consuming operations for faster
+ response at the cost of less comprehensive data.
+ """
+
+ mcc: int
"""
+ Optional Merchant Category Code (MCC) to help identify the business category or
+ industry.
+ """
+
+ phone: float
+ """Optional phone number from the transaction to help verify brand match."""
timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
"""Optional timeout in milliseconds for the request.
@@ -162,3 +790,12 @@ class BrandRetrieveParams(TypedDict, total=False):
If the request takes longer than this value, it will be aborted with a 408
status code. Maximum allowed value is 300000ms (5 minutes).
"""
+
+
+BrandRetrieveParams: TypeAlias = Union[
+ BrandRetrieveByDomainRequest,
+ BrandRetrieveByNameRequest,
+ BrandRetrieveByEmailRequest,
+ BrandRetrieveByTickerRequest,
+ BrandRetrieveFromTransactionRequest,
+]
diff --git a/src/context/dev/types/utility_prefetch_by_email_params.py b/src/context/dev/types/utility_prefetch_by_email_params.py
deleted file mode 100644
index b9a36a8..0000000
--- a/src/context/dev/types/utility_prefetch_by_email_params.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, Annotated, TypedDict
-
-from .._utils import PropertyInfo
-
-__all__ = ["UtilityPrefetchByEmailParams"]
-
-
-class UtilityPrefetchByEmailParams(TypedDict, total=False):
- email: Required[str]
- """Email address to prefetch brand 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.
- """
-
- timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
- """Optional timeout in milliseconds for the request.
-
- If the request takes longer than this value, it will be aborted with a 408
- status code. Maximum allowed value is 300000ms (5 minutes).
- """
diff --git a/src/context/dev/types/utility_prefetch_by_email_response.py b/src/context/dev/types/utility_prefetch_by_email_response.py
deleted file mode 100644
index cf7ee7f..0000000
--- a/src/context/dev/types/utility_prefetch_by_email_response.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from .._models import BaseModel
-
-__all__ = ["UtilityPrefetchByEmailResponse", "KeyMetadata"]
-
-
-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 UtilityPrefetchByEmailResponse(BaseModel):
- domain: Optional[str] = None
- """The domain that was queued for prefetching"""
-
- 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.
- """
-
- message: Optional[str] = None
- """Success message"""
-
- status: Optional[str] = None
- """Status of the response, e.g., 'ok'"""
diff --git a/src/context/dev/types/utility_prefetch_params.py b/src/context/dev/types/utility_prefetch_params.py
index 51993af..ad6b529 100644
--- a/src/context/dev/types/utility_prefetch_params.py
+++ b/src/context/dev/types/utility_prefetch_params.py
@@ -2,16 +2,19 @@
from __future__ import annotations
-from typing_extensions import Required, Annotated, TypedDict
+from typing_extensions import Literal, Required, Annotated, TypedDict
from .._utils import PropertyInfo
-__all__ = ["UtilityPrefetchParams"]
+__all__ = ["UtilityPrefetchParams", "Identifier"]
class UtilityPrefetchParams(TypedDict, total=False):
- domain: Required[str]
- """Domain name to prefetch brand data for"""
+ identifier: Required[Identifier]
+ """Identifier of the brand to prefetch. Provide exactly one of domain or email."""
+
+ type: Required[Literal["brand"]]
+ """What to prefetch. Currently only 'brand' is supported."""
timeout_ms: Annotated[int, PropertyInfo(alias="timeoutMS")]
"""Optional timeout in milliseconds for the request.
@@ -19,3 +22,17 @@ class UtilityPrefetchParams(TypedDict, total=False):
If the request takes longer than this value, it will be aborted with a 408
status code. Maximum allowed value is 300000ms (5 minutes).
"""
+
+
+class Identifier(TypedDict, total=False):
+ """Identifier of the brand to prefetch. Provide exactly one of domain or email."""
+
+ domain: str
+ """Domain name to prefetch brand data for"""
+
+ email: str
+ """Email address to prefetch brand 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 b950e87..346abd0 100644
--- a/src/context/dev/types/utility_prefetch_response.py
+++ b/src/context/dev/types/utility_prefetch_response.py
@@ -1,6 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
from .._models import BaseModel
@@ -36,3 +37,9 @@ 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')
+ """
diff --git a/tests/api_resources/test_ai.py b/tests/api_resources/test_ai.py
index 4635049..1920c36 100644
--- a/tests/api_resources/test_ai.py
+++ b/tests/api_resources/test_ai.py
@@ -10,7 +10,6 @@
from context.dev import ContextDev, AsyncContextDev
from tests.utils import assert_matches_type
from context.dev.types import (
- AIAIQueryResponse,
AIExtractProductResponse,
AIExtractProductsResponse,
)
@@ -21,97 +20,6 @@
class TestAI:
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_ai_query(self, client: ContextDev) -> None:
- ai = client.ai.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- }
- ],
- domain="domain",
- )
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_ai_query_with_all_params(self, client: ContextDev) -> None:
- ai = client.ai.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- "datapoint_list_type": "string",
- "datapoint_object_schema": {
- "testimonial_text": "string",
- "testimonial_author": "string",
- },
- }
- ],
- domain="domain",
- specific_pages={
- "about_us": True,
- "blog": True,
- "careers": True,
- "contact_us": True,
- "faq": True,
- "home_page": True,
- "pricing": True,
- "privacy_policy": True,
- "terms_and_conditions": True,
- },
- timeout_ms=1000,
- )
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_raw_response_ai_query(self, client: ContextDev) -> None:
- response = client.ai.with_raw_response.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- }
- ],
- domain="domain",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- ai = response.parse()
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_ai_query(self, client: ContextDev) -> None:
- with client.ai.with_streaming_response.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- }
- ],
- domain="domain",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- ai = response.parse()
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_extract_product(self, client: ContextDev) -> None:
@@ -252,97 +160,6 @@ class TestAsyncAI:
"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_ai_query(self, async_client: AsyncContextDev) -> None:
- ai = await async_client.ai.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- }
- ],
- domain="domain",
- )
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_ai_query_with_all_params(self, async_client: AsyncContextDev) -> None:
- ai = await async_client.ai.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- "datapoint_list_type": "string",
- "datapoint_object_schema": {
- "testimonial_text": "string",
- "testimonial_author": "string",
- },
- }
- ],
- domain="domain",
- specific_pages={
- "about_us": True,
- "blog": True,
- "careers": True,
- "contact_us": True,
- "faq": True,
- "home_page": True,
- "pricing": True,
- "privacy_policy": True,
- "terms_and_conditions": True,
- },
- timeout_ms=1000,
- )
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_ai_query(self, async_client: AsyncContextDev) -> None:
- response = await async_client.ai.with_raw_response.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- }
- ],
- domain="domain",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- ai = await response.parse()
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_ai_query(self, async_client: AsyncContextDev) -> None:
- async with async_client.ai.with_streaming_response.ai_query(
- data_to_extract=[
- {
- "datapoint_description": "datapoint_description",
- "datapoint_example": "datapoint_example",
- "datapoint_name": "datapoint_name",
- "datapoint_type": "text",
- }
- ],
- domain="domain",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- ai = await response.parse()
- assert_matches_type(AIAIQueryResponse, ai, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_extract_product(self, async_client: AsyncContextDev) -> None:
diff --git a/tests/api_resources/test_brand.py b/tests/api_resources/test_brand.py
index 2a25909..9d0fbf6 100644
--- a/tests/api_resources/test_brand.py
+++ b/tests/api_resources/test_brand.py
@@ -11,12 +11,7 @@
from tests.utils import assert_matches_type
from context.dev.types import (
BrandRetrieveResponse,
- BrandRetrieveByIsinResponse,
- BrandRetrieveByNameResponse,
- BrandRetrieveByEmailResponse,
- BrandRetrieveByTickerResponse,
BrandRetrieveSimplifiedResponse,
- BrandIdentifyFromTransactionResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -27,7 +22,7 @@ class TestBrand:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve(self, client: ContextDev) -> None:
+ def test_method_retrieve_overload_1(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
domain="domain",
)
@@ -35,11 +30,11 @@ def test_method_retrieve(self, client: ContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_with_all_params(self, client: ContextDev) -> None:
+ def test_method_retrieve_with_all_params_overload_1(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
domain="domain",
force_language="afrikaans",
- max_age_ms=86400000,
+ max_age_ms=0,
max_speed=True,
timeout_ms=1000,
)
@@ -47,7 +42,7 @@ def test_method_retrieve_with_all_params(self, client: ContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_retrieve(self, client: ContextDev) -> None:
+ def test_raw_response_retrieve_overload_1(self, client: ContextDev) -> None:
response = client.brand.with_raw_response.retrieve(
domain="domain",
)
@@ -59,7 +54,7 @@ def test_raw_response_retrieve(self, client: ContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_retrieve(self, client: ContextDev) -> None:
+ def test_streaming_response_retrieve_overload_1(self, client: ContextDev) -> None:
with client.brand.with_streaming_response.retrieve(
domain="domain",
) as response:
@@ -73,237 +68,191 @@ def test_streaming_response_retrieve(self, client: ContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_identify_from_transaction(self, client: ContextDev) -> None:
- brand = client.brand.identify_from_transaction(
- transaction_info="transaction_info",
+ def test_method_retrieve_overload_2(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
+ name="xxx",
)
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_identify_from_transaction_with_all_params(self, client: ContextDev) -> None:
- brand = client.brand.identify_from_transaction(
- transaction_info="transaction_info",
- city="city",
- country_gl="ad",
+ def test_method_retrieve_with_all_params_overload_2(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
+ name="xxx",
+ country_gl="country_gl",
force_language="afrikaans",
- high_confidence_only=True,
+ max_age_ms=0,
max_speed=True,
- mcc="mcc",
- phone=0,
timeout_ms=1000,
)
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_identify_from_transaction(self, client: ContextDev) -> None:
- response = client.brand.with_raw_response.identify_from_transaction(
- transaction_info="transaction_info",
+ def test_raw_response_retrieve_overload_2(self, client: ContextDev) -> None:
+ response = client.brand.with_raw_response.retrieve(
+ name="xxx",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_identify_from_transaction(self, client: ContextDev) -> None:
- with client.brand.with_streaming_response.identify_from_transaction(
- transaction_info="transaction_info",
+ def test_streaming_response_retrieve_overload_2(self, client: ContextDev) -> None:
+ with client.brand.with_streaming_response.retrieve(
+ name="xxx",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_by_email(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_email(
+ def test_method_retrieve_overload_3(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
email="dev@stainless.com",
)
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_by_email_with_all_params(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_email(
+ def test_method_retrieve_with_all_params_overload_3(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
email="dev@stainless.com",
force_language="afrikaans",
- max_age_ms=86400000,
+ max_age_ms=0,
max_speed=True,
timeout_ms=1000,
)
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_retrieve_by_email(self, client: ContextDev) -> None:
- response = client.brand.with_raw_response.retrieve_by_email(
+ def test_raw_response_retrieve_overload_3(self, client: ContextDev) -> None:
+ response = client.brand.with_raw_response.retrieve(
email="dev@stainless.com",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_retrieve_by_email(self, client: ContextDev) -> None:
- with client.brand.with_streaming_response.retrieve_by_email(
+ def test_streaming_response_retrieve_overload_3(self, client: ContextDev) -> None:
+ with client.brand.with_streaming_response.retrieve(
email="dev@stainless.com",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_retrieve_by_isin(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_isin(
- isin="SE60513A9993",
- )
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_retrieve_by_isin_with_all_params(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_isin(
- isin="SE60513A9993",
- force_language="afrikaans",
- max_age_ms=86400000,
- max_speed=True,
- timeout_ms=1000,
- )
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_raw_response_retrieve_by_isin(self, client: ContextDev) -> None:
- response = client.brand.with_raw_response.retrieve_by_isin(
- isin="SE60513A9993",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- brand = response.parse()
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_retrieve_by_isin(self, client: ContextDev) -> None:
- with client.brand.with_streaming_response.retrieve_by_isin(
- isin="SE60513A9993",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- brand = response.parse()
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_by_name(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_name(
- name="xxx",
+ def test_method_retrieve_overload_4(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
+ ticker="ticker",
)
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_by_name_with_all_params(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_name(
- name="xxx",
- country_gl="ad",
+ def test_method_retrieve_with_all_params_overload_4(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
+ ticker="ticker",
force_language="afrikaans",
- max_age_ms=86400000,
+ max_age_ms=0,
max_speed=True,
+ ticker_exchange="ticker_exchange",
timeout_ms=1000,
)
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_retrieve_by_name(self, client: ContextDev) -> None:
- response = client.brand.with_raw_response.retrieve_by_name(
- name="xxx",
+ def test_raw_response_retrieve_overload_4(self, client: ContextDev) -> None:
+ response = client.brand.with_raw_response.retrieve(
+ ticker="ticker",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_retrieve_by_name(self, client: ContextDev) -> None:
- with client.brand.with_streaming_response.retrieve_by_name(
- name="xxx",
+ def test_streaming_response_retrieve_overload_4(self, client: ContextDev) -> None:
+ with client.brand.with_streaming_response.retrieve(
+ ticker="ticker",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_by_ticker(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_ticker(
- ticker="ticker",
+ def test_method_retrieve_overload_5(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
+ transaction_info="xxx",
)
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_retrieve_by_ticker_with_all_params(self, client: ContextDev) -> None:
- brand = client.brand.retrieve_by_ticker(
- ticker="ticker",
+ def test_method_retrieve_with_all_params_overload_5(self, client: ContextDev) -> None:
+ brand = client.brand.retrieve(
+ transaction_info="xxx",
+ city="city",
+ country_gl="country_gl",
force_language="afrikaans",
- max_age_ms=86400000,
+ high_confidence_only=True,
max_speed=True,
- ticker_exchange="AMEX",
+ mcc=0,
+ phone=0,
timeout_ms=1000,
)
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_retrieve_by_ticker(self, client: ContextDev) -> None:
- response = client.brand.with_raw_response.retrieve_by_ticker(
- ticker="ticker",
+ def test_raw_response_retrieve_overload_5(self, client: ContextDev) -> None:
+ response = client.brand.with_raw_response.retrieve(
+ transaction_info="xxx",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_retrieve_by_ticker(self, client: ContextDev) -> None:
- with client.brand.with_streaming_response.retrieve_by_ticker(
- ticker="ticker",
+ def test_streaming_response_retrieve_overload_5(self, client: ContextDev) -> None:
+ with client.brand.with_streaming_response.retrieve(
+ transaction_info="xxx",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = response.parse()
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -359,7 +308,7 @@ class TestAsyncBrand:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_retrieve(self, async_client: AsyncContextDev) -> None:
+ async def test_method_retrieve_overload_1(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
domain="domain",
)
@@ -367,11 +316,11 @@ async def test_method_retrieve(self, async_client: AsyncContextDev) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_retrieve_with_all_params(self, async_client: AsyncContextDev) -> None:
+ async def test_method_retrieve_with_all_params_overload_1(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
domain="domain",
force_language="afrikaans",
- max_age_ms=86400000,
+ max_age_ms=0,
max_speed=True,
timeout_ms=1000,
)
@@ -379,7 +328,7 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncContextD
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncContextDev) -> None:
+ async def test_raw_response_retrieve_overload_1(self, async_client: AsyncContextDev) -> None:
response = await async_client.brand.with_raw_response.retrieve(
domain="domain",
)
@@ -391,7 +340,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncContextDev) -> Non
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncContextDev) -> None:
+ async def test_streaming_response_retrieve_overload_1(self, async_client: AsyncContextDev) -> None:
async with async_client.brand.with_streaming_response.retrieve(
domain="domain",
) as response:
@@ -405,237 +354,191 @@ async def test_streaming_response_retrieve(self, async_client: AsyncContextDev)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_identify_from_transaction(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.identify_from_transaction(
- transaction_info="transaction_info",
+ async def test_method_retrieve_overload_2(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
+ name="xxx",
)
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_identify_from_transaction_with_all_params(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.identify_from_transaction(
- transaction_info="transaction_info",
- city="city",
- country_gl="ad",
+ async def test_method_retrieve_with_all_params_overload_2(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
+ name="xxx",
+ country_gl="country_gl",
force_language="afrikaans",
- high_confidence_only=True,
+ max_age_ms=0,
max_speed=True,
- mcc="mcc",
- phone=0,
timeout_ms=1000,
)
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_identify_from_transaction(self, async_client: AsyncContextDev) -> None:
- response = await async_client.brand.with_raw_response.identify_from_transaction(
- transaction_info="transaction_info",
+ async def test_raw_response_retrieve_overload_2(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.brand.with_raw_response.retrieve(
+ name="xxx",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_identify_from_transaction(self, async_client: AsyncContextDev) -> None:
- async with async_client.brand.with_streaming_response.identify_from_transaction(
- transaction_info="transaction_info",
+ async def test_streaming_response_retrieve_overload_2(self, async_client: AsyncContextDev) -> None:
+ async with async_client.brand.with_streaming_response.retrieve(
+ name="xxx",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandIdentifyFromTransactionResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, 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_retrieve_by_email(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_email(
+ async def test_method_retrieve_overload_3(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
email="dev@stainless.com",
)
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_retrieve_by_email_with_all_params(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_email(
+ async def test_method_retrieve_with_all_params_overload_3(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
email="dev@stainless.com",
force_language="afrikaans",
- max_age_ms=86400000,
+ max_age_ms=0,
max_speed=True,
timeout_ms=1000,
)
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_retrieve_by_email(self, async_client: AsyncContextDev) -> None:
- response = await async_client.brand.with_raw_response.retrieve_by_email(
+ async def test_raw_response_retrieve_overload_3(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.brand.with_raw_response.retrieve(
email="dev@stainless.com",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandRetrieveByEmailResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_retrieve_by_email(self, async_client: AsyncContextDev) -> None:
- async with async_client.brand.with_streaming_response.retrieve_by_email(
+ async def test_streaming_response_retrieve_overload_3(self, async_client: AsyncContextDev) -> None:
+ async with async_client.brand.with_streaming_response.retrieve(
email="dev@stainless.com",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandRetrieveByEmailResponse, 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_retrieve_by_isin(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_isin(
- isin="SE60513A9993",
- )
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_retrieve_by_isin_with_all_params(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_isin(
- isin="SE60513A9993",
- force_language="afrikaans",
- max_age_ms=86400000,
- max_speed=True,
- timeout_ms=1000,
- )
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_retrieve_by_isin(self, async_client: AsyncContextDev) -> None:
- response = await async_client.brand.with_raw_response.retrieve_by_isin(
- isin="SE60513A9993",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- brand = await response.parse()
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_retrieve_by_isin(self, async_client: AsyncContextDev) -> None:
- async with async_client.brand.with_streaming_response.retrieve_by_isin(
- isin="SE60513A9993",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- brand = await response.parse()
- assert_matches_type(BrandRetrieveByIsinResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, 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_retrieve_by_name(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_name(
- name="xxx",
+ async def test_method_retrieve_overload_4(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
+ ticker="ticker",
)
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_retrieve_by_name_with_all_params(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_name(
- name="xxx",
- country_gl="ad",
+ async def test_method_retrieve_with_all_params_overload_4(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
+ ticker="ticker",
force_language="afrikaans",
- max_age_ms=86400000,
+ max_age_ms=0,
max_speed=True,
+ ticker_exchange="ticker_exchange",
timeout_ms=1000,
)
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_retrieve_by_name(self, async_client: AsyncContextDev) -> None:
- response = await async_client.brand.with_raw_response.retrieve_by_name(
- name="xxx",
+ async def test_raw_response_retrieve_overload_4(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.brand.with_raw_response.retrieve(
+ ticker="ticker",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_retrieve_by_name(self, async_client: AsyncContextDev) -> None:
- async with async_client.brand.with_streaming_response.retrieve_by_name(
- name="xxx",
+ async def test_streaming_response_retrieve_overload_4(self, async_client: AsyncContextDev) -> None:
+ async with async_client.brand.with_streaming_response.retrieve(
+ ticker="ticker",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandRetrieveByNameResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, 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_retrieve_by_ticker(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_ticker(
- ticker="ticker",
+ async def test_method_retrieve_overload_5(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
+ transaction_info="xxx",
)
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_retrieve_by_ticker_with_all_params(self, async_client: AsyncContextDev) -> None:
- brand = await async_client.brand.retrieve_by_ticker(
- ticker="ticker",
+ async def test_method_retrieve_with_all_params_overload_5(self, async_client: AsyncContextDev) -> None:
+ brand = await async_client.brand.retrieve(
+ transaction_info="xxx",
+ city="city",
+ country_gl="country_gl",
force_language="afrikaans",
- max_age_ms=86400000,
+ high_confidence_only=True,
max_speed=True,
- ticker_exchange="AMEX",
+ mcc=0,
+ phone=0,
timeout_ms=1000,
)
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_retrieve_by_ticker(self, async_client: AsyncContextDev) -> None:
- response = await async_client.brand.with_raw_response.retrieve_by_ticker(
- ticker="ticker",
+ async def test_raw_response_retrieve_overload_5(self, async_client: AsyncContextDev) -> None:
+ response = await async_client.brand.with_raw_response.retrieve(
+ transaction_info="xxx",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_retrieve_by_ticker(self, async_client: AsyncContextDev) -> None:
- async with async_client.brand.with_streaming_response.retrieve_by_ticker(
- ticker="ticker",
+ async def test_streaming_response_retrieve_overload_5(self, async_client: AsyncContextDev) -> None:
+ async with async_client.brand.with_streaming_response.retrieve(
+ transaction_info="xxx",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
brand = await response.parse()
- assert_matches_type(BrandRetrieveByTickerResponse, brand, path=["response"])
+ assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_utility.py b/tests/api_resources/test_utility.py
index 112de67..2c7dfd1 100644
--- a/tests/api_resources/test_utility.py
+++ b/tests/api_resources/test_utility.py
@@ -9,10 +9,7 @@
from context.dev import ContextDev, AsyncContextDev
from tests.utils import assert_matches_type
-from context.dev.types import (
- UtilityPrefetchResponse,
- UtilityPrefetchByEmailResponse,
-)
+from context.dev.types import UtilityPrefetchResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -24,7 +21,8 @@ class TestUtility:
@parametrize
def test_method_prefetch(self, client: ContextDev) -> None:
utility = client.utility.prefetch(
- domain="domain",
+ identifier={},
+ type="brand",
)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
@@ -32,7 +30,11 @@ def test_method_prefetch(self, client: ContextDev) -> None:
@parametrize
def test_method_prefetch_with_all_params(self, client: ContextDev) -> None:
utility = client.utility.prefetch(
- domain="domain",
+ identifier={
+ "domain": "domain",
+ "email": "dev@stainless.com",
+ },
+ type="brand",
timeout_ms=1000,
)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
@@ -41,7 +43,8 @@ def test_method_prefetch_with_all_params(self, client: ContextDev) -> None:
@parametrize
def test_raw_response_prefetch(self, client: ContextDev) -> None:
response = client.utility.with_raw_response.prefetch(
- domain="domain",
+ identifier={},
+ type="brand",
)
assert response.is_closed is True
@@ -53,7 +56,8 @@ def test_raw_response_prefetch(self, client: ContextDev) -> None:
@parametrize
def test_streaming_response_prefetch(self, client: ContextDev) -> None:
with client.utility.with_streaming_response.prefetch(
- domain="domain",
+ identifier={},
+ type="brand",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -63,49 +67,6 @@ def test_streaming_response_prefetch(self, client: ContextDev) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_prefetch_by_email(self, client: ContextDev) -> None:
- utility = client.utility.prefetch_by_email(
- email="dev@stainless.com",
- )
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_prefetch_by_email_with_all_params(self, client: ContextDev) -> None:
- utility = client.utility.prefetch_by_email(
- email="dev@stainless.com",
- timeout_ms=1000,
- )
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_raw_response_prefetch_by_email(self, client: ContextDev) -> None:
- response = client.utility.with_raw_response.prefetch_by_email(
- email="dev@stainless.com",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- utility = response.parse()
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_prefetch_by_email(self, client: ContextDev) -> None:
- with client.utility.with_streaming_response.prefetch_by_email(
- email="dev@stainless.com",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- utility = response.parse()
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
class TestAsyncUtility:
parametrize = pytest.mark.parametrize(
@@ -116,7 +77,8 @@ class TestAsyncUtility:
@parametrize
async def test_method_prefetch(self, async_client: AsyncContextDev) -> None:
utility = await async_client.utility.prefetch(
- domain="domain",
+ identifier={},
+ type="brand",
)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
@@ -124,7 +86,11 @@ async def test_method_prefetch(self, async_client: AsyncContextDev) -> None:
@parametrize
async def test_method_prefetch_with_all_params(self, async_client: AsyncContextDev) -> None:
utility = await async_client.utility.prefetch(
- domain="domain",
+ identifier={
+ "domain": "domain",
+ "email": "dev@stainless.com",
+ },
+ type="brand",
timeout_ms=1000,
)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
@@ -133,7 +99,8 @@ async def test_method_prefetch_with_all_params(self, async_client: AsyncContextD
@parametrize
async def test_raw_response_prefetch(self, async_client: AsyncContextDev) -> None:
response = await async_client.utility.with_raw_response.prefetch(
- domain="domain",
+ identifier={},
+ type="brand",
)
assert response.is_closed is True
@@ -145,7 +112,8 @@ async def test_raw_response_prefetch(self, async_client: AsyncContextDev) -> Non
@parametrize
async def test_streaming_response_prefetch(self, async_client: AsyncContextDev) -> None:
async with async_client.utility.with_streaming_response.prefetch(
- domain="domain",
+ identifier={},
+ type="brand",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -154,46 +122,3 @@ async def test_streaming_response_prefetch(self, async_client: AsyncContextDev)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_prefetch_by_email(self, async_client: AsyncContextDev) -> None:
- utility = await async_client.utility.prefetch_by_email(
- email="dev@stainless.com",
- )
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_prefetch_by_email_with_all_params(self, async_client: AsyncContextDev) -> None:
- utility = await async_client.utility.prefetch_by_email(
- email="dev@stainless.com",
- timeout_ms=1000,
- )
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_prefetch_by_email(self, async_client: AsyncContextDev) -> None:
- response = await async_client.utility.with_raw_response.prefetch_by_email(
- email="dev@stainless.com",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- utility = await response.parse()
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_prefetch_by_email(self, async_client: AsyncContextDev) -> None:
- async with async_client.utility.with_streaming_response.prefetch_by_email(
- email="dev@stainless.com",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- utility = await response.parse()
- assert_matches_type(UtilityPrefetchByEmailResponse, utility, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/test_client.py b/tests/test_client.py
index 0dfc394..c30fd00 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -883,20 +883,36 @@ def test_parse_retry_after_header(
@mock.patch("context.dev._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: ContextDev) -> None:
- respx_mock.get("/brand/retrieve").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.post("/web/extract").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.brand.with_streaming_response.retrieve(domain="domain").__enter__()
+ client.web.with_streaming_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ ).__enter__()
assert _get_open_connections(client) == 0
@mock.patch("context.dev._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: ContextDev) -> None:
- respx_mock.get("/brand/retrieve").mock(return_value=httpx.Response(500))
+ respx_mock.post("/web/extract").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.brand.with_streaming_response.retrieve(domain="domain").__enter__()
+ client.web.with_streaming_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ ).__enter__()
assert _get_open_connections(client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -923,9 +939,17 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/brand/retrieve").mock(side_effect=retry_handler)
+ respx_mock.post("/web/extract").mock(side_effect=retry_handler)
- response = client.brand.with_raw_response.retrieve(domain="domain")
+ response = client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ )
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -947,10 +971,17 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/brand/retrieve").mock(side_effect=retry_handler)
+ respx_mock.post("/web/extract").mock(side_effect=retry_handler)
- response = client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": Omit()}
+ response = client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ extra_headers={"x-stainless-retry-count": Omit()},
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -972,10 +1003,17 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/brand/retrieve").mock(side_effect=retry_handler)
+ respx_mock.post("/web/extract").mock(side_effect=retry_handler)
- response = client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": "42"}
+ response = client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ extra_headers={"x-stainless-retry-count": "42"},
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1821,10 +1859,18 @@ async def test_parse_retry_after_header(
async def test_retrying_timeout_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncContextDev
) -> None:
- respx_mock.get("/brand/retrieve").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.post("/web/extract").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.brand.with_streaming_response.retrieve(domain="domain").__aenter__()
+ await async_client.web.with_streaming_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ ).__aenter__()
assert _get_open_connections(async_client) == 0
@@ -1833,10 +1879,18 @@ async def test_retrying_timeout_errors_doesnt_leak(
async def test_retrying_status_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncContextDev
) -> None:
- respx_mock.get("/brand/retrieve").mock(return_value=httpx.Response(500))
+ respx_mock.post("/web/extract").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.brand.with_streaming_response.retrieve(domain="domain").__aenter__()
+ await async_client.web.with_streaming_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ ).__aenter__()
assert _get_open_connections(async_client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1863,9 +1917,17 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/brand/retrieve").mock(side_effect=retry_handler)
+ respx_mock.post("/web/extract").mock(side_effect=retry_handler)
- response = await client.brand.with_raw_response.retrieve(domain="domain")
+ response = await client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ )
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1887,10 +1949,17 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/brand/retrieve").mock(side_effect=retry_handler)
+ respx_mock.post("/web/extract").mock(side_effect=retry_handler)
- response = await client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": Omit()}
+ response = await client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ extra_headers={"x-stainless-retry-count": Omit()},
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1912,10 +1981,17 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.get("/brand/retrieve").mock(side_effect=retry_handler)
+ respx_mock.post("/web/extract").mock(side_effect=retry_handler)
- response = await client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": "42"}
+ response = await client.web.with_raw_response.extract(
+ schema={
+ "type": "bar",
+ "properties": "bar",
+ "required": "bar",
+ "additionalProperties": "bar",
+ },
+ url="https://example.com",
+ extra_headers={"x-stainless-retry-count": "42"},
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From 4aa172e6efe35e35b050168b4f4ab3102651a935 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 05:33:16 +0000
Subject: [PATCH 15/18] feat(api): manual updates
---
.stats.yml | 4 +-
README.md | 90 ++++++++-----------------------
tests/test_client.py | 124 +++++++++----------------------------------
3 files changed, 47 insertions(+), 171 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 151723e..0ae96ea 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 29
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-2e40370ce4d7d019b30d43020674bb02aaaf2a67a8916772084815c874f99950.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-9de98d1d4d2c9a431961599cb54716212c06200a919e09adedd42244038ec07b.yml
openapi_spec_hash: a44b7d4172c8c7cd395237738867d5cb
-config_hash: 472cc1adb51663e5b3d8dce16f6d29d9
+config_hash: ff35e224e809656528c44163aa41bebd
diff --git a/README.md b/README.md
index d8ce5e8..366323c 100644
--- a/README.md
+++ b/README.md
@@ -41,16 +41,10 @@ client = ContextDev(
api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted
)
-response = client.web.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+brand = client.brand.retrieve(
+ domain="REPLACE_ME",
)
-print(response.data)
+print(brand.brand)
```
While you can provide an `api_key` keyword argument,
@@ -73,16 +67,10 @@ client = AsyncContextDev(
async def main() -> None:
- response = await client.web.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+ brand = await client.brand.retrieve(
+ domain="REPLACE_ME",
)
- print(response.data)
+ print(brand.brand)
asyncio.run(main())
@@ -115,16 +103,10 @@ async def main() -> None:
api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted
http_client=DefaultAioHttpClient(),
) as client:
- response = await client.web.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+ brand = await client.brand.retrieve(
+ domain="REPLACE_ME",
)
- print(response.data)
+ print(brand.brand)
asyncio.run(main())
@@ -177,14 +159,8 @@ from context.dev import ContextDev
client = ContextDev()
try:
- client.web.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+ client.brand.retrieve(
+ domain="REPLACE_ME",
)
except context.dev.APIConnectionError as e:
print("The server could not be reached")
@@ -228,14 +204,8 @@ client = ContextDev(
)
# Or, configure per-request:
-client.with_options(max_retries=5).web.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+client.with_options(max_retries=5).brand.retrieve(
+ domain="REPLACE_ME",
)
```
@@ -259,14 +229,8 @@ client = ContextDev(
)
# Override per-request:
-client.with_options(timeout=5.0).web.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+client.with_options(timeout=5.0).brand.retrieve(
+ domain="REPLACE_ME",
)
```
@@ -308,19 +272,13 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
from context.dev import ContextDev
client = ContextDev()
-response = client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+response = client.brand.with_raw_response.retrieve(
+ domain="REPLACE_ME",
)
print(response.headers.get('X-My-Header'))
-web = response.parse() # get the object that `web.extract()` would have returned
-print(web.data)
+brand = response.parse() # get the object that `brand.retrieve()` would have returned
+print(brand.brand)
```
These methods return an [`APIResponse`](https://github.com/context-dot-dev/context-python-sdk/tree/main/src/context/dev/_response.py) object.
@@ -334,14 +292,8 @@ The above interface eagerly reads the full response body when you make the reque
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.
```python
-with client.web.with_streaming_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
+with client.brand.with_streaming_response.retrieve(
+ domain="REPLACE_ME",
) as response:
print(response.headers.get("X-My-Header"))
diff --git a/tests/test_client.py b/tests/test_client.py
index c30fd00..951eedf 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -883,36 +883,20 @@ def test_parse_retry_after_header(
@mock.patch("context.dev._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: ContextDev) -> None:
- respx_mock.post("/web/extract").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.post("/brand/retrieve").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.web.with_streaming_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- ).__enter__()
+ client.brand.with_streaming_response.retrieve(domain="domain").__enter__()
assert _get_open_connections(client) == 0
@mock.patch("context.dev._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
@pytest.mark.respx(base_url=base_url)
def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: ContextDev) -> None:
- respx_mock.post("/web/extract").mock(return_value=httpx.Response(500))
+ respx_mock.post("/brand/retrieve").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.web.with_streaming_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- ).__enter__()
+ client.brand.with_streaming_response.retrieve(domain="domain").__enter__()
assert _get_open_connections(client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -939,17 +923,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/web/extract").mock(side_effect=retry_handler)
+ respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- )
+ response = client.brand.with_raw_response.retrieve(domain="domain")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -971,17 +947,10 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/web/extract").mock(side_effect=retry_handler)
+ respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- extra_headers={"x-stainless-retry-count": Omit()},
+ response = client.brand.with_raw_response.retrieve(
+ domain="domain", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1003,17 +972,10 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/web/extract").mock(side_effect=retry_handler)
+ respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- extra_headers={"x-stainless-retry-count": "42"},
+ response = client.brand.with_raw_response.retrieve(
+ domain="domain", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1859,18 +1821,10 @@ async def test_parse_retry_after_header(
async def test_retrying_timeout_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncContextDev
) -> None:
- respx_mock.post("/web/extract").mock(side_effect=httpx.TimeoutException("Test timeout error"))
+ respx_mock.post("/brand/retrieve").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.web.with_streaming_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- ).__aenter__()
+ await async_client.brand.with_streaming_response.retrieve(domain="domain").__aenter__()
assert _get_open_connections(async_client) == 0
@@ -1879,18 +1833,10 @@ async def test_retrying_timeout_errors_doesnt_leak(
async def test_retrying_status_errors_doesnt_leak(
self, respx_mock: MockRouter, async_client: AsyncContextDev
) -> None:
- respx_mock.post("/web/extract").mock(return_value=httpx.Response(500))
+ respx_mock.post("/brand/retrieve").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.web.with_streaming_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- ).__aenter__()
+ await async_client.brand.with_streaming_response.retrieve(domain="domain").__aenter__()
assert _get_open_connections(async_client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1917,17 +1863,9 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/web/extract").mock(side_effect=retry_handler)
+ respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = await client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- )
+ response = await client.brand.with_raw_response.retrieve(domain="domain")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1949,17 +1887,10 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/web/extract").mock(side_effect=retry_handler)
+ respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = await client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- extra_headers={"x-stainless-retry-count": Omit()},
+ response = await client.brand.with_raw_response.retrieve(
+ domain="domain", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1981,17 +1912,10 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
return httpx.Response(500)
return httpx.Response(200)
- respx_mock.post("/web/extract").mock(side_effect=retry_handler)
+ respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = await client.web.with_raw_response.extract(
- schema={
- "type": "bar",
- "properties": "bar",
- "required": "bar",
- "additionalProperties": "bar",
- },
- url="https://example.com",
- extra_headers={"x-stainless-retry-count": "42"},
+ response = await client.brand.with_raw_response.retrieve(
+ domain="domain", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From 79826c4324757cb3f32a4a0392d94d7093d39562 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 05:45:04 +0000
Subject: [PATCH 16/18] feat(api): api update
---
.stats.yml | 4 +--
.../dev/types/utility_prefetch_params.py | 25 ++++++++++++++-----
tests/api_resources/test_utility.py | 22 ++++++----------
3 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0ae96ea..c36fec2 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 29
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-9de98d1d4d2c9a431961599cb54716212c06200a919e09adedd42244038ec07b.yml
-openapi_spec_hash: a44b7d4172c8c7cd395237738867d5cb
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-5280c0f42603633a06d2404b120b98d0d9aa43256d13680bbdead7579a90452a.yml
+openapi_spec_hash: 34869d638c12bf076949bb7e050dd634
config_hash: ff35e224e809656528c44163aa41bebd
diff --git a/src/context/dev/types/utility_prefetch_params.py b/src/context/dev/types/utility_prefetch_params.py
index ad6b529..05d5a10 100644
--- a/src/context/dev/types/utility_prefetch_params.py
+++ b/src/context/dev/types/utility_prefetch_params.py
@@ -2,11 +2,17 @@
from __future__ import annotations
-from typing_extensions import Literal, Required, Annotated, TypedDict
+from typing import Union
+from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict
from .._utils import PropertyInfo
-__all__ = ["UtilityPrefetchParams", "Identifier"]
+__all__ = [
+ "UtilityPrefetchParams",
+ "Identifier",
+ "IdentifierUtilityPrefetchDomainIdentifier",
+ "IdentifierUtilityPrefetchEmailIdentifier",
+]
class UtilityPrefetchParams(TypedDict, total=False):
@@ -24,15 +30,22 @@ class UtilityPrefetchParams(TypedDict, total=False):
"""
-class Identifier(TypedDict, total=False):
- """Identifier of the brand to prefetch. Provide exactly one of domain or email."""
+class IdentifierUtilityPrefetchDomainIdentifier(TypedDict, total=False):
+ """Prefetch brand data by domain."""
- domain: str
+ domain: Required[str]
"""Domain name to prefetch brand data for"""
- email: str
+
+class IdentifierUtilityPrefetchEmailIdentifier(TypedDict, total=False):
+ """Prefetch brand data by email. The domain will be extracted and validated."""
+
+ email: Required[str]
"""Email address to prefetch brand 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.
"""
+
+
+Identifier: TypeAlias = Union[IdentifierUtilityPrefetchDomainIdentifier, IdentifierUtilityPrefetchEmailIdentifier]
diff --git a/tests/api_resources/test_utility.py b/tests/api_resources/test_utility.py
index 2c7dfd1..a4b6cdf 100644
--- a/tests/api_resources/test_utility.py
+++ b/tests/api_resources/test_utility.py
@@ -21,7 +21,7 @@ class TestUtility:
@parametrize
def test_method_prefetch(self, client: ContextDev) -> None:
utility = client.utility.prefetch(
- identifier={},
+ identifier={"domain": "domain"},
type="brand",
)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
@@ -30,10 +30,7 @@ def test_method_prefetch(self, client: ContextDev) -> None:
@parametrize
def test_method_prefetch_with_all_params(self, client: ContextDev) -> None:
utility = client.utility.prefetch(
- identifier={
- "domain": "domain",
- "email": "dev@stainless.com",
- },
+ identifier={"domain": "domain"},
type="brand",
timeout_ms=1000,
)
@@ -43,7 +40,7 @@ def test_method_prefetch_with_all_params(self, client: ContextDev) -> None:
@parametrize
def test_raw_response_prefetch(self, client: ContextDev) -> None:
response = client.utility.with_raw_response.prefetch(
- identifier={},
+ identifier={"domain": "domain"},
type="brand",
)
@@ -56,7 +53,7 @@ def test_raw_response_prefetch(self, client: ContextDev) -> None:
@parametrize
def test_streaming_response_prefetch(self, client: ContextDev) -> None:
with client.utility.with_streaming_response.prefetch(
- identifier={},
+ identifier={"domain": "domain"},
type="brand",
) as response:
assert not response.is_closed
@@ -77,7 +74,7 @@ class TestAsyncUtility:
@parametrize
async def test_method_prefetch(self, async_client: AsyncContextDev) -> None:
utility = await async_client.utility.prefetch(
- identifier={},
+ identifier={"domain": "domain"},
type="brand",
)
assert_matches_type(UtilityPrefetchResponse, utility, path=["response"])
@@ -86,10 +83,7 @@ async def test_method_prefetch(self, async_client: AsyncContextDev) -> None:
@parametrize
async def test_method_prefetch_with_all_params(self, async_client: AsyncContextDev) -> None:
utility = await async_client.utility.prefetch(
- identifier={
- "domain": "domain",
- "email": "dev@stainless.com",
- },
+ identifier={"domain": "domain"},
type="brand",
timeout_ms=1000,
)
@@ -99,7 +93,7 @@ async def test_method_prefetch_with_all_params(self, async_client: AsyncContextD
@parametrize
async def test_raw_response_prefetch(self, async_client: AsyncContextDev) -> None:
response = await async_client.utility.with_raw_response.prefetch(
- identifier={},
+ identifier={"domain": "domain"},
type="brand",
)
@@ -112,7 +106,7 @@ async def test_raw_response_prefetch(self, async_client: AsyncContextDev) -> Non
@parametrize
async def test_streaming_response_prefetch(self, async_client: AsyncContextDev) -> None:
async with async_client.utility.with_streaming_response.prefetch(
- identifier={},
+ identifier={"domain": "domain"},
type="brand",
) as response:
assert not response.is_closed
From f63569e84571a403cd05fbff990ea991b83e0821 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 07:05:26 +0000
Subject: [PATCH 17/18] feat(api): api update
---
.stats.yml | 4 +-
README.md | 8 +++
src/context/dev/resources/brand.py | 50 ++++++++++++++++++-
.../dev/types/brand_retrieve_params.py | 15 ++++++
tests/api_resources/test_brand.py | 40 +++++++++++++++
tests/test_client.py | 20 ++++----
6 files changed, 123 insertions(+), 14 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c36fec2..f52f430 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 29
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-5280c0f42603633a06d2404b120b98d0d9aa43256d13680bbdead7579a90452a.yml
-openapi_spec_hash: 34869d638c12bf076949bb7e050dd634
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-7dbd739a81e6aaf7fc7ef1858606e7d572d309af55082a66431d9292e655e66f.yml
+openapi_spec_hash: a6374d5d718a7bd9d3d54fb657e2bd9d
config_hash: ff35e224e809656528c44163aa41bebd
diff --git a/README.md b/README.md
index 366323c..98acec8 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,7 @@ client = ContextDev(
brand = client.brand.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
print(brand.brand)
```
@@ -69,6 +70,7 @@ client = AsyncContextDev(
async def main() -> None:
brand = await client.brand.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
print(brand.brand)
@@ -105,6 +107,7 @@ async def main() -> None:
) as client:
brand = await client.brand.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
print(brand.brand)
@@ -161,6 +164,7 @@ client = ContextDev()
try:
client.brand.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
except context.dev.APIConnectionError as e:
print("The server could not be reached")
@@ -206,6 +210,7 @@ client = ContextDev(
# Or, configure per-request:
client.with_options(max_retries=5).brand.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
```
@@ -231,6 +236,7 @@ client = ContextDev(
# Override per-request:
client.with_options(timeout=5.0).brand.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
```
@@ -274,6 +280,7 @@ from context.dev import ContextDev
client = ContextDev()
response = client.brand.with_raw_response.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
)
print(response.headers.get('X-My-Header'))
@@ -294,6 +301,7 @@ To stream the response body, use `.with_streaming_response` instead, which requi
```python
with client.brand.with_streaming_response.retrieve(
domain="REPLACE_ME",
+ type="by_domain",
) as response:
print(response.headers.get("X-My-Header"))
diff --git a/src/context/dev/resources/brand.py b/src/context/dev/resources/brand.py
index 2c5be6a..01fd7d5 100644
--- a/src/context/dev/resources/brand.py
+++ b/src/context/dev/resources/brand.py
@@ -49,6 +49,7 @@ def retrieve(
self,
*,
domain: str,
+ type: Literal["by_domain"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -191,6 +192,8 @@ def retrieve(
Args:
domain: Domain name to retrieve brand data for (e.g., 'stripe.com').
+ type: Discriminator for domain-based brand retrieval.
+
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
@@ -219,6 +222,7 @@ def retrieve(
self,
*,
name: str,
+ type: Literal["by_name"],
country_gl: str | Omit = omit,
force_language: Literal[
"afrikaans",
@@ -362,6 +366,8 @@ def retrieve(
Args:
name: Company name to retrieve brand data for (e.g., 'Apple Inc').
+ type: Discriminator for name-based brand retrieval.
+
country_gl: Optional country code hint (GL parameter) to specify the country when looking up
by company name.
@@ -393,6 +399,7 @@ def retrieve(
self,
*,
email: str,
+ type: Literal["by_email"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -535,6 +542,8 @@ def retrieve(
Args:
email: Email address to retrieve brand data for (e.g., 'jane@stripe.com').
+ type: Discriminator for email-based brand retrieval.
+
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
@@ -563,6 +572,7 @@ def retrieve(
self,
*,
ticker: str,
+ type: Literal["by_ticker"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -706,6 +716,8 @@ def retrieve(
Args:
ticker: Stock ticker symbol to retrieve brand data for (e.g., 'AAPL').
+ type: Discriminator for ticker-based brand retrieval.
+
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
@@ -736,6 +748,7 @@ def retrieve(
self,
*,
transaction_info: str,
+ type: Literal["by_transaction"],
city: str | Omit = omit,
country_gl: str | Omit = omit,
force_language: Literal[
@@ -882,6 +895,8 @@ def retrieve(
Args:
transaction_info: Transaction information to identify the brand.
+ type: Discriminator for transaction-based brand retrieval.
+
city: Optional city name to prioritize when searching for the brand.
country_gl: Optional country code hint (GL parameter) to specify the country when
@@ -913,11 +928,18 @@ def retrieve(
"""
...
- @required_args(["domain"], ["name"], ["email"], ["ticker"], ["transaction_info"])
+ @required_args(
+ ["domain", "type"], ["name", "type"], ["email", "type"], ["ticker", "type"], ["transaction_info", "type"]
+ )
def retrieve(
self,
*,
domain: str | Omit = omit,
+ type: Literal["by_domain"]
+ | Literal["by_name"]
+ | Literal["by_email"]
+ | Literal["by_ticker"]
+ | Literal["by_transaction"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -1066,6 +1088,7 @@ def retrieve(
body=maybe_transform(
{
"domain": domain,
+ "type": type,
"force_language": force_language,
"max_age_ms": max_age_ms,
"max_speed": max_speed,
@@ -1172,6 +1195,7 @@ async def retrieve(
self,
*,
domain: str,
+ type: Literal["by_domain"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -1314,6 +1338,8 @@ async def retrieve(
Args:
domain: Domain name to retrieve brand data for (e.g., 'stripe.com').
+ type: Discriminator for domain-based brand retrieval.
+
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
@@ -1342,6 +1368,7 @@ async def retrieve(
self,
*,
name: str,
+ type: Literal["by_name"],
country_gl: str | Omit = omit,
force_language: Literal[
"afrikaans",
@@ -1485,6 +1512,8 @@ async def retrieve(
Args:
name: Company name to retrieve brand data for (e.g., 'Apple Inc').
+ type: Discriminator for name-based brand retrieval.
+
country_gl: Optional country code hint (GL parameter) to specify the country when looking up
by company name.
@@ -1516,6 +1545,7 @@ async def retrieve(
self,
*,
email: str,
+ type: Literal["by_email"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -1658,6 +1688,8 @@ async def retrieve(
Args:
email: Email address to retrieve brand data for (e.g., 'jane@stripe.com').
+ type: Discriminator for email-based brand retrieval.
+
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
@@ -1686,6 +1718,7 @@ async def retrieve(
self,
*,
ticker: str,
+ type: Literal["by_ticker"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -1829,6 +1862,8 @@ async def retrieve(
Args:
ticker: Stock ticker symbol to retrieve brand data for (e.g., 'AAPL').
+ type: Discriminator for ticker-based brand retrieval.
+
max_age_ms: Maximum age in milliseconds for cached brand data before the API performs a hard
refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms)
are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1
@@ -1859,6 +1894,7 @@ async def retrieve(
self,
*,
transaction_info: str,
+ type: Literal["by_transaction"],
city: str | Omit = omit,
country_gl: str | Omit = omit,
force_language: Literal[
@@ -2005,6 +2041,8 @@ async def retrieve(
Args:
transaction_info: Transaction information to identify the brand.
+ type: Discriminator for transaction-based brand retrieval.
+
city: Optional city name to prioritize when searching for the brand.
country_gl: Optional country code hint (GL parameter) to specify the country when
@@ -2036,11 +2074,18 @@ async def retrieve(
"""
...
- @required_args(["domain"], ["name"], ["email"], ["ticker"], ["transaction_info"])
+ @required_args(
+ ["domain", "type"], ["name", "type"], ["email", "type"], ["ticker", "type"], ["transaction_info", "type"]
+ )
async def retrieve(
self,
*,
domain: str | Omit = omit,
+ type: Literal["by_domain"]
+ | Literal["by_name"]
+ | Literal["by_email"]
+ | Literal["by_ticker"]
+ | Literal["by_transaction"],
force_language: Literal[
"afrikaans",
"albanian",
@@ -2189,6 +2234,7 @@ async def retrieve(
body=await async_maybe_transform(
{
"domain": domain,
+ "type": type,
"force_language": force_language,
"max_age_ms": max_age_ms,
"max_speed": max_speed,
diff --git a/src/context/dev/types/brand_retrieve_params.py b/src/context/dev/types/brand_retrieve_params.py
index 2d1b2e1..dedeeb1 100644
--- a/src/context/dev/types/brand_retrieve_params.py
+++ b/src/context/dev/types/brand_retrieve_params.py
@@ -21,6 +21,9 @@ class BrandRetrieveByDomainRequest(TypedDict, total=False):
domain: Required[str]
"""Domain name to retrieve brand data for (e.g., 'stripe.com')."""
+ type: Required[Literal["by_domain"]]
+ """Discriminator for domain-based brand retrieval."""
+
force_language: Literal[
"afrikaans",
"albanian",
@@ -171,6 +174,9 @@ class BrandRetrieveByNameRequest(TypedDict, total=False):
name: Required[str]
"""Company name to retrieve brand data for (e.g., 'Apple Inc')."""
+ type: Required[Literal["by_name"]]
+ """Discriminator for name-based brand retrieval."""
+
country_gl: str
"""
Optional country code hint (GL parameter) to specify the country when looking up
@@ -327,6 +333,9 @@ class BrandRetrieveByEmailRequest(TypedDict, total=False):
email: Required[str]
"""Email address to retrieve brand data for (e.g., 'jane@stripe.com')."""
+ type: Required[Literal["by_email"]]
+ """Discriminator for email-based brand retrieval."""
+
force_language: Literal[
"afrikaans",
"albanian",
@@ -477,6 +486,9 @@ class BrandRetrieveByTickerRequest(TypedDict, total=False):
ticker: Required[str]
"""Stock ticker symbol to retrieve brand data for (e.g., 'AAPL')."""
+ type: Required[Literal["by_ticker"]]
+ """Discriminator for ticker-based brand retrieval."""
+
force_language: Literal[
"afrikaans",
"albanian",
@@ -630,6 +642,9 @@ class BrandRetrieveFromTransactionRequest(TypedDict, total=False):
transaction_info: Required[str]
"""Transaction information to identify the brand."""
+ type: Required[Literal["by_transaction"]]
+ """Discriminator for transaction-based brand retrieval."""
+
city: str
"""Optional city name to prioritize when searching for the brand."""
diff --git a/tests/api_resources/test_brand.py b/tests/api_resources/test_brand.py
index 9d0fbf6..67f64eb 100644
--- a/tests/api_resources/test_brand.py
+++ b/tests/api_resources/test_brand.py
@@ -25,6 +25,7 @@ class TestBrand:
def test_method_retrieve_overload_1(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
domain="domain",
+ type="by_domain",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -33,6 +34,7 @@ def test_method_retrieve_overload_1(self, client: ContextDev) -> None:
def test_method_retrieve_with_all_params_overload_1(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
domain="domain",
+ type="by_domain",
force_language="afrikaans",
max_age_ms=0,
max_speed=True,
@@ -45,6 +47,7 @@ def test_method_retrieve_with_all_params_overload_1(self, client: ContextDev) ->
def test_raw_response_retrieve_overload_1(self, client: ContextDev) -> None:
response = client.brand.with_raw_response.retrieve(
domain="domain",
+ type="by_domain",
)
assert response.is_closed is True
@@ -57,6 +60,7 @@ def test_raw_response_retrieve_overload_1(self, client: ContextDev) -> None:
def test_streaming_response_retrieve_overload_1(self, client: ContextDev) -> None:
with client.brand.with_streaming_response.retrieve(
domain="domain",
+ type="by_domain",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -71,6 +75,7 @@ def test_streaming_response_retrieve_overload_1(self, client: ContextDev) -> Non
def test_method_retrieve_overload_2(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
name="xxx",
+ type="by_name",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -79,6 +84,7 @@ def test_method_retrieve_overload_2(self, client: ContextDev) -> None:
def test_method_retrieve_with_all_params_overload_2(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
name="xxx",
+ type="by_name",
country_gl="country_gl",
force_language="afrikaans",
max_age_ms=0,
@@ -92,6 +98,7 @@ def test_method_retrieve_with_all_params_overload_2(self, client: ContextDev) ->
def test_raw_response_retrieve_overload_2(self, client: ContextDev) -> None:
response = client.brand.with_raw_response.retrieve(
name="xxx",
+ type="by_name",
)
assert response.is_closed is True
@@ -104,6 +111,7 @@ def test_raw_response_retrieve_overload_2(self, client: ContextDev) -> None:
def test_streaming_response_retrieve_overload_2(self, client: ContextDev) -> None:
with client.brand.with_streaming_response.retrieve(
name="xxx",
+ type="by_name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -118,6 +126,7 @@ def test_streaming_response_retrieve_overload_2(self, client: ContextDev) -> Non
def test_method_retrieve_overload_3(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
email="dev@stainless.com",
+ type="by_email",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -126,6 +135,7 @@ def test_method_retrieve_overload_3(self, client: ContextDev) -> None:
def test_method_retrieve_with_all_params_overload_3(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
email="dev@stainless.com",
+ type="by_email",
force_language="afrikaans",
max_age_ms=0,
max_speed=True,
@@ -138,6 +148,7 @@ def test_method_retrieve_with_all_params_overload_3(self, client: ContextDev) ->
def test_raw_response_retrieve_overload_3(self, client: ContextDev) -> None:
response = client.brand.with_raw_response.retrieve(
email="dev@stainless.com",
+ type="by_email",
)
assert response.is_closed is True
@@ -150,6 +161,7 @@ def test_raw_response_retrieve_overload_3(self, client: ContextDev) -> None:
def test_streaming_response_retrieve_overload_3(self, client: ContextDev) -> None:
with client.brand.with_streaming_response.retrieve(
email="dev@stainless.com",
+ type="by_email",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -164,6 +176,7 @@ def test_streaming_response_retrieve_overload_3(self, client: ContextDev) -> Non
def test_method_retrieve_overload_4(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
ticker="ticker",
+ type="by_ticker",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -172,6 +185,7 @@ def test_method_retrieve_overload_4(self, client: ContextDev) -> None:
def test_method_retrieve_with_all_params_overload_4(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
ticker="ticker",
+ type="by_ticker",
force_language="afrikaans",
max_age_ms=0,
max_speed=True,
@@ -185,6 +199,7 @@ def test_method_retrieve_with_all_params_overload_4(self, client: ContextDev) ->
def test_raw_response_retrieve_overload_4(self, client: ContextDev) -> None:
response = client.brand.with_raw_response.retrieve(
ticker="ticker",
+ type="by_ticker",
)
assert response.is_closed is True
@@ -197,6 +212,7 @@ def test_raw_response_retrieve_overload_4(self, client: ContextDev) -> None:
def test_streaming_response_retrieve_overload_4(self, client: ContextDev) -> None:
with client.brand.with_streaming_response.retrieve(
ticker="ticker",
+ type="by_ticker",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -211,6 +227,7 @@ def test_streaming_response_retrieve_overload_4(self, client: ContextDev) -> Non
def test_method_retrieve_overload_5(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
transaction_info="xxx",
+ type="by_transaction",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -219,6 +236,7 @@ def test_method_retrieve_overload_5(self, client: ContextDev) -> None:
def test_method_retrieve_with_all_params_overload_5(self, client: ContextDev) -> None:
brand = client.brand.retrieve(
transaction_info="xxx",
+ type="by_transaction",
city="city",
country_gl="country_gl",
force_language="afrikaans",
@@ -235,6 +253,7 @@ def test_method_retrieve_with_all_params_overload_5(self, client: ContextDev) ->
def test_raw_response_retrieve_overload_5(self, client: ContextDev) -> None:
response = client.brand.with_raw_response.retrieve(
transaction_info="xxx",
+ type="by_transaction",
)
assert response.is_closed is True
@@ -247,6 +266,7 @@ def test_raw_response_retrieve_overload_5(self, client: ContextDev) -> None:
def test_streaming_response_retrieve_overload_5(self, client: ContextDev) -> None:
with client.brand.with_streaming_response.retrieve(
transaction_info="xxx",
+ type="by_transaction",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -311,6 +331,7 @@ class TestAsyncBrand:
async def test_method_retrieve_overload_1(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
domain="domain",
+ type="by_domain",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -319,6 +340,7 @@ async def test_method_retrieve_overload_1(self, async_client: AsyncContextDev) -
async def test_method_retrieve_with_all_params_overload_1(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
domain="domain",
+ type="by_domain",
force_language="afrikaans",
max_age_ms=0,
max_speed=True,
@@ -331,6 +353,7 @@ async def test_method_retrieve_with_all_params_overload_1(self, async_client: As
async def test_raw_response_retrieve_overload_1(self, async_client: AsyncContextDev) -> None:
response = await async_client.brand.with_raw_response.retrieve(
domain="domain",
+ type="by_domain",
)
assert response.is_closed is True
@@ -343,6 +366,7 @@ async def test_raw_response_retrieve_overload_1(self, async_client: AsyncContext
async def test_streaming_response_retrieve_overload_1(self, async_client: AsyncContextDev) -> None:
async with async_client.brand.with_streaming_response.retrieve(
domain="domain",
+ type="by_domain",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -357,6 +381,7 @@ async def test_streaming_response_retrieve_overload_1(self, async_client: AsyncC
async def test_method_retrieve_overload_2(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
name="xxx",
+ type="by_name",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -365,6 +390,7 @@ async def test_method_retrieve_overload_2(self, async_client: AsyncContextDev) -
async def test_method_retrieve_with_all_params_overload_2(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
name="xxx",
+ type="by_name",
country_gl="country_gl",
force_language="afrikaans",
max_age_ms=0,
@@ -378,6 +404,7 @@ async def test_method_retrieve_with_all_params_overload_2(self, async_client: As
async def test_raw_response_retrieve_overload_2(self, async_client: AsyncContextDev) -> None:
response = await async_client.brand.with_raw_response.retrieve(
name="xxx",
+ type="by_name",
)
assert response.is_closed is True
@@ -390,6 +417,7 @@ async def test_raw_response_retrieve_overload_2(self, async_client: AsyncContext
async def test_streaming_response_retrieve_overload_2(self, async_client: AsyncContextDev) -> None:
async with async_client.brand.with_streaming_response.retrieve(
name="xxx",
+ type="by_name",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -404,6 +432,7 @@ async def test_streaming_response_retrieve_overload_2(self, async_client: AsyncC
async def test_method_retrieve_overload_3(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
email="dev@stainless.com",
+ type="by_email",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -412,6 +441,7 @@ async def test_method_retrieve_overload_3(self, async_client: AsyncContextDev) -
async def test_method_retrieve_with_all_params_overload_3(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
email="dev@stainless.com",
+ type="by_email",
force_language="afrikaans",
max_age_ms=0,
max_speed=True,
@@ -424,6 +454,7 @@ async def test_method_retrieve_with_all_params_overload_3(self, async_client: As
async def test_raw_response_retrieve_overload_3(self, async_client: AsyncContextDev) -> None:
response = await async_client.brand.with_raw_response.retrieve(
email="dev@stainless.com",
+ type="by_email",
)
assert response.is_closed is True
@@ -436,6 +467,7 @@ async def test_raw_response_retrieve_overload_3(self, async_client: AsyncContext
async def test_streaming_response_retrieve_overload_3(self, async_client: AsyncContextDev) -> None:
async with async_client.brand.with_streaming_response.retrieve(
email="dev@stainless.com",
+ type="by_email",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -450,6 +482,7 @@ async def test_streaming_response_retrieve_overload_3(self, async_client: AsyncC
async def test_method_retrieve_overload_4(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
ticker="ticker",
+ type="by_ticker",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -458,6 +491,7 @@ async def test_method_retrieve_overload_4(self, async_client: AsyncContextDev) -
async def test_method_retrieve_with_all_params_overload_4(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
ticker="ticker",
+ type="by_ticker",
force_language="afrikaans",
max_age_ms=0,
max_speed=True,
@@ -471,6 +505,7 @@ async def test_method_retrieve_with_all_params_overload_4(self, async_client: As
async def test_raw_response_retrieve_overload_4(self, async_client: AsyncContextDev) -> None:
response = await async_client.brand.with_raw_response.retrieve(
ticker="ticker",
+ type="by_ticker",
)
assert response.is_closed is True
@@ -483,6 +518,7 @@ async def test_raw_response_retrieve_overload_4(self, async_client: AsyncContext
async def test_streaming_response_retrieve_overload_4(self, async_client: AsyncContextDev) -> None:
async with async_client.brand.with_streaming_response.retrieve(
ticker="ticker",
+ type="by_ticker",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -497,6 +533,7 @@ async def test_streaming_response_retrieve_overload_4(self, async_client: AsyncC
async def test_method_retrieve_overload_5(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
transaction_info="xxx",
+ type="by_transaction",
)
assert_matches_type(BrandRetrieveResponse, brand, path=["response"])
@@ -505,6 +542,7 @@ async def test_method_retrieve_overload_5(self, async_client: AsyncContextDev) -
async def test_method_retrieve_with_all_params_overload_5(self, async_client: AsyncContextDev) -> None:
brand = await async_client.brand.retrieve(
transaction_info="xxx",
+ type="by_transaction",
city="city",
country_gl="country_gl",
force_language="afrikaans",
@@ -521,6 +559,7 @@ async def test_method_retrieve_with_all_params_overload_5(self, async_client: As
async def test_raw_response_retrieve_overload_5(self, async_client: AsyncContextDev) -> None:
response = await async_client.brand.with_raw_response.retrieve(
transaction_info="xxx",
+ type="by_transaction",
)
assert response.is_closed is True
@@ -533,6 +572,7 @@ async def test_raw_response_retrieve_overload_5(self, async_client: AsyncContext
async def test_streaming_response_retrieve_overload_5(self, async_client: AsyncContextDev) -> None:
async with async_client.brand.with_streaming_response.retrieve(
transaction_info="xxx",
+ type="by_transaction",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/test_client.py b/tests/test_client.py
index 951eedf..95769ce 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -886,7 +886,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien
respx_mock.post("/brand/retrieve").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.brand.with_streaming_response.retrieve(domain="domain").__enter__()
+ client.brand.with_streaming_response.retrieve(domain="domain", type="by_domain").__enter__()
assert _get_open_connections(client) == 0
@@ -896,7 +896,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client
respx_mock.post("/brand/retrieve").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.brand.with_streaming_response.retrieve(domain="domain").__enter__()
+ client.brand.with_streaming_response.retrieve(domain="domain", type="by_domain").__enter__()
assert _get_open_connections(client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -925,7 +925,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = client.brand.with_raw_response.retrieve(domain="domain")
+ response = client.brand.with_raw_response.retrieve(domain="domain", type="by_domain")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -950,7 +950,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
response = client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": Omit()}
+ domain="domain", type="by_domain", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -975,7 +975,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
response = client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": "42"}
+ domain="domain", type="by_domain", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1824,7 +1824,7 @@ async def test_retrying_timeout_errors_doesnt_leak(
respx_mock.post("/brand/retrieve").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.brand.with_streaming_response.retrieve(domain="domain").__aenter__()
+ await async_client.brand.with_streaming_response.retrieve(domain="domain", type="by_domain").__aenter__()
assert _get_open_connections(async_client) == 0
@@ -1836,7 +1836,7 @@ async def test_retrying_status_errors_doesnt_leak(
respx_mock.post("/brand/retrieve").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.brand.with_streaming_response.retrieve(domain="domain").__aenter__()
+ await async_client.brand.with_streaming_response.retrieve(domain="domain", type="by_domain").__aenter__()
assert _get_open_connections(async_client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1865,7 +1865,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
- response = await client.brand.with_raw_response.retrieve(domain="domain")
+ response = await client.brand.with_raw_response.retrieve(domain="domain", type="by_domain")
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1890,7 +1890,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
response = await client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": Omit()}
+ domain="domain", type="by_domain", extra_headers={"x-stainless-retry-count": Omit()}
)
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1915,7 +1915,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/brand/retrieve").mock(side_effect=retry_handler)
response = await client.brand.with_raw_response.retrieve(
- domain="domain", extra_headers={"x-stainless-retry-count": "42"}
+ domain="domain", type="by_domain", extra_headers={"x-stainless-retry-count": "42"}
)
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
From 743809919f84d6deaf8848e1e70a40306a25db78 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 07:11:55 +0000
Subject: [PATCH 18/18] release: 2.0.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 19 +++++++++++++++++++
pyproject.toml | 2 +-
src/context/dev/_version.py | 2 +-
4 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 2a8f4ff..65f558e 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.3.0"
+ ".": "2.0.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ccedbfa..5bbd0e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
# Changelog
+## 2.0.0 (2026-07-06)
+
+Full Changelog: [v1.3.0...v2.0.0](https://github.com/context-dot-dev/context-python-sdk/compare/v1.3.0...v2.0.0)
+
+### Features
+
+* **api:** api update ([f63569e](https://github.com/context-dot-dev/context-python-sdk/commit/f63569e84571a403cd05fbff990ea991b83e0821))
+* **api:** api update ([79826c4](https://github.com/context-dot-dev/context-python-sdk/commit/79826c4324757cb3f32a4a0392d94d7093d39562))
+* **api:** api update ([4bbf3b1](https://github.com/context-dot-dev/context-python-sdk/commit/4bbf3b1ad847353571b27118e0875bb2ff96c0c7))
+* **api:** api update ([41ee2e8](https://github.com/context-dot-dev/context-python-sdk/commit/41ee2e823e3a91c608861da5fe46b263518c223e))
+* **api:** api update ([000bd7c](https://github.com/context-dot-dev/context-python-sdk/commit/000bd7c50e673065f0023267aea7457f3bb1f6d9))
+* **api:** api update ([a2650d4](https://github.com/context-dot-dev/context-python-sdk/commit/a2650d40a7422733a94b1f2e7e558144230189a0))
+* **api:** api update ([c15ed56](https://github.com/context-dot-dev/context-python-sdk/commit/c15ed56b283f8fe464891afda1566b74b120e2d5))
+* **api:** api update ([fd00858](https://github.com/context-dot-dev/context-python-sdk/commit/fd00858ed8bc9806aebdb5f5c352d119ab2466d1))
+* **api:** api update ([789eb86](https://github.com/context-dot-dev/context-python-sdk/commit/789eb8671cd52aba441a03c0139f6993455b5f4d))
+* **api:** manual updates ([4aa172e](https://github.com/context-dot-dev/context-python-sdk/commit/4aa172e6efe35e35b050168b4f4ab3102651a935))
+* **api:** manual updates ([63d9bdf](https://github.com/context-dot-dev/context-python-sdk/commit/63d9bdfc771270ccecff225a339af6ec51dfc1f7))
+* **api:** manual updates ([f80c306](https://github.com/context-dot-dev/context-python-sdk/commit/f80c3061d969b6650d9f5a2f9df5ca8f371e14d7))
+
## 1.3.0 (2026-06-27)
Full Changelog: [v1.2.0...v1.3.0](https://github.com/context-dot-dev/context-python-sdk/compare/v1.2.0...v1.3.0)
diff --git a/pyproject.toml b/pyproject.toml
index 315b9a6..3566c2c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "context.dev"
-version = "1.3.0"
+version = "2.0.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 70d3d53..92dbce7 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__ = "1.3.0" # x-release-please-version
+__version__ = "2.0.0" # x-release-please-version