diff --git a/HISTORY.rst b/HISTORY.rst index df1c4bcb..efcf3025 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,11 @@ Release History ----------- + +11.12.5(2018-08-10) +*Updated service proxies to support customer address, campaign level profile criteria, similar audiences for remarketing lists, and new change history report columns. For details see the service release notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes?view=bingads-12#august2018. +*Added BulkEntity mappings for campaign level profile criteria i.e., added BulkCampaignCompanyNameCriterion, BulkCampaignJobFunctionCriterion, and BulkCampaignIndustryCriterion. + 11.12.4(2018-07-10) * Added a mapping for the Domain column in the Bulk file to the BulkExpandedTextAd object. * Limited the scope to bingads.manage for access token requests. Previously the default scope was used, which can vary if a user granted your app permissions to multiple scopes. The Bing Ads SDKs only support the bingads.manage scope. diff --git a/bingads/manifest.py b/bingads/manifest.py index 3250405e..f3058bf4 100644 --- a/bingads/manifest.py +++ b/bingads/manifest.py @@ -1,5 +1,5 @@ import sys -VERSION = '11.12.4' +VERSION = '11.12.5' BULK_FORMAT_VERSION_5 = '5.0' BULK_FORMAT_VERSION_6 = '6.0' WORKING_NAME = 'BingAdsSDKPython' diff --git a/bingads/v11/bulk/entities/bulk_ad_group.py b/bingads/v11/bulk/entities/bulk_ad_group.py index 536e0f9c..865a1a12 100644 --- a/bingads/v11/bulk/entities/bulk_ad_group.py +++ b/bingads/v11/bulk/entities/bulk_ad_group.py @@ -7,6 +7,34 @@ from bingads.v11.internal.extensions import * +def coop_setting_to_csv(bulk_ad_group, row_values): + if not bulk_ad_group.ad_group.Settings or not bulk_ad_group.ad_group.Settings.Setting: + return + settings = [setting for setting in bulk_ad_group.ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] + if len(settings) == 0: + return + if len(settings) != 1: + raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') + + row_values[_StringTable.MaximumBid] = settings[0].BidMaxValue + row_values[_StringTable.BidBoostValue] = settings[0].BidBoostValue + row_values[_StringTable.BidOption] = settings[0].BidOption + pass + +def csv_to_coop_setting(row_values, bulk_ad_group): + maximum_bid_success, maximum_bid = row_values.try_get_value(_StringTable.MaximumBid) + bid_boost_value_success, bid_boost_value = row_values.try_get_value(_StringTable.BidBoostValue) + bid_option_success, bid_option = row_values.try_get_value(_StringTable.BidOption) + + if maximum_bid_success or bid_boost_value_success or bid_option_success: + coop_setting = _CAMPAIGN_OBJECT_FACTORY_V11.create('CoOpSetting') + coop_setting.Type = 'CoOpSetting' + coop_setting.BidOption = bid_option if bid_option else None + coop_setting.BidBoostValue = float(bid_boost_value) if bid_boost_value else None + coop_setting.BidMaxValue = float(maximum_bid) if maximum_bid else None + bulk_ad_group.ad_group.Settings.Setting.append(coop_setting) + pass + def bidding_scheme_to_csv(bulk_ad_group, row_values): bid_strategy_type = field_to_csv_BidStrategyType(bulk_ad_group.ad_group) if not bid_strategy_type: @@ -251,21 +279,7 @@ def performance_data(self): csv_to_field=lambda c, v: setattr(c.ad_group, 'RemarketingTargetingSetting', v if v else None) ), - _SimpleBulkMapping( - header=_StringTable.BidOption, - field_to_csv=lambda c: bid_option_to_csv(c.ad_group), - csv_to_field=lambda c, v: csv_to_bid_option(c.ad_group, v) - ), - _SimpleBulkMapping( - header=_StringTable.BidBoostValue, - field_to_csv=lambda c: bid_boost_value_to_csv(c.ad_group), - csv_to_field=lambda c, v: csv_to_bid_boost_value(c.ad_group, v) - ), - _SimpleBulkMapping( - header=_StringTable.MaximumBid, - field_to_csv=lambda c: maximum_bid_to_csv(c.ad_group), - csv_to_field=lambda c, v: csv_to_maximum_bid(c.ad_group, v) - ), + _ComplexBulkMapping(coop_setting_to_csv, csv_to_coop_setting), ] def process_mappings_from_row_values(self, row_values): diff --git a/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_negative_profile_criterion.py b/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_negative_profile_criterion.py index fead238a..7350cabb 100644 --- a/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_negative_profile_criterion.py +++ b/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_negative_profile_criterion.py @@ -7,12 +7,11 @@ from abc import ABCMeta, abstractmethod class BulkAdGroupNegativeProfileCriterion(_SingleRecordBulkEntity): - """ Represents an Ad Group Negative Profile Criterion that can be read or written in a bulk file. + """ The base class for Ad group level negative profile criterion that can be read or written in a bulk file. - This class exposes the :attr:`negative_ad_group_criterion` property that can be read and written as fields of the - Ad Group Negative Profile Criterion record in a bulk file. + This class exposes the :attr:`negative_ad_group_criterion` property that can be read and written in a bulk file. - For more information, see Ad Group Negative Profile Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + For more information, see Bulk File Schema at https://go.microsoft.com/fwlink/?linkid=846127. *See also:* diff --git a/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py b/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py index ec8a97ae..8047dadd 100644 --- a/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py +++ b/bingads/v11/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py @@ -7,12 +7,11 @@ from abc import ABCMeta, abstractmethod class BulkAdGroupProfileCriterion(_SingleRecordBulkEntity): - """ Represents an Ad Group Profile Criterion that can be read or written in a bulk file. + """ The base class for Ad group level profile criterion that can be read or written in a bulk file. - This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written as fields of the - Ad Group Profile Criterion record in a bulk file. + This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written in a bulk file. - For more information, see Ad Group Profile Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + For more information, see Bulk File Schema at https://go.microsoft.com/fwlink/?linkid=846127. *See also:* diff --git a/bingads/v11/internal/bulk/csv_headers.py b/bingads/v11/internal/bulk/csv_headers.py index 0d45d1c8..1c53e6ce 100644 --- a/bingads/v11/internal/bulk/csv_headers.py +++ b/bingads/v11/internal/bulk/csv_headers.py @@ -22,7 +22,6 @@ class _CsvHeaders: _StringTable.BudgetType, _StringTable.BudgetName, _StringTable.BudgetId, - _StringTable.KeywordVariantMatchEnabled, # AdGroup _StringTable.StartDate, diff --git a/bingads/v11/internal/bulk/string_table.py b/bingads/v11/internal/bulk/string_table.py index e6ba9d2a..ef30df25 100644 --- a/bingads/v11/internal/bulk/string_table.py +++ b/bingads/v11/internal/bulk/string_table.py @@ -12,7 +12,6 @@ class _StringTable: BudgetType = "Budget Type" BudgetName = "Budget Name" BudgetId = "Budget Id" - KeywordVariantMatchEnabled = "KeywordVariantMatchEnabled" AdGroup = "Ad Group" Keyword = "Keyword" TextAd = "Text Ad" diff --git a/bingads/v11/internal/extensions.py b/bingads/v11/internal/extensions.py index a1bb2404..1b802f2a 100644 --- a/bingads/v11/internal/extensions.py +++ b/bingads/v11/internal/extensions.py @@ -1184,66 +1184,6 @@ def parse_rule_PageVisitors(rule_str): rule.RuleItemGroups = parse_rule_groups(rule_str) return rule -def maximum_bid_to_csv(ad_group): - if not ad_group.Settings or not ad_group.Settings.Setting: - return None - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return None - if len(settings) != 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - coop_setting = settings[0] - return coop_setting.BidMaxValue - -def csv_to_maximum_bid(ad_group, value): - coop_setting = validate_coop_setting(ad_group) - coop_setting.BidMaxValue = float(value) if value else None - -def bid_boost_value_to_csv(ad_group): - if not ad_group.Settings or not ad_group.Settings.Setting: - return None - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return None - if len(settings) != 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - coop_setting = settings[0] - return coop_setting.BidBoostValue - -def csv_to_bid_boost_value(ad_group, value): - coop_setting = validate_coop_setting(ad_group) - coop_setting.BidBoostValue = float(value) if value else None - -def bid_option_to_csv(ad_group): - if not ad_group.Settings or not ad_group.Settings.Setting: - return None - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return None - if len(settings) != 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - coop_setting = settings[0] - return coop_setting.BidOption - -def csv_to_bid_option(ad_group, value): - coop_setting = validate_coop_setting(ad_group) - coop_setting.BidOption = value if value else None - -def validate_coop_setting(ad_group): - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return create_coop_setting(ad_group) - - if len(settings) > 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - return settings[0] - -def create_coop_setting(ad_group): - coop_setting = _CAMPAIGN_OBJECT_FACTORY_V11.create('CoOpSetting') - coop_setting.Type = 'CoOpSetting' - ad_group.Settings.Setting.append(coop_setting) - return coop_setting - def target_setting_to_csv(ad_group): if not ad_group.Settings or not ad_group.Settings.Setting: return None diff --git a/bingads/v11/proxies/campaign_management_service.xml b/bingads/v11/proxies/campaign_management_service.xml index 9c8ea806..95b20e20 100644 --- a/bingads/v11/proxies/campaign_management_service.xml +++ b/bingads/v11/proxies/campaign_management_service.xml @@ -1483,6 +1483,13 @@ + + + + 4 + + + @@ -9982,7 +9989,7 @@ - + diff --git a/bingads/v12/bulk/entities/bulk_ad_group.py b/bingads/v12/bulk/entities/bulk_ad_group.py index 6e94682d..ec7841f6 100644 --- a/bingads/v12/bulk/entities/bulk_ad_group.py +++ b/bingads/v12/bulk/entities/bulk_ad_group.py @@ -6,6 +6,34 @@ from bingads.v12.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping from bingads.v12.internal.extensions import * +def coop_setting_to_csv(bulk_ad_group, row_values): + if not bulk_ad_group.ad_group.Settings or not bulk_ad_group.ad_group.Settings.Setting: + return + settings = [setting for setting in bulk_ad_group.ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] + if len(settings) == 0: + return + if len(settings) != 1: + raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') + + row_values[_StringTable.MaximumBid] = settings[0].BidMaxValue + row_values[_StringTable.BidBoostValue] = settings[0].BidBoostValue + row_values[_StringTable.BidOption] = settings[0].BidOption + pass + +def csv_to_coop_setting(row_values, bulk_ad_group): + maximum_bid_success, maximum_bid = row_values.try_get_value(_StringTable.MaximumBid) + bid_boost_value_success, bid_boost_value = row_values.try_get_value(_StringTable.BidBoostValue) + bid_option_success, bid_option = row_values.try_get_value(_StringTable.BidOption) + + if maximum_bid_success or bid_boost_value_success or bid_option_success: + coop_setting = _CAMPAIGN_OBJECT_FACTORY_V12.create('CoOpSetting') + coop_setting.Type = 'CoOpSetting' + coop_setting.BidOption = bid_option if bid_option else None + coop_setting.BidBoostValue = float(bid_boost_value) if bid_boost_value else None + coop_setting.BidMaxValue = float(maximum_bid) if maximum_bid else None + bulk_ad_group.ad_group.Settings.Setting.append(coop_setting) + pass + def bidding_scheme_to_csv(bulk_ad_group, row_values): bid_strategy_type = field_to_csv_BidStrategyType(bulk_ad_group.ad_group) if not bid_strategy_type: @@ -216,21 +244,8 @@ def performance_data(self): field_to_csv=lambda c: bulk_str(c.ad_group.PrivacyStatus), csv_to_field=lambda c, v: setattr(c.ad_group, 'PrivacyStatus', v if v else None) ), - _SimpleBulkMapping( - header=_StringTable.BidOption, - field_to_csv=lambda c: bid_option_to_csv(c.ad_group), - csv_to_field=lambda c, v: csv_to_bid_option(c.ad_group, v) - ), - _SimpleBulkMapping( - header=_StringTable.BidBoostValue, - field_to_csv=lambda c: bid_boost_value_to_csv(c.ad_group), - csv_to_field=lambda c, v: csv_to_bid_boost_value(c.ad_group, v) - ), - _SimpleBulkMapping( - header=_StringTable.MaximumBid, - field_to_csv=lambda c: maximum_bid_to_csv(c.ad_group), - csv_to_field=lambda c, v: csv_to_maximum_bid(c.ad_group, v) - ), + + _ComplexBulkMapping(coop_setting_to_csv, csv_to_coop_setting), ] def process_mappings_from_row_values(self, row_values): diff --git a/bingads/v12/bulk/entities/target_criterions/__init__.py b/bingads/v12/bulk/entities/target_criterions/__init__.py index 05c9bb95..b11e590b 100644 --- a/bingads/v12/bulk/entities/target_criterions/__init__.py +++ b/bingads/v12/bulk/entities/target_criterions/__init__.py @@ -21,3 +21,4 @@ from .bulk_campaign_location_intent_criterion import * from .bulk_campaign_negative_location_criterion import * from .bulk_campaign_radius_criterion import * +from .bulk_campaign_profile_criterion import * diff --git a/bingads/v12/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py b/bingads/v12/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py index 810d3932..ddb17587 100644 --- a/bingads/v12/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py +++ b/bingads/v12/bulk/entities/target_criterions/bulk_ad_group_profile_criterion.py @@ -7,12 +7,11 @@ from abc import ABCMeta, abstractmethod class BulkAdGroupProfileCriterion(_SingleRecordBulkEntity): - """ Represents an Ad Group Profile Criterion that can be read or written in a bulk file. + """ The base class for Ad Group level profile criterion that can be read or written in a bulk file. - This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written as fields of the - Ad Group Profile Criterion record in a bulk file. + This class exposes the :attr:`biddable_ad_group_criterion` property that can be read and written in a bulk file. - For more information, see Ad Group Profile Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + For more information, see Bulk File Schema at https://go.microsoft.com/fwlink/?linkid=846127. *See also:* diff --git a/bingads/v12/bulk/entities/target_criterions/bulk_campaign_profile_criterion.py b/bingads/v12/bulk/entities/target_criterions/bulk_campaign_profile_criterion.py new file mode 100644 index 00000000..7cfd8ef6 --- /dev/null +++ b/bingads/v12/bulk/entities/target_criterions/bulk_campaign_profile_criterion.py @@ -0,0 +1,193 @@ +from bingads.v12.bulk.entities import * +from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V12 +from bingads.v12.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity +from bingads.v12.internal.bulk.mappings import _SimpleBulkMapping +from bingads.v12.internal.bulk.string_table import _StringTable +from bingads.v12.internal.extensions import * +from abc import ABCMeta, abstractmethod + +class BulkCampaignProfileCriterion(_SingleRecordBulkEntity): + """ The base class for campaign level profile criterion that can be read or written in a bulk file. + + This class exposes the :attr:`biddable_campaign_criterion` property that can be read and written in a bulk file. + + For more information, see Bulk File Schema at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + biddable_campaign_criterion=None, + campaign_name=None, ): + super(BulkCampaignProfileCriterion, self).__init__() + + self._biddable_campaign_criterion = biddable_campaign_criterion + self._campaign_name = campaign_name + + _MAPPINGS = [ + _SimpleBulkMapping( + _StringTable.Status, + field_to_csv=lambda c: bulk_str(c.biddable_campaign_criterion.Status), + csv_to_field=lambda c, v: setattr(c.biddable_campaign_criterion, 'Status', v if v else None) + ), + _SimpleBulkMapping( + _StringTable.Id, + field_to_csv=lambda c: bulk_str(c.biddable_campaign_criterion.Id), + csv_to_field=lambda c, v: setattr(c.biddable_campaign_criterion, 'Id', int(v) if v else None) + ), + _SimpleBulkMapping( + _StringTable.ParentId, + field_to_csv=lambda c: bulk_str(c.biddable_campaign_criterion.CampaignId), + csv_to_field=lambda c, v: setattr(c.biddable_campaign_criterion, 'CampaignId', int(v) if v else None) + ), + _SimpleBulkMapping( + _StringTable.Campaign, + field_to_csv=lambda c: c.campaign_name, + csv_to_field=lambda c, v: setattr(c, 'campaign_name', v) + ), + _SimpleBulkMapping( + _StringTable.BidAdjustment, + field_to_csv=lambda c: field_to_csv_BidAdjustment(c.biddable_campaign_criterion), + csv_to_field=lambda c, v: csv_to_field_BidAdjustment(c.biddable_campaign_criterion, float(v) if v else None) + ), + _SimpleBulkMapping( + _StringTable.Profile, + field_to_csv=lambda c: c.profile_name, + csv_to_field=lambda c, v: setattr(c, 'profile_name', v) + ), + _SimpleBulkMapping( + _StringTable.ProfileId, + field_to_csv=lambda c: bulk_str(c.biddable_campaign_criterion.Criterion.ProfileId), + csv_to_field=lambda c, v: setattr(c.biddable_campaign_criterion.Criterion, 'ProfileId', int(v) if v else None) + ), + ] + + @property + def biddable_campaign_criterion(self): + """ Defines a Campaign Criterion """ + + return self._biddable_campaign_criterion + + @biddable_campaign_criterion.setter + def biddable_campaign_criterion(self, biddable_campaign_criterion): + self._biddable_campaign_criterion = biddable_campaign_criterion + + @property + def campaign_name(self): + """ The name of the Campaign + + :rtype: str + """ + + return self._campaign_name + + @campaign_name.setter + def campaign_name(self, campaign_name): + self._campaign_name = campaign_name + + def process_mappings_to_row_values(self, row_values, exclude_readonly_data): + self._validate_property_not_null(self.biddable_campaign_criterion, 'biddable_campaign_criterion') + self.convert_to_values(row_values, BulkCampaignProfileCriterion._MAPPINGS) + + def process_mappings_from_row_values(self, row_values): + self._biddable_campaign_criterion = _CAMPAIGN_OBJECT_FACTORY_V12.create('BiddableCampaignCriterion') + self._biddable_campaign_criterion.Type = 'BiddableCampaignCriterion' + self._biddable_campaign_criterion.Criterion = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProfileCriterion') + self._biddable_campaign_criterion.Criterion.ProfileType = self.profile_type() + self._biddable_campaign_criterion.Criterion.Type = 'ProfileCriterion' + self._biddable_campaign_criterion.CriterionBid = _CAMPAIGN_OBJECT_FACTORY_V12.create('BidMultiplier') + self._biddable_campaign_criterion.CriterionBid.Type = 'BidMultiplier' + row_values.convert_to_entity(self, BulkCampaignProfileCriterion._MAPPINGS) + + def read_additional_data(self, stream_reader): + super(BulkCampaignProfileCriterion, self).read_additional_data(stream_reader) + + @abstractmethod + def profile_type(self): + pass + +class BulkCampaignCompanyNameCriterion(BulkCampaignProfileCriterion): + """ Represents an Campaign CompanyName Criterion that can be read or written in a bulk file. + + This class exposes the :attr:`biddable_campaign_criterion` property that can be read and written as fields of the + Campaign CompanyName Criterion record in a bulk file. + + For more information, see Campaign CompanyName Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + biddable_campaign_criterion=None, + campaign_name=None): + super(BulkCampaignCompanyNameCriterion, self).__init__() + + self._biddable_campaign_criterion = biddable_campaign_criterion + self._campaign_name = campaign_name + + def profile_type(self): + return 'CompanyName' + +class BulkCampaignIndustryCriterion(BulkCampaignProfileCriterion): + """ Represents an Campaign Industry Criterion that can be read or written in a bulk file. + + This class exposes the :attr:`biddable_campaign_criterion` property that can be read and written as fields of the + Campaign Industry Criterion record in a bulk file. + + For more information, see Campaign Industry Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + biddable_campaign_criterion=None, + campaign_name=None): + super(BulkCampaignIndustryCriterion, self).__init__() + + self._biddable_campaign_criterion = biddable_campaign_criterion + self._campaign_name = campaign_name + + def profile_type(self): + return 'Industry' + +class BulkCampaignJobFunctionCriterion(BulkCampaignProfileCriterion): + """ Represents an Campaign JobFunction Criterion that can be read or written in a bulk file. + + This class exposes the :attr:`biddable_campaign_criterion` property that can be read and written as fields of the + Campaign JobFunction Criterion record in a bulk file. + + For more information, see Campaign JobFunction Criterion at https://go.microsoft.com/fwlink/?linkid=846127. + + *See also:* + + * :class:`.BulkServiceManager` + * :class:`.BulkOperation` + * :class:`.BulkFileReader` + * :class:`.BulkFileWriter` + """ + + def __init__(self, + biddable_campaign_criterion=None, + campaign_name=None): + super(BulkCampaignJobFunctionCriterion, self).__init__() + + self._biddable_campaign_criterion = biddable_campaign_criterion + self._campaign_name = campaign_name + + def profile_type(self): + return 'JobFunction' \ No newline at end of file diff --git a/bingads/v12/internal/bulk/bulk_object_factory.py b/bingads/v12/internal/bulk/bulk_object_factory.py index 9e8f4412..8fa3f898 100644 --- a/bingads/v12/internal/bulk/bulk_object_factory.py +++ b/bingads/v12/internal/bulk/bulk_object_factory.py @@ -90,14 +90,17 @@ class _BulkObjectFactory(): 'Ad Group Location Intent Criterion': _EntityInfo(lambda: BulkAdGroupLocationIntentCriterion()), 'Ad Group Negative Location Criterion': _EntityInfo(lambda: BulkAdGroupNegativeLocationCriterion()), 'Ad Group Radius Criterion': _EntityInfo(lambda: BulkAdGroupRadiusCriterion()), - 'Campaign Age Criterion': _EntityInfo(lambda: BulkCampaignAgeCriterion()), - 'Campaign DayTime Criterion': _EntityInfo(lambda: BulkCampaignDayTimeCriterion()), - 'Campaign DeviceOS Criterion': _EntityInfo(lambda: BulkCampaignDeviceCriterion()), - 'Campaign Gender Criterion': _EntityInfo(lambda: BulkCampaignGenderCriterion()), - 'Campaign Location Criterion': _EntityInfo(lambda: BulkCampaignLocationCriterion()), - 'Campaign Location Intent Criterion': _EntityInfo(lambda: BulkCampaignLocationIntentCriterion()), - 'Campaign Negative Location Criterion': _EntityInfo(lambda: BulkCampaignNegativeLocationCriterion()), - 'Campaign Radius Criterion': _EntityInfo(lambda: BulkCampaignRadiusCriterion()), + _StringTable.CampaignAgeCriterion: _EntityInfo(lambda: BulkCampaignAgeCriterion()), + _StringTable.CampaignDayTimeCriterion: _EntityInfo(lambda: BulkCampaignDayTimeCriterion()), + _StringTable.CampaignDeviceOSCriterion: _EntityInfo(lambda: BulkCampaignDeviceCriterion()), + _StringTable.CampaignGenderCriterion: _EntityInfo(lambda: BulkCampaignGenderCriterion()), + _StringTable.CampaignLocationCriterion: _EntityInfo(lambda: BulkCampaignLocationCriterion()), + _StringTable.CampaignLocationIntentCriterion: _EntityInfo(lambda: BulkCampaignLocationIntentCriterion()), + _StringTable.CampaignNegativeLocationCriterion: _EntityInfo(lambda: BulkCampaignNegativeLocationCriterion()), + _StringTable.CampaignRadiusCriterion: _EntityInfo(lambda: BulkCampaignRadiusCriterion()), + _StringTable.CampaignCompanyNameCriterion: _EntityInfo(lambda: BulkCampaignCompanyNameCriterion()), + _StringTable.CampaignJobFunctionCriterion: _EntityInfo(lambda: BulkCampaignJobFunctionCriterion()), + _StringTable.CampaignIndustryCriterion: _EntityInfo(lambda: BulkCampaignIndustryCriterion()), _StringTable.ProductAudience: _EntityInfo(lambda: BulkProductAudience()), _StringTable.AdGroupProductAudienceAssociation: _EntityInfo(lambda: BulkAdGroupProductAudienceAssociation()), _StringTable.AdGroupNegativeProductAudienceAssociation: _EntityInfo(lambda: BulkAdGroupNegativeProductAudienceAssociation()), diff --git a/bingads/v12/internal/bulk/csv_headers.py b/bingads/v12/internal/bulk/csv_headers.py index 81aa9ec4..70543ba8 100644 --- a/bingads/v12/internal/bulk/csv_headers.py +++ b/bingads/v12/internal/bulk/csv_headers.py @@ -22,7 +22,6 @@ class _CsvHeaders: _StringTable.BudgetType, _StringTable.BudgetName, _StringTable.BudgetId, - _StringTable.KeywordVariantMatchEnabled, # AdGroup _StringTable.StartDate, diff --git a/bingads/v12/internal/bulk/string_table.py b/bingads/v12/internal/bulk/string_table.py index de32be18..24b3a692 100644 --- a/bingads/v12/internal/bulk/string_table.py +++ b/bingads/v12/internal/bulk/string_table.py @@ -12,7 +12,6 @@ class _StringTable: BudgetType = "Budget Type" BudgetName = "Budget Name" BudgetId = "Budget Id" - KeywordVariantMatchEnabled = "KeywordVariantMatchEnabled" AdGroup = "Ad Group" Keyword = "Keyword" TextAd = "Text Ad" @@ -414,3 +413,16 @@ class _StringTable: ConversionTime = "Conversion Time" ConversionValue = "Conversion Value" MicrosoftClickId = "Microsoft Click Id" + + # Campaign Criterion + CampaignAgeCriterion = 'Campaign Age Criterion' + CampaignDayTimeCriterion = 'Campaign DayTime Criterion' + CampaignDeviceOSCriterion = 'Campaign DeviceOS Criterion' + CampaignGenderCriterion = 'Campaign Gender Criterion' + CampaignLocationCriterion = 'Campaign Location Criterion' + CampaignLocationIntentCriterion = 'Campaign Location Intent Criterion' + CampaignNegativeLocationCriterion = 'Campaign Negative Location Criterion' + CampaignRadiusCriterion = 'Campaign Radius Criterion' + CampaignCompanyNameCriterion = 'Campaign Company Name Criterion' + CampaignJobFunctionCriterion = 'Campaign Job Function Criterion' + CampaignIndustryCriterion = 'Campaign Industry Criterion' diff --git a/bingads/v12/internal/extensions.py b/bingads/v12/internal/extensions.py index ab024ded..f5f31a43 100644 --- a/bingads/v12/internal/extensions.py +++ b/bingads/v12/internal/extensions.py @@ -1176,66 +1176,6 @@ def csv_to_field_LongitudeDegrees(entity, value): if entity is not None and entity.Criterion is not None and isinstance(entity.Criterion,type(RadiusCriterion)): setattr(entity.Criterion, "LongitudeDegrees", value) -def maximum_bid_to_csv(ad_group): - if not ad_group.Settings or not ad_group.Settings.Setting: - return None - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return None - if len(settings) != 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - coop_setting = settings[0] - return coop_setting.BidMaxValue - -def csv_to_maximum_bid(ad_group, value): - coop_setting = validate_coop_setting(ad_group) - coop_setting.BidMaxValue = float(value) if value else None - -def bid_boost_value_to_csv(ad_group): - if not ad_group.Settings or not ad_group.Settings.Setting: - return None - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return None - if len(settings) != 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - coop_setting = settings[0] - return coop_setting.BidBoostValue - -def csv_to_bid_boost_value(ad_group, value): - coop_setting = validate_coop_setting(ad_group) - coop_setting.BidBoostValue = float(value) if value else None - -def bid_option_to_csv(ad_group): - if not ad_group.Settings or not ad_group.Settings.Setting: - return None - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return None - if len(settings) != 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - coop_setting = settings[0] - return coop_setting.BidOption - -def csv_to_bid_option(ad_group, value): - coop_setting = validate_coop_setting(ad_group) - coop_setting.BidOption = value if value else None - -def validate_coop_setting(ad_group): - settings = [setting for setting in ad_group.Settings.Setting if isinstance(setting, CoOpSetting_Type)] - if len(settings) == 0: - return create_coop_setting(ad_group) - - if len(settings) > 1: - raise ValueError('Can only have 1 CoOpSetting in AdGroup Settings.') - return settings[0] - -def create_coop_setting(ad_group): - coop_setting = _CAMPAIGN_OBJECT_FACTORY_V12.create('CoOpSetting') - coop_setting.Type = 'CoOpSetting' - ad_group.Settings.Setting.append(coop_setting) - return coop_setting - def target_setting_to_csv(ad_group): if not ad_group.Settings or not ad_group.Settings.Setting: return None diff --git a/bingads/v12/proxies/campaign_management_service.xml b/bingads/v12/proxies/campaign_management_service.xml index daf3a998..f928d493 100644 --- a/bingads/v12/proxies/campaign_management_service.xml +++ b/bingads/v12/proxies/campaign_management_service.xml @@ -1457,6 +1457,13 @@ + + + + 4 + + + @@ -2402,6 +2409,13 @@ + + + + 524288 + + + @@ -2676,6 +2690,7 @@ + @@ -3400,6 +3415,27 @@ + + + + 32768 + + + + + + + 65536 + + + + + + + 131072 + + + @@ -3757,6 +3793,16 @@ + + + + + + + + + + diff --git a/setup.py b/setup.py index 41278ea6..ac04bb17 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ except ImportError: from distutils.core import setup -VERSION = '11.12.4' +VERSION = '11.12.5' with open('README.rst', 'r') as f: readme = f.read()