Skip to content

Commit

Permalink
v13.0.19
Browse files Browse the repository at this point in the history
  • Loading branch information
xinyuwen2 committed Mar 25, 2024
1 parent 05fbf75 commit 64bc0ed
Show file tree
Hide file tree
Showing 21 changed files with 3,487 additions and 15 deletions.
9 changes: 9 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
.. :changelog:
Release History
13.0.19(2024-03-25)
+++++++++++++++++++++++++
* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://learn.microsoft.com/en-us/advertising/guides/release-notes?view=bingads-13.
* Added bulk mappings for Account Level Negative Keyword List i.e., BulkAccountNegativeKeywordList, BulkAccountNegativeKeywordListAssociation and BulkAccountSharedNegativeKeyword.
* Added bulk mappings for BulkSeasonalityAdjustment and BulkDataExclusion.
* Removed mappings for VerifiedTrackingSetting field in BulkCampaign.
* Added mappings for new field in BulkCampaign: AutoGeneratedImageOptOut and AutoGeneratedTextOptOut.
* Added PerformanceMaxsetting for PageFeedIds field in BulkCampaign.
* Added mappings for new BiddingScheme: CostPerSaleBiddingScheme.

13.0.18.1(2024-01-30)
+++++++++++++++++++++++++
Expand Down
2 changes: 1 addition & 1 deletion bingads/manifest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
VERSION = '13.0.18.1'
VERSION = '13.0.19'
BULK_FORMAT_VERSION_6 = '6.0'
WORKING_NAME = 'BingAdsSDKPython'
USER_AGENT = '{0} {1} {2}'.format(WORKING_NAME, VERSION, sys.version_info[0:3])
3 changes: 3 additions & 0 deletions bingads/v13/bulk/entities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@
from .bulk_asset_group_listing_group import *
from .bulk_audience_group_asset_group_association import *
from .bulk_campaign_negative_webpage import *
from .bulk_seasonality_adjustment import *
from .bulk_data_exclusion import *
from .bulk_account_negative_keyword_list import *
164 changes: 164 additions & 0 deletions bingads/v13/bulk/entities/bulk_account_negative_keyword_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13
from bingads.v13.internal.bulk.string_table import _StringTable
from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping
from bingads.v13.internal.extensions import bulk_str

class BulkAccountNegativeKeywordList(_SingleRecordBulkEntity):
""" Represents an account negative keyword list association that can be read or written in a bulk file.
This class exposes the :attr:`.BulkAccountNegativeKeywordList.account_negative_keyword_list` property that can be read and
written as fields of the account negative keyword list association record in a bulk file.
For more information, see account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127.
*See also:*
* :class:`.BulkServiceManager`
* :class:`.BulkOperation`
* :class:`.BulkFileReader`
* :class:`.BulkFileWriter`
"""

def __init__(self, status=None, account_negative_keyword_list=None):
super(BulkAccountNegativeKeywordList, self).__init__()

self._status = status
self._account_negative_keyword_list = account_negative_keyword_list

@property
def account_negative_keyword_list(self):
""" The account negative keyword list association.
see account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127.
"""

return self._account_negative_keyword_list

@account_negative_keyword_list.setter
def account_negative_keyword_list(self, account_negative_keyword_list):
self._account_negative_keyword_list = account_negative_keyword_list

@property
def status(self):
""" The status of the account negative keyword list association.
:rtype: str
"""

return self._status

@status.setter
def status(self, status):
self._status = status

_MAPPINGS = [
_SimpleBulkMapping(
header=_StringTable.Id,
field_to_csv=lambda c: bulk_str(c.account_negative_keyword_list.Id),
csv_to_field=lambda c, v: setattr(c.account_negative_keyword_list, 'Id', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.Status,
field_to_csv=lambda c: bulk_str(c.status),
csv_to_field=lambda c, v: setattr(c, 'status', v if v else None)
),
_SimpleBulkMapping(
header=_StringTable.Name,
field_to_csv=lambda c: c.account_negative_keyword_list.Name,
csv_to_field=lambda c, v: setattr(c.account_negative_keyword_list, 'Name', v)
)
]

def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self._validate_property_not_null(self._account_negative_keyword_list, 'account_negative_keyword_list')
self.convert_to_values(row_values, BulkAccountNegativeKeywordList._MAPPINGS)

def process_mappings_from_row_values(self, row_values):
self._account_negative_keyword_list = _CAMPAIGN_OBJECT_FACTORY_V13.create('AccountNegativeKeywordList')
self._account_negative_keyword_list.Type = 'AccountNegativeKeywordList'
row_values.convert_to_entity(self, BulkAccountNegativeKeywordList._MAPPINGS)

def read_additional_data(self, stream_reader):
super(BulkAccountNegativeKeywordList, self).read_additional_data(stream_reader)

class BulkAccountNegativeKeywordListAssociation(_SingleRecordBulkEntity):
""" Represents an account negative keyword list association that is assigned to a campaign. Each account negative keyword list association can be read or written in a bulk file.
This class exposes the :attr:`BulkAccountNegativeKeywordListAssociation.SharedEntityAssociation` property that can be read
and written as fields of the account negative keyword list association record in a bulk file.
For more information, see account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127.
*See also:*
* :class:`.BulkServiceManager`
* :class:`.BulkOperation`
* :class:`.BulkFileReader`
* :class:`.BulkFileWriter`
"""

def __init__(self, status=None, shared_entity_association=None):
super(BulkAccountNegativeKeywordListAssociation, self).__init__()

self._shared_entity_association = shared_entity_association
self._status = status

@property
def status(self):
""" The status of the account negative keyword list association.
:rtype: str
"""

return self._status

@status.setter
def status(self, status):
self._status = status

@property
def shared_entity_association(self):
""" The campaign and account negative keyword list association identifiers.
see Campaign account negative keyword list association at https://go.microsoft.com/fwlink/?linkid=846127.
"""

return self._shared_entity_association

@shared_entity_association.setter
def shared_entity_association(self, shared_entity_association):
self._shared_entity_association = shared_entity_association

_MAPPINGS = [
_SimpleBulkMapping(
header=_StringTable.Status,
field_to_csv=lambda c: c.status,
csv_to_field=lambda c, v: setattr(c, 'status', v if v else None)
),
_SimpleBulkMapping(
header=_StringTable.Id,
field_to_csv=lambda c: bulk_str(c.shared_entity_association.SharedEntityId),
csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'SharedEntityId', int(v))
),
_SimpleBulkMapping(
header=_StringTable.ParentId,
field_to_csv=lambda c: bulk_str(c.shared_entity_association.EntityId),
csv_to_field=lambda c, v: setattr(c.shared_entity_association, 'EntityId', int(v))
),
]

def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self._validate_property_not_null(self._shared_entity_association, 'shared_entity_association')
self.convert_to_values(row_values, BulkAccountNegativeKeywordListAssociation._MAPPINGS)

def process_mappings_from_row_values(self, row_values):
self._shared_entity_association = _CAMPAIGN_OBJECT_FACTORY_V13.create('SharedEntityAssociation')
self._shared_entity_association.EntityType = 'Account'
self._shared_entity_association.SharedEntityType = 'NegativeKeywordList'
row_values.convert_to_entity(self, BulkAccountNegativeKeywordListAssociation._MAPPINGS)

def read_additional_data(self, stream_reader):
super(BulkAccountNegativeKeywordListAssociation, self).read_additional_data(stream_reader)


99 changes: 87 additions & 12 deletions bingads/v13/bulk/entities/bulk_campaign.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def __init__(self, account_id=None, campaign=None):
self._verified_tracking_data = None
self._destination_channel = None
self._is_multi_channel_campaign = None
self._should_serve_on_msan = None

@property
def account_id(self):
Expand Down Expand Up @@ -137,6 +138,14 @@ def is_multi_channel_campaign(self):
def is_multi_channel_campaign(self, value):
self._is_multi_channel_campaign = value

@property
def should_serve_on_msan(self):
return self._should_serve_on_msan

@should_serve_on_msan.setter
def should_serve_on_msan(self, value):
self._should_serve_on_msan = value

def _get_dynamic_feed_setting(self):
return self._get_setting(_DynamicFeedSetting, 'DynamicFeedSetting')

Expand Down Expand Up @@ -419,20 +428,76 @@ def _read_page_feed_ids(c, v):
if not c.campaign.CampaignType:
return None
campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType]
dsa_setting = c._get_dsa_setting()
if not dsa_setting:
return None
dsa_setting.PageFeedIds.long = csv_to_field_PageFeedIds(v)
if 'performancemax' in campgaign_types:
performance_max_setting = c._get_performance_max_setting()
if not performance_max_setting:
return None
performance_max_setting.PageFeedIds.long = csv_to_field_PageFeedIds(v)
else:
dsa_setting = c._get_dsa_setting()
if not dsa_setting:
return None
dsa_setting.PageFeedIds.long = csv_to_field_PageFeedIds(v)

@staticmethod
def _write_page_feed_ids(c):
if not c.campaign.CampaignType:
return None
campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType]
dsa_setting = c._get_dsa_setting()
if not dsa_setting:
if 'performancemax' in campgaign_types:
performance_max_setting = c._get_performance_max_setting()
if not performance_max_setting:
return None
return field_to_csv_Ids(performance_max_setting.PageFeedIds, c.campaign.Id)
else:
dsa_setting = c._get_dsa_setting()
if not dsa_setting:
return None
return field_to_csv_Ids(dsa_setting.PageFeedIds, c.campaign.Id)

@staticmethod
def _read_text_opt_out(c, v):
if not c.campaign.CampaignType:
return None
return field_to_csv_Ids(dsa_setting.PageFeedIds, c.campaign.Id)
campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType]
if 'performancemax' in campgaign_types:
performance_max_setting = c._get_performance_max_setting()
if not performance_max_setting:
return None
performance_max_setting.AutoGeneratedTextOptOut = parse_bool(v)

@staticmethod
def _write_text_opt_out(c):
if not c.campaign.CampaignType:
return None
campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType]
if 'performancemax' in campgaign_types:
performance_max_setting = c._get_performance_max_setting()
if not performance_max_setting:
return None
return bulk_str(performance_max_setting.AutoGeneratedTextOptOut)

@staticmethod
def _read_image_opt_out(c, v):
if not c.campaign.CampaignType:
return None
campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType]
if 'performancemax' in campgaign_types:
performance_max_setting = c._get_performance_max_setting()
if not performance_max_setting:
return None
performance_max_setting.AutoGeneratedImageOptOut = parse_bool(v)

@staticmethod
def _write_image_opt_out(c):
if not c.campaign.CampaignType:
return None
campgaign_types = [campaign_type.lower() for campaign_type in c.campaign.CampaignType]
if 'performancemax' in campgaign_types:
performance_max_setting = c._get_performance_max_setting()
if not performance_max_setting:
return None
return bulk_str(performance_max_setting.AutoGeneratedImageOptOut)

@staticmethod
def _read_website(c, v):
Expand Down Expand Up @@ -639,11 +704,6 @@ def _write_website(c):
field_to_csv=lambda c: BulkCampaign._write_DynamicDescriptionEnabled(c),
csv_to_field=lambda c, v: BulkCampaign._read_DynamicDescriptionEnabled(c, v)
),
_SimpleBulkMapping(
header=_StringTable.Details,
field_to_csv=lambda c: to_verified_tracking_setting_string(c.verified_tracking_data),
csv_to_field=lambda c, v: setattr(c, 'verified_tracking_data', parse_verified_tracking_setting(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.DestinationChannel,
field_to_csv=lambda c: c.destination_channel,
Expand All @@ -654,6 +714,21 @@ def _write_website(c):
field_to_csv=lambda c: field_to_csv_bool(c.is_multi_channel_campaign),
csv_to_field=lambda c, v: setattr(c, 'is_multi_channel_campaign', parse_bool(v))
),
_SimpleBulkMapping(
header=_StringTable.AutoGeneratedTextOptOut,
field_to_csv=lambda c: BulkCampaign._write_text_opt_out(c),
csv_to_field=lambda c, v: BulkCampaign._read_text_opt_out(c, v)
),
_SimpleBulkMapping(
header=_StringTable.AutoGeneratedImageOptOut,
field_to_csv=lambda c: BulkCampaign._write_image_opt_out(c),
csv_to_field=lambda c, v: BulkCampaign._read_image_opt_out(c, v)
),
_SimpleBulkMapping(
header=_StringTable.ShouldServeOnMSAN,
field_to_csv=lambda c: field_to_csv_bool(c.should_serve_on_msan),
csv_to_field=lambda c, v: setattr(c, 'should_serve_on_msan', parse_bool(v))
),
]

def read_additional_data(self, stream_reader):
Expand Down
Loading

0 comments on commit 64bc0ed

Please sign in to comment.