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.
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/PKG-INFO +1 -1
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/__init__.py +5 -1
- python_amazon_ad_api-1.1.4/ad_api/api/sb/budget_rules.py +235 -0
- python_amazon_ad_api-1.1.4/ad_api/api/sb/optimization_rules.py +153 -0
- python_amazon_ad_api-1.1.4/ad_api/version.py +1 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/PKG-INFO +1 -1
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/SOURCES.txt +2 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/setup.cfg +1 -1
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/setup.py +1 -1
- python_amazon_ad_api-1.1.2/ad_api/version.py +0 -1
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/LICENSE +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/README.md +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/account.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/advertising_test_account.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/attribution.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/audiences.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/billing.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/brand_metrics.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/creative_assets.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/eligibility.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/exports.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/history.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/insights.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/invoices.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/localization.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/manager_accounts.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/metadata.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/portfolios.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/portfolios_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/profiles.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/reports.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ad_creatives_v4.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ad_groups.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ad_groups_v4.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/ads_v4.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/benchmarks.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/bid_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/brands.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/campaigns.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/campaigns_v4.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/forecast.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/keywords.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/keywords_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/landing_page_asins.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/media.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/negative_keywords.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/negative_product_targeting.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/product_targeting.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/reports.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/stores.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/targeting_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/themes.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/ad_groups.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/bid_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/brand_safety.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/budget_rules.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/campaigns.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/campaigns_budget_usage.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/creatives.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/forecast.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/negative_product_targeting.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/product_ads.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/product_targeting.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/reports.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/snapshots.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/targeting_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/ad_groups_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/bid_recommendations_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_initial_recommendation.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_rules.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_rules_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaign_consolidated_recommendations.py +0 -0
- {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
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaign_negative_targets.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaigns_budget_usage.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaigns_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaings_optimization.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/keywords_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/negative_keywords_v3.py +0 -0
- {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
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_ads_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_recommendations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_targeting_v3.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/ranked_keywords_recommendations.py +0 -0
- {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
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/stores.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/stream.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/ad_groups.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/ads.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/campaigns.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/v1/targets.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/validation_configurations.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/access_token_client.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/access_token_response.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/credentials.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/exceptions.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/__init__.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/api_response.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/base_client.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/client.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/config.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/credential_provider.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/exceptions.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/helpers.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/marketplaces.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/utils.py +0 -0
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/pyproject.toml +0 -0
- {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
- {python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/requires.txt +0 -0
- {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
|
@@ -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"
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/SOURCES.txt
RENAMED
|
@@ -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 +0,0 @@
|
|
|
1
|
-
__version__ = "1.1.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/advertising_test_account.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/bid_recommendations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/keywords_recommendations.py
RENAMED
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/landing_page_asins.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/negative_keywords.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/product_targeting.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sb/targeting_recommendations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/bid_recommendations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/campaigns_budget_usage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/product_targeting.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sd/targeting_recommendations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/bid_recommendations_v3.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/budget_recommendations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaign_negative_targets.py
RENAMED
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaigns_budget_usage.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/campaings_optimization.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/negative_keywords_v3.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_recommendations.py
RENAMED
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/sp/product_targeting_v3.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/api/validation_configurations.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/access_token_client.py
RENAMED
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/auth/access_token_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/ad_api/base/credential_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_amazon_ad_api-1.1.2 → python_amazon_ad_api-1.1.4}/python_amazon_ad_api.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|