python-amazon-ad-api 1.1.2__tar.gz → 1.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/PKG-INFO +1 -1
  2. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/__init__.py +5 -1
  3. python_amazon_ad_api-1.1.4/ad_api/api/sb/budget_rules.py +235 -0
  4. python_amazon_ad_api-1.1.4/ad_api/api/sb/optimization_rules.py +153 -0
  5. python_amazon_ad_api-1.1.4/ad_api/version.py +1 -0
  6. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/PKG-INFO +1 -1
  7. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/SOURCES.txt +2 -0
  8. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/setup.cfg +1 -1
  9. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/setup.py +1 -1
  10. python_amazon_ad_api-1.1.2/ad_api/version.py +0 -1
  11. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/LICENSE +0 -0
  12. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/README.md +0 -0
  13. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/__init__.py +0 -0
  14. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/__init__.py +0 -0
  15. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/account.py +0 -0
  16. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/advertising_test_account.py +0 -0
  17. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/attribution.py +0 -0
  18. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/audiences.py +0 -0
  19. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/billing.py +0 -0
  20. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/brand_metrics.py +0 -0
  21. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/creative_assets.py +0 -0
  22. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/eligibility.py +0 -0
  23. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/exports.py +0 -0
  24. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/history.py +0 -0
  25. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/insights.py +0 -0
  26. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/invoices.py +0 -0
  27. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/localization.py +0 -0
  28. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/manager_accounts.py +0 -0
  29. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/metadata.py +0 -0
  30. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/portfolios.py +0 -0
  31. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/portfolios_v3.py +0 -0
  32. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/profiles.py +0 -0
  33. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/recommendations.py +0 -0
  34. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/reports.py +0 -0
  35. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ad_creatives_v4.py +0 -0
  36. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ad_groups.py +0 -0
  37. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ad_groups_v4.py +0 -0
  38. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ads_v4.py +0 -0
  39. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/benchmarks.py +0 -0
  40. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/bid_recommendations.py +0 -0
  41. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/brands.py +0 -0
  42. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/campaigns.py +0 -0
  43. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/campaigns_v4.py +0 -0
  44. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/forecast.py +0 -0
  45. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/keywords.py +0 -0
  46. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/keywords_recommendations.py +0 -0
  47. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/landing_page_asins.py +0 -0
  48. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/media.py +0 -0
  49. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/negative_keywords.py +0 -0
  50. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/negative_product_targeting.py +0 -0
  51. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/product_targeting.py +0 -0
  52. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/recommendations.py +0 -0
  53. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/reports.py +0 -0
  54. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/stores.py +0 -0
  55. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/targeting_recommendations.py +0 -0
  56. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/themes.py +0 -0
  57. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/__init__.py +0 -0
  58. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/ad_groups.py +0 -0
  59. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/bid_recommendations.py +0 -0
  60. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/brand_safety.py +0 -0
  61. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/budget_rules.py +0 -0
  62. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/campaigns.py +0 -0
  63. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/campaigns_budget_usage.py +0 -0
  64. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/creatives.py +0 -0
  65. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/forecast.py +0 -0
  66. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/negative_product_targeting.py +0 -0
  67. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/product_ads.py +0 -0
  68. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/product_targeting.py +0 -0
  69. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/recommendations.py +0 -0
  70. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/reports.py +0 -0
  71. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/snapshots.py +0 -0
  72. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/targeting_recommendations.py +0 -0
  73. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/__init__.py +0 -0
  74. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/ad_groups_v3.py +0 -0
  75. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/bid_recommendations_v3.py +0 -0
  76. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_initial_recommendation.py +0 -0
  77. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_recommendations.py +0 -0
  78. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_rules.py +0 -0
  79. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_rules_recommendations.py +0 -0
  80. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaign_consolidated_recommendations.py +0 -0
  81. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaign_negative_keywords_v3.py +0 -0
  82. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaign_negative_targets.py +0 -0
  83. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaigns_budget_usage.py +0 -0
  84. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaigns_v3.py +0 -0
  85. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaings_optimization.py +0 -0
  86. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/keywords_v3.py +0 -0
  87. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/negative_keywords_v3.py +0 -0
  88. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/negative_product_targeting_v3.py +0 -0
  89. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_ads_v3.py +0 -0
  90. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_recommendations.py +0 -0
  91. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_targeting_v3.py +0 -0
  92. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/ranked_keywords_recommendations.py +0 -0
  93. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/schedule_based_bid_optimization.py +0 -0
  94. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/stores.py +0 -0
  95. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/stream.py +0 -0
  96. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/__init__.py +0 -0
  97. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/ad_groups.py +0 -0
  98. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/ads.py +0 -0
  99. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/campaigns.py +0 -0
  100. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/targets.py +0 -0
  101. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/validation_configurations.py +0 -0
  102. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/__init__.py +0 -0
  103. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/access_token_client.py +0 -0
  104. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/access_token_response.py +0 -0
  105. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/credentials.py +0 -0
  106. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/exceptions.py +0 -0
  107. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/__init__.py +0 -0
  108. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/api_response.py +0 -0
  109. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/base_client.py +0 -0
  110. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/client.py +0 -0
  111. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/config.py +0 -0
  112. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/credential_provider.py +0 -0
  113. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/exceptions.py +0 -0
  114. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/helpers.py +0 -0
  115. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/marketplaces.py +0 -0
  116. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/utils.py +0 -0
  117. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/pyproject.toml +0 -0
  118. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/dependency_links.txt +0 -0
  119. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/requires.txt +0 -0
  120. {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-amazon-ad-api
3
- Version: 1.1.2
3
+ Version: 1.1.4
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
@@ -20,6 +20,8 @@ from .media import Media
20
20
  from .reports import Reports
21
21
  from .benchmarks import Benchmarks
22
22
  from .themes import Themes
23
+ from .budget_rules import BudgetRules
24
+ from .optimization_rules import OptimizationRules
23
25
 
24
26
  __all__ = [
25
27
  "Brands",
@@ -43,5 +45,7 @@ __all__ = [
43
45
  "Media",
44
46
  "Reports",
45
47
  "Benchmarks",
46
- "Themes"
48
+ "Themes",
49
+ "BudgetRules",
50
+ "OptimizationRules",
47
51
  ]
@@ -0,0 +1,235 @@
1
+ from ad_api.base import Client, sp_endpoint, fill_query_params, ApiResponse, Utils
2
+
3
+
4
+ class BudgetRules(Client):
5
+ """Sponsored Brands budget rules.
6
+
7
+ Documentation: https://advertising.amazon.com/API/docs/en-us/sponsored-brands/4-0/openapi
8
+
9
+ Read routes were probed against the live service; the write routes are built
10
+ from the contract and not exercised, because they change campaign budgets.
11
+
12
+ .. note::
13
+ ``budget_recommendations`` only answers with the versioned media type.
14
+ Sending ``application/json`` makes the router answer ``404 Could not find
15
+ resource``, as if the route did not exist. Amazon routes on media type.
16
+
17
+ .. note::
18
+ An unknown ``budgetRuleId`` answers ``400 InvalidParameterValue`` with
19
+ ``errorCode 240002``, not a 404. The identifier is validated before it is
20
+ looked up.
21
+ """
22
+
23
+ _MEDIA_JSON = 'application/json'
24
+ _MEDIA_USAGE = 'application/vnd.sbcampaignbudgetusage.v1+json'
25
+ _MEDIA_RECS = 'application/vnd.sbbudgetrecommendation.v4+json'
26
+
27
+ @sp_endpoint('/sb/budgetRules', method='GET')
28
+ def list_budget_rules(self, pageSize, **kwargs) -> ApiResponse:
29
+ """
30
+ Gets the budget rules of the advertiser.
31
+
32
+ Keyword Args
33
+ | query **pageSize** (number): [required] Results per page.
34
+ | query **nextToken** (string): Pagination token. [optional]
35
+
36
+ Returns:
37
+ | ApiResponse, with the rules under ``budgetRulesForAdvertiserResponse``
38
+ and a ``nextToken``.
39
+ """
40
+ return self._request(kwargs.pop('path'), params=kwargs,
41
+ headers={'Accept': self._MEDIA_JSON})
42
+
43
+ @sp_endpoint('/sb/budgetRules/{}', method='GET')
44
+ def get_budget_rule(self, budgetRuleId, **kwargs) -> ApiResponse:
45
+ """
46
+ Gets one budget rule by identifier.
47
+
48
+ Keyword Args
49
+ | path **budgetRuleId** (string): [required]
50
+ """
51
+ return self._request(fill_query_params(kwargs.pop('path'), budgetRuleId),
52
+ params=kwargs, headers={'Accept': self._MEDIA_JSON})
53
+
54
+ @sp_endpoint('/sb/budgetRules/{}/campaigns', method='GET')
55
+ def list_rule_campaigns(self, budgetRuleId, pageSize, **kwargs) -> ApiResponse:
56
+ """
57
+ Gets the campaigns associated with a budget rule.
58
+
59
+ Keyword Args
60
+ | path **budgetRuleId** (string): [required]
61
+ | query **pageSize** (number): [required]
62
+ | query **nextToken** (string): [optional]
63
+ """
64
+ return self._request(fill_query_params(kwargs.pop('path'), budgetRuleId),
65
+ params=kwargs, headers={'Accept': self._MEDIA_JSON})
66
+
67
+ @sp_endpoint('/sb/campaigns/{}/budgetRules', method='GET')
68
+ def list_campaign_rules(self, campaignId, **kwargs) -> ApiResponse:
69
+ """
70
+ Gets the budget rules associated with a campaign.
71
+
72
+ Keyword Args
73
+ | path **campaignId** (number): [required]
74
+
75
+ Returns:
76
+ | ApiResponse, with the rules under ``associatedRules``.
77
+ """
78
+ return self._request(fill_query_params(kwargs.pop('path'), campaignId),
79
+ params=kwargs, headers={'Accept': self._MEDIA_JSON})
80
+
81
+ @sp_endpoint('/sb/budgetRules', method='POST')
82
+ def create_budget_rules(self, budgetRulesDetails, **kwargs) -> ApiResponse:
83
+ """
84
+ Creates budget rules.
85
+
86
+ Request Body [Required]
87
+ | **budgetRulesDetails** (array): One entry per rule.
88
+ | **name** (string): Rule name.
89
+ | **ruleType** (string): ``SCHEDULE`` or ``PERFORMANCE``.
90
+ | **budgetIncreaseBy** ({}): ``type`` (``PERCENT``) and ``value``.
91
+ | **performanceMeasureCondition** ({}): ``metricName`` (``IS``,
92
+ ``NTB`` or ``ROAS``), ``comparisonOperator`` (``GREATER_THAN``,
93
+ ``LESS_THAN``, ``LESS_THAN_OR_EQUAL_TO``,
94
+ ``GREATER_THAN_OR_EQUAL_TO``) and ``threshold``.
95
+ | **duration** ({}): ``eventTypeRuleDuration`` with ``eventId``, or
96
+ ``dateRangeTypeRuleDuration`` with ``startDate``.
97
+ | **recurrence** ({}): ``type`` (``DAILY`` or ``WEEKLY``),
98
+ ``daysOfWeek`` and ``intraDaySchedule``.
99
+
100
+ Returns:
101
+ | ApiResponse, status ``207``.
102
+
103
+ .. note::
104
+ Not probed: creates budget rules on the account.
105
+ """
106
+ return self._request(kwargs.pop('path'),
107
+ data=Utils.convert_body({'budgetRulesDetails': budgetRulesDetails}, False),
108
+ params=kwargs, headers={'Accept': self._MEDIA_JSON,
109
+ 'Content-Type': self._MEDIA_JSON})
110
+
111
+ @sp_endpoint('/sb/budgetRules', method='PUT')
112
+ def update_budget_rules(self, budgetRulesDetails, **kwargs) -> ApiResponse:
113
+ """
114
+ Updates budget rules.
115
+
116
+ Request Body [Required]
117
+ | **budgetRulesDetails** (array): Each entry needs ``ruleId`` and may
118
+ carry ``ruleState`` (``ACTIVE`` or ``PAUSED``) and ``ruleDetails``
119
+ with the same shape used on creation.
120
+
121
+ Returns:
122
+ | ApiResponse, status ``207``.
123
+
124
+ .. note::
125
+ Not probed: updates live budget rules.
126
+ """
127
+ return self._request(kwargs.pop('path'),
128
+ data=Utils.convert_body({'budgetRulesDetails': budgetRulesDetails}, False),
129
+ params=kwargs, headers={'Accept': self._MEDIA_JSON,
130
+ 'Content-Type': self._MEDIA_JSON})
131
+
132
+ @sp_endpoint('/sb/campaigns/{}/budgetRules', method='POST')
133
+ def associate_budget_rules(self, campaignId, budgetRuleIds, **kwargs) -> ApiResponse:
134
+ """
135
+ Associates budget rules with a campaign.
136
+
137
+ Keyword Args
138
+ | path **campaignId** (number): [required]
139
+
140
+ Request Body [Required]
141
+ | **budgetRuleIds** (array of string): [required]
142
+
143
+ Returns:
144
+ | ApiResponse, status ``207``.
145
+
146
+ .. note::
147
+ Not probed: changes which rules apply to a live campaign.
148
+ """
149
+ return self._request(fill_query_params(kwargs.pop('path'), campaignId),
150
+ data=Utils.convert_body({'budgetRuleIds': budgetRuleIds}, False),
151
+ params=kwargs, headers={'Accept': self._MEDIA_JSON,
152
+ 'Content-Type': self._MEDIA_JSON})
153
+
154
+ @sp_endpoint('/sb/campaigns/{}/budgetRules/{}', method='DELETE')
155
+ def disassociate_budget_rule(self, campaignId, budgetRuleId, **kwargs) -> ApiResponse:
156
+ """
157
+ Disassociates one budget rule from a campaign.
158
+
159
+ Keyword Args
160
+ | path **campaignId** (number): [required]
161
+ | path **budgetRuleId** (string): [required]
162
+
163
+ Returns:
164
+ | ApiResponse, status ``200``.
165
+
166
+ .. note::
167
+ Not probed: changes which rules apply to a live campaign.
168
+ """
169
+ path = fill_query_params(kwargs.pop('path'), campaignId)
170
+ return self._request(fill_query_params(path, budgetRuleId),
171
+ params=kwargs, headers={'Accept': self._MEDIA_JSON})
172
+
173
+ @sp_endpoint('/sb/campaigns/budget/usage', method='POST')
174
+ def get_budget_usage(self, campaignIds, **kwargs) -> ApiResponse:
175
+ """
176
+ Gets budget usage for campaigns.
177
+
178
+ Request Body [Required]
179
+ | **campaignIds** (array of string): [required]
180
+
181
+ Returns:
182
+ | ApiResponse, with per-campaign entries under ``success`` and failures
183
+ under ``error``. Each success entry carries ``budget``,
184
+ ``budgetUsagePercent``, ``campaignId``, ``index`` and
185
+ ``usageUpdatedTimestamp``.
186
+
187
+ Example::
188
+
189
+ {"success": [{"budget": 10.0, "budgetUsagePercent": 0.0,
190
+ "campaignId": "95988386496299", "index": 0,
191
+ "usageUpdatedTimestamp": "2026-10-25T00:00:00Z"}],
192
+ "error": []}
193
+ """
194
+ return self._request(kwargs.pop('path'),
195
+ data=Utils.convert_body({'campaignIds': campaignIds}, False),
196
+ params=kwargs, headers={'Accept': self._MEDIA_USAGE,
197
+ 'Content-Type': self._MEDIA_USAGE})
198
+
199
+ @sp_endpoint('/sb/campaigns/budgetRecommendations', method='POST')
200
+ def get_budget_recommendations(self, campaignIds, **kwargs) -> ApiResponse:
201
+ """
202
+ Gets budget recommendations for campaigns.
203
+
204
+ Request Body [Required]
205
+ | **campaignIds** (array of string): [required]
206
+
207
+ Returns:
208
+ | ApiResponse, status ``207``.
209
+
210
+ .. warning::
211
+ This route only answers with its versioned media type. With
212
+ ``application/json`` the service answers ``404 Could not find
213
+ resource``, which reads like a missing route but is only the wrong
214
+ media type.
215
+ """
216
+ return self._request(kwargs.pop('path'),
217
+ data=Utils.convert_body({'campaignIds': campaignIds}, False),
218
+ params=kwargs, headers={'Accept': self._MEDIA_RECS,
219
+ 'Content-Type': self._MEDIA_RECS})
220
+
221
+ @sp_endpoint('/sb/campaigns/budgetRules/recommendations', method='POST')
222
+ def get_budget_rules_recommendation(self, **kwargs) -> ApiResponse:
223
+ """
224
+ Gets budget rule recommendations.
225
+
226
+ Returns:
227
+ | ApiResponse
228
+
229
+ .. note::
230
+ Declared in the 3.0 contract, not in 4.0. Not probed.
231
+ """
232
+ return self._request(kwargs.pop('path'),
233
+ data=Utils.convert_body(kwargs.pop('body', {}), False),
234
+ params=kwargs, headers={'Accept': self._MEDIA_JSON,
235
+ 'Content-Type': self._MEDIA_JSON})
@@ -0,0 +1,153 @@
1
+ from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
2
+
3
+
4
+ class OptimizationRules(Client):
5
+ """Sponsored Brands optimization rules.
6
+
7
+ Documentation: https://advertising.amazon.com/API/docs/en-us/sponsored-brands/4-0/openapi
8
+
9
+ Every route in this family takes a versioned media type on the way in, and the
10
+ service routes on it:
11
+
12
+ .. warning::
13
+ With ``application/json`` the router answers ``404 Could not find
14
+ resource`` on every route here, which reads like a missing route but is
15
+ only the wrong media type. Verified on ``list`` and ``recommendations``.
16
+
17
+ The two read routes were probed against a live account; the four write routes
18
+ are built from the contract and not exercised.
19
+ """
20
+
21
+ _MEDIA_RULES = 'application/vnd.sbruleoptimization.v4+json'
22
+ _MEDIA_RECS = 'application/vnd.sboptimizationrecommendationresource.v4+json'
23
+
24
+ @sp_endpoint('/sb/rules/optimization/list', method='POST')
25
+ def list_optimization_rules(self, **kwargs) -> ApiResponse:
26
+ """
27
+ Lists optimization rules.
28
+
29
+ Request Body [Optional]
30
+ | **entityFilter** ({}): ``entityType`` and ``entityId``.
31
+ | **optimizationRuleIdFilter** ({}): ``include``, a list of rule ids.
32
+ | **maxResults** (number): Page size.
33
+ | **nextToken** (string): Pagination token.
34
+
35
+ Returns:
36
+ | ApiResponse, ``200``, with ``optimizationRules`` and ``totalCount``.
37
+
38
+ Example::
39
+
40
+ {"optimizationRules": [], "totalCount": 0}
41
+ """
42
+ return self._request(kwargs.pop('path'),
43
+ data=Utils.convert_body(kwargs.pop('body', {}), False),
44
+ params=kwargs, headers={'Accept': self._MEDIA_RULES,
45
+ 'Content-Type': self._MEDIA_RULES})
46
+
47
+ @sp_endpoint('/sb/recommendations/optimization', method='POST')
48
+ def get_optimization_recommendation(self, costControlMetric, landingPages, **kwargs) -> ApiResponse:
49
+ """
50
+ Gets an optimization rule recommendation.
51
+
52
+ Request Body [Required]
53
+ | **costControlMetric** ({}): [required] Cost control metric.
54
+ | **landingPages** (array): [required] Each entry carries ``pageType``
55
+ and either ``asins`` or ``url``.
56
+
57
+ Returns:
58
+ | ApiResponse, status ``207``.
59
+
60
+ .. note::
61
+ An empty body answers ``400`` with both members named:
62
+ *"Value null at 'costControlMetric' failed to satisfy constraint"*.
63
+ """
64
+ return self._request(kwargs.pop('path'),
65
+ data=Utils.convert_body({'costControlMetric': costControlMetric,
66
+ 'landingPages': landingPages}, False),
67
+ params=kwargs, headers={'Accept': self._MEDIA_RECS,
68
+ 'Content-Type': self._MEDIA_RECS})
69
+
70
+ @sp_endpoint('/sb/rules/optimization', method='POST')
71
+ def create_optimization_rules(self, optimizationRules, **kwargs) -> ApiResponse:
72
+ """
73
+ Creates optimization rules.
74
+
75
+ Request Body [Required]
76
+ | **optimizationRules** (array): [required]
77
+ | **entityType** (string): Type of the entity the rule applies to.
78
+ | **entityId** (string): Identifier of that entity.
79
+ | **conditions** (array): Each entry needs ``attributeName`` and
80
+ ``criteria`` with ``comparisonOperator`` and ``value``.
81
+
82
+ Returns:
83
+ | ApiResponse, status ``207``.
84
+
85
+ .. note::
86
+ Not probed: creates optimization rules on the account.
87
+ """
88
+ return self._request(kwargs.pop('path'),
89
+ data=Utils.convert_body({'optimizationRules': optimizationRules}, False),
90
+ params=kwargs, headers={'Accept': self._MEDIA_RULES,
91
+ 'Content-Type': self._MEDIA_RULES})
92
+
93
+ @sp_endpoint('/sb/rules/optimization', method='PUT')
94
+ def update_optimization_rules(self, optimizationRules, **kwargs) -> ApiResponse:
95
+ """
96
+ Updates optimization rules.
97
+
98
+ Request Body [Required]
99
+ | **optimizationRules** (array): [required] Each entry needs
100
+ ``optimizationRuleId`` and ``conditions``.
101
+
102
+ Returns:
103
+ | ApiResponse, status ``207``.
104
+
105
+ .. note::
106
+ Not probed: updates live optimization rules.
107
+ """
108
+ return self._request(kwargs.pop('path'),
109
+ data=Utils.convert_body({'optimizationRules': optimizationRules}, False),
110
+ params=kwargs, headers={'Accept': self._MEDIA_RULES,
111
+ 'Content-Type': self._MEDIA_RULES})
112
+
113
+ @sp_endpoint('/sb/rules/optimization/associate', method='POST')
114
+ def associate_optimization_rules(self, optimizationRuleAssociations, **kwargs) -> ApiResponse:
115
+ """
116
+ Associates optimization rules with entities.
117
+
118
+ Request Body [Required]
119
+ | **optimizationRuleAssociations** (array): [required] Each entry needs
120
+ ``entityId``, ``entityType`` and ``optimizationRuleId``.
121
+
122
+ Returns:
123
+ | ApiResponse, status ``207``.
124
+
125
+ .. note::
126
+ Not probed: changes which rules apply to live campaigns.
127
+ """
128
+ return self._request(kwargs.pop('path'),
129
+ data=Utils.convert_body(
130
+ {'optimizationRuleAssociations': optimizationRuleAssociations}, False),
131
+ params=kwargs, headers={'Accept': self._MEDIA_RULES,
132
+ 'Content-Type': self._MEDIA_RULES})
133
+
134
+ @sp_endpoint('/sb/rules/optimization/disassociate', method='POST')
135
+ def disassociate_optimization_rules(self, optimizationRuleDisassociations, **kwargs) -> ApiResponse:
136
+ """
137
+ Disassociates optimization rules from entities.
138
+
139
+ Request Body [Required]
140
+ | **optimizationRuleDisassociations** (array): [required] Each entry
141
+ needs ``entityId``, ``entityType`` and ``optimizationRuleId``.
142
+
143
+ Returns:
144
+ | ApiResponse, status ``207``.
145
+
146
+ .. note::
147
+ Not probed: changes which rules apply to live campaigns.
148
+ """
149
+ return self._request(kwargs.pop('path'),
150
+ data=Utils.convert_body(
151
+ {'optimizationRuleDisassociations': optimizationRuleDisassociations}, False),
152
+ params=kwargs, headers={'Accept': self._MEDIA_RULES,
153
+ 'Content-Type': self._MEDIA_RULES})
@@ -0,0 +1 @@
1
+ __version__ = "1.1.4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-amazon-ad-api
3
- Version: 1.1.2
3
+ Version: 1.1.4
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
@@ -37,6 +37,7 @@ ad_api/api/sb/ads_v4.py
37
37
  ad_api/api/sb/benchmarks.py
38
38
  ad_api/api/sb/bid_recommendations.py
39
39
  ad_api/api/sb/brands.py
40
+ ad_api/api/sb/budget_rules.py
40
41
  ad_api/api/sb/campaigns.py
41
42
  ad_api/api/sb/campaigns_v4.py
42
43
  ad_api/api/sb/forecast.py
@@ -46,6 +47,7 @@ ad_api/api/sb/landing_page_asins.py
46
47
  ad_api/api/sb/media.py
47
48
  ad_api/api/sb/negative_keywords.py
48
49
  ad_api/api/sb/negative_product_targeting.py
50
+ ad_api/api/sb/optimization_rules.py
49
51
  ad_api/api/sb/product_targeting.py
50
52
  ad_api/api/sb/recommendations.py
51
53
  ad_api/api/sb/reports.py
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = python-amazon-ad-api
3
- version = 1.1.2
3
+ version = 1.1.4
4
4
  author = Daniel Alvaro
5
5
  author_email = denisneuf@hotmail.com
6
6
  description = Python wrapper for the Amazon Advertising API
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='python-amazon-ad-api',
5
- version='1.1.2',
5
+ version='1.1.4',
6
6
  install_requires=[
7
7
  "requests>=2.27.1,<2.35.0",
8
8
  "six>=1.16,<1.18",
@@ -1 +0,0 @@
1
- __version__ = "1.1.2"