channel3-sdk 2.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. channel3_sdk/__init__.py +102 -0
  2. channel3_sdk/_base_client.py +2001 -0
  3. channel3_sdk/_client.py +636 -0
  4. channel3_sdk/_compat.py +219 -0
  5. channel3_sdk/_constants.py +14 -0
  6. channel3_sdk/_exceptions.py +108 -0
  7. channel3_sdk/_files.py +123 -0
  8. channel3_sdk/_models.py +857 -0
  9. channel3_sdk/_qs.py +150 -0
  10. channel3_sdk/_resource.py +43 -0
  11. channel3_sdk/_response.py +832 -0
  12. channel3_sdk/_streaming.py +333 -0
  13. channel3_sdk/_types.py +261 -0
  14. channel3_sdk/_utils/__init__.py +64 -0
  15. channel3_sdk/_utils/_compat.py +45 -0
  16. channel3_sdk/_utils/_datetime_parse.py +136 -0
  17. channel3_sdk/_utils/_logs.py +25 -0
  18. channel3_sdk/_utils/_proxy.py +65 -0
  19. channel3_sdk/_utils/_reflection.py +42 -0
  20. channel3_sdk/_utils/_resources_proxy.py +24 -0
  21. channel3_sdk/_utils/_streams.py +12 -0
  22. channel3_sdk/_utils/_sync.py +58 -0
  23. channel3_sdk/_utils/_transform.py +457 -0
  24. channel3_sdk/_utils/_typing.py +156 -0
  25. channel3_sdk/_utils/_utils.py +421 -0
  26. channel3_sdk/_version.py +4 -0
  27. channel3_sdk/lib/.keep +4 -0
  28. channel3_sdk/py.typed +0 -0
  29. channel3_sdk/resources/__init__.py +89 -0
  30. channel3_sdk/resources/brands.py +169 -0
  31. channel3_sdk/resources/enrich.py +169 -0
  32. channel3_sdk/resources/price_tracking.py +450 -0
  33. channel3_sdk/resources/products.py +206 -0
  34. channel3_sdk/resources/search.py +231 -0
  35. channel3_sdk/resources/websites.py +171 -0
  36. channel3_sdk/types/__init__.py +30 -0
  37. channel3_sdk/types/availability_status.py +9 -0
  38. channel3_sdk/types/brand.py +20 -0
  39. channel3_sdk/types/brand_find_params.py +11 -0
  40. channel3_sdk/types/enrich_enrich_url_params.py +12 -0
  41. channel3_sdk/types/paginated_subscriptions.py +14 -0
  42. channel3_sdk/types/price.py +18 -0
  43. channel3_sdk/types/price_history.py +43 -0
  44. channel3_sdk/types/price_tracking_get_history_params.py +12 -0
  45. channel3_sdk/types/price_tracking_list_subscriptions_params.py +14 -0
  46. channel3_sdk/types/price_tracking_start_params.py +11 -0
  47. channel3_sdk/types/price_tracking_stop_params.py +11 -0
  48. channel3_sdk/types/product.py +89 -0
  49. channel3_sdk/types/product_detail.py +84 -0
  50. channel3_sdk/types/product_retrieve_params.py +26 -0
  51. channel3_sdk/types/redirect_mode.py +7 -0
  52. channel3_sdk/types/search_config_param.py +27 -0
  53. channel3_sdk/types/search_filter_price_param.py +18 -0
  54. channel3_sdk/types/search_filters_param.py +44 -0
  55. channel3_sdk/types/search_perform_params.py +37 -0
  56. channel3_sdk/types/search_perform_response.py +10 -0
  57. channel3_sdk/types/subscription.py +16 -0
  58. channel3_sdk/types/variant.py +13 -0
  59. channel3_sdk/types/website.py +16 -0
  60. channel3_sdk/types/website_find_params.py +11 -0
  61. channel3_sdk-2.11.0.dist-info/METADATA +411 -0
  62. channel3_sdk-2.11.0.dist-info/RECORD +64 -0
  63. channel3_sdk-2.11.0.dist-info/WHEEL +4 -0
  64. channel3_sdk-2.11.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,636 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import TYPE_CHECKING, Any, Mapping
7
+ from typing_extensions import Self, override
8
+
9
+ import httpx
10
+
11
+ from . import _exceptions
12
+ from ._qs import Querystring
13
+ from ._types import (
14
+ Omit,
15
+ Timeout,
16
+ NotGiven,
17
+ Transport,
18
+ ProxiesTypes,
19
+ RequestOptions,
20
+ not_given,
21
+ )
22
+ from ._utils import is_given, get_async_library
23
+ from ._compat import cached_property
24
+ from ._version import __version__
25
+ from ._streaming import Stream as Stream, AsyncStream as AsyncStream
26
+ from ._exceptions import Channel3Error, APIStatusError
27
+ from ._base_client import (
28
+ DEFAULT_MAX_RETRIES,
29
+ SyncAPIClient,
30
+ AsyncAPIClient,
31
+ )
32
+
33
+ if TYPE_CHECKING:
34
+ from .resources import brands, enrich, search, products, websites, price_tracking
35
+ from .resources.brands import BrandsResource, AsyncBrandsResource
36
+ from .resources.enrich import EnrichResource, AsyncEnrichResource
37
+ from .resources.search import SearchResource, AsyncSearchResource
38
+ from .resources.products import ProductsResource, AsyncProductsResource
39
+ from .resources.websites import WebsitesResource, AsyncWebsitesResource
40
+ from .resources.price_tracking import PriceTrackingResource, AsyncPriceTrackingResource
41
+
42
+ __all__ = [
43
+ "Timeout",
44
+ "Transport",
45
+ "ProxiesTypes",
46
+ "RequestOptions",
47
+ "Channel3",
48
+ "AsyncChannel3",
49
+ "Client",
50
+ "AsyncClient",
51
+ ]
52
+
53
+
54
+ class Channel3(SyncAPIClient):
55
+ # client options
56
+ api_key: str
57
+
58
+ def __init__(
59
+ self,
60
+ *,
61
+ api_key: str | None = None,
62
+ base_url: str | httpx.URL | None = None,
63
+ timeout: float | Timeout | None | NotGiven = not_given,
64
+ max_retries: int = DEFAULT_MAX_RETRIES,
65
+ default_headers: Mapping[str, str] | None = None,
66
+ default_query: Mapping[str, object] | None = None,
67
+ # Configure a custom httpx client.
68
+ # We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
69
+ # See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details.
70
+ http_client: httpx.Client | None = None,
71
+ # Enable or disable schema validation for data returned by the API.
72
+ # When enabled an error APIResponseValidationError is raised
73
+ # if the API responds with invalid data for the expected schema.
74
+ #
75
+ # This parameter may be removed or changed in the future.
76
+ # If you rely on this feature, please open a GitHub issue
77
+ # outlining your use-case to help us decide if it should be
78
+ # part of our public interface in the future.
79
+ _strict_response_validation: bool = False,
80
+ ) -> None:
81
+ """Construct a new synchronous Channel3 client instance.
82
+
83
+ This automatically infers the `api_key` argument from the `CHANNEL3_API_KEY` environment variable if it is not provided.
84
+ """
85
+ if api_key is None:
86
+ api_key = os.environ.get("CHANNEL3_API_KEY")
87
+ if api_key is None:
88
+ raise Channel3Error(
89
+ "The api_key client option must be set either by passing api_key to the client or by setting the CHANNEL3_API_KEY environment variable"
90
+ )
91
+ self.api_key = api_key
92
+
93
+ if base_url is None:
94
+ base_url = os.environ.get("CHANNEL3_BASE_URL")
95
+ if base_url is None:
96
+ base_url = f"https://api.trychannel3.com"
97
+
98
+ super().__init__(
99
+ version=__version__,
100
+ base_url=base_url,
101
+ max_retries=max_retries,
102
+ timeout=timeout,
103
+ http_client=http_client,
104
+ custom_headers=default_headers,
105
+ custom_query=default_query,
106
+ _strict_response_validation=_strict_response_validation,
107
+ )
108
+
109
+ @cached_property
110
+ def search(self) -> SearchResource:
111
+ from .resources.search import SearchResource
112
+
113
+ return SearchResource(self)
114
+
115
+ @cached_property
116
+ def products(self) -> ProductsResource:
117
+ from .resources.products import ProductsResource
118
+
119
+ return ProductsResource(self)
120
+
121
+ @cached_property
122
+ def brands(self) -> BrandsResource:
123
+ from .resources.brands import BrandsResource
124
+
125
+ return BrandsResource(self)
126
+
127
+ @cached_property
128
+ def websites(self) -> WebsitesResource:
129
+ from .resources.websites import WebsitesResource
130
+
131
+ return WebsitesResource(self)
132
+
133
+ @cached_property
134
+ def enrich(self) -> EnrichResource:
135
+ from .resources.enrich import EnrichResource
136
+
137
+ return EnrichResource(self)
138
+
139
+ @cached_property
140
+ def price_tracking(self) -> PriceTrackingResource:
141
+ from .resources.price_tracking import PriceTrackingResource
142
+
143
+ return PriceTrackingResource(self)
144
+
145
+ @cached_property
146
+ def with_raw_response(self) -> Channel3WithRawResponse:
147
+ return Channel3WithRawResponse(self)
148
+
149
+ @cached_property
150
+ def with_streaming_response(self) -> Channel3WithStreamedResponse:
151
+ return Channel3WithStreamedResponse(self)
152
+
153
+ @property
154
+ @override
155
+ def qs(self) -> Querystring:
156
+ return Querystring(array_format="comma")
157
+
158
+ @property
159
+ @override
160
+ def auth_headers(self) -> dict[str, str]:
161
+ api_key = self.api_key
162
+ return {"x-api-key": api_key}
163
+
164
+ @property
165
+ @override
166
+ def default_headers(self) -> dict[str, str | Omit]:
167
+ return {
168
+ **super().default_headers,
169
+ "X-Stainless-Async": "false",
170
+ **self._custom_headers,
171
+ }
172
+
173
+ def copy(
174
+ self,
175
+ *,
176
+ api_key: str | None = None,
177
+ base_url: str | httpx.URL | None = None,
178
+ timeout: float | Timeout | None | NotGiven = not_given,
179
+ http_client: httpx.Client | None = None,
180
+ max_retries: int | NotGiven = not_given,
181
+ default_headers: Mapping[str, str] | None = None,
182
+ set_default_headers: Mapping[str, str] | None = None,
183
+ default_query: Mapping[str, object] | None = None,
184
+ set_default_query: Mapping[str, object] | None = None,
185
+ _extra_kwargs: Mapping[str, Any] = {},
186
+ ) -> Self:
187
+ """
188
+ Create a new client instance re-using the same options given to the current client with optional overriding.
189
+ """
190
+ if default_headers is not None and set_default_headers is not None:
191
+ raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")
192
+
193
+ if default_query is not None and set_default_query is not None:
194
+ raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")
195
+
196
+ headers = self._custom_headers
197
+ if default_headers is not None:
198
+ headers = {**headers, **default_headers}
199
+ elif set_default_headers is not None:
200
+ headers = set_default_headers
201
+
202
+ params = self._custom_query
203
+ if default_query is not None:
204
+ params = {**params, **default_query}
205
+ elif set_default_query is not None:
206
+ params = set_default_query
207
+
208
+ http_client = http_client or self._client
209
+ return self.__class__(
210
+ api_key=api_key or self.api_key,
211
+ base_url=base_url or self.base_url,
212
+ timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
213
+ http_client=http_client,
214
+ max_retries=max_retries if is_given(max_retries) else self.max_retries,
215
+ default_headers=headers,
216
+ default_query=params,
217
+ **_extra_kwargs,
218
+ )
219
+
220
+ # Alias for `copy` for nicer inline usage, e.g.
221
+ # client.with_options(timeout=10).foo.create(...)
222
+ with_options = copy
223
+
224
+ @override
225
+ def _make_status_error(
226
+ self,
227
+ err_msg: str,
228
+ *,
229
+ body: object,
230
+ response: httpx.Response,
231
+ ) -> APIStatusError:
232
+ if response.status_code == 400:
233
+ return _exceptions.BadRequestError(err_msg, response=response, body=body)
234
+
235
+ if response.status_code == 401:
236
+ return _exceptions.AuthenticationError(err_msg, response=response, body=body)
237
+
238
+ if response.status_code == 403:
239
+ return _exceptions.PermissionDeniedError(err_msg, response=response, body=body)
240
+
241
+ if response.status_code == 404:
242
+ return _exceptions.NotFoundError(err_msg, response=response, body=body)
243
+
244
+ if response.status_code == 409:
245
+ return _exceptions.ConflictError(err_msg, response=response, body=body)
246
+
247
+ if response.status_code == 422:
248
+ return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body)
249
+
250
+ if response.status_code == 429:
251
+ return _exceptions.RateLimitError(err_msg, response=response, body=body)
252
+
253
+ if response.status_code >= 500:
254
+ return _exceptions.InternalServerError(err_msg, response=response, body=body)
255
+ return APIStatusError(err_msg, response=response, body=body)
256
+
257
+
258
+ class AsyncChannel3(AsyncAPIClient):
259
+ # client options
260
+ api_key: str
261
+
262
+ def __init__(
263
+ self,
264
+ *,
265
+ api_key: str | None = None,
266
+ base_url: str | httpx.URL | None = None,
267
+ timeout: float | Timeout | None | NotGiven = not_given,
268
+ max_retries: int = DEFAULT_MAX_RETRIES,
269
+ default_headers: Mapping[str, str] | None = None,
270
+ default_query: Mapping[str, object] | None = None,
271
+ # Configure a custom httpx client.
272
+ # We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
273
+ # See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details.
274
+ http_client: httpx.AsyncClient | None = None,
275
+ # Enable or disable schema validation for data returned by the API.
276
+ # When enabled an error APIResponseValidationError is raised
277
+ # if the API responds with invalid data for the expected schema.
278
+ #
279
+ # This parameter may be removed or changed in the future.
280
+ # If you rely on this feature, please open a GitHub issue
281
+ # outlining your use-case to help us decide if it should be
282
+ # part of our public interface in the future.
283
+ _strict_response_validation: bool = False,
284
+ ) -> None:
285
+ """Construct a new async AsyncChannel3 client instance.
286
+
287
+ This automatically infers the `api_key` argument from the `CHANNEL3_API_KEY` environment variable if it is not provided.
288
+ """
289
+ if api_key is None:
290
+ api_key = os.environ.get("CHANNEL3_API_KEY")
291
+ if api_key is None:
292
+ raise Channel3Error(
293
+ "The api_key client option must be set either by passing api_key to the client or by setting the CHANNEL3_API_KEY environment variable"
294
+ )
295
+ self.api_key = api_key
296
+
297
+ if base_url is None:
298
+ base_url = os.environ.get("CHANNEL3_BASE_URL")
299
+ if base_url is None:
300
+ base_url = f"https://api.trychannel3.com"
301
+
302
+ super().__init__(
303
+ version=__version__,
304
+ base_url=base_url,
305
+ max_retries=max_retries,
306
+ timeout=timeout,
307
+ http_client=http_client,
308
+ custom_headers=default_headers,
309
+ custom_query=default_query,
310
+ _strict_response_validation=_strict_response_validation,
311
+ )
312
+
313
+ @cached_property
314
+ def search(self) -> AsyncSearchResource:
315
+ from .resources.search import AsyncSearchResource
316
+
317
+ return AsyncSearchResource(self)
318
+
319
+ @cached_property
320
+ def products(self) -> AsyncProductsResource:
321
+ from .resources.products import AsyncProductsResource
322
+
323
+ return AsyncProductsResource(self)
324
+
325
+ @cached_property
326
+ def brands(self) -> AsyncBrandsResource:
327
+ from .resources.brands import AsyncBrandsResource
328
+
329
+ return AsyncBrandsResource(self)
330
+
331
+ @cached_property
332
+ def websites(self) -> AsyncWebsitesResource:
333
+ from .resources.websites import AsyncWebsitesResource
334
+
335
+ return AsyncWebsitesResource(self)
336
+
337
+ @cached_property
338
+ def enrich(self) -> AsyncEnrichResource:
339
+ from .resources.enrich import AsyncEnrichResource
340
+
341
+ return AsyncEnrichResource(self)
342
+
343
+ @cached_property
344
+ def price_tracking(self) -> AsyncPriceTrackingResource:
345
+ from .resources.price_tracking import AsyncPriceTrackingResource
346
+
347
+ return AsyncPriceTrackingResource(self)
348
+
349
+ @cached_property
350
+ def with_raw_response(self) -> AsyncChannel3WithRawResponse:
351
+ return AsyncChannel3WithRawResponse(self)
352
+
353
+ @cached_property
354
+ def with_streaming_response(self) -> AsyncChannel3WithStreamedResponse:
355
+ return AsyncChannel3WithStreamedResponse(self)
356
+
357
+ @property
358
+ @override
359
+ def qs(self) -> Querystring:
360
+ return Querystring(array_format="comma")
361
+
362
+ @property
363
+ @override
364
+ def auth_headers(self) -> dict[str, str]:
365
+ api_key = self.api_key
366
+ return {"x-api-key": api_key}
367
+
368
+ @property
369
+ @override
370
+ def default_headers(self) -> dict[str, str | Omit]:
371
+ return {
372
+ **super().default_headers,
373
+ "X-Stainless-Async": f"async:{get_async_library()}",
374
+ **self._custom_headers,
375
+ }
376
+
377
+ def copy(
378
+ self,
379
+ *,
380
+ api_key: str | None = None,
381
+ base_url: str | httpx.URL | None = None,
382
+ timeout: float | Timeout | None | NotGiven = not_given,
383
+ http_client: httpx.AsyncClient | None = None,
384
+ max_retries: int | NotGiven = not_given,
385
+ default_headers: Mapping[str, str] | None = None,
386
+ set_default_headers: Mapping[str, str] | None = None,
387
+ default_query: Mapping[str, object] | None = None,
388
+ set_default_query: Mapping[str, object] | None = None,
389
+ _extra_kwargs: Mapping[str, Any] = {},
390
+ ) -> Self:
391
+ """
392
+ Create a new client instance re-using the same options given to the current client with optional overriding.
393
+ """
394
+ if default_headers is not None and set_default_headers is not None:
395
+ raise ValueError("The `default_headers` and `set_default_headers` arguments are mutually exclusive")
396
+
397
+ if default_query is not None and set_default_query is not None:
398
+ raise ValueError("The `default_query` and `set_default_query` arguments are mutually exclusive")
399
+
400
+ headers = self._custom_headers
401
+ if default_headers is not None:
402
+ headers = {**headers, **default_headers}
403
+ elif set_default_headers is not None:
404
+ headers = set_default_headers
405
+
406
+ params = self._custom_query
407
+ if default_query is not None:
408
+ params = {**params, **default_query}
409
+ elif set_default_query is not None:
410
+ params = set_default_query
411
+
412
+ http_client = http_client or self._client
413
+ return self.__class__(
414
+ api_key=api_key or self.api_key,
415
+ base_url=base_url or self.base_url,
416
+ timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
417
+ http_client=http_client,
418
+ max_retries=max_retries if is_given(max_retries) else self.max_retries,
419
+ default_headers=headers,
420
+ default_query=params,
421
+ **_extra_kwargs,
422
+ )
423
+
424
+ # Alias for `copy` for nicer inline usage, e.g.
425
+ # client.with_options(timeout=10).foo.create(...)
426
+ with_options = copy
427
+
428
+ @override
429
+ def _make_status_error(
430
+ self,
431
+ err_msg: str,
432
+ *,
433
+ body: object,
434
+ response: httpx.Response,
435
+ ) -> APIStatusError:
436
+ if response.status_code == 400:
437
+ return _exceptions.BadRequestError(err_msg, response=response, body=body)
438
+
439
+ if response.status_code == 401:
440
+ return _exceptions.AuthenticationError(err_msg, response=response, body=body)
441
+
442
+ if response.status_code == 403:
443
+ return _exceptions.PermissionDeniedError(err_msg, response=response, body=body)
444
+
445
+ if response.status_code == 404:
446
+ return _exceptions.NotFoundError(err_msg, response=response, body=body)
447
+
448
+ if response.status_code == 409:
449
+ return _exceptions.ConflictError(err_msg, response=response, body=body)
450
+
451
+ if response.status_code == 422:
452
+ return _exceptions.UnprocessableEntityError(err_msg, response=response, body=body)
453
+
454
+ if response.status_code == 429:
455
+ return _exceptions.RateLimitError(err_msg, response=response, body=body)
456
+
457
+ if response.status_code >= 500:
458
+ return _exceptions.InternalServerError(err_msg, response=response, body=body)
459
+ return APIStatusError(err_msg, response=response, body=body)
460
+
461
+
462
+ class Channel3WithRawResponse:
463
+ _client: Channel3
464
+
465
+ def __init__(self, client: Channel3) -> None:
466
+ self._client = client
467
+
468
+ @cached_property
469
+ def search(self) -> search.SearchResourceWithRawResponse:
470
+ from .resources.search import SearchResourceWithRawResponse
471
+
472
+ return SearchResourceWithRawResponse(self._client.search)
473
+
474
+ @cached_property
475
+ def products(self) -> products.ProductsResourceWithRawResponse:
476
+ from .resources.products import ProductsResourceWithRawResponse
477
+
478
+ return ProductsResourceWithRawResponse(self._client.products)
479
+
480
+ @cached_property
481
+ def brands(self) -> brands.BrandsResourceWithRawResponse:
482
+ from .resources.brands import BrandsResourceWithRawResponse
483
+
484
+ return BrandsResourceWithRawResponse(self._client.brands)
485
+
486
+ @cached_property
487
+ def websites(self) -> websites.WebsitesResourceWithRawResponse:
488
+ from .resources.websites import WebsitesResourceWithRawResponse
489
+
490
+ return WebsitesResourceWithRawResponse(self._client.websites)
491
+
492
+ @cached_property
493
+ def enrich(self) -> enrich.EnrichResourceWithRawResponse:
494
+ from .resources.enrich import EnrichResourceWithRawResponse
495
+
496
+ return EnrichResourceWithRawResponse(self._client.enrich)
497
+
498
+ @cached_property
499
+ def price_tracking(self) -> price_tracking.PriceTrackingResourceWithRawResponse:
500
+ from .resources.price_tracking import PriceTrackingResourceWithRawResponse
501
+
502
+ return PriceTrackingResourceWithRawResponse(self._client.price_tracking)
503
+
504
+
505
+ class AsyncChannel3WithRawResponse:
506
+ _client: AsyncChannel3
507
+
508
+ def __init__(self, client: AsyncChannel3) -> None:
509
+ self._client = client
510
+
511
+ @cached_property
512
+ def search(self) -> search.AsyncSearchResourceWithRawResponse:
513
+ from .resources.search import AsyncSearchResourceWithRawResponse
514
+
515
+ return AsyncSearchResourceWithRawResponse(self._client.search)
516
+
517
+ @cached_property
518
+ def products(self) -> products.AsyncProductsResourceWithRawResponse:
519
+ from .resources.products import AsyncProductsResourceWithRawResponse
520
+
521
+ return AsyncProductsResourceWithRawResponse(self._client.products)
522
+
523
+ @cached_property
524
+ def brands(self) -> brands.AsyncBrandsResourceWithRawResponse:
525
+ from .resources.brands import AsyncBrandsResourceWithRawResponse
526
+
527
+ return AsyncBrandsResourceWithRawResponse(self._client.brands)
528
+
529
+ @cached_property
530
+ def websites(self) -> websites.AsyncWebsitesResourceWithRawResponse:
531
+ from .resources.websites import AsyncWebsitesResourceWithRawResponse
532
+
533
+ return AsyncWebsitesResourceWithRawResponse(self._client.websites)
534
+
535
+ @cached_property
536
+ def enrich(self) -> enrich.AsyncEnrichResourceWithRawResponse:
537
+ from .resources.enrich import AsyncEnrichResourceWithRawResponse
538
+
539
+ return AsyncEnrichResourceWithRawResponse(self._client.enrich)
540
+
541
+ @cached_property
542
+ def price_tracking(self) -> price_tracking.AsyncPriceTrackingResourceWithRawResponse:
543
+ from .resources.price_tracking import AsyncPriceTrackingResourceWithRawResponse
544
+
545
+ return AsyncPriceTrackingResourceWithRawResponse(self._client.price_tracking)
546
+
547
+
548
+ class Channel3WithStreamedResponse:
549
+ _client: Channel3
550
+
551
+ def __init__(self, client: Channel3) -> None:
552
+ self._client = client
553
+
554
+ @cached_property
555
+ def search(self) -> search.SearchResourceWithStreamingResponse:
556
+ from .resources.search import SearchResourceWithStreamingResponse
557
+
558
+ return SearchResourceWithStreamingResponse(self._client.search)
559
+
560
+ @cached_property
561
+ def products(self) -> products.ProductsResourceWithStreamingResponse:
562
+ from .resources.products import ProductsResourceWithStreamingResponse
563
+
564
+ return ProductsResourceWithStreamingResponse(self._client.products)
565
+
566
+ @cached_property
567
+ def brands(self) -> brands.BrandsResourceWithStreamingResponse:
568
+ from .resources.brands import BrandsResourceWithStreamingResponse
569
+
570
+ return BrandsResourceWithStreamingResponse(self._client.brands)
571
+
572
+ @cached_property
573
+ def websites(self) -> websites.WebsitesResourceWithStreamingResponse:
574
+ from .resources.websites import WebsitesResourceWithStreamingResponse
575
+
576
+ return WebsitesResourceWithStreamingResponse(self._client.websites)
577
+
578
+ @cached_property
579
+ def enrich(self) -> enrich.EnrichResourceWithStreamingResponse:
580
+ from .resources.enrich import EnrichResourceWithStreamingResponse
581
+
582
+ return EnrichResourceWithStreamingResponse(self._client.enrich)
583
+
584
+ @cached_property
585
+ def price_tracking(self) -> price_tracking.PriceTrackingResourceWithStreamingResponse:
586
+ from .resources.price_tracking import PriceTrackingResourceWithStreamingResponse
587
+
588
+ return PriceTrackingResourceWithStreamingResponse(self._client.price_tracking)
589
+
590
+
591
+ class AsyncChannel3WithStreamedResponse:
592
+ _client: AsyncChannel3
593
+
594
+ def __init__(self, client: AsyncChannel3) -> None:
595
+ self._client = client
596
+
597
+ @cached_property
598
+ def search(self) -> search.AsyncSearchResourceWithStreamingResponse:
599
+ from .resources.search import AsyncSearchResourceWithStreamingResponse
600
+
601
+ return AsyncSearchResourceWithStreamingResponse(self._client.search)
602
+
603
+ @cached_property
604
+ def products(self) -> products.AsyncProductsResourceWithStreamingResponse:
605
+ from .resources.products import AsyncProductsResourceWithStreamingResponse
606
+
607
+ return AsyncProductsResourceWithStreamingResponse(self._client.products)
608
+
609
+ @cached_property
610
+ def brands(self) -> brands.AsyncBrandsResourceWithStreamingResponse:
611
+ from .resources.brands import AsyncBrandsResourceWithStreamingResponse
612
+
613
+ return AsyncBrandsResourceWithStreamingResponse(self._client.brands)
614
+
615
+ @cached_property
616
+ def websites(self) -> websites.AsyncWebsitesResourceWithStreamingResponse:
617
+ from .resources.websites import AsyncWebsitesResourceWithStreamingResponse
618
+
619
+ return AsyncWebsitesResourceWithStreamingResponse(self._client.websites)
620
+
621
+ @cached_property
622
+ def enrich(self) -> enrich.AsyncEnrichResourceWithStreamingResponse:
623
+ from .resources.enrich import AsyncEnrichResourceWithStreamingResponse
624
+
625
+ return AsyncEnrichResourceWithStreamingResponse(self._client.enrich)
626
+
627
+ @cached_property
628
+ def price_tracking(self) -> price_tracking.AsyncPriceTrackingResourceWithStreamingResponse:
629
+ from .resources.price_tracking import AsyncPriceTrackingResourceWithStreamingResponse
630
+
631
+ return AsyncPriceTrackingResourceWithStreamingResponse(self._client.price_tracking)
632
+
633
+
634
+ Client = Channel3
635
+
636
+ AsyncClient = AsyncChannel3