diff --git a/ad_api/api/sb/__init__.py b/ad_api/api/sb/__init__.py index 4124f6c..79adbaf 100644 --- a/ad_api/api/sb/__init__.py +++ b/ad_api/api/sb/__init__.py @@ -21,6 +21,7 @@ from .reports import Reports from .snapshots import Snapshots from .benchmarks import Benchmarks +from .themes import Themes __all__ = [ "Brands", @@ -45,5 +46,6 @@ "Media", "Reports", "Snapshots", - "Benchmarks" + "Benchmarks", + "Themes" ] diff --git a/ad_api/api/sb/themes.py b/ad_api/api/sb/themes.py new file mode 100644 index 0000000..8da072b --- /dev/null +++ b/ad_api/api/sb/themes.py @@ -0,0 +1,79 @@ +from ad_api.base import Client, sp_endpoint, ApiResponse, Utils + + +class Themes(Client): + """ + Amazon Ads API - Sponsored Brands - Theme Targeting + + Theme targeting automatically targets keywords related to your brand or landing pages. + """ + + @sp_endpoint('/sb/themes/list', method='POST') + def list_themes(self, **kwargs) -> ApiResponse: + r""" + Gets a list of theme targets associated with the client identifier, filtered by specified criteria. + + Request Body + | '**nextToken**': *string*, {'description': 'Token for pagination. Operations that return paginated results include a pagination token in this field.'} + | '**maxResults**': *number*, {'description': 'Maximum number of results to return. Defaults to API maximum.'} + | '**campaignIdFilter**': *object*, {'description': 'List of campaign identifiers to filter by (max 100).'} + | '**adGroupIdFilter**': *object*, {'description': 'List of ad group identifiers to filter by (max 100).'} + | '**themeIdFilter**': *object*, {'description': 'List of theme target identifiers to filter by (max 100).'} + | '**stateFilter**': *object*, {'description': 'List of theme target states to filter by. Valid values: enabled, paused, archived. Default: enabled, paused.'} + | '**themeTypeFilter**': *object*, {'description': 'List of theme types to filter by. Valid values: KEYWORDS_RELATED_TO_YOUR_BRAND, KEYWORDS_RELATED_TO_YOUR_LANDING_PAGES.'} + + Returns: + | ApiResponse + """ + headers = {'Accept': 'application/vnd.sbthemeslistresponse.v3+json'} + body = Utils.convert_body(kwargs.pop('body'), wrap=False) + return self._request(kwargs.pop('path'), data=body, params=kwargs, headers=headers) + + @sp_endpoint('/sb/themes', method='POST') + def create_themes(self, **kwargs) -> ApiResponse: + r""" + Create one or more theme targets. + + Note that theme targets can be created on multi-adGroup campaigns where campaign serving status is not archived, terminated, rejected, or ended. + Note that ad group state must not be archived. + Note that only one target can be created for each themeType per adGroup. + Note that this operation supports a maximum list size of 100 theme targets. + + Request Body + | '**themes**': *array*, {'description': 'List of theme targets to create (max 100).'} + | '**adGroupId**': *string*, {'description': 'The identifier of the ad group'} + | '**campaignId**': *string*, {'description': 'The identifier of the campaign'} + | '**themeType**': *string*, {'description': 'Theme type', 'Enum': 'KEYWORDS_RELATED_TO_YOUR_BRAND, KEYWORDS_RELATED_TO_YOUR_LANDING_PAGES'} + | '**bid**': *number*, {'description': 'The bid amount'} + + Returns: + | ApiResponse + """ + headers = {'Accept': 'application/vnd.sbthemescreateresponse.v3+json'} + body = Utils.convert_body(kwargs.pop('body'), wrap=False) + return self._request(kwargs.pop('path'), data=body, params=kwargs, headers=headers) + + @sp_endpoint('/sb/themes', method='PUT') + def update_themes(self, **kwargs) -> ApiResponse: + r""" + Updates one or more theme targets. + + Note that theme targets can be updated on multi-adGroup campaigns where campaign serving status is not archived, terminated, rejected, or ended. + Note that ad group state must not be archived. + Note that this operation supports a maximum list size of 100 theme targets. + Note that bid is only mutable when the corresponding campaign does not have any enabled optimization rule. + + Request Body + | '**themes**': *array*, {'description': 'List of theme targets to update (max 100).'} + | '**themeId**': *string*, {'description': 'The identifier of the theme target'} + | '**adGroupId**': *string*, {'description': 'The identifier of the ad group'} + | '**campaignId**': *string*, {'description': 'The identifier of the campaign'} + | '**state**': *string*, {'description': 'Theme target state', 'Enum': 'enabled, paused, archived'} + | '**bid**': *number*, {'description': 'The bid amount'} + + Returns: + | ApiResponse + """ + headers = {'Accept': 'application/vnd.sbthemesupdateresponse.v3+json'} + body = Utils.convert_body(kwargs.pop('body'), wrap=False) + return self._request(kwargs.pop('path'), data=body, params=kwargs, headers=headers) \ No newline at end of file diff --git a/docs/sb/themes.rst b/docs/sb/themes.rst new file mode 100644 index 0000000..39b1bc6 --- /dev/null +++ b/docs/sb/themes.rst @@ -0,0 +1,106 @@ +Themes +====== + +.. autoclass:: ad_api.api.sb.Themes + + .. autofunction:: ad_api.api.sb.Themes.list_themes + + ### Example Python + + .. code-block:: python + + from ad_api.api.sb.themes import Themes + + result = Themes().list_themes() + print(result) + + .. autofunction:: ad_api.api.sb.Themes.create_themes + + ### Example Python + + .. code-block:: python + + from ad_api.api.sb.themes import Themes + import json + + # Example data for themes + themes_to_create = [ + { + "adGroupId": "YOUR_ADGROUP_ID", + "campaignId": "YOUR_CAMPAIGN_ID", + "themeType": "KEYWORDS_RELATED_TO_YOUR_BRAND", + "bid": 0.75 + } + # Add more theme objects as needed, up to 100 + ] + + # For a real scenario, you might read this from a file like in your Keywords example + # file = open("create_themes.json") + # data = file.read() + # file.close() + # result = Themes().create_themes(body=data) + + result = Themes().create_themes(themes=themes_to_create) + print(result) + + ### Example JSON (for request body) + + .. code-block:: json + + { + "themes": [ + { + "adGroupId": "string", + "campaignId": "string", + "themeType": "KEYWORDS_RELATED_TO_YOUR_BRAND|KEYWORDS_RELATED_TO_YOUR_LANDING_PAGES", + "bid": 0.75 + } + ] + } + + + .. autofunction:: ad_api.api.sb.Themes.update_themes + + ### Example Python + + .. code-block:: python + + from ad_api.api.sb.themes import Themes + import json + + # Example data for themes to update + themes_to_update = [ + { + "themeId": "YOUR_THEME_ID", + "adGroupId": "YOUR_ADGROUP_ID", + "campaignId": "YOUR_CAMPAIGN_ID", + "state": "paused", # or "enabled", "archived" + "bid": 0.80 # Optional, if updating bid + } + # Add more theme objects as needed, up to 100 + ] + + # For a real scenario, you might read this from a file + # file = open("update_themes.json") + # data = file.read() + # file.close() + # result = Themes().update_themes(body=data) + + result = Themes().update_themes(themes=themes_to_update) + print(result) + + ### Example JSON (for request body) + + .. code-block:: json + + { + "themes": [ + { + "themeId": "string", + "adGroupId": "string", + "campaignId": "string", + "state": "enabled|paused|archived", + "bid": 0.80 + } + ] + } \ No newline at end of file diff --git a/docs/sb_v3.rst b/docs/sb_v3.rst index 971603a..3424c3c 100644 --- a/docs/sb_v3.rst +++ b/docs/sb_v3.rst @@ -19,4 +19,5 @@ sb/moderation sb/reports sb/snapshots + sb/themes