async-amazon-ads-api-v1 0.3.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 (67) hide show
  1. async_amazon_ads_api_v1/__init__.py +30 -0
  2. async_amazon_ads_api_v1/_base.py +171 -0
  3. async_amazon_ads_api_v1/client/sb/__init__.py +121 -0
  4. async_amazon_ads_api_v1/client/sb/ad_extensions.py +39 -0
  5. async_amazon_ads_api_v1/client/sb/ad_groups.py +41 -0
  6. async_amazon_ads_api_v1/client/sb/ads.py +37 -0
  7. async_amazon_ads_api_v1/client/sb/advertising_deal_targets.py +41 -0
  8. async_amazon_ads_api_v1/client/sb/advertising_deals.py +44 -0
  9. async_amazon_ads_api_v1/client/sb/branded_keywords_pricings.py +24 -0
  10. async_amazon_ads_api_v1/client/sb/campaigns.py +41 -0
  11. async_amazon_ads_api_v1/client/sb/keyword_reservation_validations.py +24 -0
  12. async_amazon_ads_api_v1/client/sb/recommendation_types.py +26 -0
  13. async_amazon_ads_api_v1/client/sb/recommendations.py +24 -0
  14. async_amazon_ads_api_v1/client/sb/targets.py +41 -0
  15. async_amazon_ads_api_v1/client/sd/__init__.py +65 -0
  16. async_amazon_ads_api_v1/client/sd/ad_groups.py +41 -0
  17. async_amazon_ads_api_v1/client/sd/ads.py +37 -0
  18. async_amazon_ads_api_v1/client/sd/campaigns.py +41 -0
  19. async_amazon_ads_api_v1/client/sd/targets.py +41 -0
  20. async_amazon_ads_api_v1/client/sp/__init__.py +73 -0
  21. async_amazon_ads_api_v1/client/sp/ad_extensions.py +40 -0
  22. async_amazon_ads_api_v1/client/sp/ad_groups.py +43 -0
  23. async_amazon_ads_api_v1/client/sp/ads.py +39 -0
  24. async_amazon_ads_api_v1/client/sp/campaigns.py +43 -0
  25. async_amazon_ads_api_v1/client/sp/targets.py +43 -0
  26. async_amazon_ads_api_v1/config/__init__.py +1 -0
  27. async_amazon_ads_api_v1/config/loader.py +82 -0
  28. async_amazon_ads_api_v1/config/region.py +20 -0
  29. async_amazon_ads_api_v1/config/settings.py +136 -0
  30. async_amazon_ads_api_v1/config/token_cache.py +192 -0
  31. async_amazon_ads_api_v1/config/token_manager.py +124 -0
  32. async_amazon_ads_api_v1/errors.py +144 -0
  33. async_amazon_ads_api_v1/models/base.py +3 -0
  34. async_amazon_ads_api_v1/models/sb/__init__.py +34 -0
  35. async_amazon_ads_api_v1/models/sb/ad_extensions.py +262 -0
  36. async_amazon_ads_api_v1/models/sb/ad_groups.py +197 -0
  37. async_amazon_ads_api_v1/models/sb/ads.py +973 -0
  38. async_amazon_ads_api_v1/models/sb/advertising_deal_targets.py +153 -0
  39. async_amazon_ads_api_v1/models/sb/advertising_deals.py +220 -0
  40. async_amazon_ads_api_v1/models/sb/branded_keywords_pricings.py +96 -0
  41. async_amazon_ads_api_v1/models/sb/campaigns.py +724 -0
  42. async_amazon_ads_api_v1/models/sb/enums.py +205 -0
  43. async_amazon_ads_api_v1/models/sb/keyword_reservation_validations.py +67 -0
  44. async_amazon_ads_api_v1/models/sb/recommendation_types.py +37 -0
  45. async_amazon_ads_api_v1/models/sb/recommendations.py +177 -0
  46. async_amazon_ads_api_v1/models/sb/shared.py +176 -0
  47. async_amazon_ads_api_v1/models/sb/targets.py +585 -0
  48. async_amazon_ads_api_v1/models/sd/__init__.py +27 -0
  49. async_amazon_ads_api_v1/models/sd/ad_groups.py +348 -0
  50. async_amazon_ads_api_v1/models/sd/ads.py +518 -0
  51. async_amazon_ads_api_v1/models/sd/campaigns.py +413 -0
  52. async_amazon_ads_api_v1/models/sd/enums.py +193 -0
  53. async_amazon_ads_api_v1/models/sd/shared.py +97 -0
  54. async_amazon_ads_api_v1/models/sd/targets.py +661 -0
  55. async_amazon_ads_api_v1/models/sp/__init__.py +28 -0
  56. async_amazon_ads_api_v1/models/sp/ad_extensions.py +300 -0
  57. async_amazon_ads_api_v1/models/sp/ad_groups.py +275 -0
  58. async_amazon_ads_api_v1/models/sp/ads.py +390 -0
  59. async_amazon_ads_api_v1/models/sp/campaigns.py +706 -0
  60. async_amazon_ads_api_v1/models/sp/enums.py +197 -0
  61. async_amazon_ads_api_v1/models/sp/shared.py +217 -0
  62. async_amazon_ads_api_v1/models/sp/targets.py +668 -0
  63. async_amazon_ads_api_v1/py.typed +0 -0
  64. async_amazon_ads_api_v1-0.3.0.dist-info/METADATA +197 -0
  65. async_amazon_ads_api_v1-0.3.0.dist-info/RECORD +67 -0
  66. async_amazon_ads_api_v1-0.3.0.dist-info/WHEEL +4 -0
  67. async_amazon_ads_api_v1-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,30 @@
1
+ """Pure async Amazon Ads API v1 client — Sponsored Products, Sponsored Brands, Sponsored Display."""
2
+
3
+ from async_amazon_ads_api_v1.client.sb import SBClient
4
+ from async_amazon_ads_api_v1.client.sd import SDClient
5
+ from async_amazon_ads_api_v1.client.sp import SPClient
6
+ from async_amazon_ads_api_v1.config.region import Region
7
+ from async_amazon_ads_api_v1.config.settings import AmazonAdsConfig, CacheBackend
8
+ from async_amazon_ads_api_v1.config.token_cache import (
9
+ BaseTokenCache,
10
+ FileTokenCache,
11
+ RedisTokenCache,
12
+ close_all_redis,
13
+ )
14
+ from async_amazon_ads_api_v1.config.token_manager import TokenCredentials, TokenManager
15
+
16
+ __all__ = [
17
+ "AmazonAdsConfig",
18
+ "BaseTokenCache",
19
+ "CacheBackend",
20
+ "FileTokenCache",
21
+ "RedisTokenCache",
22
+ "Region",
23
+ "SBClient",
24
+ "SDClient",
25
+ "SPClient",
26
+ "TokenCredentials",
27
+ "TokenManager",
28
+ "close_all_redis",
29
+ ]
30
+ __version__ = "0.3.0"
@@ -0,0 +1,171 @@
1
+ """Shared HTTP session and base resource class for all API resource classes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import logging
7
+ import random
8
+ from dataclasses import dataclass
9
+ from typing import Any, TypeVar, cast
10
+
11
+ import httpx
12
+ from pydantic import BaseModel, ValidationError
13
+
14
+ from .config.settings import AmazonAdsConfig
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ _T = TypeVar("_T", bound=BaseModel)
19
+
20
+
21
+ class ClientContext:
22
+ """Shared HTTP state for all resource instances.
23
+
24
+ Lazily creates and caches the ``httpx.AsyncClient`` on first use.
25
+ """
26
+
27
+ __slots__ = ("config", "_client")
28
+
29
+ def __init__(self, config: AmazonAdsConfig) -> None:
30
+ self.config: AmazonAdsConfig = config
31
+ self._client: httpx.AsyncClient | None = None
32
+
33
+ async def get_client(self) -> httpx.AsyncClient:
34
+ if self._client is None:
35
+ self._client = httpx.AsyncClient(
36
+ base_url=self.config.base_url,
37
+ timeout=httpx.Timeout(self.config.timeout),
38
+ )
39
+ return self._client
40
+
41
+ def _response(self, model_cls: type[_T], resp: httpx.Response) -> _T | dict[str, Any]:
42
+ if self.config.raw_response:
43
+ return cast(dict[str, Any], resp.json())
44
+ try:
45
+ return model_cls.model_validate_json(resp.content, extra="ignore")
46
+ except ValidationError:
47
+ logger.warning(
48
+ "Failed to validate response for %s (status=%s): %s",
49
+ model_cls.__name__,
50
+ resp.status_code,
51
+ resp.text,
52
+ )
53
+ raise
54
+
55
+
56
+ @dataclass
57
+ class _ResourceSpec:
58
+ """Metadata for a REST resource (campaigns, adGroups, etc)."""
59
+
60
+ name: str
61
+ create_model: type[BaseModel]
62
+ update_model: type[BaseModel] | None = None
63
+ delete_key: str | None = None
64
+ path_suffix: str = ""
65
+
66
+
67
+ class _ResourceBase:
68
+ """Base class providing shared HTTP operations for resource classes."""
69
+
70
+ __slots__ = ("_ctx",)
71
+
72
+ def __init__(self, ctx: ClientContext) -> None:
73
+ self._ctx: ClientContext = ctx
74
+
75
+ async def _request(
76
+ self,
77
+ method: str,
78
+ path: str,
79
+ *,
80
+ params: dict[str, Any] | None = None,
81
+ json: dict[str, Any] | None = None,
82
+ accept_async: bool = False,
83
+ ) -> httpx.Response:
84
+ client = await self._ctx.get_client()
85
+ accept = "application/vnd.createasyncrequestresults.v3+json" if accept_async else "application/json"
86
+ if self._ctx.config.access_token is None and self._ctx.config.refresh_token:
87
+ await self._ctx.config.refresh_access_token()
88
+ headers = {
89
+ "Authorization": f"Bearer {self._ctx.config.access_token}",
90
+ "Accept": accept,
91
+ "Amazon-Ads-ClientId": self._ctx.config.client_id,
92
+ }
93
+ if self._ctx.config.profile_id is not None:
94
+ headers["Amazon-Advertising-API-Scope"] = self._ctx.config.profile_id
95
+ for attempt in range(self._ctx.config.max_retries):
96
+ try:
97
+ resp = await client.request(
98
+ method=method,
99
+ url=path,
100
+ params=params,
101
+ json=json,
102
+ headers=headers,
103
+ )
104
+ resp.raise_for_status()
105
+ return resp
106
+ except httpx.HTTPStatusError as exc:
107
+ if exc.response.status_code == 401 and self._ctx.config.refresh_token and attempt == 0:
108
+ await self._ctx.config.refresh_access_token()
109
+ headers["Authorization"] = f"Bearer {self._ctx.config.access_token}"
110
+ continue
111
+ if exc.response.status_code in (429, 503, 504):
112
+ if attempt < self._ctx.config.max_retries - 1:
113
+ wait_time = 2**attempt + random.uniform(0, 1)
114
+ logger.warning(f"Rate limit exceeded, retrying in %.2f seconds {exc}", wait_time)
115
+ await asyncio.sleep(wait_time)
116
+ continue
117
+ logger.error(f"{exc.response.status_code} {exc.response.text}")
118
+ raise
119
+ except httpx.ConnectError:
120
+ if attempt < self._ctx.config.max_retries - 1:
121
+ await asyncio.sleep(2**attempt + random.uniform(0, 1))
122
+ continue
123
+ raise
124
+ raise RuntimeError("Retry loop exited unexpectedly")
125
+
126
+ def _response(self, model_cls: type[_T], resp: httpx.Response) -> _T | dict[str, Any]:
127
+ return self._ctx._response(model_cls, resp)
128
+
129
+ def _validate(self, items: list[Any], model_cls: type[_T]) -> list[dict[str, Any]]:
130
+ result: list[dict[str, Any]] = []
131
+ for item in items:
132
+ if isinstance(item, model_cls):
133
+ result.append(item.model_dump(mode="json", exclude_none=True))
134
+ else:
135
+ result.append(model_cls(**item).model_dump(mode="json", exclude_none=True))
136
+ return result
137
+
138
+ async def _create(self, items: list[Any], spec: _ResourceSpec, response_cls: type[_T]) -> _T | dict[str, Any]:
139
+ validated = self._validate(items, spec.create_model)
140
+ resp = await self._request(
141
+ "POST",
142
+ f"/adsApi/v1/create/{spec.name}{spec.path_suffix}",
143
+ json={spec.name: validated},
144
+ accept_async=True,
145
+ )
146
+ return self._response(response_cls, resp)
147
+
148
+ async def _update(self, items: list[Any], spec: _ResourceSpec, response_cls: type[_T]) -> _T | dict[str, Any]:
149
+ assert spec.update_model is not None, f"{spec.name} has no update model"
150
+ validated = self._validate(items, spec.update_model)
151
+ resp = await self._request(
152
+ "POST",
153
+ f"/adsApi/v1/update/{spec.name}{spec.path_suffix}",
154
+ json={spec.name: validated},
155
+ accept_async=True,
156
+ )
157
+ return self._response(response_cls, resp)
158
+
159
+ async def _delete(self, ids: list[str], spec: _ResourceSpec, response_cls: type[_T]) -> _T | dict[str, Any]:
160
+ assert spec.delete_key is not None, f"{spec.name} has no delete operation"
161
+ resp = await self._request(
162
+ "POST",
163
+ f"/adsApi/v1/delete/{spec.name}{spec.path_suffix}",
164
+ json={spec.delete_key: ids},
165
+ accept_async=True,
166
+ )
167
+ return self._response(response_cls, resp)
168
+
169
+ async def _query(self, body: BaseModel, path: str, response_cls: type[_T]) -> _T | dict[str, Any]:
170
+ resp = await self._request("POST", path, json=body.model_dump(exclude_none=True))
171
+ return self._response(response_cls, resp)
@@ -0,0 +1,121 @@
1
+ """Sponsored Brands async HTTP client."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import ClientContext
8
+ from async_amazon_ads_api_v1.config.settings import AmazonAdsConfig
9
+
10
+ from .ad_extensions import AdExtensions
11
+ from .ad_groups import AdGroups
12
+ from .ads import Ads
13
+ from .advertising_deal_targets import AdvertisingDealTargets
14
+ from .advertising_deals import AdvertisingDeals
15
+ from .branded_keywords_pricings import BrandedKeywordsPricings
16
+ from .campaigns import Campaigns
17
+ from .keyword_reservation_validations import KeywordReservationValidations
18
+ from .recommendation_types import RecommendationTypes
19
+ from .recommendations import Recommendations
20
+ from .targets import Targets
21
+
22
+
23
+ class SBClient:
24
+ """Async HTTP client for Amazon Ads Sponsored Brands API.
25
+
26
+ Parameters
27
+ ----------
28
+ config : AmazonAdsConfig
29
+ Client configuration (auth, region, timeouts, retries).
30
+ """
31
+
32
+ def __init__(self, config: AmazonAdsConfig) -> None:
33
+ self._ctx = ClientContext(config)
34
+ self.__campaign: Campaigns | None = None
35
+ self.__ad_group: AdGroups | None = None
36
+ self.__ad: Ads | None = None
37
+ self.__target: Targets | None = None
38
+ self.__ad_extension: AdExtensions | None = None
39
+ self.__advertising_deal_target: AdvertisingDealTargets | None = None
40
+ self.__advertising_deal: AdvertisingDeals | None = None
41
+ self.__branded_keywords_pricing: BrandedKeywordsPricings | None = None
42
+ self.__keyword_reservation_validation: KeywordReservationValidations | None = None
43
+ self.__recommendation_type: RecommendationTypes | None = None
44
+ self.__recommendation: Recommendations | None = None
45
+
46
+ async def __aenter__(self) -> SBClient:
47
+ return self
48
+
49
+ async def __aexit__(self, *args: Any) -> None:
50
+ await self.close()
51
+
52
+ async def close(self) -> None:
53
+ if self._ctx._client is not None:
54
+ await self._ctx._client.aclose()
55
+ self._ctx._client = None
56
+
57
+ @property
58
+ def campaigns(self) -> Campaigns:
59
+ if self.__campaign is None:
60
+ self.__campaign = Campaigns(self._ctx)
61
+ return self.__campaign
62
+
63
+ @property
64
+ def ad_groups(self) -> AdGroups:
65
+ if self.__ad_group is None:
66
+ self.__ad_group = AdGroups(self._ctx)
67
+ return self.__ad_group
68
+
69
+ @property
70
+ def ads(self) -> Ads:
71
+ if self.__ad is None:
72
+ self.__ad = Ads(self._ctx)
73
+ return self.__ad
74
+
75
+ @property
76
+ def targets(self) -> Targets:
77
+ if self.__target is None:
78
+ self.__target = Targets(self._ctx)
79
+ return self.__target
80
+
81
+ @property
82
+ def ad_extensions(self) -> AdExtensions:
83
+ if self.__ad_extension is None:
84
+ self.__ad_extension = AdExtensions(self._ctx)
85
+ return self.__ad_extension
86
+
87
+ @property
88
+ def advertising_deal_targets(self) -> AdvertisingDealTargets:
89
+ if self.__advertising_deal_target is None:
90
+ self.__advertising_deal_target = AdvertisingDealTargets(self._ctx)
91
+ return self.__advertising_deal_target
92
+
93
+ @property
94
+ def advertising_deals(self) -> AdvertisingDeals:
95
+ if self.__advertising_deal is None:
96
+ self.__advertising_deal = AdvertisingDeals(self._ctx)
97
+ return self.__advertising_deal
98
+
99
+ @property
100
+ def branded_keywords_pricings(self) -> BrandedKeywordsPricings:
101
+ if self.__branded_keywords_pricing is None:
102
+ self.__branded_keywords_pricing = BrandedKeywordsPricings(self._ctx)
103
+ return self.__branded_keywords_pricing
104
+
105
+ @property
106
+ def keyword_reservation_validations(self) -> KeywordReservationValidations:
107
+ if self.__keyword_reservation_validation is None:
108
+ self.__keyword_reservation_validation = KeywordReservationValidations(self._ctx)
109
+ return self.__keyword_reservation_validation
110
+
111
+ @property
112
+ def recommendation_types(self) -> RecommendationTypes:
113
+ if self.__recommendation_type is None:
114
+ self.__recommendation_type = RecommendationTypes(self._ctx)
115
+ return self.__recommendation_type
116
+
117
+ @property
118
+ def recommendations(self) -> Recommendations:
119
+ if self.__recommendation is None:
120
+ self.__recommendation = Recommendations(self._ctx)
121
+ return self.__recommendation
@@ -0,0 +1,39 @@
1
+ """SB AdExtension resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBAdExtensionCreate,
10
+ SBAdExtensionMultiStatusResponse,
11
+ SBAdExtensionSuccessResponse,
12
+ SBAdExtensionUpdate,
13
+ SBQueryAdExtensionRequest,
14
+ )
15
+
16
+
17
+ class AdExtensions(_ResourceBase):
18
+ _spec = _ResourceSpec(
19
+ name="adExtensions",
20
+ create_model=SBAdExtensionCreate,
21
+ update_model=SBAdExtensionUpdate,
22
+ )
23
+
24
+ async def create(
25
+ self, ad_extensions: list[dict[str, Any] | SBAdExtensionCreate]
26
+ ) -> SBAdExtensionSuccessResponse | dict[str, Any]:
27
+ return await self._create(ad_extensions, self._spec, SBAdExtensionSuccessResponse)
28
+
29
+ async def query(
30
+ self, body: dict[str, Any] | SBQueryAdExtensionRequest
31
+ ) -> SBAdExtensionSuccessResponse | dict[str, Any]:
32
+ if isinstance(body, dict):
33
+ body = SBQueryAdExtensionRequest(**body)
34
+ return await self._query(body, "/adsApi/v1/query/adExtensions", SBAdExtensionSuccessResponse)
35
+
36
+ async def update(
37
+ self, ad_extensions: list[dict[str, Any] | SBAdExtensionUpdate]
38
+ ) -> SBAdExtensionMultiStatusResponse | dict[str, Any]:
39
+ return await self._update(ad_extensions, self._spec, SBAdExtensionMultiStatusResponse)
@@ -0,0 +1,41 @@
1
+ """SB AdGroup resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBAdGroupCreate,
10
+ SBAdGroupMultiStatusResponse,
11
+ SBAdGroupSuccessResponse,
12
+ SBAdGroupUpdate,
13
+ SBQueryAdGroupRequest,
14
+ )
15
+
16
+
17
+ class AdGroups(_ResourceBase):
18
+ _spec = _ResourceSpec(
19
+ name="adGroups",
20
+ create_model=SBAdGroupCreate,
21
+ update_model=SBAdGroupUpdate,
22
+ delete_key="adGroupIds",
23
+ )
24
+
25
+ async def create(
26
+ self, ad_groups: list[dict[str, Any] | SBAdGroupCreate]
27
+ ) -> SBAdGroupMultiStatusResponse | dict[str, Any]:
28
+ return await self._create(ad_groups, self._spec, SBAdGroupMultiStatusResponse)
29
+
30
+ async def query(self, body: dict[str, Any] | SBQueryAdGroupRequest) -> SBAdGroupSuccessResponse | dict[str, Any]:
31
+ if isinstance(body, dict):
32
+ body = SBQueryAdGroupRequest(**body)
33
+ return await self._query(body, "/adsApi/v1/query/adGroups", SBAdGroupSuccessResponse)
34
+
35
+ async def update(
36
+ self, ad_groups: list[dict[str, Any] | SBAdGroupUpdate]
37
+ ) -> SBAdGroupMultiStatusResponse | dict[str, Any]:
38
+ return await self._update(ad_groups, self._spec, SBAdGroupMultiStatusResponse)
39
+
40
+ async def delete(self, ad_group_ids: list[str]) -> SBAdGroupMultiStatusResponse | dict[str, Any]:
41
+ return await self._delete(ad_group_ids, self._spec, SBAdGroupMultiStatusResponse)
@@ -0,0 +1,37 @@
1
+ """SB Ad resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBAdCreate,
10
+ SBAdMultiStatusResponse,
11
+ SBAdSuccessResponse,
12
+ SBAdUpdate,
13
+ SBQueryAdRequest,
14
+ )
15
+
16
+
17
+ class Ads(_ResourceBase):
18
+ _spec = _ResourceSpec(
19
+ name="ads",
20
+ create_model=SBAdCreate,
21
+ update_model=SBAdUpdate,
22
+ delete_key="adIds",
23
+ )
24
+
25
+ async def create(self, ads: list[dict[str, Any] | SBAdCreate]) -> SBAdMultiStatusResponse | dict[str, Any]:
26
+ return await self._create(ads, self._spec, SBAdMultiStatusResponse)
27
+
28
+ async def query(self, body: dict[str, Any] | SBQueryAdRequest) -> SBAdSuccessResponse | dict[str, Any]:
29
+ if isinstance(body, dict):
30
+ body = SBQueryAdRequest(**body)
31
+ return await self._query(body, "/adsApi/v1/query/ads", SBAdSuccessResponse)
32
+
33
+ async def update(self, ads: list[dict[str, Any] | SBAdUpdate]) -> SBAdMultiStatusResponse | dict[str, Any]:
34
+ return await self._update(ads, self._spec, SBAdMultiStatusResponse)
35
+
36
+ async def delete(self, ad_ids: list[str]) -> SBAdMultiStatusResponse | dict[str, Any]:
37
+ return await self._delete(ad_ids, self._spec, SBAdMultiStatusResponse)
@@ -0,0 +1,41 @@
1
+ """SB AdvertisingDealTarget resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBAdvertisingDealTargetCreate,
10
+ SBAdvertisingDealTargetMultiStatusResponse,
11
+ SBAdvertisingDealTargetSuccessResponse,
12
+ SBQueryAdvertisingDealTargetRequest,
13
+ )
14
+
15
+
16
+ class AdvertisingDealTargets(_ResourceBase):
17
+ _spec = _ResourceSpec(
18
+ name="advertisingDealTargets",
19
+ create_model=SBAdvertisingDealTargetCreate,
20
+ delete_key="advertisingDealTargetIds",
21
+ path_suffix="/sb",
22
+ )
23
+
24
+ async def create(
25
+ self, items: list[dict[str, Any] | SBAdvertisingDealTargetCreate]
26
+ ) -> SBAdvertisingDealTargetSuccessResponse | dict[str, Any]:
27
+ return await self._create(items, self._spec, SBAdvertisingDealTargetSuccessResponse)
28
+
29
+ async def query(
30
+ self, body: dict[str, Any] | SBQueryAdvertisingDealTargetRequest
31
+ ) -> SBAdvertisingDealTargetSuccessResponse | dict[str, Any]:
32
+ if isinstance(body, dict):
33
+ body = SBQueryAdvertisingDealTargetRequest(**body)
34
+ return await self._query(
35
+ body,
36
+ "/adsApi/v1/query/advertisingDealTargets/sb",
37
+ SBAdvertisingDealTargetSuccessResponse,
38
+ )
39
+
40
+ async def delete(self, ids: list[str]) -> SBAdvertisingDealTargetMultiStatusResponse | dict[str, Any]:
41
+ return await self._delete(ids, self._spec, SBAdvertisingDealTargetMultiStatusResponse)
@@ -0,0 +1,44 @@
1
+ """SB AdvertisingDeal resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBAdvertisingDealCreate,
10
+ SBAdvertisingDealMultiStatusResponse,
11
+ SBAdvertisingDealSuccessResponse,
12
+ SBAdvertisingDealUpdate,
13
+ SBQueryAdvertisingDealRequest,
14
+ )
15
+
16
+
17
+ class AdvertisingDeals(_ResourceBase):
18
+ _spec = _ResourceSpec(
19
+ name="advertisingDeals",
20
+ create_model=SBAdvertisingDealCreate,
21
+ update_model=SBAdvertisingDealUpdate,
22
+ delete_key="advertisingDealIds",
23
+ path_suffix="/sb",
24
+ )
25
+
26
+ async def create(
27
+ self, items: list[dict[str, Any] | SBAdvertisingDealCreate]
28
+ ) -> SBAdvertisingDealSuccessResponse | dict[str, Any]:
29
+ return await self._create(items, self._spec, SBAdvertisingDealSuccessResponse)
30
+
31
+ async def query(
32
+ self, body: dict[str, Any] | SBQueryAdvertisingDealRequest
33
+ ) -> SBAdvertisingDealSuccessResponse | dict[str, Any]:
34
+ if isinstance(body, dict):
35
+ body = SBQueryAdvertisingDealRequest(**body)
36
+ return await self._query(body, "/adsApi/v1/query/advertisingDeals/sb", SBAdvertisingDealSuccessResponse)
37
+
38
+ async def update(
39
+ self, items: list[dict[str, Any] | SBAdvertisingDealUpdate]
40
+ ) -> SBAdvertisingDealMultiStatusResponse | dict[str, Any]:
41
+ return await self._update(items, self._spec, SBAdvertisingDealMultiStatusResponse)
42
+
43
+ async def delete(self, ids: list[str]) -> SBAdvertisingDealMultiStatusResponse | dict[str, Any]:
44
+ return await self._delete(ids, self._spec, SBAdvertisingDealMultiStatusResponse)
@@ -0,0 +1,24 @@
1
+ """SB BrandedKeywordsPricing resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBBrandedKeywordsPricingCreate,
10
+ SBBrandedKeywordsPricingMultiStatusResponse,
11
+ )
12
+
13
+
14
+ class BrandedKeywordsPricings(_ResourceBase):
15
+ _spec = _ResourceSpec(
16
+ name="brandedKeywordsPricings",
17
+ create_model=SBBrandedKeywordsPricingCreate,
18
+ path_suffix="/sb",
19
+ )
20
+
21
+ async def create(
22
+ self, items: list[dict[str, Any] | SBBrandedKeywordsPricingCreate]
23
+ ) -> SBBrandedKeywordsPricingMultiStatusResponse | dict[str, Any]:
24
+ return await self._create(items, self._spec, SBBrandedKeywordsPricingMultiStatusResponse)
@@ -0,0 +1,41 @@
1
+ """SB Campaign resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBCampaignCreate,
10
+ SBCampaignMultiStatusResponse,
11
+ SBCampaignSuccessResponse,
12
+ SBCampaignUpdate,
13
+ SBQueryCampaignRequest,
14
+ )
15
+
16
+
17
+ class Campaigns(_ResourceBase):
18
+ _spec = _ResourceSpec(
19
+ name="campaigns",
20
+ create_model=SBCampaignCreate,
21
+ update_model=SBCampaignUpdate,
22
+ delete_key="campaignIds",
23
+ )
24
+
25
+ async def create(
26
+ self, campaigns: list[dict[str, Any] | SBCampaignCreate]
27
+ ) -> SBCampaignMultiStatusResponse | dict[str, Any]:
28
+ return await self._create(campaigns, self._spec, SBCampaignMultiStatusResponse)
29
+
30
+ async def query(self, body: dict[str, Any] | SBQueryCampaignRequest) -> SBCampaignSuccessResponse | dict[str, Any]:
31
+ if isinstance(body, dict):
32
+ body = SBQueryCampaignRequest(**body)
33
+ return await self._query(body, "/adsApi/v1/query/campaigns", SBCampaignSuccessResponse)
34
+
35
+ async def update(
36
+ self, campaigns: list[dict[str, Any] | SBCampaignUpdate]
37
+ ) -> SBCampaignMultiStatusResponse | dict[str, Any]:
38
+ return await self._update(campaigns, self._spec, SBCampaignMultiStatusResponse)
39
+
40
+ async def delete(self, campaign_ids: list[str]) -> SBCampaignMultiStatusResponse | dict[str, Any]:
41
+ return await self._delete(campaign_ids, self._spec, SBCampaignMultiStatusResponse)
@@ -0,0 +1,24 @@
1
+ """SB KeywordReservationValidation resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBKeywordReservationValidationCreate,
10
+ SBKeywordReservationValidationMultiStatusResponse,
11
+ )
12
+
13
+
14
+ class KeywordReservationValidations(_ResourceBase):
15
+ _spec = _ResourceSpec(
16
+ name="keywordReservationValidations",
17
+ create_model=SBKeywordReservationValidationCreate,
18
+ path_suffix="/sb",
19
+ )
20
+
21
+ async def create(
22
+ self, items: list[dict[str, Any] | SBKeywordReservationValidationCreate]
23
+ ) -> SBKeywordReservationValidationMultiStatusResponse | dict[str, Any]:
24
+ return await self._create(items, self._spec, SBKeywordReservationValidationMultiStatusResponse)
@@ -0,0 +1,26 @@
1
+ """SB RecommendationType resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBQueryRecommendationTypeRequest,
10
+ SBRecommendationTypeSuccessResponse,
11
+ )
12
+
13
+
14
+ class RecommendationTypes(_ResourceBase):
15
+ _spec = _ResourceSpec(
16
+ name="recommendationTypes",
17
+ create_model=SBRecommendationTypeSuccessResponse,
18
+ path_suffix="/sb",
19
+ )
20
+
21
+ async def query(
22
+ self, body: dict[str, Any] | SBQueryRecommendationTypeRequest
23
+ ) -> SBRecommendationTypeSuccessResponse | dict[str, Any]:
24
+ if isinstance(body, dict):
25
+ body = SBQueryRecommendationTypeRequest(**body)
26
+ return await self._query(body, "/adsApi/v1/query/recommendationTypes/sb", SBRecommendationTypeSuccessResponse)
@@ -0,0 +1,24 @@
1
+ """SB Recommendation resource operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from async_amazon_ads_api_v1._base import _ResourceBase, _ResourceSpec
8
+ from async_amazon_ads_api_v1.models.sb import (
9
+ SBRecommendationCreate,
10
+ SBRecommendationMultiStatusResponse,
11
+ )
12
+
13
+
14
+ class Recommendations(_ResourceBase):
15
+ _spec = _ResourceSpec(
16
+ name="recommendations",
17
+ create_model=SBRecommendationCreate,
18
+ path_suffix="/sb",
19
+ )
20
+
21
+ async def create(
22
+ self, items: list[dict[str, Any] | SBRecommendationCreate]
23
+ ) -> SBRecommendationMultiStatusResponse | dict[str, Any]:
24
+ return await self._create(items, self._spec, SBRecommendationMultiStatusResponse)