Skip to content

Commit

Permalink
Merge pull request #180 from BingAds/users/qitia/13.0.9
Browse files Browse the repository at this point in the history
Version 13.0.9
  • Loading branch information
qitia committed Apr 29, 2021
2 parents 4f1ed7f + 7d72959 commit 47f7a11
Show file tree
Hide file tree
Showing 27 changed files with 41,596 additions and 393 deletions.
6 changes: 6 additions & 0 deletions HISTORY.rst
@@ -1,6 +1,12 @@
.. :changelog:
Release History
13.0.9(2021-04-29)
+++++++++++++++++++++++++
* Update Bing Ads API Version 13 service proxies to reflect recent interface changes. For details please see the Bing Ads API Release Notes: https://docs.microsoft.com/en-us/bingads/guides/release-notes.
* Add bulk mappings for video ad extensions i.e., BulkVideoAdExtension, BulkAccountVideoAdExtension, BulkAdGroupVideoAdExtension, and BulkCampaignVideoAdExtension.
* Add CashbackAdjustment mapping in the BulkAdGroupBiddableCriterion and BulkCampaignBiddableCriterion.
* Cache SDK snapshot of the singleWsdl proxies for all Bing Ads API Version 13 services.

13.0.8(2021-03-10)
+++++++++++++++++++++++++
Expand Down
2 changes: 1 addition & 1 deletion bingads/manifest.py
@@ -1,5 +1,5 @@
import sys
VERSION = '13.0.8'
VERSION = '13.0.9'
BULK_FORMAT_VERSION_6 = '6.0'
WORKING_NAME = 'BingAdsSDKPython'
USER_AGENT = '{0} {1} {2}'.format(WORKING_NAME, VERSION, sys.version_info[0:3])
13 changes: 6 additions & 7 deletions bingads/service_client.py
Expand Up @@ -31,6 +31,7 @@ def __init__(self, service, version, authorization_data=None, environment='produ
self._authorization_data = authorization_data
self._refresh_oauth_tokens_automatically = True
self._version = ServiceClient._format_version(version)


# TODO This is a temp fix for set default suds temp folder with user info, suds development branch has already fixed it.
if 'cache' not in suds_options:
Expand Down Expand Up @@ -94,7 +95,7 @@ def factory(self):
"""

return self.soap_client.factory

@property
def service_url(self):
""" The wsdl url of service based on the specific service and environment.
Expand All @@ -105,9 +106,8 @@ def service_url(self):
key = (self._service, self._environment)
service_info_dict = ServiceClient._get_service_info_dict(self._version)
if key not in service_info_dict:
raise ValueError(str.format('Cannot find version: [v{0}] service: [{1}] under environment: [{2}].',
self._version, self._input_service, self._input_environment))
return service_info_dict[(self._service, self._environment)].url
return service_info_dict[(self._service, 'sandbox')]
return service_info_dict[(self._service, self._environment)]


@property
Expand Down Expand Up @@ -200,7 +200,6 @@ def _format_version(version):
return 13
raise ValueError(str.format('version error: [{0}] is not supported.', version))


@staticmethod
def _get_service_info_dict(version):
"""
Expand Down Expand Up @@ -296,9 +295,9 @@ def name(self):
from suds.sudsobject import Property
from suds.sax.text import Text


# this is used to create entity only. Given the sandbox should have the same contract, we are good to use sandbox wsdl.
_CAMPAIGN_MANAGEMENT_SERVICE_V13 = Client(
'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/campaign_management_service.xml'))
'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/sandbox/campaignmanagement_service.xml'))
_CAMPAIGN_OBJECT_FACTORY_V13 = _CAMPAIGN_MANAGEMENT_SERVICE_V13.factory
_CAMPAIGN_OBJECT_FACTORY_V13.object_cache = {}
_CAMPAIGN_OBJECT_FACTORY_V13.create_without_cache = _CAMPAIGN_OBJECT_FACTORY_V13.create
Expand Down
104 changes: 5 additions & 99 deletions bingads/service_info.py
@@ -1,105 +1,11 @@
class _ServiceInfo:

@property
def name(self):
return self._name

@property
def env(self):
return self._env

@property
def url(self):
return self._url

@url.setter
def url(self, url):
self._url = url


def __init__(self, name, env, url):
self._name = name
self._env = env
self._url = url

_SERVICE_INFO_LIST_V13 = [
# ad insight service
_ServiceInfo(
"adinsight",
"production",
"https://adinsight.api.bingads.microsoft.com/Api/Advertiser/AdInsight/V13/AdInsightService.svc?singleWsdl"
),
_ServiceInfo(
"adinsight",
"sandbox",
"https://adinsight.api.sandbox.bingads.microsoft.com/Api/Advertiser/AdInsight/V13/AdInsightService.svc?singleWsdl"
),

# bulk service
_ServiceInfo(
"bulk",
"production",
"https://bulk.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl"
),
_ServiceInfo(
"bulk",
"sandbox",
"https://bulk.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/BulkService.svc?singleWsdl"
),

# campaign management
_ServiceInfo(
"campaignmanagement",
"production",
"https://campaign.api.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl"
),
_ServiceInfo(
"campaignmanagement",
"sandbox",
"https://campaign.api.sandbox.bingads.microsoft.com/Api/Advertiser/CampaignManagement/v13/CampaignManagementService.svc?singleWsdl"
),

# customer billing
_ServiceInfo(
"customerbilling",
"production",
"https://clientcenter.api.bingads.microsoft.com/Api/Billing/v13/CustomerBillingService.svc?singleWsdl"
),
_ServiceInfo(
"customerbilling",
"sandbox",
"https://clientcenter.api.sandbox.bingads.microsoft.com/Api/Billing/v13/CustomerBillingService.svc?singleWsdl"
),

# customer management
_ServiceInfo(
"customermanagement",
"production",
"https://clientcenter.api.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl"
),
_ServiceInfo(
"customermanagement",
"sandbox",
"https://clientcenter.api.sandbox.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl"
),

# reporting
_ServiceInfo(
"reporting",
"production",
"https://reporting.api.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl"
),
_ServiceInfo(
"reporting",
"sandbox",
"https://reporting.api.sandbox.bingads.microsoft.com/Api/Advertiser/Reporting/v13/ReportingService.svc?singleWsdl"
),
]
import pkg_resources

_SERVICE_LIST = ['adinsight', 'bulk', 'campaignmanagement', 'customerbilling', 'customermanagement', 'reporting']

SERVICE_INFO_DICT_V13 = {}

for service_info in _SERVICE_INFO_LIST_V13:
SERVICE_INFO_DICT_V13[(service_info.name, service_info.env)] = service_info
for service in _SERVICE_LIST:
SERVICE_INFO_DICT_V13[(service, 'production')] = 'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/production/%s_service.xml' % (service))
SERVICE_INFO_DICT_V13[(service, 'sandbox')] = 'file:///' + pkg_resources.resource_filename('bingads', 'v13/proxies/sandbox/%s_service.xml' % (service))

SERVICE_INFO_DICT = {13: SERVICE_INFO_DICT_V13}
3 changes: 2 additions & 1 deletion bingads/v13/bulk/entities/ad_extensions/__init__.py
Expand Up @@ -12,4 +12,5 @@
from .bulk_action_ad_extensions import *
from .bulk_promotion_ad_extensions import *
from .bulk_filterlink_ad_extensions import *
from .bulk_flyer_ad_extensions import *
from .bulk_flyer_ad_extensions import *
from .bulk_video_ad_extensions import *
182 changes: 182 additions & 0 deletions bingads/v13/bulk/entities/ad_extensions/bulk_video_ad_extensions.py
@@ -0,0 +1,182 @@
from bingads.v13.internal.bulk.mappings import _SimpleBulkMapping
from bingads.v13.internal.bulk.string_table import _StringTable
from bingads.service_client import _CAMPAIGN_OBJECT_FACTORY_V13

from bingads.v13.internal.extensions import *
from .common import _BulkAdExtensionBase
from .common import _BulkCampaignAdExtensionAssociation
from .common import _BulkAdGroupAdExtensionAssociation
from .common import _BulkAccountAdExtensionAssociation

_VideoAdExtension = type(_CAMPAIGN_OBJECT_FACTORY_V13.create('VideoAdExtension'))


class BulkVideoAdExtension(_BulkAdExtensionBase):
""" Represents a video ad extension.
This class exposes the :attr:`video_ad_extension` property that can be read and written
as fields of the Video Ad Extension record in a bulk file.
For more information, see Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
*See also:*
* :class:`.BulkServiceManager`
* :class:`.BulkOperation`
* :class:`.BulkFileReader`
* :class:`.BulkFileWriter`
"""

def __init__(self, account_id=None, ad_extension=None):
if ad_extension and not isinstance(ad_extension, _VideoAdExtension):
raise ValueError('The type of ad_extension is: {0}, should be: {1}'.format(
type(ad_extension),
'VideoAdExtension'
))
super(BulkVideoAdExtension, self).__init__(
account_id=account_id,
ad_extension=ad_extension
)

@property
def video_ad_extension(self):
""" The video ad extension.
see Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
"""

return self._ad_extension

@video_ad_extension.setter
def video_ad_extension(self, value):
self._ad_extension = value

_MAPPINGS = [
_SimpleBulkMapping(
header=_StringTable.Name,
field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.Name, c.video_ad_extension.Id),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'Name', v if v else '')
),
_SimpleBulkMapping(
header=_StringTable.DisplayText,
field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.DisplayText, c.video_ad_extension.Id),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'DisplayText', v if v else '')
),
_SimpleBulkMapping(
header=_StringTable.AltText,
field_to_csv=lambda c: bulk_str(c.video_ad_extension.AlternativeText),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'AlternativeText', v)
),
_SimpleBulkMapping(
header=_StringTable.ActionText,
field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.ActionText, c.video_ad_extension.Id),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'ActionText', v if v else '')
),
_SimpleBulkMapping(
header=_StringTable.ThumbnailUrl,
field_to_csv=lambda c: bulk_str(c.video_ad_extension.ThumbnailUrl),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'ThumbnailUrl', v)
),
_SimpleBulkMapping(
header=_StringTable.ThumbnailId,
field_to_csv=lambda c: bulk_str(c.video_ad_extension.ThumbnailId),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'ThumbnailId', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.VideoId,
field_to_csv=lambda c: bulk_str(c.video_ad_extension.VideoId),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'VideoId', int(v) if v else None)
),
_SimpleBulkMapping(
header=_StringTable.FinalUrlSuffix,
field_to_csv=lambda c: bulk_optional_str(c.video_ad_extension.FinalUrlSuffix, c.video_ad_extension.Id),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'FinalUrlSuffix', v)
),
_SimpleBulkMapping(
header=_StringTable.TrackingTemplate,
field_to_csv=lambda c: bulk_str(c.video_ad_extension.TrackingUrlTemplate),
csv_to_field=lambda c, v: setattr(c.video_ad_extension, 'TrackingUrlTemplate', v if v else None)
),
_SimpleBulkMapping(
header=_StringTable.CustomParameter,
field_to_csv=lambda c: field_to_csv_UrlCustomParameters(c.video_ad_extension),
csv_to_field=lambda c, v: csv_to_field_UrlCustomParameters(c.video_ad_extension, v)
),
_SimpleBulkMapping(
header=_StringTable.FinalUrl,
field_to_csv=lambda c: field_to_csv_Urls(c.video_ad_extension.FinalUrls, c.video_ad_extension.Id),
csv_to_field=lambda c, v: csv_to_field_Urls(c.video_ad_extension.FinalUrls, v)
),
_SimpleBulkMapping(
header=_StringTable.FinalMobileUrl,
field_to_csv=lambda c: field_to_csv_Urls(c.video_ad_extension.FinalMobileUrls, c.video_ad_extension.Id),
csv_to_field=lambda c, v: csv_to_field_Urls(c.video_ad_extension.FinalMobileUrls, v)
)
]

def process_mappings_from_row_values(self, row_values):
self.video_ad_extension = _CAMPAIGN_OBJECT_FACTORY_V13.create('VideoAdExtension')
self.video_ad_extension.Type = 'VideoAdExtension'
super(BulkVideoAdExtension, self).process_mappings_from_row_values(row_values)
row_values.convert_to_entity(self, BulkVideoAdExtension._MAPPINGS)

def process_mappings_to_row_values(self, row_values, exclude_readonly_data):
self._validate_property_not_null(self.video_ad_extension, 'video_ad_extension')
super(BulkVideoAdExtension, self).process_mappings_to_row_values(row_values, exclude_readonly_data)
self.convert_to_values(row_values, BulkVideoAdExtension._MAPPINGS)


class BulkAccountVideoAdExtension(_BulkAccountAdExtensionAssociation):
""" Represents an account level video ad extension.
This class exposes properties that can be read and written
as fields of the Account Video Ad Extension record in a bulk file.
For more information, see Account Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
*See also:*
* :class:`.BulkServiceManager`
* :class:`.BulkOperation`
* :class:`.BulkFileReader`
* :class:`.BulkFileWriter`
"""

pass


class BulkCampaignVideoAdExtension(_BulkCampaignAdExtensionAssociation):
""" Represents a campaign level video ad extension.
This class exposes properties that can be read and written
as fields of the Campaign Video Ad Extension record in a bulk file.
For more information, see Campaign Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
*See also:*
* :class:`.BulkServiceManager`
* :class:`.BulkOperation`
* :class:`.BulkFileReader`
* :class:`.BulkFileWriter`
"""

pass

class BulkAdGroupVideoAdExtension(_BulkAdGroupAdExtensionAssociation):
""" Represents an ad group level video ad extension.
This class exposes properties that can be read and written
as fields of the Ad Group Video Ad Extension record in a bulk file.
For more information, see Ad Group Video Ad Extension at https://go.microsoft.com/fwlink/?linkid=846127.
*See also:*
* :class:`.BulkServiceManager`
* :class:`.BulkOperation`
* :class:`.BulkFileReader`
* :class:`.BulkFileWriter`
"""

pass
Expand Up @@ -59,6 +59,11 @@ def __init__(self,
_StringTable.BidAdjustment,
field_to_csv=lambda c: field_to_csv_BidAdjustment(c.biddable_ad_group_criterion),
csv_to_field=lambda c, v: csv_to_field_BidAdjustment(c.biddable_ad_group_criterion, float(v) if v else None)
),
_SimpleBulkMapping(
_StringTable.CashbackAdjustment,
field_to_csv=lambda c: field_to_csv_CashbackAdjustment(c.biddable_ad_group_criterion),
csv_to_field=lambda c, v: csv_to_field_CashbackAdjustment(c.biddable_ad_group_criterion, float(v) if v else None)
)
]

Expand Down Expand Up @@ -110,6 +115,8 @@ def process_mappings_from_row_values(self, row_values):
self.create_criterion()
self._biddable_ad_group_criterion.CriterionBid = _CAMPAIGN_OBJECT_FACTORY_V13.create('BidMultiplier')
self._biddable_ad_group_criterion.CriterionBid.Type = 'BidMultiplier'
self._biddable_ad_group_criterion.CriterionCashback = _CAMPAIGN_OBJECT_FACTORY_V13.create('CashbackAdjustment')
self._biddable_ad_group_criterion.CriterionCashback.Type = 'CashbackAdjustment'
row_values.convert_to_entity(self, BulkAdGroupBiddableCriterion._MAPPINGS)

def create_criterion(self):
Expand Down

0 comments on commit 47f7a11

Please sign in to comment.