python-amazon-ad-api 1.5.8__py3-none-any.whl → 1.5.10__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.
@@ -39,7 +39,8 @@ class PortfoliosV3(Client):
39
39
  if prefer:
40
40
  headers.update({"Prefer": prefer_value})
41
41
 
42
- return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
42
+ body = kwargs.pop('body', {})
43
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(body if body is not None else {}, False), params=kwargs, headers=headers)
43
44
 
44
45
 
45
46
 
ad_api/api/sb/media.py CHANGED
@@ -3,15 +3,22 @@ from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
3
3
 
4
4
  class Media(Client):
5
5
  """
6
- Use this interface to request and retrieve store information. This can be used for Sponsored Brands campaign creation, to pull the store URL information, and for asset registration for Stores.
7
- """
6
+ Poll the status of media already uploaded for Sponsored Brands.
7
+
8
+ The v3 contract carries a single operation on this resource, GET
9
+ /media/describe, which answers the state of a media id. A creative can be
10
+ attached to a campaign once its media reaches PendingDeepValidation, but it
11
+ may still fail validation afterwards and move to Failed, so a campaign can
12
+ be rejected later. Only Available means the media finished processing and
13
+ is published for use.
8
14
 
9
- # NOTE: /media/upload and /media/complete are NOT in the v3 contract.
10
- # Probing /media/upload answers 403 IncompleteSignatureException before the
11
- # router sees it, which suggests the route expects an AWS SigV4 signature
12
- # rather than the bearer token this client sends. Not verified either way.
13
- # /media/complete answers 500 with a NullPointerException on an empty body,
14
- # so the route exists but its expected fields are unknown.
15
+ /media/upload and /media/complete sit outside that contract. Probing
16
+ /media/upload answers 403 IncompleteSignatureException before the router
17
+ sees it, which suggests it expects an AWS SigV4 signature rather than the
18
+ bearer token this client sends. /media/complete answers 500 with a
19
+ NullPointerException on an empty body, so the route exists but its expected
20
+ fields are unknown. Neither is verified.
21
+ """
15
22
 
16
23
  @sp_endpoint('/media/upload', method='POST')
17
24
  def create_media(self, **kwargs) -> ApiResponse:
@@ -34,6 +41,24 @@ class Media(Client):
34
41
 
35
42
  @sp_endpoint('/media/complete', method='PUT')
36
43
  def complete_media(self, **kwargs) -> ApiResponse:
44
+ """
45
+ Notifies the service that an upload started by create_media finished.
46
+
47
+ The upload location returned by create_media expires in 15 minutes, and
48
+ this call closes the loop after the PUT to that location succeeds.
49
+
50
+ The route answers 500 with a NullPointerException when the body is
51
+ empty, so the body is required but its fields are not documented in any
52
+ contract this package tracks. Pass a body as the registered example
53
+ does and inspect the error if the service refuses it.
54
+
55
+ Keyword Args
56
+ | body **body** (string | dict): the completion payload. [required]
57
+
58
+ Returns:
59
+ | ApiResponse
60
+
61
+ """
37
62
  return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs)
38
63
 
39
64
  @sp_endpoint('/media/describe', method='GET')
@@ -41,15 +66,17 @@ class Media(Client):
41
66
  """
42
67
  Describes an uploaded media resource.
43
68
 
44
- The media id goes in the query string. Answered ``400 InvalidMediaId``
45
- for an id that does not exist, which means the route is live.
69
+ The media id goes in the query string, as the contract requires. The
70
+ answer carries a status of PendingDeepValidation, Available or Failed,
71
+ and 404 means the id is unknown. A media id that does not exist answers
72
+ 400 InvalidMediaId, which means the route is live.
46
73
 
47
74
  Keyword Args
48
- | path **mediaId** (string): The media identifier. [required]
75
+ | query **mediaId** (string): The media identifier. [required]
49
76
 
50
77
  Returns:
51
78
  | ApiResponse
52
79
 
53
- Documentation: https://advertising.amazon.com/API/docs/en-us/sponsored-brands/3-0/openapi
80
+ Documentation: https://advertising.amazon.com/API/docs/en-us/sponsored-brands/3-0/openapi#tag/Media
54
81
  """
55
82
  return self._request(kwargs.pop('path'), params={'mediaId': mediaId, **kwargs})
@@ -2,6 +2,34 @@ from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
2
2
 
3
3
 
4
4
  class Recommendations(Client):
5
+ """
6
+ Ask for headline suggestions to use in a Sponsored Brands creative.
7
+
8
+ The resource has a single operation, POST with a HeadlineSuggestionRequest,
9
+ and it exists only in the 4.0 contract: the 3.0 contract does not carry the
10
+ route. The call suggests headlines; it neither creates nor changes a
11
+ creative, so it is safe to run while a campaign is live.
12
+ """
13
+
5
14
  @sp_endpoint('/sb/recommendations/creative/headline', method='POST')
6
15
  def list_recommendations(self, **kwargs) -> ApiResponse:
16
+ """
17
+ Returns suggested headlines for the products or store pages given.
18
+
19
+ The request names what the headlines are for, either by ASIN or by store
20
+ page, and caps how many suggestions come back. An answer of 422 means
21
+ the parameters were understood but rejected, which is what an empty or
22
+ contradictory request produces.
23
+
24
+ Request body (HeadlineSuggestionRequest)
25
+ | **asins** (array): the products the headlines are for.
26
+ | **storePages** (array): the store pages the headlines are for.
27
+ | **maxNumSuggestions** (number): how many suggestions to return.
28
+ | **adFormat** (string): the format the headlines are written for.
29
+
30
+ Returns:
31
+ | ApiResponse
32
+
33
+ Documentation: https://advertising.amazon.com/API/docs/en-us/sponsored-brands/4-0/openapi
34
+ """
7
35
  return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs)
@@ -3,15 +3,35 @@ from ad_api.base import Client, sp_endpoint, fill_query_params, ApiResponse, Uti
3
3
 
4
4
  class Snapshots(Client):
5
5
  """
6
- Use the Amazon Advertising API for Sponsored Products for campaign, ad group, keyword, negative keyword, and product ad management operations. For more information about Sponsored Products, see the Sponsored Products Support Center. For onboarding information, see the account setup topic.
6
+ Request and read Sponsored Display snapshots.
7
+
8
+ A snapshot is an asynchronous record of what the account held at a moment:
9
+ the POST asks for one and answers 202 with no body, and the GET polls by
10
+ snapshot id until the record is ready. Both routes are marked deprecated in
11
+ the 3.0 contract, so they may stop answering; they are kept because the
12
+ account still uses them.
13
+
14
+ The contract also carries GET /sd/snapshots/{snapshotId}/download, which
15
+ answers 307 and redirects to the file. It is not wrapped here: a direct
16
+ download of the location returned by get_snapshot answers 401 unless the
17
+ client sends its own headers, which download_snapshot below already does.
7
18
  """
8
19
 
9
20
  @sp_endpoint('/sd/{}/snapshot', method='POST')
10
21
  def post_snapshot(self, recordType, **kwargs) -> ApiResponse:
11
22
  """
23
+ Requests a snapshot of one record type.
24
+
25
+ The contract answers 202 with an empty body and no snapshot id, so the
26
+ id has to be read from the account afterwards. Marked deprecated in the
27
+ 3.0 contract.
28
+
29
+ Keyword Args
30
+ | path **recordType** (string): the record the snapshot covers. [required]
12
31
 
13
32
  Returns:
14
- ApiResponse
33
+ | ApiResponse
34
+
15
35
  """
16
36
  return self._request(fill_query_params(kwargs.pop('path'), recordType), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs)
17
37
 
@@ -20,8 +40,15 @@ class Snapshots(Client):
20
40
  r"""
21
41
  Gets the status of a requested snapshot.
22
42
 
43
+ Answers 202 while the record is still being built. Once it is ready the
44
+ location field points at the file, and passing that location to
45
+ download_snapshot saves it. Marked deprecated in the 3.0 contract.
46
+
47
+ Keyword Args
48
+ | path **snapshotId** (string): the identifier of the snapshot. [required]
49
+
23
50
  Returns:
24
- ApiResponse
51
+ | ApiResponse
25
52
  """
26
53
  return self._request(fill_query_params(kwargs.pop('path'), snapshotId), params=kwargs)
27
54
 
@@ -34,7 +61,7 @@ class Snapshots(Client):
34
61
  kwarg parameter **format** if not provided a format will return a url to download the snapshot (this url has a expiration time)
35
62
 
36
63
  Keyword Args
37
- | **url** (string): The location obatined from get_snapshot [required]
64
+ | **url** (string): the location obtained from get_snapshot [required]
38
65
  | **file** (string): The path to save the file if mode is download json, zip or gzip. [optional]
39
66
  | **format** (string): The mode to download the snapshot: data (list), raw, url, json, zip, gzip. Default (url) [optional]
40
67
 
ad_api/api/stores.py CHANGED
@@ -3,33 +3,51 @@ from ad_api.base import Client, sp_endpoint, fill_query_params, ApiResponse, Uti
3
3
 
4
4
  class Stores(Client):
5
5
  """
6
- Brand Metrics provides a new measurement solution that quantifies opportunities for your brand at each stage of the customer journey on Amazon, and helps brands understand the value of different shopping engagements that impact stages of that journey. You can now access Awareness and Consideration indices that compare your performance to peers using models predictive of consideration and sales. Brand Metrics quantifies the number of customers in the awareness and consideration marketing funnel stages and is built at scale to measure all shopping engagements with your brand on Amazon, not just ad-attributed engagements. Additionally, BM breaks out key shopping engagements at each stage of the shopping journey, along with the Return on Engagement, so you can measure the historical sales following a consideration event or purchase.
6
+ Read engagement and insight metrics for a Brand Store.
7
+
8
+ Both routes are keyed by the brand entity id and both answer a versioned
9
+ media type: the client asks for v1 by default and the service picks the
10
+ shape of the answer from it. The 3.0 contract declares both as POST, which
11
+ is why they carry a body even though they only read.
7
12
  """
8
13
 
9
14
  @sp_endpoint('/stores/{}/asinMetrics', method='POST')
10
15
  def get_asin_engagement_for_store(self, brandEntityId, version: int = 1, **kwargs) -> ApiResponse:
11
16
  r"""
12
- getAsinEngagementForStore
17
+ Engagement figures for the ASINs of a store.
18
+
19
+ Keyword Args
20
+ | path **brandEntityId** (string): the brand entity id of the store. [required]
21
+ | **version** (int): the media type version asked for. Defaults to 1.
22
+ | body **body** (string | dict): the ASIN list to measure. [required]
23
+
24
+ Returns:
25
+ | ApiResponse
13
26
  """
14
27
  content_type = 'application/vnd.GetAsinEngagementForStoreRequest.v'+ str(version) +'+json'
15
28
  accept = 'application/vnd.GetAsinEngagementForStoreResponse.v'+ str(version) +'+json'
16
29
  headers = {'Content-Type': content_type, 'Accept': accept}
17
30
  return self._request(fill_query_params(kwargs.pop('path'), brandEntityId), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
18
31
 
19
- @sp_endpoint('/stores/{}/insights', method='GET')
32
+ @sp_endpoint('/stores/{}/insights', method='POST')
20
33
  def get_insights_for_store_api(self, brandEntityId, version: int = 1, **kwargs) -> ApiResponse:
21
34
  r"""
22
- getInsightsForStoreAPI
35
+ Insight metrics for a store, over the period named in the body.
36
+
37
+ The contract declares this route as POST, so a body is expected even
38
+ though the call only reads. An earlier version of this method sent the
39
+ same body on a GET.
40
+
41
+ Keyword Args
42
+ | path **brandEntityId** (string): the brand entity id of the store. [required]
43
+ | **version** (int): the media type version asked for. Defaults to 1.
44
+ | body **body** (string | dict): the period and grouping to report. [required]
45
+
46
+ Returns:
47
+ | ApiResponse
48
+
49
+ Documentation: https://advertising.amazon.com/API/docs/en-us/stores
23
50
  """
24
51
  content_type = 'application/vnd.GetInsightsForStoreRequest.v'+ str(version) +'+json'
25
- # accept = 'application/vnd.GetInsightsForStoreResponse.v'+ str(version) +'+json'
26
- headers = {
27
- 'Content-Type': content_type,
28
- # 'Accept': accept,
29
- }
30
- # return self._request(fill_query_params(kwargs.pop('path'), brandEntityId),
31
- # data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs)
52
+ headers = {'Content-Type': content_type}
32
53
  return self._request(fill_query_params(kwargs.pop('path'), brandEntityId), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
33
-
34
-
35
-
ad_api/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.5.8"
1
+ __version__ = "1.5.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-amazon-ad-api
3
- Version: 1.5.8
3
+ Version: 1.5.10
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
@@ -1,5 +1,5 @@
1
1
  ad_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- ad_api/version.py,sha256=aGdl9Y3XkJkVSG47nNBoRdRr4veFwvs7t9uDlneAtdg,22
2
+ ad_api/version.py,sha256=b1kzkZXlJIxgfQrS-SYzjuS4nL4Yu8J0TS_UxMfSCW8,23
3
3
  ad_api/api/__init__.py,sha256=M07SD5BRC1L4_PqxLc8cKPI9Iq5zC2jPhkFUeHoh6CM,1632
4
4
  ad_api/api/account.py,sha256=CmOvCfHoPWaeTUJvtB0pNoNulZVSz4oMMCKIpVTpHos,2931
5
5
  ad_api/api/account_budgets.py,sha256=jFce5eLWAFK3ydjnYR7_Sv7B0-gHTG5bMTx_TcHyy1A,2319
@@ -18,11 +18,11 @@ ad_api/api/localization.py,sha256=HdkChAawloJ8zj5rCye9NVf7kLnQ7vW6aKsBLZ2W-gI,17
18
18
  ad_api/api/manager_accounts.py,sha256=tnmJxOGIKTuJ3i8wciwfs931REW0aeNKQiqCpBrTZ2Y,5107
19
19
  ad_api/api/metadata.py,sha256=vWPbDGvEB72421fjSu4KrNkTdrIijHTPV8k36hceSbA,2406
20
20
  ad_api/api/portfolios.py,sha256=Oe3LS2HsjMJSq1Id8cwOWrH2AiPMcBb7oTkFHjudnTI,7103
21
- ad_api/api/portfolios_v3.py,sha256=qqIzXmhnb3g2QmTENsgzOayhvOObgI-rD7PTfftgDQg,6842
21
+ ad_api/api/portfolios_v3.py,sha256=GH1HOifNJxhFXD0hG9ZfnyGmIwbaorxNhVMJXeaqFgU,6894
22
22
  ad_api/api/profiles.py,sha256=mMSCUd5HdR_nFBDFngLY94tIfMCA4yGnjHz-PSMe0rE,7200
23
23
  ad_api/api/recommendations.py,sha256=_r4LsJkRTkiuOvzS7wrtR2ZmxA7gGe-T4jRDAqM6pRo,6198
24
24
  ad_api/api/reports.py,sha256=gNmDHLULD2uaJgsMpIbCX9kabwhMXRr9WfZBtHUdsOY,6043
25
- ad_api/api/stores.py,sha256=7W3RJKZyZOQ3nHzInvK9FDhWTXCH6Xe9a6dCBatEZ-o,2484
25
+ ad_api/api/stores.py,sha256=bvEguxr9A8Liy1TlVDDRNvJ_r5Twc9YGNfvsOpBdUNo,2616
26
26
  ad_api/api/stream.py,sha256=JpnF8SKniOAHiEnEq1RPrh6tNy-Q2-8GPBTmnlxEXqQ,2989
27
27
  ad_api/api/validation_configurations.py,sha256=BBoUv7iWJjB33Wp4pClNbzSUX9iNW36lJEIDn6CqgD8,4008
28
28
  ad_api/api/sb/__init__.py,sha256=APbCAkWM1gzYuhpEUU98XDIKJKJx1NXALjLBXA9zdBU,1538
@@ -40,13 +40,13 @@ ad_api/api/sb/forecast.py,sha256=qf2ivhGX3_dv_uMGP9cmrt_x3S7QLg-P_5nCI8bAr00,396
40
40
  ad_api/api/sb/keywords.py,sha256=P1dGqcLia349O0CwpBRURlIzgRc0cbFotkAGTSrErt4,7634
41
41
  ad_api/api/sb/keywords_recommendations.py,sha256=oA4FRBwDtk52SZK0RgWvjNQ7K2GX0G2zSoisJGiEYDw,629
42
42
  ad_api/api/sb/landing_page_asins.py,sha256=j3qi2-KccuEzGLZrl6EfZBSikW2R4B4l7TixpkAnTq8,1259
43
- ad_api/api/sb/media.py,sha256=5LTeM4AHSDKw_58aTB2nEZhIYdWkztH0syBXaovS1rs,2529
43
+ ad_api/api/sb/media.py,sha256=JLLpBSSYa5hFEKS8Jf-cIyH8b8yjI23xqLg0KE9OZmw,3637
44
44
  ad_api/api/sb/migration.py,sha256=QfbtB9yhRDn6OyS-DSypETAhhp_WDJbELRUoBsxc07U,7086
45
45
  ad_api/api/sb/negative_keywords.py,sha256=uHLtOnu-OUHr23_Yh05qTSlVcnV2ITci6QvaY6n9f_I,6986
46
46
  ad_api/api/sb/negative_product_targeting.py,sha256=QbK1EhhzmnNOzGtbkrAZ4HS5OqiLU3nZBmsl1scd2D0,5085
47
47
  ad_api/api/sb/optimization_rules.py,sha256=aj9tZwKdaOzjnAN-8FHb49aiejNZKCCCcR8fjffH4k0,6802
48
48
  ad_api/api/sb/product_targeting.py,sha256=o6aB3hIh9jKvi_uTXFi--1hpnPFuXzQ-U9N7VUP_Bz4,5362
49
- ad_api/api/sb/recommendations.py,sha256=_21L8tZPuArmJ30XyR1SKQHQH_yswvF0IMqwD9sLhgY,347
49
+ ad_api/api/sb/recommendations.py,sha256=6fEOdAMKKFGmdDX4Fh4NXHgzSTteu3iT6PuIWwjGWOg,1605
50
50
  ad_api/api/sb/reports.py,sha256=icw5DpRrqfj0idEo0NN1GPDpIWQun2h_c2Uwc7CpNUA,3801
51
51
  ad_api/api/sb/stores.py,sha256=g0NbaYcd49JOJg95l4hiyCEreSu7inoWRdbEwT32KgQ,4335
52
52
  ad_api/api/sb/targeting_categories.py,sha256=QqOB2vTiS5c8u9qvbjRpeKJdGBkMWfgwWSoF3h-Eg4c,5114
@@ -66,7 +66,7 @@ ad_api/api/sd/product_ads.py,sha256=xrj7xjp5rzO7pVhZCCNLor2X2Ue-r_dxR1-SWbmA4no,
66
66
  ad_api/api/sd/product_targeting.py,sha256=w5BuMayi5emarC8neaijnHn_sh_LUgcyyq8nlPtRT1w,13461
67
67
  ad_api/api/sd/recommendations.py,sha256=cwNIlvc3bBnmzKCHmV4KFQP_F4Uora5J5VhRKQKXrtA,1436
68
68
  ad_api/api/sd/reports.py,sha256=qtzUCJdddYLNKJuJJPPPG6WcMsEUweF8ObU2zSsdpbk,4713
69
- ad_api/api/sd/snapshots.py,sha256=XJ5s0Hd74KpNllIrb4-31_Wh_sLyQTnpZb7eHW-LRHc,2288
69
+ ad_api/api/sd/snapshots.py,sha256=0Km-7YGm1D_YsravmzomUDa91nVPQZFr_mww_skEwpw,3376
70
70
  ad_api/api/sd/targeting_recommendations.py,sha256=FmuJxGS5GIXod8iFTS1Ryls_-QFTdf8B3uWL_nne80U,3668
71
71
  ad_api/api/sp/__init__.py,sha256=FSa1GNhjWljF2S3QMXDUtVng3L1YoKeCyXQTro1hYHc,1704
72
72
  ad_api/api/sp/ad_groups_v3.py,sha256=UCK0es4KvWcYMtlO01pel52T2ZBaWDgW0iGKYueK7Rg,5294
@@ -124,8 +124,8 @@ ad_api/base/exceptions.py,sha256=9D3M40ZIlLS0fA-aQh1BTWPOW-Nvf0tRhbA85jFnDJ4,438
124
124
  ad_api/base/helpers.py,sha256=UK7Q13vZ0mNdF54xzfzoGDn2O_cd2yPrK2X4rOzC41c,2334
125
125
  ad_api/base/marketplaces.py,sha256=44lvCcluXNpqTprWQ80e3weSQmQbJoWL-WDSOWVbCyQ,4657
126
126
  ad_api/base/utils.py,sha256=_qnCBOvyJTLgaZjJzUWTi38GGLHkQszXELs79133Rb4,5618
127
- python_amazon_ad_api-1.5.8.dist-info/licenses/LICENSE,sha256=h2rpqlmmLy-4l1tN6KpWAFxx1JEMYeEFrMrZUbx_B_o,1105
128
- python_amazon_ad_api-1.5.8.dist-info/METADATA,sha256=H-CSkEpq4IYNWM_YPyh57IIeZcPCnxrdrWgtapxHJh8,24150
129
- python_amazon_ad_api-1.5.8.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
130
- python_amazon_ad_api-1.5.8.dist-info/top_level.txt,sha256=nN9twUos-8pkP514ZwpvRU9YL9L2XyQyHsMQFfudGTU,7
131
- python_amazon_ad_api-1.5.8.dist-info/RECORD,,
127
+ python_amazon_ad_api-1.5.10.dist-info/licenses/LICENSE,sha256=h2rpqlmmLy-4l1tN6KpWAFxx1JEMYeEFrMrZUbx_B_o,1105
128
+ python_amazon_ad_api-1.5.10.dist-info/METADATA,sha256=H9DngSBLjNuAqxRGkFey4Umg-yUbAGzJdULqdQhho5g,24151
129
+ python_amazon_ad_api-1.5.10.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
130
+ python_amazon_ad_api-1.5.10.dist-info/top_level.txt,sha256=nN9twUos-8pkP514ZwpvRU9YL9L2XyQyHsMQFfudGTU,7
131
+ python_amazon_ad_api-1.5.10.dist-info/RECORD,,