python-amazon-ad-api 1.5.11__py3-none-any.whl → 1.7.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.
- ad_api/api/exports.py +110 -17
- ad_api/api/v1/__init__.py +2 -0
- ad_api/api/v1/location_indexes.py +109 -0
- ad_api/auth/access_token_client.py +1 -1
- ad_api/base/__init__.py +1 -2
- ad_api/base/client.py +1 -1
- ad_api/shared/__init__.py +0 -0
- ad_api/version.py +1 -1
- python_amazon_ad_api-1.7.0.dist-info/METADATA +499 -0
- {python_amazon_ad_api-1.5.11.dist-info → python_amazon_ad_api-1.7.0.dist-info}/RECORD +14 -12
- python_amazon_ad_api-1.5.11.dist-info/METADATA +0 -492
- /ad_api/{base → shared}/base_client.py +0 -0
- {python_amazon_ad_api-1.5.11.dist-info → python_amazon_ad_api-1.7.0.dist-info}/WHEEL +0 -0
- {python_amazon_ad_api-1.5.11.dist-info → python_amazon_ad_api-1.7.0.dist-info}/licenses/LICENSE +0 -0
- {python_amazon_ad_api-1.5.11.dist-info → python_amazon_ad_api-1.7.0.dist-info}/top_level.txt +0 -0
ad_api/api/exports.py
CHANGED
|
@@ -2,55 +2,148 @@ from ad_api.base import Client, sp_endpoint, fill_query_params, ApiResponse, Uti
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class Exports(Client):
|
|
5
|
-
"""
|
|
5
|
+
"""
|
|
6
|
+
Ask for a snapshot of one entity type and poll it until it is ready.
|
|
7
|
+
|
|
8
|
+
Four routes request an export, one per entity, and a fifth reads the result.
|
|
9
|
+
A request answers 202 with an export id; the file is built afterwards, so the
|
|
10
|
+
id is polled until its status reads COMPLETED and a download url appears.
|
|
11
|
+
|
|
12
|
+
The route picks the entity, not the body: /ads/export exports ads,
|
|
13
|
+
/campaigns/export exports campaigns, and so on. The body only narrows which
|
|
14
|
+
rows of that entity come back, by ad product and by state.
|
|
15
|
+
|
|
16
|
+
The status moves through PROCESSING, COMPLETED and FAILED. Only COMPLETED
|
|
17
|
+
carries a url, and that url expires at urlExpiresAt. On FAILED the answer
|
|
18
|
+
carries an error object with the reason.
|
|
19
|
+
|
|
20
|
+
Every route names its own media type, application/vnd.<entity>export.v<n>+json,
|
|
21
|
+
built from the entity and the version argument. The service routes on that
|
|
22
|
+
type, so the wrong one answers 406.
|
|
6
23
|
"""
|
|
7
24
|
@sp_endpoint('/ads/export', method='POST')
|
|
8
25
|
def ads_export(self, version: int = 1, **kwargs) -> ApiResponse:
|
|
9
26
|
r"""
|
|
10
|
-
|
|
27
|
+
Requests an export of the ads.
|
|
28
|
+
|
|
29
|
+
Keyword Args
|
|
30
|
+
| body **body** (string | dict): filters. Every field is optional, and
|
|
31
|
+
omitting one leaves its default in place.
|
|
32
|
+
| **adProductFilter** (array): which ad products to include. One to
|
|
33
|
+
three of SPONSORED_BRANDS, SPONSORED_DISPLAY, SPONSORED_PRODUCTS.
|
|
34
|
+
Omitted, all three are included.
|
|
35
|
+
| **stateFilter** (array): which states to include. One to three of
|
|
36
|
+
ARCHIVED, ENABLED, PAUSED. Omitted, only ENABLED and PAUSED come
|
|
37
|
+
back, never ARCHIVED.
|
|
38
|
+
| **version** (int): media type version. Defaults to 1.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
| ApiResponse, 202 with an export id
|
|
11
42
|
"""
|
|
12
|
-
content_type = 'application/vnd.adsexport.v'+ str(version) +'+json'
|
|
13
|
-
accept = 'application/vnd.adsexport.v'+ str(version) +'+json'
|
|
43
|
+
content_type = 'application/vnd.adsexport.v' + str(version) + '+json'
|
|
44
|
+
accept = 'application/vnd.adsexport.v' + str(version) + '+json'
|
|
14
45
|
headers = {'Content-Type': content_type, 'Accept': accept}
|
|
15
46
|
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
16
47
|
|
|
17
48
|
@sp_endpoint('/campaigns/export', method='POST')
|
|
18
49
|
def campaigns_export(self, version: int = 1, **kwargs) -> ApiResponse:
|
|
19
50
|
r"""
|
|
20
|
-
|
|
51
|
+
Requests an export of the campaigns.
|
|
52
|
+
|
|
53
|
+
Keyword Args
|
|
54
|
+
| body **body** (string | dict): filters. Every field is optional, and
|
|
55
|
+
omitting one leaves its default in place.
|
|
56
|
+
| **adProductFilter** (array): which ad products to include. One to
|
|
57
|
+
three of SPONSORED_BRANDS, SPONSORED_DISPLAY, SPONSORED_PRODUCTS.
|
|
58
|
+
Omitted, all three are included.
|
|
59
|
+
| **stateFilter** (array): which states to include. One to three of
|
|
60
|
+
ARCHIVED, ENABLED, PAUSED. Omitted, only ENABLED and PAUSED come
|
|
61
|
+
back, never ARCHIVED.
|
|
62
|
+
| **version** (int): media type version. Defaults to 1.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
| ApiResponse, 202 with an export id
|
|
21
66
|
"""
|
|
22
|
-
content_type = 'application/vnd.campaignsexport.v'+ str(version) +'+json'
|
|
23
|
-
accept = 'application/vnd.campaignsexport.v'+ str(version) +'+json'
|
|
67
|
+
content_type = 'application/vnd.campaignsexport.v' + str(version) + '+json'
|
|
68
|
+
accept = 'application/vnd.campaignsexport.v' + str(version) + '+json'
|
|
24
69
|
headers = {'Content-Type': content_type, 'Accept': accept}
|
|
25
70
|
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
26
71
|
|
|
27
|
-
|
|
28
72
|
@sp_endpoint('/adGroups/export', method='POST')
|
|
29
73
|
def adgroups_export(self, version: int = 1, **kwargs) -> ApiResponse:
|
|
30
74
|
r"""
|
|
31
|
-
|
|
75
|
+
Requests an export of the ad groups.
|
|
76
|
+
|
|
77
|
+
Keyword Args
|
|
78
|
+
| body **body** (string | dict): filters. Every field is optional, and
|
|
79
|
+
omitting one leaves its default in place.
|
|
80
|
+
| **adProductFilter** (array): which ad products to include. One to
|
|
81
|
+
three of SPONSORED_BRANDS, SPONSORED_DISPLAY, SPONSORED_PRODUCTS.
|
|
82
|
+
Omitted, all three are included.
|
|
83
|
+
| **stateFilter** (array): which states to include. One to three of
|
|
84
|
+
ARCHIVED, ENABLED, PAUSED. Omitted, only ENABLED and PAUSED come
|
|
85
|
+
back, never ARCHIVED.
|
|
86
|
+
| **version** (int): media type version. Defaults to 1.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
| ApiResponse, 202 with an export id
|
|
32
90
|
"""
|
|
33
|
-
content_type = 'application/vnd.adgroupsexport.v'+ str(version) +'+json'
|
|
34
|
-
accept = 'application/vnd.adgroupsexport.v'+ str(version) +'+json'
|
|
91
|
+
content_type = 'application/vnd.adgroupsexport.v' + str(version) + '+json'
|
|
92
|
+
accept = 'application/vnd.adgroupsexport.v' + str(version) + '+json'
|
|
35
93
|
headers = {'Content-Type': content_type, 'Accept': accept}
|
|
36
94
|
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
37
95
|
|
|
38
|
-
|
|
39
96
|
@sp_endpoint('/targets/export', method='POST')
|
|
40
97
|
def targets_export(self, version: int = 1, **kwargs) -> ApiResponse:
|
|
41
98
|
r"""
|
|
42
|
-
|
|
99
|
+
Requests an export of the targets.
|
|
100
|
+
|
|
101
|
+
This route adds two filters of its own on top of the shared pair.
|
|
102
|
+
|
|
103
|
+
Keyword Args
|
|
104
|
+
| body **body** (string | dict): filters. Every field is optional, and
|
|
105
|
+
omitting one leaves its default in place.
|
|
106
|
+
| **adProductFilter** (array): which ad products to include. One to
|
|
107
|
+
three of SPONSORED_BRANDS, SPONSORED_DISPLAY, SPONSORED_PRODUCTS.
|
|
108
|
+
Omitted, all three are included.
|
|
109
|
+
| **stateFilter** (array): which states to include. One to three of
|
|
110
|
+
ARCHIVED, ENABLED, PAUSED. Omitted, only ENABLED and PAUSED come
|
|
111
|
+
back, never ARCHIVED.
|
|
112
|
+
| **negativeFilter** (array): booleans choosing negative targets,
|
|
113
|
+
positive targets, or both. Omitted, both come back.
|
|
114
|
+
| **targetLevelFilter** (array): AD_GROUP, CAMPAIGN, or both.
|
|
115
|
+
Omitted, both levels come back.
|
|
116
|
+
| **version** (int): media type version. Defaults to 1.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
| ApiResponse, 202 with an export id
|
|
43
120
|
"""
|
|
44
|
-
content_type = 'application/vnd.targetsexport.v'+ str(version) +'+json'
|
|
45
|
-
accept = 'application/vnd.targetsexport.v'+ str(version) +'+json'
|
|
121
|
+
content_type = 'application/vnd.targetsexport.v' + str(version) + '+json'
|
|
122
|
+
accept = 'application/vnd.targetsexport.v' + str(version) + '+json'
|
|
46
123
|
headers = {'Content-Type': content_type, 'Accept': accept}
|
|
47
124
|
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
48
125
|
|
|
49
|
-
|
|
50
126
|
@sp_endpoint('/exports/{}', method='GET')
|
|
51
127
|
def get_export(self, exportId, typeExport, version: int = 1, **kwargs) -> ApiResponse:
|
|
52
128
|
r"""
|
|
129
|
+
Reads the state of an export requested earlier.
|
|
130
|
+
|
|
131
|
+
Answers the export with its status and, once COMPLETED, the download url
|
|
132
|
+
and its expiry. A FAILED export carries an error object instead.
|
|
133
|
+
|
|
134
|
+
Keyword Args
|
|
135
|
+
| path **exportId** (string): the id returned when the export was
|
|
136
|
+
requested. [required]
|
|
137
|
+
| **typeExport** (string): the entity the export covers, used to build
|
|
138
|
+
the media type: ads, campaigns, adGroups or targets. [required]
|
|
139
|
+
| **version** (int): media type version. Defaults to 1.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
| ApiResponse
|
|
143
|
+
| **exportId** (string), **status** (string)
|
|
144
|
+
| **url** (string), **urlExpiresAt** (string)
|
|
145
|
+
| **createdAt**, **generatedAt**, **fileSize**, **error**
|
|
53
146
|
"""
|
|
54
|
-
content_type = 'application/vnd.'+typeExport+'export.v' + str(version) + '+json'
|
|
147
|
+
content_type = 'application/vnd.' + typeExport + 'export.v' + str(version) + '+json'
|
|
55
148
|
headers = {'Content-Type': content_type, 'Accept': content_type}
|
|
56
149
|
return self._request(fill_query_params(kwargs.pop('path'), exportId), params=kwargs, headers=headers)
|
ad_api/api/v1/__init__.py
CHANGED
|
@@ -16,6 +16,7 @@ from .recommendations import Recommendations
|
|
|
16
16
|
from .selling_accounts import SellingAccounts
|
|
17
17
|
from .label_object_associations import LabelObjectAssociations
|
|
18
18
|
from .geo_locations import GeoLocations
|
|
19
|
+
from .location_indexes import LocationIndexes
|
|
19
20
|
from .recommendation_types import RecommendationTypes
|
|
20
21
|
|
|
21
22
|
__all__ = [
|
|
@@ -37,5 +38,6 @@ __all__ = [
|
|
|
37
38
|
"SellingAccounts",
|
|
38
39
|
"LabelObjectAssociations",
|
|
39
40
|
"GeoLocations",
|
|
41
|
+
"LocationIndexes",
|
|
40
42
|
"RecommendationTypes",
|
|
41
43
|
]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class LocationIndexes(Client):
|
|
5
|
+
"""
|
|
6
|
+
Manage Smart Location Indexes for a campaign.
|
|
7
|
+
|
|
8
|
+
A Smart Location Index is a named dataset that maps postal codes to index
|
|
9
|
+
values, expressing relative audience quality or sales potential for one
|
|
10
|
+
advertiser. The values are supplied by the caller; the service only stores
|
|
11
|
+
and serves them for smart location targeting.
|
|
12
|
+
|
|
13
|
+
Writes are asynchronous. Creating or updating an index leaves it in PENDING
|
|
14
|
+
until the service has processed the data, and only then does it read ENABLED
|
|
15
|
+
and become usable for targeting. An index that fails processing carries
|
|
16
|
+
FAILED, or UPDATE_FAILED when it was an existing index being rewritten.
|
|
17
|
+
|
|
18
|
+
The contract requires one of advertiser_campaign_edit, campaign_edit,
|
|
19
|
+
dsp_campaign_edit or MasterAccount_Manager to write, and campaign_view
|
|
20
|
+
among others to read. On a Sponsored Ads seller profile this family is not
|
|
21
|
+
reachable: a probe answers 401 Customer <id> is not authorized to access
|
|
22
|
+
account, even though campaign_view is declared as enough.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
@sp_endpoint('/adsApi/v1/create/locationIndexes', method='POST')
|
|
26
|
+
def create_location_index(self, **kwargs) -> ApiResponse:
|
|
27
|
+
r"""
|
|
28
|
+
Creates one or more Smart Location Indexes.
|
|
29
|
+
|
|
30
|
+
The index is processed asynchronously: it arrives with status PENDING and
|
|
31
|
+
only turns ENABLED once the service has read the data.
|
|
32
|
+
|
|
33
|
+
Request body
|
|
34
|
+
| **locationIndexes** (array): [required] one or more indexes.
|
|
35
|
+
| **indexName** (string): [required] the name of the index.
|
|
36
|
+
| **indexData** (dict): [required] the values.
|
|
37
|
+
| **campaignId** (string): the campaign the index belongs to.
|
|
38
|
+
| **countryCode** (string): one of AU, BE, BR, CA, DE, ES, FR,
|
|
39
|
+
GB, IE, IN, IT, JP, MX, NL, SE, TR, US.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
| ApiResponse
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
schema_version = 'application/json'
|
|
46
|
+
headers = {"Accept": schema_version, "Content-Type": schema_version}
|
|
47
|
+
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
48
|
+
|
|
49
|
+
@sp_endpoint('/adsApi/v1/locationIndexes', method='GET')
|
|
50
|
+
def list_location_indexes(self, **kwargs) -> ApiResponse:
|
|
51
|
+
r"""
|
|
52
|
+
Lists every Smart Location Index of the advertiser, with its status.
|
|
53
|
+
|
|
54
|
+
Answers a page and a nextToken; when that token is empty there are no
|
|
55
|
+
more pages.
|
|
56
|
+
|
|
57
|
+
Keyword Args
|
|
58
|
+
| **maxResults** (int): page size.
|
|
59
|
+
| **nextToken** (string): the token from the previous page.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
| ApiResponse
|
|
63
|
+
| **locationIndexes** (array), **nextToken** (string)
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
schema_version = 'application/json'
|
|
67
|
+
headers = {"Accept": schema_version, "Content-Type": schema_version}
|
|
68
|
+
return self._request(kwargs.pop('path'), params=kwargs, headers=headers)
|
|
69
|
+
|
|
70
|
+
@sp_endpoint('/adsApi/v1/retrieve/locationIndexes', method='POST')
|
|
71
|
+
def retrieve_location_indexes(self, **kwargs) -> ApiResponse:
|
|
72
|
+
r"""
|
|
73
|
+
Reads one or more Smart Location Indexes by id.
|
|
74
|
+
|
|
75
|
+
An index still in PENDING is being processed and cannot yet be used for
|
|
76
|
+
smart location targeting.
|
|
77
|
+
|
|
78
|
+
Request body
|
|
79
|
+
| **indexIds** (array): [required] the identifiers to read.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
| ApiResponse
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
schema_version = 'application/json'
|
|
86
|
+
headers = {"Accept": schema_version, "Content-Type": schema_version}
|
|
87
|
+
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
88
|
+
|
|
89
|
+
@sp_endpoint('/adsApi/v1/update/locationIndexes', method='POST')
|
|
90
|
+
def update_location_indexes(self, **kwargs) -> ApiResponse:
|
|
91
|
+
r"""
|
|
92
|
+
Replaces the data of existing Smart Location Indexes.
|
|
93
|
+
|
|
94
|
+
The supplied values replace the ones the index held. The update is
|
|
95
|
+
asynchronous too: the index returns to PENDING until the new data has
|
|
96
|
+
been processed, and UPDATE_FAILED if that processing fails.
|
|
97
|
+
|
|
98
|
+
Request body
|
|
99
|
+
| **locationIndexes** (array): [required] one or more updates.
|
|
100
|
+
| **indexId** (string): [required] the index to rewrite.
|
|
101
|
+
| **indexData** (dict): the new values.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
| ApiResponse
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
schema_version = 'application/json'
|
|
108
|
+
headers = {"Accept": schema_version, "Content-Type": schema_version}
|
|
109
|
+
return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
|
|
@@ -2,7 +2,7 @@ import requests
|
|
|
2
2
|
import hashlib
|
|
3
3
|
import logging
|
|
4
4
|
from cachetools import TTLCache
|
|
5
|
-
from ad_api.
|
|
5
|
+
from ad_api.shared.base_client import BaseClient
|
|
6
6
|
|
|
7
7
|
from .credentials import Credentials
|
|
8
8
|
from .access_token_response import AccessTokenResponse
|
ad_api/base/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .base_client import BaseClient
|
|
1
|
+
from ad_api.shared.base_client import BaseClient
|
|
2
2
|
from .client import Client
|
|
3
3
|
from .helpers import fill_query_params, sp_endpoint
|
|
4
4
|
from .marketplaces import Marketplaces, MarketplacesIds, Currencies, CurrencySymbols, Locales
|
|
@@ -11,7 +11,6 @@ from .api_response import ApiResponse
|
|
|
11
11
|
from .utils import Utils
|
|
12
12
|
|
|
13
13
|
__all__ = [
|
|
14
|
-
'AccessTokenClient',
|
|
15
14
|
'ApiResponse',
|
|
16
15
|
'Client',
|
|
17
16
|
'BaseClient',
|
ad_api/base/client.py
CHANGED
|
@@ -5,7 +5,7 @@ from cachetools import TTLCache
|
|
|
5
5
|
from requests import request
|
|
6
6
|
from ad_api.auth import AccessTokenClient, AccessTokenResponse
|
|
7
7
|
from .api_response import ApiResponse
|
|
8
|
-
from .base_client import BaseClient
|
|
8
|
+
from ad_api.shared.base_client import BaseClient
|
|
9
9
|
from .exceptions import get_exception_for_code, get_exception_for_content
|
|
10
10
|
from .marketplaces import Marketplaces
|
|
11
11
|
import os
|
|
File without changes
|
ad_api/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "1.
|
|
1
|
+
__version__ = "1.7.0"
|