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 +51 -0
- ad_api/api/brand_metrics.py +63 -7
- ad_api/api/v1/__init__.py +4 -0
- ad_api/api/v1/ad_extensions.py +125 -0
- ad_api/api/v1/advertiser_accounts.py +122 -0
- ad_api/version.py +1 -1
- {python_amazon_ad_api-1.3.0.dist-info → python_amazon_ad_api-1.4.1.dist-info}/METADATA +4 -2
- {python_amazon_ad_api-1.3.0.dist-info → python_amazon_ad_api-1.4.1.dist-info}/RECORD +11 -9
- {python_amazon_ad_api-1.3.0.dist-info → python_amazon_ad_api-1.4.1.dist-info}/WHEEL +0 -0
- {python_amazon_ad_api-1.3.0.dist-info → python_amazon_ad_api-1.4.1.dist-info}/licenses/LICENSE +0 -0
- {python_amazon_ad_api-1.3.0.dist-info → python_amazon_ad_api-1.4.1.dist-info}/top_level.txt +0 -0
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
|
|
ad_api/api/brand_metrics.py
CHANGED
|
@@ -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
|
|
11
|
+
r"""Requests a Brand Metrics report.
|
|
12
12
|
|
|
13
|
-
|
|
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
|
-
| **
|
|
17
|
-
| **
|
|
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: "
|
|
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.
|
|
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
|
+
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.
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
113
|
-
python_amazon_ad_api-1.
|
|
114
|
-
python_amazon_ad_api-1.
|
|
115
|
-
python_amazon_ad_api-1.
|
|
116
|
-
python_amazon_ad_api-1.
|
|
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,,
|
|
File without changes
|
{python_amazon_ad_api-1.3.0.dist-info → python_amazon_ad_api-1.4.1.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|