python-amazon-ad-api 1.3.0__py3-none-any.whl → 1.4.1__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.
ad_api/api/attribution.py CHANGED
@@ -9,6 +9,31 @@ class Attribution(Client):
9
9
  def get_advertisers(self, **kwargs) -> ApiResponse:
10
10
  r"""
11
11
  Gets a list of advertisers associated with an Amazon Attribution account.
12
+
13
+ Takes no query parameters. Send the request as is.
14
+
15
+ Returns:
16
+ ApiResponse. ``payload`` holds ``{"advertisers": [...]}`` with one
17
+ entry per advertiser:
18
+
19
+ - ``advertiserId`` (string): the identifier the other Attribution
20
+ routes accept as ``advertiserIds``.
21
+ - ``advertiserName`` (string): the display name.
22
+
23
+ Example:
24
+
25
+ .. code-block:: python
26
+
27
+ from ad_api.api import Attribution
28
+
29
+ attribution = Attribution(account="my_account")
30
+ attribution.get_advertisers().payload
31
+ # {'advertisers': [{'advertiserName': 'MY BRAND SPAIN',
32
+ # 'advertiserId': '586616515354498787'}]}
33
+
34
+ An account without Attribution access answers ``200`` with an empty
35
+ ``advertisers`` list, not a ``403``, so check the list itself.
36
+ ``ApiResponse`` does not carry the HTTP status code.
12
37
  """
13
38
  return self._request(fill_query_params(kwargs.pop("path")), params=kwargs)
14
39
 
@@ -16,6 +41,32 @@ class Attribution(Client):
16
41
  def get_publishers(self, **kwargs) -> ApiResponse:
17
42
  r"""
18
43
  Gets a list of all available publishers.
44
+
45
+ Takes no query parameters. Send the request as is. This is the call that
46
+ tells you which of the two tag routes each publisher belongs to.
47
+
48
+ Returns:
49
+ ApiResponse. ``payload`` holds ``{"publishers": [...]}`` with one
50
+ entry per publisher:
51
+
52
+ - ``id`` (string): the value to pass as ``publisherIds``.
53
+ - ``name`` (string): the display name, such as ``Google Ads``.
54
+ - ``macroEnabled`` (boolean): ``True`` when the publisher expands
55
+ tracking macros in its click-through URLs, and therefore belongs
56
+ to :meth:`get_macro_tag`. ``False`` means it needs fixed values
57
+ and belongs to :meth:`get_non_macro_template_tag`.
58
+
59
+ Example:
60
+
61
+ .. code-block:: python
62
+
63
+ publishers = Attribution(account="my_account").get_publishers().payload["publishers"]
64
+ macro = [p["id"] for p in publishers if p["macroEnabled"]]
65
+ plain = [p["id"] for p in publishers if not p["macroEnabled"]]
66
+
67
+ Google Ads, Facebook Ads, Microsoft Ads and Pinterest Ads report
68
+ ``macroEnabled`` true. The rest, among them Snapchat, Twitter, LinkedIn
69
+ and TikTok, report false.
19
70
  """
20
71
  return self._request(fill_query_params(kwargs.pop("path")), params=kwargs)
21
72
 
@@ -8,22 +8,60 @@ class BrandMetrics(Client):
8
8
 
9
9
  @sp_endpoint('/insights/brandMetrics/report', method='POST')
10
10
  def post_report(self, **kwargs) -> ApiResponse:
11
- r"""Requests a Sponsored Brands report.
11
+ r"""Requests a Brand Metrics report.
12
12
 
13
- Generates the Brand Metrics report in CSV or JSON format. Customize the report by passing a specific categoryNodeTreeName, categoryNodePath, brandName, reportStartDate, reportEndDate, lookbackPeriod, format or a list of metrics from the available metrics in the metrics field. If an empty request body is passed, report for the latest available report date in JSON format will get generated with all the available brands and metrics for an advertiser. The report may or may not contain the Brand Metrics data for one or more brands depending on data availability.
13
+ Asks the service to generate the report; the answer is a handle, not the
14
+ data. It carries a ``reportId``, a ``status`` and an empty
15
+ ``location``, and the report is produced asynchronously. Pass the
16
+ ``reportId`` to :meth:`get_report` until ``status`` reads
17
+ ``SUCCESSFUL``, then download ``location``.
18
+
19
+ Generates the Brand Metrics report in CSV or JSON format. Customize the report by passing a specific categoryTreeName, categoryPath, brandName, reportStartDate, reportEndDate, lookBackPeriod, format or a list of metrics from the available metrics in the metrics field. If an empty request body is passed, report for the latest available report date in JSON format will get generated with all the available brands and metrics for an advertiser. The report may or may not contain the Brand Metrics data for one or more brands depending on data availability.
20
+
21
+ Every field is optional. An empty ``body`` generates the latest
22
+ available report in JSON with every brand and metric on the account.
14
23
 
15
24
  Request body
16
- | **categoryNodeTreeName** (string): [optional] The node at the top of a browse tree. It is the start node of a tree. example: us-home
17
- | **categoryNodePath** (string): [optional] The hierarchical path that leads to a node starting with the root node. If no Category Node Name is passed, then all data available for all brands belonging to the entity are retrieved. example: List [ "Categories", "Snack Food", "Granola & Snack Bars" ]]
25
+ | **categoryTreeName** (string): [optional] The node at the top of a browse tree. It is the start node of a tree. example: us-home
26
+ | **categoryPath** (array of arrays): [optional] The hierarchical path that leads to a node starting with the root node, as a list of paths where each path is a list of levels. If no category path is passed, then all data available for all brands belonging to the entity are retrieved. example: [ ["Categories", "Granola & Snack Bars", "Snack Food"] ]
27
+
18
28
  | **brandName** (string): [optional] Brand Name. If no Brand Name is passed, then all data available for all brands belonging to the entity are retrieved. example: Mattress Mogul
19
29
  | **reportStartDate** (string($date)): [optional] Retrieves metrics with metricsComputationDate between reportStartDate and reportEndDate (inclusive). The date will be in the Coordinated Universal Time (UTC) timezone in YYYY-MM-DD format. If no date is passed in reportStartDate, all available metrics with metricsComputationDate till the reportEndDate will be provided. If no date is passed for either reportStartDate or reportEndDate, the metrics with the most receont metricsComputationDate will be returned. example: 2021-01-01
20
- | **lookBackPeriod** (string) [optional] Currently supported values: "1w" (one week), "1m" (one month) and "1cm" (one calendar month). This defines the period of time used to determine the number of shoppers in the metrics computation [ 1m, 1w, 1cm ]. default: 1w
30
+ | **lookBackPeriod** (string) [optional] Currently supported values: "1W" (one week), "1M" (one month) and "1CM" (one calendar month), which is the enum the v1 contract declares; the v1.1 contract declares the lower case forms and the service accepted both. This defines the period of time used to determine the number of shoppers in the metrics computation. default: 1w
21
31
  | **format** (string) [optional] Format of the report. [ JSON, CSV ]. default: JSON
22
32
  | **metrics** (list) [optional] Specify an array of string of metrics field names to include in the report. If no metric field names are specified, all metrics are returned.
23
33
  | **reportEndDate** (string($date)) [optional] Retrieves metrics with metricsComputationDate between reportStartDate and reportEndDate (inclusive). The date will be in the Coordinated Universal Time (UTC) timezone in YYYY-MM-DD format. If no date is passed in reportEndDate, all available metrics with metricsComputationDate from the reportStartDate will be provided. If no date is passed for either reportStartDate or reportEndDate, the metrics with the most receont metricsComputationDate will be returned. example: 2021-01-30
24
34
 
35
+ The contract names the two category fields ``categoryTreeName`` and
36
+ ``categoryPath``, while the answers come back carrying
37
+ ``categoryNodeTreeName`` and ``categoryNodeName``. Neither spelling
38
+ filters: both were sent with different values, and a tree name that does
39
+ not exist (``zz-no-existe-zz``) was answered with the account's full set
40
+ exactly like a real one. Send the contract names, but do not expect them
41
+ to narrow the report -- filter on ``brandName`` and the date range
42
+ instead, which are the fields the service was seen to honour.
43
+
25
44
  Returns:
26
- ApiResponse
45
+ ApiResponse. ``payload`` holds:
46
+
47
+ - ``reportId`` (string): the handle for :meth:`get_report`.
48
+ - ``status`` (string): ``IN_PROGRESS`` on a fresh request.
49
+ - ``statusDetails`` (string): a sentence describing that status.
50
+ - ``expiration`` (integer): how long the result stays available.
51
+ - ``format`` (string): echoes the requested format.
52
+ - ``location`` (string): empty until the report is ready.
53
+
54
+ Example:
55
+
56
+ .. code-block:: python
57
+
58
+ from ad_api.api import BrandMetrics
59
+
60
+ bm = BrandMetrics(account="my_account")
61
+ bm.post_report(body={"format": "JSON", "lookBackPeriod": "1w"}).payload
62
+ # {'reportId': '8d3e7143-...', 'status': 'IN_PROGRESS',
63
+ # 'statusDetails': 'Generation of the report is in progress!',
64
+ # 'expiration': 300000, 'format': 'JSON', 'location': ''}
27
65
 
28
66
  """
29
67
  return self._request(fill_query_params(kwargs.pop('path')), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs)
@@ -32,11 +70,29 @@ class BrandMetrics(Client):
32
70
  def get_report(self, reportId, **kwargs) -> ApiResponse:
33
71
  r"""Gets a previously requested report specified by identifier.
34
72
 
73
+ This is the polling call. A report is generated asynchronously, so call
74
+ this with the ``reportId`` that :meth:`post_report` returned until
75
+ ``status`` reads ``SUCCESSFUL``; only then does ``location`` carry
76
+ a signed S3 address that can be downloaded.
77
+
35
78
  Keyword Args
36
79
  | path **reportId** (string): [required] The report Id to be fetched.
37
80
 
38
81
  Returns:
39
- ApiResponse
82
+ ApiResponse. ``payload`` holds:
83
+
84
+ - ``status`` (string): ``IN_PROGRESS``, ``SUCCESSFUL`` or a
85
+ failure status.
86
+ - ``statusDetails`` (string): the sentence behind that status.
87
+ - ``location`` (string): the signed URL, empty until success.
88
+ - ``format`` (string): the format the report was generated in.
89
+ - ``expiration`` (integer): how long the result stays available.
90
+ - ``brandsInfo`` (array): the brands the report covers, each with
91
+ ``id`` and ``name``. Absent while the report is still running.
92
+
93
+ An unknown identifier is not a ``404``: the service answers ``400``
94
+ with ``NoDataFoundException`` and a message naming the id, which means
95
+ the route ran and looked it up.
40
96
  """
41
97
  return self._request(fill_query_params(kwargs.pop('path'), reportId), params=kwargs)
42
98
 
ad_api/api/v1/__init__.py CHANGED
@@ -2,10 +2,14 @@ from .campaigns import Campaigns
2
2
  from .ad_groups import AdGroups
3
3
  from .ads import Ads
4
4
  from .targets import Targets
5
+ from .ad_extensions import AdExtensions
6
+ from .advertiser_accounts import AdvertiserAccounts
5
7
 
6
8
  __all__ = [
7
9
  "Campaigns",
8
10
  "AdGroups",
9
11
  "Ads",
10
12
  "Targets",
13
+ "AdExtensions",
14
+ "AdvertiserAccounts",
11
15
  ]
@@ -0,0 +1,125 @@
1
+ from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
2
+
3
+
4
+ class AdExtensions(Client):
5
+ r"""
6
+ AdExtensions(account='default', marketplace: Marketplaces = Marketplaces.EU, credentials=None, debug=False)
7
+
8
+ Amazon Ads API v1 - unified AdExtensions endpoints
9
+
10
+ An ad extension adds delivery detail to an existing Sponsored Products ad
11
+ rather than creating a new one. The contract declares exactly two types:
12
+
13
+ - ``PROMPTS`` -- a prompt-style text extension.
14
+ - ``VIDEO`` -- a video extension.
15
+
16
+ There is no delete route. An extension is created, queried and updated; the
17
+ only thing ``update`` changes is ``state``, so ending one means pausing or
18
+ archiving it. Editing its content means creating a new extension and
19
+ archiving the old one.
20
+
21
+ Like every v1 resource, the product is chosen in the body through
22
+ ``adProductFilter`` / ``adProduct``, never in the path. For this contract
23
+ the enum is a single value, ``SPONSORED_PRODUCTS``.
24
+ """
25
+
26
+ @sp_endpoint('/adsApi/v1/query/adExtensions', method='POST')
27
+ def query_ad_extensions(self, **kwargs) -> ApiResponse:
28
+ r"""
29
+ query_ad_extensions(body: dict) -> ApiResponse
30
+
31
+ Amazon Ads API v1 - Query AdExtensions (operationId: SPQueryAdExtension)
32
+
33
+ Request Body
34
+ | **adProductFilter** (dict) [optional here, required by the service in practice]
35
+ | **include** (list<AdProduct>) : Enum [ SPONSORED_PRODUCTS ]
36
+ | **adIdFilter** (dict) [optional]
37
+ | **include** (list<string>) : 1..300 ad identifiers
38
+ | **adGroupIdFilter** (dict) [optional]
39
+ | **include** (list<string>) : ad group identifiers
40
+ | **adExtensionIdFilter** (dict) [optional]
41
+ | **include** (list<string>) : extension identifiers
42
+ | **adExtensionStatusFilter** (dict) [optional]
43
+ | **include** (list<AdExtensionStatus>)
44
+ | **adExtensionTypeFilter** (dict) [optional]
45
+ | **include** (list<AdExtensionType>) : Enum [ PROMPTS, VIDEO ], exactly one value
46
+ | **stateFilter** (dict) [optional]
47
+ | **include** (list<State>) : Enum [ ENABLED, PAUSED, ARCHIVED ], 1..3 values
48
+ | **maxResults** (int) [optional] Maximum number of records in the response
49
+ | **nextToken** (string) [optional] Token to navigate to the next page
50
+
51
+ Every filter object is shaped ``{"include": [...]}``, and ``include`` is
52
+ required inside each one. An empty ``{}`` body is not the same as no
53
+ filter: send the body you mean.
54
+
55
+ Returns
56
+ ApiResponse
57
+ """
58
+ headers = {"Accept": "application/json", "Content-Type": "application/json"}
59
+ return self._request(
60
+ kwargs.pop('path'),
61
+ data=Utils.convert_body(kwargs.pop('body'), False),
62
+ params=kwargs,
63
+ headers=headers,
64
+ )
65
+
66
+ @sp_endpoint('/adsApi/v1/create/adExtensions', method='POST')
67
+ def create_ad_extensions(self, **kwargs) -> ApiResponse:
68
+ r"""
69
+ create_ad_extensions(body: dict) -> ApiResponse
70
+
71
+ Amazon Ads API v1 - Create AdExtensions (operationId: SPCreateAdExtension)
72
+
73
+ Request Body [Required]
74
+ | **adExtensions** (list, 1..50) [required]
75
+
76
+ Each element:
77
+ | **adExtensionSettings** (SPCreateAdExtensionSettings) [required]
78
+ | **adExtensionType** (string) [required] Enum [ PROMPTS, VIDEO ]
79
+ | **adProduct** (string) [required] Enum [ SPONSORED_PRODUCTS ]
80
+ | **marketplaceScope** (string) [required] Enum [ SINGLE_MARKETPLACE ]
81
+ | **marketplaces** (list<string>) [required] marketplaces the extension applies to
82
+ | **state** (string) [required] Enum [ ENABLED, PAUSED ]
83
+ | **adExtensionStatus** (SPAdExtensionStatus) [optional]
84
+ | **adGroupId** (string) [optional] ad group the extension belongs to
85
+ | **adId** (string) [optional] ad the extension belongs to
86
+
87
+ Returns
88
+ ApiResponse
89
+ """
90
+ headers = {"Accept": "application/json", "Content-Type": "application/json"}
91
+ return self._request(
92
+ kwargs.pop('path'),
93
+ data=Utils.convert_body(kwargs.pop('body'), False),
94
+ params=kwargs,
95
+ headers=headers,
96
+ )
97
+
98
+ @sp_endpoint('/adsApi/v1/update/adExtensions', method='POST')
99
+ def update_ad_extensions(self, **kwargs) -> ApiResponse:
100
+ r"""
101
+ update_ad_extensions(body: dict) -> ApiResponse
102
+
103
+ Amazon Ads API v1 - Update AdExtensions (operationId: SPUpdateAdExtension)
104
+
105
+ The contract accepts only an identifier and a state here. There is no
106
+ field to change the extension's own content, so this route switches an
107
+ extension on, off or out of the way; it does not rewrite it.
108
+
109
+ Request Body [Required]
110
+ | **adExtensions** (list, 1..50) [required]
111
+
112
+ Each element:
113
+ | **adExtensionId** (string) [required] extension to update
114
+ | **state** (string) [optional] Enum [ ENABLED, PAUSED, ARCHIVED ]
115
+
116
+ Returns
117
+ ApiResponse
118
+ """
119
+ headers = {"Accept": "application/json", "Content-Type": "application/json"}
120
+ return self._request(
121
+ kwargs.pop('path'),
122
+ data=Utils.convert_body(kwargs.pop('body'), False),
123
+ params=kwargs,
124
+ headers=headers,
125
+ )
@@ -0,0 +1,122 @@
1
+ from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
2
+
3
+
4
+ class AdvertiserAccounts(Client):
5
+ r"""
6
+ AdvertiserAccounts(account='default', marketplace: Marketplaces = Marketplaces.EU, credentials=None, debug=False)
7
+
8
+ Amazon Ads API v1 - unified AdvertiserAccounts endpoints
9
+
10
+ Three routes and no delete, like the rest of the account family:
11
+
12
+ - ``create_advertiser_accounts`` -- 1 to 100 accounts per call.
13
+ - ``query_advertiser_accounts`` -- filter by identifier or by global flag.
14
+ - ``update_advertiser_accounts`` -- here the mutable fields really are
15
+ mutable: currency, time zone, display name, industry, manager link.
16
+
17
+ Unlike Ads, Targets or AdExtensions this is not an ad-product resource, so
18
+ there is no ``adProductFilter```; querying is by ``advertiserAccountIdFilter``
19
+ or ``isGlobalAccountFilter``.
20
+
21
+ ``managerAccountId`` decides what the account can run: without it the account
22
+ is created for Sponsored Ads only, and DSP needs it set.
23
+ """
24
+
25
+ @sp_endpoint('/adsApi/v1/query/advertiserAccounts', method='POST')
26
+ def query_advertiser_accounts(self, **kwargs) -> ApiResponse:
27
+ r"""
28
+ query_advertiser_accounts(body: dict) -> ApiResponse
29
+
30
+ Amazon Ads API v1 - Query AdvertiserAccounts (operationId: QueryAdvertiserAccount)
31
+
32
+ Request Body
33
+ | **advertiserAccountIdFilter** (dict) [optional]
34
+ | **include** (list<string>) : advertiser account identifiers
35
+ | **isGlobalAccountFilter** (dict) [optional]
36
+ | **include** (list<boolean>) : true for global accounts
37
+ | **maxResults** (int) [optional] Maximum number of records in the response
38
+ | **nextToken** (string) [optional] Token to navigate to the next page
39
+
40
+ Returns
41
+ ApiResponse. ``payload`` holds ``advertiserAccounts`` and ``nextToken``.
42
+ """
43
+ headers = {"Accept": "application/json", "Content-Type": "application/json"}
44
+ return self._request(
45
+ kwargs.pop('path'),
46
+ data=Utils.convert_body(kwargs.pop('body'), False),
47
+ params=kwargs,
48
+ headers=headers,
49
+ )
50
+
51
+ @sp_endpoint('/adsApi/v1/create/advertiserAccounts', method='POST')
52
+ def create_advertiser_accounts(self, **kwargs) -> ApiResponse:
53
+ r"""
54
+ create_advertiser_accounts(body: dict) -> ApiResponse
55
+
56
+ Amazon Ads API v1 - Create AdvertiserAccounts (operationId: CreateAdvertiserAccount)
57
+
58
+ Request Body [Required]
59
+ | **advertiserAccounts** (list, 1..100) [required]
60
+
61
+ Each element:
62
+ | **businessDetails** (list, exactly 1) [required]
63
+ Carries either ``addressToken`` for an existing selling account
64
+ address, or ``address`` when that account has none. Also accepts
65
+ ``businessRegistrationNumber`` and ``website`.
66
+ | **currencyCode** (string) [optional] Enum of 34 ISO codes,
67
+ including ``EUR``, ``USD``, ``GBP`
68
+ | **displayName** (string) [optional] name shown for the account
69
+ | **industryVertical** (string) [optional] Enum of 19 sectors
70
+ | **isGlobalAccount** (boolean) [optional]
71
+ | **isTestAccount** (boolean) [optional]
72
+ | **managerAccountId** (string) [optional] Required for
73
+ ADSP-enabled accounts; without it the account is created for
74
+ Sponsored Ads only.
75
+ | **sellingAccountLinkRequests** (list, 0..1) [optional]
76
+ | **timeZoneIana** (string) [optional] Enum of 42 IANA zones
77
+
78
+ The full enum lists live in the contract; they are not repeated here.
79
+
80
+ Returns
81
+ ApiResponse
82
+ """
83
+ headers = {"Accept": "application/json", "Content-Type": "application/json"}
84
+ return self._request(
85
+ kwargs.pop('path'),
86
+ data=Utils.convert_body(kwargs.pop('body'), False),
87
+ params=kwargs,
88
+ headers=headers,
89
+ )
90
+
91
+ @sp_endpoint('/adsApi/v1/update/advertiserAccounts', method='POST')
92
+ def update_advertiser_accounts(self, **kwargs) -> ApiResponse:
93
+ r"""
94
+ update_advertiser_accounts(body: dict) -> ApiResponse
95
+
96
+ Amazon Ads API v1 - Update AdvertiserAccounts (operationId: UpdateAdvertiserAccount)
97
+
98
+ Request Body [Required]
99
+ | **advertiserAccounts** (list) [required]
100
+
101
+ Each element:
102
+ | **advertiserAccountId** (string) [required] account to update
103
+ | **businessDetails** (list) [optional]
104
+ | **currencyCode** (string) [optional]
105
+ | **displayName** (string) [optional]
106
+ | **industryVertical** (string) [optional]
107
+ | **isGlobalAccount** (boolean) [optional]
108
+ | **isTestAccount** (boolean) [optional]
109
+ | **managerAccountId** (string) [optional]
110
+ | **sellingAccountLinkRequests** (list) [optional]
111
+ | **timeZoneIana** (string) [optional]
112
+
113
+ Returns
114
+ ApiResponse
115
+ """
116
+ headers = {"Accept": "application/json", "Content-Type": "application/json"}
117
+ return self._request(
118
+ kwargs.pop('path'),
119
+ data=Utils.convert_body(kwargs.pop('body'), False),
120
+ params=kwargs,
121
+ headers=headers,
122
+ )
ad_api/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.3.0"
1
+ __version__ = "1.4.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-amazon-ad-api
3
- Version: 1.3.0
3
+ Version: 1.4.1
4
4
  Summary: Python wrapper for the Amazon Advertising API
5
5
  Home-page: https://github.com/denisneuf/python-amazon-ad-api
6
6
  Author: Daniel Alvaro
@@ -15,7 +15,7 @@ License-File: LICENSE
15
15
  Requires-Dist: requests<2.35.0,>=2.27.1
16
16
  Requires-Dist: six<1.18,>=1.16
17
17
  Requires-Dist: cachetools<7.3,>=5.0
18
- Requires-Dist: pycryptodome<4.2,>=3.13
18
+ Requires-Dist: pycryptodome<4.3,>=3.13
19
19
  Requires-Dist: pytz<2027.0,>=2021.3
20
20
  Requires-Dist: confuse<2.4,>=1.7
21
21
  Dynamic: author
@@ -304,6 +304,8 @@ The v1 API lives under `/adsApi/v1/` and is **not** split by product: every call
304
304
  * [Ad Groups](https://python-amazon-ad-api.readthedocs.io/en/latest/v1/ad_groups.html#ad_api.api.v1.AdGroups.AdGroups.query_ad_groups)
305
305
  * [Ads](https://python-amazon-ad-api.readthedocs.io/en/latest/v1/ads.html#ad_api.api.v1.Ads.Ads.query_ads)
306
306
  * [Targets](https://python-amazon-ad-api.readthedocs.io/en/latest/v1/targets.html#ad_api.api.v1.Targets.Targets.query_targets)
307
+ * [Ad Extensions](https://python-amazon-ad-api.readthedocs.io/en/latest/v1/ad_extensions.html#ad_api.api.v1.AdExtensions.AdExtensions.query_ad_extensions)
308
+ * [Advertiser Accounts](https://python-amazon-ad-api.readthedocs.io/en/latest/v1/advertiser_accounts.html#ad_api.api.v1.AdvertiserAccounts.AdvertiserAccounts.query_advertiser_accounts)
307
309
 
308
310
 
309
311
  ### [Modules Available Sponsored Products](https://python-amazon-ad-api.readthedocs.io/en/latest/sp.html)
@@ -1,13 +1,13 @@
1
1
  ad_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- ad_api/version.py,sha256=F5mW07pSyGrqDNY2Ehr-UpDzpBtN-FsYU0QGZWf6PJE,22
2
+ ad_api/version.py,sha256=BqOI5y46o1G1RWC9bF1DPL-YM68lGYPmZt1pn6FZFZs,22
3
3
  ad_api/api/__init__.py,sha256=TLMefdmuyrj3-vtxGlzX4Sl-lHmE3Rs6daYgw3zwO0c,1600
4
4
  ad_api/api/account.py,sha256=CmOvCfHoPWaeTUJvtB0pNoNulZVSz4oMMCKIpVTpHos,2931
5
5
  ad_api/api/account_budgets.py,sha256=jFce5eLWAFK3ydjnYR7_Sv7B0-gHTG5bMTx_TcHyy1A,2319
6
6
  ad_api/api/advertising_test_account.py,sha256=btOVbdk2tBDmyKSJaQbcIFyzNG8KFJVUmTe4p9xMhpU,1507
7
- ad_api/api/attribution.py,sha256=vHmXP0wDqhEqaS1q3tJyERxJ1JwntqoEb73LVXNHxR0,5121
7
+ ad_api/api/attribution.py,sha256=TWYJSEqG2Li2qQRSSv8GtE2WOiK_RJICCeyN-xVrF6A,7273
8
8
  ad_api/api/audiences.py,sha256=TQPt4avswFdCodNfQGDGxcJ2mY2LP2BfYvjxP6oJ0qY,3491
9
9
  ad_api/api/billing.py,sha256=pmBQzejCM8YIsI51KTVunDTVTKMIaox0D2B4acH4w6Y,23526
10
- ad_api/api/brand_metrics.py,sha256=IlOlVJ2t6cL5DA49RaM3M1AW_3KFEyal08e0ZcnLdVE,6036
10
+ ad_api/api/brand_metrics.py,sha256=DVg9qu_-sALxaQhQjRG6Isi_5SYxA5nmTg99jTe5Tls,9237
11
11
  ad_api/api/creative_assets.py,sha256=u0bCnioUFpGOQO5Z_MO0ErSLcAgSZB5GWM5wm2oW6L0,9687
12
12
  ad_api/api/eligibility.py,sha256=xbHMNxpRqToQDlG8y7nhhSr55ZZIJ_ZA304rmWa7Jx0,3680
13
13
  ad_api/api/exports.py,sha256=Y59C99axCAltMgu3gbfzdnoLKjNTsJ7s1z18yzcxzls,2788
@@ -89,9 +89,11 @@ ad_api/api/sp/product_recommendations.py,sha256=vXoZIRqcFc5bo9MUprArKndxcEYe_Puy
89
89
  ad_api/api/sp/product_targeting_v3.py,sha256=vk_T0piHzP5uwt8HSHm5hFKP_0sXJD8nbyooPtM-BTs,9567
90
90
  ad_api/api/sp/ranked_keywords_recommendations.py,sha256=QYFje19TFmwhedh7sn5VJIypL8gp6d6tpBQCpf_SIXw,13094
91
91
  ad_api/api/sp/schedule_based_bid_optimization.py,sha256=G8VkS7iP1lTIAxZgbfRCLz8njw1DkVH9HQPOZ63pWNU,2371
92
- ad_api/api/v1/__init__.py,sha256=F2CvJLkWZDG_ykzVnivBb10CvmSWw2lVf-7dy5oH8LM,189
92
+ ad_api/api/v1/__init__.py,sha256=PZUV64EpTwGeZaEJQO5GBr4WKloUaFPh2H55IidNscM,327
93
+ ad_api/api/v1/ad_extensions.py,sha256=kL-7xHaXXqb2jXTwZrY0oGttLAG0CW_IjBAqL_CI92U,5519
93
94
  ad_api/api/v1/ad_groups.py,sha256=pQhCVdve_O6kbL4mBA5bxxhKcKNl_BKqa7z9DvrxwaM,12626
94
95
  ad_api/api/v1/ads.py,sha256=YwZGQ-4WuYquleELtwRI9L8w0fGw7FBRejQE-tZ5hKY,7941
96
+ ad_api/api/v1/advertiser_accounts.py,sha256=_Y8GTHgQ2G-RhNg4cuvvfXvjIhLzstQAGSyr1WMRRfg,5405
95
97
  ad_api/api/v1/campaigns.py,sha256=u5PlvoAhgVhMxbCvYkPgqtbYK3TXXcb7TMie0Qjrgwc,9573
96
98
  ad_api/api/v1/targets.py,sha256=a4BzPjg9m1JJwqphhpQOFkNIcgCw7v4-K0sNzOihMZI,12355
97
99
  ad_api/auth/__init__.py,sha256=B_yKdmsHENQaKfMFAIcSxQqG4aBUmNBm5orKIMUYObk,229
@@ -109,8 +111,8 @@ ad_api/base/exceptions.py,sha256=9D3M40ZIlLS0fA-aQh1BTWPOW-Nvf0tRhbA85jFnDJ4,438
109
111
  ad_api/base/helpers.py,sha256=UK7Q13vZ0mNdF54xzfzoGDn2O_cd2yPrK2X4rOzC41c,2334
110
112
  ad_api/base/marketplaces.py,sha256=44lvCcluXNpqTprWQ80e3weSQmQbJoWL-WDSOWVbCyQ,4657
111
113
  ad_api/base/utils.py,sha256=_qnCBOvyJTLgaZjJzUWTi38GGLHkQszXELs79133Rb4,5618
112
- python_amazon_ad_api-1.3.0.dist-info/licenses/LICENSE,sha256=h2rpqlmmLy-4l1tN6KpWAFxx1JEMYeEFrMrZUbx_B_o,1105
113
- python_amazon_ad_api-1.3.0.dist-info/METADATA,sha256=rN92CtI2QXdshEfkqjmzsNCIN7wVnJFGHXLBuPdVw50,21553
114
- python_amazon_ad_api-1.3.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
115
- python_amazon_ad_api-1.3.0.dist-info/top_level.txt,sha256=nN9twUos-8pkP514ZwpvRU9YL9L2XyQyHsMQFfudGTU,7
116
- python_amazon_ad_api-1.3.0.dist-info/RECORD,,
114
+ python_amazon_ad_api-1.4.1.dist-info/licenses/LICENSE,sha256=h2rpqlmmLy-4l1tN6KpWAFxx1JEMYeEFrMrZUbx_B_o,1105
115
+ python_amazon_ad_api-1.4.1.dist-info/METADATA,sha256=60IbkJFCBtnuSn85xriw-jm_P-9LPPXvSvY9FmktSEw,21893
116
+ python_amazon_ad_api-1.4.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
117
+ python_amazon_ad_api-1.4.1.dist-info/top_level.txt,sha256=nN9twUos-8pkP514ZwpvRU9YL9L2XyQyHsMQFfudGTU,7
118
+ python_amazon_ad_api-1.4.1.dist-info/RECORD,,