Skip to content

Commit 8c4c132

Browse files
committed
update to version 12.13.5
1 parent d23e804 commit 8c4c132

File tree

8 files changed

+177
-77
lines changed

8 files changed

+177
-77
lines changed

HISTORY.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
.. :changelog:
22
33
Release History
4+
12.13.5(2019-09-12)
5+
+++++++++++++++++++++++++
6+
* Map the Bid Adjustment column to a BidMultiplier via BulkAdGroupProductPartition.
7+
* Updated Bing Ads API version 12 and 13 service proxies to reflect recent interface changes. For more information please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/advertising/guides/release-notes.
8+
9+
410
12.13.4.1(2019-08-23)
511
+++++++++++++++++++++++++
6-
* Write TextAsset and ImageAsset to the Bulk upload file without the Type explicitly set.
12+
* Write TextAsset and ImageAsset to the Bulk upload file without the Type explicitly set.
713

814
12.13.4(2019-08-09)
915
+++++++++++++++++++++++++

bingads/manifest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys
2-
VERSION = '12.13.4.1'
2+
VERSION = '12.13.5'
33
BULK_FORMAT_VERSION_5 = '5.0'
44
BULK_FORMAT_VERSION_6 = '6.0'
55
WORKING_NAME = 'BingAdsSDKPython'

bingads/v12/bulk/entities/bulk_ad_group_product_partition.py

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,75 @@
11
from bingads.v12.bulk.entities import *
22
from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V12
33
from bingads.v12.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
4-
from bingads.v12.internal.bulk.mappings import _SimpleBulkMapping
4+
from bingads.v12.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping
55
from bingads.v12.internal.bulk.string_table import _StringTable
66
from bingads.v12.bulk.entities.common import PerformanceData
77
# from bingads.v12.internal.extensions import bulk_str
88
from bingads.v12.internal.extensions import *
99

1010
_BiddableAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V12.create('BiddableAdGroupCriterion'))
1111
_NegativeAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V12.create('NegativeAdGroupCriterion'))
12-
12+
_FixedBid = type(_CAMPAIGN_OBJECT_FACTORY_V12.create('FixedBid'))
13+
14+
def csv_to_bidding(row_values, entity):
15+
success, exclude = row_values.try_get_value(_StringTable.IsExcluded)
16+
if exclude is None:
17+
exclude = ''
18+
exclude = exclude.lower()
19+
if exclude == 'yes' or exclude == 'true':
20+
is_excluded = True
21+
elif exclude == 'no' or exclude == 'false':
22+
is_excluded = False
23+
else:
24+
raise ValueError('IsExcluded can only be set to TRUE|FALSE in Ad Group Product Partition row')
25+
if is_excluded:
26+
product_partition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductPartition')
27+
product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductCondition')
28+
product_partition.Type = 'ProductPartition'
29+
30+
negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V12.create('NegativeAdGroupCriterion')
31+
negative_ad_group_criterion.Criterion = product_partition
32+
negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
33+
34+
entity.ad_group_criterion = negative_ad_group_criterion
35+
else:
36+
product_partition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductPartition')
37+
product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductCondition')
38+
product_partition.Type = 'ProductPartition'
39+
40+
bid = _CAMPAIGN_OBJECT_FACTORY_V12.create('FixedBid')
41+
bid.Type = 'FixedBid'
42+
43+
biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V12.create('BiddableAdGroupCriterion')
44+
biddable_ad_group_criterion.Criterion = product_partition
45+
46+
success, bid_value = row_values.try_get_value(_StringTable.Bid)
47+
if success and bid_value is not None and bid_value != '':
48+
bid.Amount = float(bid_value)
49+
else:
50+
success, bid_value = row_values.try_get_value(_StringTable.BidAdjustment)
51+
if success and bid_value is not None and bid_value != '':
52+
bid = _CAMPAIGN_OBJECT_FACTORY_V12.create('BidMultiplier')
53+
bid.Type = 'BidMultiplier'
54+
bid.Multiplier = float(bid_value)
55+
56+
biddable_ad_group_criterion.CriterionBid = bid
57+
biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion'
58+
59+
entity.ad_group_criterion = biddable_ad_group_criterion
60+
61+
def bidding_to_csv(entity, row_values):
62+
if isinstance(entity.ad_group_criterion, _NegativeAdGroupCriterion):
63+
row_values[_StringTable.IsExcluded] = 'True'
64+
else:
65+
row_values[_StringTable.IsExcluded] = 'False'
66+
bid = entity.ad_group_criterion.CriterionBid
67+
if bid is None:
68+
return
69+
if isinstance(bid, _FixedBid):
70+
row_values[_StringTable.Bid] = fixed_bid_bulk_str(bid)
71+
else:
72+
row_values[_StringTable.BidAdjustment] = bid_multiplier_bulk_str(bid)
1373

1474
class BulkAdGroupProductPartition(_SingleRecordBulkEntity):
1575
""" Represents an Ad Group Criterion that can be read or written in a bulk file.
@@ -38,56 +98,7 @@ def __init__(self,
3898
self._ad_group_name = ad_group_name
3999
self._performance_data = None
40100

41-
@classmethod
42-
def _read_is_excluded(cls, entity, row_value):
43-
if row_value is None:
44-
row_value = ''
45-
row_value = row_value.lower()
46-
if row_value == 'yes' or row_value == 'true':
47-
is_excluded = True
48-
elif row_value == 'no' or row_value == 'false':
49-
is_excluded = False
50-
else:
51-
raise ValueError('IsExcluded can only be set to TRUE|FALSE in Ad Group Product Partition row')
52-
if is_excluded:
53-
product_partition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductPartition')
54-
product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductCondition')
55-
product_partition.Type = 'ProductPartition'
56-
57-
negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V12.create('NegativeAdGroupCriterion')
58-
negative_ad_group_criterion.Criterion = product_partition
59-
negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
60-
61-
entity.ad_group_criterion = negative_ad_group_criterion
62-
else:
63-
product_partition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductPartition')
64-
product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V12.create('ProductCondition')
65-
product_partition.Type = 'ProductPartition'
66-
67-
fixed_bid = _CAMPAIGN_OBJECT_FACTORY_V12.create('FixedBid')
68-
fixed_bid.Type = 'FixedBid'
69-
70-
biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V12.create('BiddableAdGroupCriterion')
71-
biddable_ad_group_criterion.Criterion = product_partition
72-
biddable_ad_group_criterion.CriterionBid = fixed_bid
73-
biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion'
74-
75-
entity.ad_group_criterion = biddable_ad_group_criterion
76-
77-
@classmethod
78-
def _write_bid(cls, entity):
79-
criterion = entity.ad_group_criterion
80-
if isinstance(criterion, _BiddableAdGroupCriterion) and \
81-
criterion.CriterionBid is not None:
82-
return fixed_bid_bulk_str(entity.ad_group_criterion.CriterionBid)
83-
84-
@classmethod
85-
def _read_bid(cls, entity, row_value):
86-
if isinstance(entity.ad_group_criterion, _BiddableAdGroupCriterion):
87-
entity.ad_group_criterion.CriterionBid = parse_fixed_bid(row_value)
88-
else:
89-
pass
90-
101+
91102
@classmethod
92103
def _write_destination_url(cls, entity):
93104
if isinstance(entity.ad_group_criterion, _BiddableAdGroupCriterion):
@@ -135,11 +146,9 @@ def _read_destination_url(cls, entity, row_value):
135146
pass
136147

137148
_MAPPINGS = [
138-
_SimpleBulkMapping(
139-
_StringTable.IsExcluded,
140-
field_to_csv=lambda c: 'True' if isinstance(c.ad_group_criterion, _NegativeAdGroupCriterion) else 'False',
141-
csv_to_field=lambda c, v: BulkAdGroupProductPartition._read_is_excluded(c, v)
142-
),
149+
150+
_ComplexBulkMapping(bidding_to_csv, csv_to_bidding),
151+
143152
_SimpleBulkMapping(
144153
_StringTable.Status,
145154
field_to_csv=lambda c: c.ad_group_criterion.Status,
@@ -186,11 +195,7 @@ def _read_destination_url(cls, entity, row_value):
186195
field_to_csv=lambda c: BulkAdGroupProductPartition._get_condition_attribute(c),
187196
csv_to_field=lambda c, v: setattr(c.ad_group_criterion.Criterion.Condition, 'Attribute', v)
188197
),
189-
_SimpleBulkMapping(
190-
_StringTable.Bid,
191-
field_to_csv=lambda c: BulkAdGroupProductPartition._write_bid(c),
192-
csv_to_field=lambda c, v: BulkAdGroupProductPartition._read_bid(c, v)
193-
),
198+
194199
_SimpleBulkMapping(
195200
_StringTable.DestinationUrl,
196201
field_to_csv=lambda c: BulkAdGroupProductPartition._write_destination_url(c),

bingads/v12/internal/extensions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,11 @@ def fixed_bid_bulk_str(value):
562562
return None
563563
return bulk_str(value.Amount)
564564

565+
def bid_multiplier_bulk_str(value):
566+
if value is None or not hasattr(value, 'Multiplier') or value.Multiplier is None:
567+
return None
568+
return bulk_str(value.Multiplier)
569+
565570
def parse_minute(value):
566571
minute_number = int(value)
567572
if minute_number == 0:

bingads/v13/bulk/entities/bulk_ad_group_product_partition.py

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,74 @@
11
from bingads.v13.bulk.entities import *
22
from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13
33
from bingads.v13.internal.bulk.entities.single_record_bulk_entity import _SingleRecordBulkEntity
4-
from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping
4+
from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping, _ComplexBulkMapping
55
from bingads.v13.internal.bulk.string_table import _StringTable
66
# from bingads.v13.internal.extensions import bulk_str
77
from bingads.v13.internal.extensions import *
88

99
_BiddableAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion'))
1010
_NegativeAdGroupCriterion = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion'))
11-
11+
_FixedBid = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid'))
12+
13+
def csv_to_bidding(row_values, entity):
14+
success, exclude = row_values.try_get_value(_StringTable.IsExcluded)
15+
if exclude is None:
16+
exclude = ''
17+
exclude = exclude.lower()
18+
if exclude == 'yes' or exclude == 'true':
19+
is_excluded = True
20+
elif exclude == 'no' or exclude == 'false':
21+
is_excluded = False
22+
else:
23+
raise ValueError('IsExcluded can only be set to TRUE|FALSE in Ad Group Product Partition row')
24+
if is_excluded:
25+
product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition')
26+
product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition')
27+
product_partition.Type = 'ProductPartition'
28+
29+
negative_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('NegativeAdGroupCriterion')
30+
negative_ad_group_criterion.Criterion = product_partition
31+
negative_ad_group_criterion.Type = 'NegativeAdGroupCriterion'
32+
33+
entity.ad_group_criterion = negative_ad_group_criterion
34+
else:
35+
product_partition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductPartition')
36+
product_partition.Condition = _CAMPAIGN_OBJECT_FACTORY_V13.create('ProductCondition')
37+
product_partition.Type = 'ProductPartition'
38+
39+
bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('FixedBid')
40+
bid.Type = 'FixedBid'
41+
42+
biddable_ad_group_criterion = _CAMPAIGN_OBJECT_FACTORY_V13.create('BiddableAdGroupCriterion')
43+
biddable_ad_group_criterion.Criterion = product_partition
44+
45+
success, bid_value = row_values.try_get_value(_StringTable.Bid)
46+
if success and bid_value is not None and bid_value != '':
47+
bid.Amount = float(bid_value)
48+
else:
49+
success, bid_value = row_values.try_get_value(_StringTable.BidAdjustment)
50+
if success and bid_value is not None and bid_value != '':
51+
bid = _CAMPAIGN_OBJECT_FACTORY_V13.create('BidMultiplier')
52+
bid.Type = 'BidMultiplier'
53+
bid.Multiplier = float(bid_value)
54+
55+
biddable_ad_group_criterion.CriterionBid = bid
56+
biddable_ad_group_criterion.Type = 'BiddableAdGroupCriterion'
57+
58+
entity.ad_group_criterion = biddable_ad_group_criterion
59+
60+
def bidding_to_csv(entity, row_values):
61+
if isinstance(entity.ad_group_criterion, _NegativeAdGroupCriterion):
62+
row_values[_StringTable.IsExcluded] = 'True'
63+
else:
64+
row_values[_StringTable.IsExcluded] = 'False'
65+
bid = entity.ad_group_criterion.CriterionBid
66+
if bid is None:
67+
return
68+
if isinstance(bid, _FixedBid):
69+
row_values[_StringTable.Bid] = fixed_bid_bulk_str(bid)
70+
else:
71+
row_values[_StringTable.BidAdjustment] = bid_multiplier_bulk_str(bid)
1272

1373
class BulkAdGroupProductPartition(_SingleRecordBulkEntity):
1474
""" Represents an Ad Group Criterion that can be read or written in a bulk file.
@@ -134,11 +194,8 @@ def _read_destination_url(cls, entity, row_value):
134194
pass
135195

136196
_MAPPINGS = [
137-
_SimpleBulkMapping(
138-
_StringTable.IsExcluded,
139-
field_to_csv=lambda c: 'True' if isinstance(c.ad_group_criterion, _NegativeAdGroupCriterion) else 'False',
140-
csv_to_field=lambda c, v: BulkAdGroupProductPartition._read_is_excluded(c, v)
141-
),
197+
_ComplexBulkMapping(bidding_to_csv, csv_to_bidding),
198+
142199
_SimpleBulkMapping(
143200
_StringTable.Status,
144201
field_to_csv=lambda c: c.ad_group_criterion.Status,
@@ -185,11 +242,6 @@ def _read_destination_url(cls, entity, row_value):
185242
field_to_csv=lambda c: BulkAdGroupProductPartition._get_condition_attribute(c),
186243
csv_to_field=lambda c, v: setattr(c.ad_group_criterion.Criterion.Condition, 'Attribute', v)
187244
),
188-
_SimpleBulkMapping(
189-
_StringTable.Bid,
190-
field_to_csv=lambda c: BulkAdGroupProductPartition._write_bid(c),
191-
csv_to_field=lambda c, v: BulkAdGroupProductPartition._read_bid(c, v)
192-
),
193245
_SimpleBulkMapping(
194246
_StringTable.DestinationUrl,
195247
field_to_csv=lambda c: BulkAdGroupProductPartition._write_destination_url(c),

bingads/v13/internal/extensions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,11 @@ def fixed_bid_bulk_str(value):
562562
return None
563563
return bulk_str(value.Amount)
564564

565+
def bid_multiplier_bulk_str(value):
566+
if value is None or not hasattr(value, 'Multiplier') or value.Multiplier is None:
567+
return None
568+
return bulk_str(value.Multiplier)
569+
565570
def parse_minute(value):
566571
minute_number = int(value)
567572
if minute_number == 0:

bingads/v13/proxies/campaign_management_service.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,11 +1707,25 @@
17071707
<xs:element minOccurs="0" name="AlternativeText" nillable="true" type="xs:string" />
17081708
<xs:element minOccurs="0" name="Description" nillable="true" type="xs:string" />
17091709
<xs:element minOccurs="0" name="DestinationUrl" nillable="true" type="xs:string" />
1710+
<xs:element minOccurs="0" name="DisplayText" nillable="true" type="xs:string">
1711+
<xs:annotation>
1712+
<xs:appinfo>
1713+
<DefaultValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/" EmitDefaultValue="false" />
1714+
</xs:appinfo>
1715+
</xs:annotation>
1716+
</xs:element>
17101717
<xs:element minOccurs="0" name="FinalAppUrls" nillable="true" type="tns:ArrayOfAppUrl" />
17111718
<xs:element xmlns:q38="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="FinalMobileUrls" nillable="true" type="q38:ArrayOfstring" />
17121719
<xs:element minOccurs="0" name="FinalUrlSuffix" nillable="true" type="xs:string" />
17131720
<xs:element xmlns:q39="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="FinalUrls" nillable="true" type="q39:ArrayOfstring" />
17141721
<xs:element xmlns:q40="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="ImageMediaIds" nillable="true" type="q40:ArrayOflong" />
1722+
<xs:element minOccurs="0" name="Images" nillable="true" type="tns:ArrayOfAssetLink">
1723+
<xs:annotation>
1724+
<xs:appinfo>
1725+
<DefaultValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/" EmitDefaultValue="false" />
1726+
</xs:appinfo>
1727+
</xs:annotation>
1728+
</xs:element>
17151729
<xs:element minOccurs="0" name="TrackingUrlTemplate" nillable="true" type="xs:string" />
17161730
<xs:element minOccurs="0" name="UrlCustomParameters" nillable="true" type="tns:CustomParameters" />
17171731
</xs:sequence>
@@ -2017,6 +2031,7 @@
20172031
<xs:element minOccurs="0" name="AccountId" type="xs:long" />
20182032
<xs:element xmlns:q51="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="AdExtensionIds" nillable="true" type="q51:ArrayOflong" />
20192033
<xs:element minOccurs="0" name="AdExtensionType" type="tns:AdExtensionsTypeFilter" />
2034+
<xs:element minOccurs="0" name="ReturnAdditionalFields" nillable="true" type="tns:AdExtensionAdditionalField" />
20202035
</xs:sequence>
20212036
</xs:complexType>
20222037
</xs:element>
@@ -2039,6 +2054,17 @@
20392054
</xs:list>
20402055
</xs:simpleType>
20412056
<xs:element name="AdExtensionsTypeFilter" nillable="true" type="tns:AdExtensionsTypeFilter" />
2057+
<xs:simpleType name="AdExtensionAdditionalField">
2058+
<xs:list>
2059+
<xs:simpleType>
2060+
<xs:restriction base="xs:string">
2061+
<xs:enumeration value="Images" />
2062+
<xs:enumeration value="DisplayText" />
2063+
</xs:restriction>
2064+
</xs:simpleType>
2065+
</xs:list>
2066+
</xs:simpleType>
2067+
<xs:element name="AdExtensionAdditionalField" nillable="true" type="tns:AdExtensionAdditionalField" />
20422068
<xs:element name="GetAdExtensionsByIdsResponse">
20432069
<xs:complexType>
20442070
<xs:sequence>
@@ -2184,6 +2210,7 @@
21842210
<xs:element minOccurs="0" name="AdExtensionType" type="tns:AdExtensionsTypeFilter" />
21852211
<xs:element minOccurs="0" name="AssociationType" type="tns:AssociationType" />
21862212
<xs:element xmlns:q54="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="EntityIds" nillable="true" type="q54:ArrayOflong" />
2213+
<xs:element minOccurs="0" name="ReturnAdditionalFields" nillable="true" type="tns:AdExtensionAdditionalField" />
21872214
</xs:sequence>
21882215
</xs:complexType>
21892216
</xs:element>

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
except ImportError:
44
from distutils.core import setup
55

6-
VERSION = '12.13.4.1'
6+
VERSION = '12.13.5'
77

88
with open('README.rst', 'r') as f:
99
readme = f.read()

0 commit comments

Comments
 (0)