From c4b88aa06161d77858a2f324645d646a9a814293 Mon Sep 17 00:00:00 2001 From: Pere Turegano Date: Fri, 5 Aug 2022 15:41:42 +0200 Subject: [PATCH 1/6] Removed parameter IncludeLinkedAccountIds from GetUser call --- examples/v13/customer_signup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/v13/customer_signup.py b/examples/v13/customer_signup.py index 368b8238..cdfb3428 100644 --- a/examples/v13/customer_signup.py +++ b/examples/v13/customer_signup.py @@ -8,8 +8,7 @@ def main(authorization_data): try: output_status_message("-----\nGetUser:") get_user_response=customer_service.GetUser( - UserId=None, - IncludeLinkedAccountIds=True + UserId=None ) user = get_user_response.User customer_roles=get_user_response.CustomerRoles From 491fbcb8f2acf28468817b8bc3b93818ca3ba8bc Mon Sep 17 00:00:00 2001 From: Pere Turegano Date: Fri, 5 Aug 2022 16:14:29 +0200 Subject: [PATCH 2/6] Removed parameter IncludeLinkedAccountIds from GetUser call --- examples/v13/invite_user.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/v13/invite_user.py b/examples/v13/invite_user.py index 15fdb30a..ad4b2586 100644 --- a/examples/v13/invite_user.py +++ b/examples/v13/invite_user.py @@ -101,8 +101,7 @@ def main(authorization_data): for info in users_info['UserInfo']: output_status_message("-----\nGetUser:") get_user_response=customer_service.GetUser( - UserId=info.Id, - IncludeLinkedAccountIds=True) + UserId=info.Id) user = get_user_response.User customer_roles=get_user_response.CustomerRoles output_status_message("User:") From 6f22c1ed0dfa10a20be8152ee3cd5020d1b1e202 Mon Sep 17 00:00:00 2001 From: Pere Turegano Date: Fri, 5 Aug 2022 16:46:41 +0200 Subject: [PATCH 3/6] Updated to supported version urllib3 --- examples/v13/geographical_locations.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/v13/geographical_locations.py b/examples/v13/geographical_locations.py index 45f78249..d165b521 100644 --- a/examples/v13/geographical_locations.py +++ b/examples/v13/geographical_locations.py @@ -1,4 +1,6 @@ -import urllib2 +import urllib3 as urllib +from urllib.error import URLError +from urllib.request import urlopen, Request from auth_helper import * from campaignmanagement_example_helper import * @@ -29,14 +31,14 @@ def main(authorization_data): output_status_message("FileUrlExpiryTimeUtc: {0}".format(get_geo_locations_file_url_response.FileUrlExpiryTimeUtc)) output_status_message("LastModifiedTimeUtc: {0}".format(get_geo_locations_file_url_response.LastModifiedTimeUtc)) - request=urllib2.Request(get_geo_locations_file_url_response.FileUrl) - response=urllib2.urlopen(request) + request=Request(get_geo_locations_file_url_response.FileUrl) + response=urlopen(request) if response.getcode() == 200: download_file(response) output_status_message("Downloaded the geographical locations to {0}.".format(LOCAL_FILE)) - except urllib2.URLError as ex: + except URLError as ex: if hasattr(ex, 'code'): output_status_message("Error code: {0}".format(ex.code)) elif hasattr(ex, 'reason'): From 2c905f450a31e5ca2e9dbdc3a48c03a939d0bfbb Mon Sep 17 00:00:00 2001 From: MrOllzzor Date: Fri, 6 Oct 2023 13:19:39 +0200 Subject: [PATCH 4/6] Fixed bid_suggestion_data.py. Implemented abstract methods in BulkKeywordBestPositionBid, BulkKeywordFirstPageBid and BulkKeywordMainLineBid. --- .../v13/bulk/entities/bid_suggestion_data.py | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/bingads/v13/bulk/entities/bid_suggestion_data.py b/bingads/v13/bulk/entities/bid_suggestion_data.py index b8b31161..f3638ea0 100644 --- a/bingads/v13/bulk/entities/bid_suggestion_data.py +++ b/bingads/v13/bulk/entities/bid_suggestion_data.py @@ -141,12 +141,45 @@ def write_if_not_null(keyword_bid_suggestion, row_writer): class BulkKeywordBestPositionBid(BulkKeywordBidSuggestion): - pass + def read_related_data_from_stream(self, stream_reader): + return super(BulkKeywordBestPositionBid, self).read_related_data_from_stream(stream_reader) + + def write_to_stream(self, row_writer, exclude_readonly_data): + return super(BulkKeywordBestPositionBid, self).write_to_stream(row_writer, exclude_readonly_data) + + @property + def can_enclose_in_multiline_entity(self): + return super(BulkKeywordBestPositionBid, self).can_enclose_in_multiline_entity + + def enclose_in_multiline_entity(self): + return super(BulkKeywordBestPositionBid, self).enclose_in_multiline_entity() class BulkKeywordFirstPageBid(BulkKeywordBidSuggestion): - pass + def read_related_data_from_stream(self, stream_reader): + return super(BulkKeywordFirstPageBid, self).read_related_data_from_stream(stream_reader) + + def write_to_stream(self, row_writer, exclude_readonly_data): + return super(BulkKeywordFirstPageBid, self).write_to_stream(row_writer, exclude_readonly_data) + + @property + def can_enclose_in_multiline_entity(self): + return super(BulkKeywordFirstPageBid, self).can_enclose_in_multiline_entity + + def enclose_in_multiline_entity(self): + return super(BulkKeywordFirstPageBid, self).enclose_in_multiline_entity() class BulkKeywordMainLineBid(BulkKeywordBidSuggestion): - pass + def read_related_data_from_stream(self, stream_reader): + return super(BulkKeywordMainLineBid, self).read_related_data_from_stream(stream_reader) + + def write_to_stream(self, row_writer, exclude_readonly_data): + return super(BulkKeywordMainLineBid, self).write_to_stream(row_writer, exclude_readonly_data) + + @property + def can_enclose_in_multiline_entity(self): + return super(BulkKeywordMainLineBid, self).can_enclose_in_multiline_entity + + def enclose_in_multiline_entity(self): + return super(BulkKeywordMainLineBid, self).enclose_in_multiline_entity() From 43a1ae1c949e40807099f9d19d986433a3d79226 Mon Sep 17 00:00:00 2001 From: MrOllzzor Date: Mon, 9 Oct 2023 09:59:50 +0200 Subject: [PATCH 5/6] Added support for all fields in BulkKeywordBestPositionBid, BulkKeywordFirstPageBid and BulkKeywordMainLineBid. --- .../v13/bulk/entities/bid_suggestion_data.py | 510 ++++++++++++++++++ 1 file changed, 510 insertions(+) diff --git a/bingads/v13/bulk/entities/bid_suggestion_data.py b/bingads/v13/bulk/entities/bid_suggestion_data.py index f3638ea0..7e04f499 100644 --- a/bingads/v13/bulk/entities/bid_suggestion_data.py +++ b/bingads/v13/bulk/entities/bid_suggestion_data.py @@ -141,6 +141,176 @@ def write_if_not_null(keyword_bid_suggestion, row_writer): class BulkKeywordBestPositionBid(BulkKeywordBidSuggestion): + def __init__(self): + super().__init__() + self._spend = None + self._impressions = None + self._clicks = None + self._ctr = None + self._avgcpc = None + self._avgcpm = None + self._avgposition = None + self._conversions = None + self._cpa = None + + @property + def keyword_text(self): + """ The keyword corresponding to the suggested bid. + + Corresponds to the 'Keyword' field in the bulk file. + :rtype: str + """ + + return self._keyword_text + + @property + def bid(self): + """ The suggested bid value for the best position in search results. + + :rtype: float + """ + + return self._bid + + @property + def spend(self): + """ The estimated average cost per week. + + :rtype: float + """ + return self._spend + + @property + def impressions(self): + """ The estimated average number of impressions per week. + + :rtype: int + """ + return self._impressions + + @property + def clicks(self): + """ The estimated average number of clicks per week. + + :rtype: int + """ + return self._clicks + + @property + def ctr(self): + """ The estimated CTR. + The formula used to calculate the CTR is (maximum number of clicks / maximum number of impressions) * 100. + + :rtype: float + """ + return self._ctr + + @property + def avgcpc(self): + """ The estimated average CPC. + The formula used to calculate the average CPC is (maximum total cost / maximum number of clicks). + + :rtype: float + """ + return self._avgcpc + + @property + def avgcpm(self): + """ The average of the cost per thousand impressions (CPM) of the ad. + The value will be 0 (zero) if the ad group to which the ad belongs does not specify the + Content ad distribution medium or if the user does not belong to the CPM pilot program. + + :rtype: float + """ + return self._avgcpm + + @property + def avgposition(self): + """ The position in the search results given the specified bid. + + :rtype: float + """ + return self._avgposition + + @property + def conversions(self): + """ The estimated number of conversions per week. + + :rtype: float + """ + return self._conversions + + @property + def cpa(self): + """ The estimated cost per conversion. + The formula for calculating the cost per conversion is (spend / conversions). + + :rtype: float + """ + return self._cpa + + def read_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkKeywordBestPositionBid._MAPPINGS) + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Keyword, + field_to_csv=lambda c: bulk_str(c.keyword_text), + csv_to_field=lambda c, v: setattr(c, '_keyword_text', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Bid, + field_to_csv=lambda c: bulk_str(c.bid), + csv_to_field=lambda c, v: setattr(c, '_bid', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Spend, + field_to_csv=lambda c: bulk_str(c.spend), + csv_to_field=lambda c, v: setattr(c, '_spend', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Impressions, + field_to_csv=lambda c: bulk_str(c.impressions), + csv_to_field=lambda c, v: setattr(c, '_impressions', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Clicks, + field_to_csv=lambda c: bulk_str(c.clicks), + csv_to_field=lambda c, v: setattr(c, '_clicks', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CTR, + field_to_csv=lambda c: bulk_str(c.ctr), + csv_to_field=lambda c, v: setattr(c, '_ctr', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgCPC, + field_to_csv=lambda c: bulk_str(c.avgcpc), + csv_to_field=lambda c, v: setattr(c, '_avgcpc', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgCPM, + field_to_csv=lambda c: bulk_str(c.avgcpm), + csv_to_field=lambda c, v: setattr(c, '_avgcpm', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgPosition, + field_to_csv=lambda c: bulk_str(c.avgposition), + csv_to_field=lambda c, v: setattr(c, '_avgposition', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Conversions, + field_to_csv=lambda c: bulk_str(c.conversions), + csv_to_field=lambda c, v: setattr(c, '_conversions', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CPA, + field_to_csv=lambda c: bulk_str(c.cpa), + csv_to_field=lambda c, v: setattr(c, '_cpa', float(v) if v else None) + ), + + ] + def read_related_data_from_stream(self, stream_reader): return super(BulkKeywordBestPositionBid, self).read_related_data_from_stream(stream_reader) @@ -156,6 +326,176 @@ def enclose_in_multiline_entity(self): class BulkKeywordFirstPageBid(BulkKeywordBidSuggestion): + def __init__(self): + super().__init__() + self._spend = None + self._impressions = None + self._clicks = None + self._ctr = None + self._avgcpc = None + self._avgcpm = None + self._avgposition = None + self._conversions = None + self._cpa = None + + @property + def keyword_text(self): + """ The keyword corresponding to the suggested bid. + + Corresponds to the 'Keyword' field in the bulk file. + :rtype: str + """ + + return self._keyword_text + + @property + def bid(self): + """ The suggested bid value for first page side bar positioning in search results. + + :rtype: float + """ + + return self._bid + + @property + def spend(self): + """ The estimated average cost per week. + + :rtype: float + """ + return self._spend + + @property + def impressions(self): + """ The estimated average number of impressions per week. + + :rtype: int + """ + return self._impressions + + @property + def clicks(self): + """ The estimated average number of clicks per week. + + :rtype: int + """ + return self._clicks + + @property + def ctr(self): + """ The estimated CTR. + The formula used to calculate the CTR is (maximum number of clicks / maximum number of impressions) * 100. + + :rtype: float + """ + return self._ctr + + @property + def avgcpc(self): + """ The estimated average CPC. + The formula used to calculate the average CPC is (maximum total cost / maximum number of clicks). + + :rtype: float + """ + return self._avgcpc + + @property + def avgcpm(self): + """ The average of the cost per thousand impressions (CPM) of the ad. + The value will be 0 (zero) if the ad group to which the ad belongs does not specify the + Content ad distribution medium or if the user does not belong to the CPM pilot program. + + :rtype: float + """ + return self._avgcpm + + @property + def avgposition(self): + """ The position in the search results given the specified bid. + + :rtype: float + """ + return self._avgposition + + @property + def conversions(self): + """ The estimated number of conversions per week. + + :rtype: float + """ + return self._conversions + + @property + def cpa(self): + """ The estimated cost per conversion. + The formula for calculating the cost per conversion is (spend / conversions). + + :rtype: float + """ + return self._cpa + + def read_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkKeywordFirstPageBid._MAPPINGS) + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Keyword, + field_to_csv=lambda c: bulk_str(c.keyword_text), + csv_to_field=lambda c, v: setattr(c, '_keyword_text', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Bid, + field_to_csv=lambda c: bulk_str(c.bid), + csv_to_field=lambda c, v: setattr(c, '_bid', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Spend, + field_to_csv=lambda c: bulk_str(c.spend), + csv_to_field=lambda c, v: setattr(c, '_spend', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Impressions, + field_to_csv=lambda c: bulk_str(c.impressions), + csv_to_field=lambda c, v: setattr(c, '_impressions', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Clicks, + field_to_csv=lambda c: bulk_str(c.clicks), + csv_to_field=lambda c, v: setattr(c, '_clicks', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CTR, + field_to_csv=lambda c: bulk_str(c.ctr), + csv_to_field=lambda c, v: setattr(c, '_ctr', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgCPC, + field_to_csv=lambda c: bulk_str(c.avgcpc), + csv_to_field=lambda c, v: setattr(c, '_avgcpc', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgCPM, + field_to_csv=lambda c: bulk_str(c.avgcpm), + csv_to_field=lambda c, v: setattr(c, '_avgcpm', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgPosition, + field_to_csv=lambda c: bulk_str(c.avgposition), + csv_to_field=lambda c, v: setattr(c, '_avgposition', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Conversions, + field_to_csv=lambda c: bulk_str(c.conversions), + csv_to_field=lambda c, v: setattr(c, '_conversions', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CPA, + field_to_csv=lambda c: bulk_str(c.cpa), + csv_to_field=lambda c, v: setattr(c, '_cpa', float(v) if v else None) + ), + + ] + def read_related_data_from_stream(self, stream_reader): return super(BulkKeywordFirstPageBid, self).read_related_data_from_stream(stream_reader) @@ -171,6 +511,176 @@ def enclose_in_multiline_entity(self): class BulkKeywordMainLineBid(BulkKeywordBidSuggestion): + def __init__(self): + super().__init__() + self._spend = None + self._impressions = None + self._clicks = None + self._ctr = None + self._avgcpc = None + self._avgcpm = None + self._avgposition = None + self._conversions = None + self._cpa = None + + @property + def keyword_text(self): + """ The keyword corresponding to the suggested bid. + + Corresponds to the 'Keyword' field in the bulk file. + :rtype: str + """ + + return self._keyword_text + + @property + def bid(self): + """ The suggested bid value for main line positioning in search results. + + :rtype: float + """ + + return self._bid + + @property + def spend(self): + """ The estimated average cost per week. + + :rtype: float + """ + return self._spend + + @property + def impressions(self): + """ The estimated average number of impressions per week. + + :rtype: int + """ + return self._impressions + + @property + def clicks(self): + """ The estimated average number of clicks per week. + + :rtype: int + """ + return self._clicks + + @property + def ctr(self): + """ The estimated CTR. + The formula used to calculate the CTR is (maximum number of clicks / maximum number of impressions) * 100. + + :rtype: float + """ + return self._ctr + + @property + def avgcpc(self): + """ The estimated average CPC. + The formula used to calculate the average CPC is (maximum total cost / maximum number of clicks). + + :rtype: float + """ + return self._avgcpc + + @property + def avgcpm(self): + """ The average of the cost per thousand impressions (CPM) of the ad. + The value will be 0 (zero) if the ad group to which the ad belongs does not specify the + Content ad distribution medium or if the user does not belong to the CPM pilot program. + + :rtype: float + """ + return self._avgcpm + + @property + def avgposition(self): + """ The position in the search results given the specified bid. + + :rtype: float + """ + return self._avgposition + + @property + def conversions(self): + """ The estimated number of conversions per week. + + :rtype: float + """ + return self._conversions + + @property + def cpa(self): + """ The estimated cost per conversion. + The formula for calculating the cost per conversion is (spend / conversions). + + :rtype: float + """ + return self._cpa + + def read_from_row_values(self, row_values): + row_values.convert_to_entity(self, BulkKeywordMainLineBid._MAPPINGS) + + _MAPPINGS = [ + _SimpleBulkMapping( + header=_StringTable.Keyword, + field_to_csv=lambda c: bulk_str(c.keyword_text), + csv_to_field=lambda c, v: setattr(c, '_keyword_text', v if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Bid, + field_to_csv=lambda c: bulk_str(c.bid), + csv_to_field=lambda c, v: setattr(c, '_bid', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Spend, + field_to_csv=lambda c: bulk_str(c.spend), + csv_to_field=lambda c, v: setattr(c, '_spend', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Impressions, + field_to_csv=lambda c: bulk_str(c.impressions), + csv_to_field=lambda c, v: setattr(c, '_impressions', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Clicks, + field_to_csv=lambda c: bulk_str(c.clicks), + csv_to_field=lambda c, v: setattr(c, '_clicks', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CTR, + field_to_csv=lambda c: bulk_str(c.ctr), + csv_to_field=lambda c, v: setattr(c, '_ctr', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgCPC, + field_to_csv=lambda c: bulk_str(c.avgcpc), + csv_to_field=lambda c, v: setattr(c, '_avgcpc', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgCPM, + field_to_csv=lambda c: bulk_str(c.avgcpm), + csv_to_field=lambda c, v: setattr(c, '_avgcpm', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.AvgPosition, + field_to_csv=lambda c: bulk_str(c.avgposition), + csv_to_field=lambda c, v: setattr(c, '_avgposition', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.Conversions, + field_to_csv=lambda c: bulk_str(c.conversions), + csv_to_field=lambda c, v: setattr(c, '_conversions', float(v) if v else None) + ), + _SimpleBulkMapping( + header=_StringTable.CPA, + field_to_csv=lambda c: bulk_str(c.cpa), + csv_to_field=lambda c, v: setattr(c, '_cpa', float(v) if v else None) + ), + + ] + def read_related_data_from_stream(self, stream_reader): return super(BulkKeywordMainLineBid, self).read_related_data_from_stream(stream_reader) From b8fc58b7a46b159a7d27380df2a5fd0de6e8acdf Mon Sep 17 00:00:00 2001 From: MrOllzzor Date: Mon, 9 Oct 2023 10:05:23 +0200 Subject: [PATCH 6/6] Added support for all fields in BulkKeywordBestPositionBid, BulkKeywordFirstPageBid and BulkKeywordMainLineBid. --- .../v13/bulk/entities/bid_suggestion_data.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bingads/v13/bulk/entities/bid_suggestion_data.py b/bingads/v13/bulk/entities/bid_suggestion_data.py index 7e04f499..a4f485dd 100644 --- a/bingads/v13/bulk/entities/bid_suggestion_data.py +++ b/bingads/v13/bulk/entities/bid_suggestion_data.py @@ -271,12 +271,12 @@ def read_from_row_values(self, row_values): _SimpleBulkMapping( header=_StringTable.Impressions, field_to_csv=lambda c: bulk_str(c.impressions), - csv_to_field=lambda c, v: setattr(c, '_impressions', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_impressions', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.Clicks, field_to_csv=lambda c: bulk_str(c.clicks), - csv_to_field=lambda c, v: setattr(c, '_clicks', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_clicks', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.CTR, @@ -301,7 +301,7 @@ def read_from_row_values(self, row_values): _SimpleBulkMapping( header=_StringTable.Conversions, field_to_csv=lambda c: bulk_str(c.conversions), - csv_to_field=lambda c, v: setattr(c, '_conversions', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_conversions', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.CPA, @@ -456,12 +456,12 @@ def read_from_row_values(self, row_values): _SimpleBulkMapping( header=_StringTable.Impressions, field_to_csv=lambda c: bulk_str(c.impressions), - csv_to_field=lambda c, v: setattr(c, '_impressions', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_impressions', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.Clicks, field_to_csv=lambda c: bulk_str(c.clicks), - csv_to_field=lambda c, v: setattr(c, '_clicks', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_clicks', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.CTR, @@ -486,7 +486,7 @@ def read_from_row_values(self, row_values): _SimpleBulkMapping( header=_StringTable.Conversions, field_to_csv=lambda c: bulk_str(c.conversions), - csv_to_field=lambda c, v: setattr(c, '_conversions', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_conversions', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.CPA, @@ -641,12 +641,12 @@ def read_from_row_values(self, row_values): _SimpleBulkMapping( header=_StringTable.Impressions, field_to_csv=lambda c: bulk_str(c.impressions), - csv_to_field=lambda c, v: setattr(c, '_impressions', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_impressions', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.Clicks, field_to_csv=lambda c: bulk_str(c.clicks), - csv_to_field=lambda c, v: setattr(c, '_clicks', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_clicks', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.CTR, @@ -671,7 +671,7 @@ def read_from_row_values(self, row_values): _SimpleBulkMapping( header=_StringTable.Conversions, field_to_csv=lambda c: bulk_str(c.conversions), - csv_to_field=lambda c, v: setattr(c, '_conversions', float(v) if v else None) + csv_to_field=lambda c, v: setattr(c, '_conversions', int(v) if v else None) ), _SimpleBulkMapping( header=_StringTable.CPA,