✨ Source Bing Ads: Stream budget and product dimension performance report (#35201)
This commit is contained in:
@@ -25,6 +25,14 @@ acceptance_tests:
|
||||
expect_records:
|
||||
path: "integration_tests/expected_records.jsonl"
|
||||
empty_streams:
|
||||
- name: product_dimension_performance_report_hourly
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: product_dimension_performance_report_daily
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: product_dimension_performance_report_weekly
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: product_dimension_performance_report_monthly
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: account_performance_report_hourly
|
||||
bypass_reason: "Hourly reports are disabled, because sync is too long"
|
||||
- name: ad_group_performance_report_hourly
|
||||
@@ -94,6 +102,14 @@ acceptance_tests:
|
||||
expect_records:
|
||||
path: "integration_tests/expected_records_no_start_date.jsonl"
|
||||
empty_streams:
|
||||
- name: product_dimension_performance_report_hourly
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: product_dimension_performance_report_daily
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: product_dimension_performance_report_weekly
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: product_dimension_performance_report_monthly
|
||||
bypass_reason: "Test Account doesn't have Merchant Center configured to add Products, testing in integration test"
|
||||
- name: app_install_ads
|
||||
bypass_reason: "Can not populate; new campaign with link to app needed; feature is not available yet"
|
||||
- name: app_install_ad_labels
|
||||
|
||||
@@ -18,6 +18,16 @@
|
||||
"sync_mode": "full_refresh",
|
||||
"destination_sync_mode": "append"
|
||||
},
|
||||
{
|
||||
"stream": {
|
||||
"name": "budget",
|
||||
"json_schema": {},
|
||||
"supported_sync_modes": ["full_refresh", "incremental"]
|
||||
},
|
||||
"sync_mode": "incremental",
|
||||
"cursor_field": ["Modified Time"],
|
||||
"destination_sync_mode": "append"
|
||||
},
|
||||
{
|
||||
"stream": {
|
||||
"name": "campaigns",
|
||||
@@ -585,6 +595,46 @@
|
||||
"sync_mode": "incremental",
|
||||
"cursor_field": ["TimePeriod"],
|
||||
"destination_sync_mode": "append"
|
||||
},
|
||||
{
|
||||
"stream": {
|
||||
"name": "product_dimension_performance_report_hourly",
|
||||
"json_schema": {},
|
||||
"supported_sync_modes": ["incremental", "full_refresh"]
|
||||
},
|
||||
"sync_mode": "incremental",
|
||||
"cursor_field": ["TimePeriod"],
|
||||
"destination_sync_mode": "append"
|
||||
},
|
||||
{
|
||||
"stream": {
|
||||
"name": "product_dimension_performance_report_daily",
|
||||
"json_schema": {},
|
||||
"supported_sync_modes": ["incremental", "full_refresh"]
|
||||
},
|
||||
"sync_mode": "incremental",
|
||||
"cursor_field": ["TimePeriod"],
|
||||
"destination_sync_mode": "append"
|
||||
},
|
||||
{
|
||||
"stream": {
|
||||
"name": "product_dimension_performance_report_weekly",
|
||||
"json_schema": {},
|
||||
"supported_sync_modes": ["incremental", "full_refresh"]
|
||||
},
|
||||
"sync_mode": "incremental",
|
||||
"cursor_field": ["TimePeriod"],
|
||||
"destination_sync_mode": "append"
|
||||
},
|
||||
{
|
||||
"stream": {
|
||||
"name": "product_dimension_performance_report_monthly",
|
||||
"json_schema": {},
|
||||
"supported_sync_modes": ["incremental", "full_refresh"]
|
||||
},
|
||||
"sync_mode": "incremental",
|
||||
"cursor_field": ["TimePeriod"],
|
||||
"destination_sync_mode": "append"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -27,3 +27,4 @@
|
||||
{"stream":"user_location_performance_report_weekly","data":{"AccountName":"Airbyte","AccountNumber":"F149MJ18","AccountId":180519267,"TimePeriod":"2023-12-17","CampaignName":"Airbyte test","CampaignId":531016227,"AdGroupName":"keywords","AdGroupId":1356799861840328,"Country":"United Arab Emirates","State":"Dubai","MetroArea":null,"CurrencyCode":"USD","AdDistribution":"Audience","Impressions":1,"Clicks":0,"Ctr":0.0,"AverageCpc":0.0,"Spend":0.0,"AveragePosition":0.0,"ProximityTargetLocation":null,"Radius":0,"Language":"English","City":"Dubai","QueryIntentCountry":"United Arab Emirates","QueryIntentState":null,"QueryIntentCity":null,"QueryIntentDMA":null,"BidMatchType":"Broad","DeliveredMatchType":"Exact","Network":"Audience","TopVsOther":"Audience network","DeviceType":"Smartphone","DeviceOS":"Android","Assists":0,"Conversions":0,"ConversionRate":null,"Revenue":0.0,"ReturnOnAdSpend":null,"CostPerConversion":null,"CostPerAssist":null,"RevenuePerConversion":null,"RevenuePerAssist":null,"County":null,"PostalCode":null,"QueryIntentCounty":null,"QueryIntentPostalCode":null,"LocationId":154645,"QueryIntentLocationId":218,"AllConversions":0,"AllRevenue":0.0,"AllConversionRate":null,"AllCostPerConversion":null,"AllReturnOnAdSpend":null,"AllRevenuePerConversion":null,"ViewThroughConversions":0,"Goal":null,"GoalType":null,"AbsoluteTopImpressionRatePercent":0.0,"TopImpressionRatePercent":0.0,"AverageCpm":0.0,"ConversionsQualified":0.0,"AllConversionsQualified":0.0,"ViewThroughConversionsQualified":null,"Neighborhood":null,"QueryIntentNeighborhood":null,"ViewThroughRevenue":0.0,"CampaignType":"Search & content","AssetGroupId":null,"AssetGroupName":null},"emitted_at":1704833830043}
|
||||
{"stream":"account_impression_performance_report_daily","data":{"AccountName":"Airbyte","AccountNumber":"F149MJ18","AccountId":180519267,"TimePeriod":"2023-12-18","CurrencyCode":"USD","AdDistribution":"Search","Impressions":22,"Clicks":0,"Ctr":0.0,"AverageCpc":0.0,"Spend":0.0,"AveragePosition":0.0,"Conversions":0,"ConversionRate":null,"CostPerConversion":null,"LowQualityClicks":0,"LowQualityClicksPercent":null,"LowQualityImpressions":6,"LowQualityImpressionsPercent":21.43,"LowQualityConversions":0,"LowQualityConversionRate":null,"DeviceType":"Computer","ImpressionSharePercent":34.92,"ImpressionLostToBudgetPercent":1.59,"ImpressionLostToRankAggPercent":63.49,"PhoneImpressions":0,"PhoneCalls":0,"Ptr":null,"Network":"Syndicated search partners","Assists":0,"Revenue":0.0,"ReturnOnAdSpend":null,"CostPerAssist":null,"RevenuePerConversion":null,"RevenuePerAssist":null,"AccountStatus":"Active","LowQualityGeneralClicks":0,"LowQualitySophisticatedClicks":0,"ExactMatchImpressionSharePercent":5.26,"ClickSharePercent":null,"AbsoluteTopImpressionSharePercent":10.2,"TopImpressionShareLostToRankPercent":68.0,"TopImpressionShareLostToBudgetPercent":0.0,"AbsoluteTopImpressionShareLostToRankPercent":89.8,"AbsoluteTopImpressionShareLostToBudgetPercent":0.0,"TopImpressionSharePercent":32.0,"AbsoluteTopImpressionRatePercent":22.73,"TopImpressionRatePercent":72.73,"AllConversions":0,"AllRevenue":0.0,"AllConversionRate":null,"AllCostPerConversion":null,"AllReturnOnAdSpend":null,"AllRevenuePerConversion":null,"ViewThroughConversions":0,"AudienceImpressionSharePercent":null,"AudienceImpressionLostToRankPercent":null,"AudienceImpressionLostToBudgetPercent":null,"AverageCpm":0.0,"ConversionsQualified":0.0,"LowQualityConversionsQualified":0.0,"AllConversionsQualified":0.0,"ViewThroughConversionsQualified":null,"ViewThroughRevenue":0.0,"VideoViews":0,"ViewThroughRate":0.0,"AverageCPV":null,"VideoViewsAt25Percent":0,"VideoViewsAt50Percent":0,"VideoViewsAt75Percent":0,"CompletedVideoViews":0,"VideoCompletionRate":0.0,"TotalWatchTimeInMS":0,"AverageWatchTimePerVideoView":null,"AverageWatchTimePerImpression":0.0,"Sales":0,"CostPerSale":null,"RevenuePerSale":null,"Installs":0,"CostPerInstall":null,"RevenuePerInstall":null},"emitted_at":1704833886551}
|
||||
{"stream":"account_impression_performance_report_weekly","data":{"AccountName":"Airbyte","AccountNumber":"F149MJ18","AccountId":180519267,"TimePeriod":"2023-12-17","CurrencyCode":"USD","AdDistribution":"Search","Impressions":639,"Clicks":14,"Ctr":2.19,"AverageCpc":0.12,"Spend":1.74,"AveragePosition":0.0,"Conversions":0,"ConversionRate":0.0,"CostPerConversion":null,"LowQualityClicks":6,"LowQualityClicksPercent":30.0,"LowQualityImpressions":53,"LowQualityImpressionsPercent":7.66,"LowQualityConversions":0,"LowQualityConversionRate":0.0,"DeviceType":"Computer","ImpressionSharePercent":13.57,"ImpressionLostToBudgetPercent":17.96,"ImpressionLostToRankAggPercent":68.47,"PhoneImpressions":0,"PhoneCalls":0,"Ptr":null,"Network":"Syndicated search partners","Assists":0,"Revenue":0.0,"ReturnOnAdSpend":0.0,"CostPerAssist":null,"RevenuePerConversion":null,"RevenuePerAssist":null,"AccountStatus":"Active","LowQualityGeneralClicks":0,"LowQualitySophisticatedClicks":6,"ExactMatchImpressionSharePercent":17.65,"ClickSharePercent":1.28,"AbsoluteTopImpressionSharePercent":3.2,"TopImpressionShareLostToRankPercent":74.15,"TopImpressionShareLostToBudgetPercent":18.25,"AbsoluteTopImpressionShareLostToRankPercent":78.51,"AbsoluteTopImpressionShareLostToBudgetPercent":18.29,"TopImpressionSharePercent":7.6,"AbsoluteTopImpressionRatePercent":22.69,"TopImpressionRatePercent":53.99,"AllConversions":0,"AllRevenue":0.0,"AllConversionRate":0.0,"AllCostPerConversion":null,"AllReturnOnAdSpend":0.0,"AllRevenuePerConversion":null,"ViewThroughConversions":0,"AudienceImpressionSharePercent":null,"AudienceImpressionLostToRankPercent":null,"AudienceImpressionLostToBudgetPercent":null,"AverageCpm":2.72,"ConversionsQualified":0.0,"LowQualityConversionsQualified":0.0,"AllConversionsQualified":0.0,"ViewThroughConversionsQualified":null,"ViewThroughRevenue":0.0,"VideoViews":0,"ViewThroughRate":0.0,"AverageCPV":null,"VideoViewsAt25Percent":0,"VideoViewsAt50Percent":0,"VideoViewsAt75Percent":0,"CompletedVideoViews":0,"VideoCompletionRate":0.0,"TotalWatchTimeInMS":0,"AverageWatchTimePerVideoView":null,"AverageWatchTimePerImpression":0.0,"Sales":0,"CostPerSale":null,"RevenuePerSale":null,"Installs":0,"CostPerInstall":null,"RevenuePerInstall":null},"emitted_at":1704833908003}
|
||||
{"stream": "budget", "data": {"Type": "Budget", "Status": "Active", "Id": 10239202868095, "Parent Id": 180519267, "Client Id": null, "Modified Time": "2024-02-28T17:52:08.900+00:00", "Budget Id": null, "Budget Name": "Test Shared Budget", "Budget": 2.0, "Budget Type": "DailyBudgetStandard", "Account Id": 180519267}, "emitted_at": 1709228203331}
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
{"stream": "ad_group_labels", "data": {"Status": "Active", "Id": 10239203506495, "Parent Id": 1350201453189474, "Campaign": null, "Ad Group": null, "Client Id": null, "Modified Time": "2023-04-27T18:00:14.970+00:00", "Account Id": 180278106}, "emitted_at": 1701982478843}
|
||||
{"stream": "labels", "data": {"Status": "Active", "Id": 10239203506496, "Client Id": null, "Modified Time": "2023-04-27T17:16:53.430+00:00", "Description": null, "Label": "campaign label 2", "Color": "#D8558B", "Account Id": 180278106}, "emitted_at": 1701982532098}
|
||||
{"stream": "campaign_labels", "data": {"Status": "Active", "Id": 10239203506495, "Parent Id": 413732450, "Campaign": null, "Client Id": null, "Modified Time": "2023-04-27T17:57:21.497+00:00", "Account Id": 180278106}, "emitted_at": 1701982600348}
|
||||
{"stream": "budget", "data": {"Type": "Budget", "Status": "Active", "Id": 10239202868095, "Parent Id": 180519267, "Client Id": null, "Modified Time": "2024-02-28T17:52:08.900+00:00", "Budget Id": null, "Budget Name": "Test Shared Budget", "Budget": 2.0, "Budget Type": "DailyBudgetStandard", "Account Id": 180519267}, "emitted_at": 1709228203331}
|
||||
|
||||
@@ -16,7 +16,7 @@ data:
|
||||
connectorSubtype: api
|
||||
connectorType: source
|
||||
definitionId: 47f25999-dd5e-4636-8c39-e7cea2453331
|
||||
dockerImageTag: 2.1.4
|
||||
dockerImageTag: 2.2.0
|
||||
dockerRepository: airbyte/source-bing-ads
|
||||
documentationUrl: https://docs.airbyte.com/integrations/sources/bing-ads
|
||||
githubIssueLabel: source-bing-ads
|
||||
|
||||
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.poetry]
|
||||
version = "2.1.4"
|
||||
version = "2.2.0"
|
||||
name = "source-bing-ads"
|
||||
description = "Source implementation for Bing Ads."
|
||||
authors = [ "Airbyte <contact@airbyte.io>",]
|
||||
|
||||
@@ -196,3 +196,12 @@ class AdGroupLabels(BingAdsBulkStream):
|
||||
|
||||
data_scope = ["EntityData"]
|
||||
download_entities = ["AdGroupLabels"]
|
||||
|
||||
|
||||
class Budget(BingAdsBulkStream):
|
||||
"""
|
||||
https://learn.microsoft.com/en-us/advertising/bulk-service/budget?view=bingads-13&viewFallbackFrom=bingads-13
|
||||
"""
|
||||
|
||||
data_scope = ["EntityData"]
|
||||
download_entities = ["Budgets"]
|
||||
|
||||
@@ -670,6 +670,45 @@ class UserLocationPerformanceReportMonthly(UserLocationPerformanceReport):
|
||||
report_aggregation = "Monthly"
|
||||
|
||||
|
||||
class ProductDimensionPerformanceReport(BingAdsReportingServicePerformanceStream, ABC):
|
||||
"""
|
||||
https://learn.microsoft.com/en-us/advertising/reporting-service/productdimensionperformancereportrequest?view=bingads-13
|
||||
"""
|
||||
|
||||
report_name: str = "ProductDimensionPerformanceReport"
|
||||
report_schema_name = "product_dimension_performance_report"
|
||||
primary_key = None
|
||||
|
||||
@property
|
||||
def report_columns(self) -> Iterable[str]:
|
||||
"""AccountId is not in reporting columns for this report"""
|
||||
properties = list(self.get_json_schema().get("properties", {}).keys())
|
||||
properties.remove("AccountId")
|
||||
return properties
|
||||
|
||||
def transform(self, record: MutableMapping[str, Any], stream_slice: Mapping[str, Any], **kwargs) -> MutableMapping[str, Any]:
|
||||
record = super().transform(record, stream_slice)
|
||||
record["AccountId"] = stream_slice["account_id"]
|
||||
return record
|
||||
|
||||
|
||||
class ProductDimensionPerformanceReportHourly(HourlyReportTransformerMixin, ProductDimensionPerformanceReport):
|
||||
report_aggregation = "Hourly"
|
||||
report_schema_name = "product_dimension_performance_report_hourly"
|
||||
|
||||
|
||||
class ProductDimensionPerformanceReportDaily(ProductDimensionPerformanceReport):
|
||||
report_aggregation = "Daily"
|
||||
|
||||
|
||||
class ProductDimensionPerformanceReportWeekly(ProductDimensionPerformanceReport):
|
||||
report_aggregation = "Weekly"
|
||||
|
||||
|
||||
class ProductDimensionPerformanceReportMonthly(ProductDimensionPerformanceReport):
|
||||
report_aggregation = "Monthly"
|
||||
|
||||
|
||||
class CustomReport(BingAdsReportingServicePerformanceStream, ABC):
|
||||
transformer: TypeTransformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization)
|
||||
custom_report_columns = []
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Account Id": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Type": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Status": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Id": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Parent Id": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Client Id": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Modified Time": {
|
||||
"type": ["null", "string"],
|
||||
"format": "date-time",
|
||||
"airbyte_type": "timestamp_with_timezone"
|
||||
},
|
||||
"Budget Id": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Budget Name": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Budget": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Budget Type": {
|
||||
"type": ["null", "string"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"AccountId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"TimePeriod": {
|
||||
"type": ["null", "string"],
|
||||
"format": "date"
|
||||
},
|
||||
"AccountName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AccountNumber": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdGroupName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdGroupId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CampaignStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AccountStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdGroupStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Network": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CampaignId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CampaignName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CurrencyCode": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"DeviceType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Language": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"MerchantProductId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Title": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Condition": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Brand": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Price": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Impressions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Clicks": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Ctr": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AverageCpc": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Spend": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Conversions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"ConversionRate": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Revenue": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"RevenuePerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"SellerName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"OfferLanguage": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CountryOfSale": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdDistribution": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ClickTypeId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"TotalClicksOnAdElements": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ClickType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ReturnOnAdSpend": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"BidStrategyType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"LocalStoreCode": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"StoreId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssistedClicks": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssistedConversions": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AllConversions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"AllRevenue": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllConversionRate": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllCostPerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllReturnOnAdSpend": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllRevenuePerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"CostPerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ViewThroughConversions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Goal": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"GoalType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductBought": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"QuantityBought": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AverageCpm": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ConversionsQualified": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AssistedConversionsQualified": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ViewThroughConversionsQualified": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ProductBoughtTitle": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"GTIN": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"MPN": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ViewThroughRevenue": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Sales": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CostPerSale": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"RevenuePerSale": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Installs": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CostPerInstall": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"RevenuePerInstall": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"CampaignType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssetGroupId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssetGroupName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssetGroupStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel0": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel1": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel2": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel3": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel4": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType1": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType2": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType3": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType4": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType5": {
|
||||
"type": ["null", "string"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"AccountId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"TimePeriod": {
|
||||
"type": ["null", "string"],
|
||||
"format": "date-time",
|
||||
"airbyte_type": "timestamp_with_timezone"
|
||||
},
|
||||
"AccountName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AccountNumber": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdGroupName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdGroupId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CampaignStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AccountStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdGroupStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Network": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CampaignId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CampaignName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CurrencyCode": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"DeviceType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Language": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"MerchantProductId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Title": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Condition": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Brand": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"Price": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Impressions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Clicks": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Ctr": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AverageCpc": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Spend": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Conversions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"ConversionRate": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Revenue": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"RevenuePerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"SellerName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"OfferLanguage": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CountryOfSale": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AdDistribution": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ClickTypeId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"TotalClicksOnAdElements": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ClickType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ReturnOnAdSpend": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"BidStrategyType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"LocalStoreCode": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"StoreId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssistedClicks": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssistedConversions": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AllConversions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"AllRevenue": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllConversionRate": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllCostPerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllReturnOnAdSpend": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AllRevenuePerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"CostPerConversion": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ViewThroughConversions": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"Goal": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"GoalType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductBought": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"QuantityBought": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AverageCpm": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ConversionsQualified": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"AssistedConversionsQualified": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ViewThroughConversionsQualified": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"ProductBoughtTitle": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"GTIN": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"MPN": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ViewThroughRevenue": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Sales": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CostPerSale": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"RevenuePerSale": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"Installs": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"CostPerInstall": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"RevenuePerInstall": {
|
||||
"type": ["null", "number"]
|
||||
},
|
||||
"CampaignType": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssetGroupId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssetGroupName": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"AssetGroupStatus": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel0": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel1": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel2": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel3": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"CustomLabel4": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType1": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType2": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType3": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType4": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"ProductType5": {
|
||||
"type": ["null", "string"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,16 @@ from airbyte_cdk.sources import AbstractSource
|
||||
from airbyte_cdk.sources.streams import Stream
|
||||
from airbyte_cdk.utils import AirbyteTracedException
|
||||
from source_bing_ads.base_streams import Accounts, AdGroups, Ads, Campaigns
|
||||
from source_bing_ads.bulk_streams import AdGroupLabels, AppInstallAdLabels, AppInstallAds, CampaignLabels, KeywordLabels, Keywords, Labels
|
||||
from source_bing_ads.bulk_streams import (
|
||||
AdGroupLabels,
|
||||
AppInstallAdLabels,
|
||||
AppInstallAds,
|
||||
Budget,
|
||||
CampaignLabels,
|
||||
KeywordLabels,
|
||||
Keywords,
|
||||
Labels,
|
||||
)
|
||||
from source_bing_ads.client import Client
|
||||
from source_bing_ads.report_streams import ( # noqa: F401
|
||||
AccountImpressionPerformanceReportDaily,
|
||||
@@ -56,6 +65,10 @@ from source_bing_ads.report_streams import ( # noqa: F401
|
||||
KeywordPerformanceReportHourly,
|
||||
KeywordPerformanceReportMonthly,
|
||||
KeywordPerformanceReportWeekly,
|
||||
ProductDimensionPerformanceReportDaily,
|
||||
ProductDimensionPerformanceReportHourly,
|
||||
ProductDimensionPerformanceReportMonthly,
|
||||
ProductDimensionPerformanceReportWeekly,
|
||||
SearchQueryPerformanceReportDaily,
|
||||
SearchQueryPerformanceReportHourly,
|
||||
SearchQueryPerformanceReportMonthly,
|
||||
@@ -131,6 +144,7 @@ class SourceBingAds(AbstractSource):
|
||||
AppInstallAds(client, config),
|
||||
AppInstallAdLabels(client, config),
|
||||
Ads(client, config),
|
||||
Budget(client, config),
|
||||
Campaigns(client, config),
|
||||
BudgetSummaryReport(client, config),
|
||||
Labels(client, config),
|
||||
@@ -150,6 +164,7 @@ class SourceBingAds(AbstractSource):
|
||||
"CampaignPerformanceReport",
|
||||
"CampaignImpressionPerformanceReport",
|
||||
"GeographicPerformanceReport",
|
||||
"ProductDimensionPerformanceReport",
|
||||
"SearchQueryPerformanceReport",
|
||||
"UserLocationPerformanceReport",
|
||||
)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional, Tuple, Union
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from airbyte_cdk.models import SyncMode
|
||||
from airbyte_cdk.test.catalog_builder import CatalogBuilder
|
||||
from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read
|
||||
from airbyte_cdk.test.mock_http import HttpMocker
|
||||
from airbyte_cdk.test.state_builder import StateBuilder
|
||||
from airbyte_protocol.models import AirbyteStateMessage
|
||||
from bingads.v13.bulk import BulkServiceManager
|
||||
from bingads.v13.reporting.reporting_service_manager import ReportingServiceManager
|
||||
from client_builder import build_request, response_with_status
|
||||
from config_builder import ConfigBuilder
|
||||
from source_bing_ads.source import SourceBingAds
|
||||
from suds.transport.https import HttpAuthenticated
|
||||
from suds_response_mock import mock_http_authenticated_send
|
||||
|
||||
|
||||
class BaseTest(TestCase):
|
||||
|
||||
@property
|
||||
def service_manager(self) -> Union[ReportingServiceManager, BulkServiceManager]:
|
||||
pass
|
||||
|
||||
def _download_file(self, file: Optional[str] = None) -> Path:
|
||||
pass
|
||||
|
||||
@property
|
||||
def _config(self) -> dict[str, Any]:
|
||||
return ConfigBuilder().build()
|
||||
|
||||
def _state(self, file: str, stream_name: str) -> list[AirbyteStateMessage]:
|
||||
state_file = Path(__file__).parent.parent / f"resource/state/{file}.json"
|
||||
with open(state_file, "r") as f:
|
||||
state = json.loads(f.read())
|
||||
return StateBuilder().with_stream_state(stream_name, state).build()
|
||||
|
||||
def auth_client(self, http_mocker: HttpMocker) -> None:
|
||||
http_mocker.post(
|
||||
request=build_request(self._config),
|
||||
responses=response_with_status("oauth", 200)
|
||||
)
|
||||
|
||||
def read_stream(
|
||||
self,
|
||||
stream_name: str,
|
||||
sync_mode: SyncMode,
|
||||
config: Dict[str, Any],
|
||||
stream_data_file: str = None,
|
||||
state: Optional[Dict[str, Any]] = None,
|
||||
expecting_exception: bool = False,
|
||||
) -> Tuple[EntrypointOutput, MagicMock]:
|
||||
with patch.object(HttpAuthenticated, "send", mock_http_authenticated_send):
|
||||
with patch.object(self.service_manager, "download_file", return_value=self._download_file(stream_data_file)) as service_call_mock:
|
||||
catalog = CatalogBuilder().with_stream(stream_name, sync_mode).build()
|
||||
return read(SourceBingAds(), config, catalog, state, expecting_exception), service_call_mock
|
||||
@@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
|
||||
from airbyte_cdk.test.mock_http import HttpRequest, HttpResponse
|
||||
from airbyte_cdk.test.mock_http.response_builder import find_template
|
||||
|
||||
|
||||
def response_with_status(resource: str, status_code: int) -> HttpResponse:
|
||||
return HttpResponse(json.dumps(find_template(resource, __file__)), status_code)
|
||||
|
||||
|
||||
def build_request(config: Dict[str, Any]) -> HttpRequest:
|
||||
body = (
|
||||
f"client_id={config['client_id']}"
|
||||
f"&client_secret={config['client_secret']}"
|
||||
"&grant_type=refresh_token"
|
||||
f"&refresh_token={config['refresh_token']}"
|
||||
"&environment=production&scope=https%3A%2F%2Fads.microsoft.com%2Fmsads.manage+offline_access&oauth_scope=msads.manage"
|
||||
f"&tenant={config['tenant_id']}"
|
||||
)
|
||||
|
||||
return HttpRequest(
|
||||
url="https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
||||
query_params={},
|
||||
body=body,
|
||||
headers={
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,44 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
|
||||
import datetime
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from airbyte_cdk.test.mock_http.response_builder import find_template
|
||||
|
||||
TENNANT_ID = "common"
|
||||
DEVELOPER_TOKEN = "test-token"
|
||||
REFRESH_TOKEN = "test-refresh-token"
|
||||
CLIENT_ID = "test-client-id"
|
||||
CLIENT_SECRET = "test-client-secret"
|
||||
LOOKBACK_WINDOW = 0
|
||||
|
||||
|
||||
class ConfigBuilder:
|
||||
def __init__(self) -> None:
|
||||
oauth_fixture: Dict[str, Any] = find_template("oauth", __file__)
|
||||
self._access_token: str = oauth_fixture["access_token"]
|
||||
self._refresh_token: str = oauth_fixture["refresh_token"]
|
||||
self._client_id: str = CLIENT_ID
|
||||
self._client_secret: str = CLIENT_SECRET
|
||||
self._refresh_token: str = REFRESH_TOKEN
|
||||
self._developer_token: str = DEVELOPER_TOKEN
|
||||
self._tenant_id: str = TENNANT_ID
|
||||
self._report_start_date: str = None
|
||||
self._lookback_window: int = LOOKBACK_WINDOW
|
||||
|
||||
def with_reports_start_date(self, start_date: str) -> "ConfigBuilder":
|
||||
self._report_start_date = start_date
|
||||
return self
|
||||
|
||||
def build(self) -> Dict[str, Any]:
|
||||
config = {
|
||||
"tenant_id": self._tenant_id,
|
||||
"developer_token": self._developer_token,
|
||||
"refresh_token": self._refresh_token,
|
||||
"client_id": self._client_id,
|
||||
"client_secret": self._client_secret,
|
||||
"lookback_window": self._lookback_window,
|
||||
}
|
||||
if self._report_start_date:
|
||||
config["reports_start_date"] = self._report_start_date
|
||||
return config
|
||||
@@ -0,0 +1,146 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
|
||||
from suds.transport import Reply, Request
|
||||
from suds.transport.https import HttpAuthenticated
|
||||
|
||||
SEARCH_ACCOUNTS_RESPONSE = b"""<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<s:Header>
|
||||
<h:TrackingId xmlns:h="https://bingads.microsoft.com/Customer/v13">6f0a329e-4cb4-4c79-9c08-2dfe601ba05a
|
||||
</h:TrackingId>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<SearchAccountsResponse xmlns="https://bingads.microsoft.com/Customer/v13">
|
||||
<Accounts xmlns:a="https://bingads.microsoft.com/Customer/v13/Entities"
|
||||
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<a:AdvertiserAccount>
|
||||
<a:BillToCustomerId>251186883</a:BillToCustomerId>
|
||||
<a:CurrencyCode>USD</a:CurrencyCode>
|
||||
<a:AccountFinancialStatus>ClearFinancialStatus</a:AccountFinancialStatus>
|
||||
<a:Id>180535609</a:Id>
|
||||
<a:Language>English</a:Language>
|
||||
<a:LastModifiedByUserId>0</a:LastModifiedByUserId>
|
||||
<a:LastModifiedTime>2023-08-11T08:24:26.603</a:LastModifiedTime>
|
||||
<a:Name>DEMO-ACCOUNT</a:Name>
|
||||
<a:Number>F149W3B6</a:Number>
|
||||
<a:ParentCustomerId>251186883</a:ParentCustomerId>
|
||||
<a:PaymentMethodId i:nil="true"/>
|
||||
<a:PaymentMethodType i:nil="true"/>
|
||||
<a:PrimaryUserId>138225488</a:PrimaryUserId>
|
||||
<a:AccountLifeCycleStatus>Pause</a:AccountLifeCycleStatus>
|
||||
<a:TimeStamp>AAAAAH10c1A=</a:TimeStamp>
|
||||
<a:TimeZone>Santiago</a:TimeZone>
|
||||
<a:PauseReason>2</a:PauseReason>
|
||||
<a:ForwardCompatibilityMap i:nil="true"
|
||||
xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
|
||||
<a:LinkedAgencies/>
|
||||
<a:SalesHouseCustomerId i:nil="true"/>
|
||||
<a:TaxInformation xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
|
||||
<a:BackUpPaymentInstrumentId i:nil="true"/>
|
||||
<a:BillingThresholdAmount i:nil="true"/>
|
||||
<a:BusinessAddress>
|
||||
<a:City>San Francisco</a:City>
|
||||
<a:CountryCode>US</a:CountryCode>
|
||||
<a:Id>149694999</a:Id>
|
||||
<a:Line1>350 29th avenue</a:Line1>
|
||||
<a:Line2 i:nil="true"/>
|
||||
<a:Line3 i:nil="true"/>
|
||||
<a:Line4 i:nil="true"/>
|
||||
<a:PostalCode>94121</a:PostalCode>
|
||||
<a:StateOrProvince>CA</a:StateOrProvince>
|
||||
<a:TimeStamp i:nil="true"/>
|
||||
<a:BusinessName>Daxtarity Inc.</a:BusinessName>
|
||||
</a:BusinessAddress>
|
||||
<a:AutoTagType>Inactive</a:AutoTagType>
|
||||
<a:SoldToPaymentInstrumentId i:nil="true"/>
|
||||
<a:AccountMode>Expert</a:AccountMode>
|
||||
</a:AdvertiserAccount>
|
||||
</Accounts>
|
||||
</SearchAccountsResponse>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
||||
"""
|
||||
|
||||
GET_USER_RESPONSE = b"""<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<s:Header xmlns="https://bingads.microsoft.com/Customer/v13">
|
||||
<TrackingId d3p1:nil="false" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance">762354725472</TrackingId>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<GetUserResponse xmlns="https://bingads.microsoft.com/Customer/v13">
|
||||
<User xmlns:e227="https://bingads.microsoft.com/Customer/v13/Entities" d4p1:nil="false" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<e227:ContactInfo d4p1:nil="false">
|
||||
<e227:Address d4p1:nil="false">
|
||||
<e227:City d4p1:nil="false">City</e227:City>
|
||||
<e227:CountryCode d4p1:nil="false">USD</e227:CountryCode>
|
||||
<e227:Id d4p1:nil="false">12345678</e227:Id>
|
||||
<e227:Line1 d4p1:nil="false">Test Line</e227:Line1>
|
||||
<e227:Line2 d4p1:nil="false">Test Line</e227:Line2>
|
||||
<e227:Line3 d4p1:nil="false">Test Line</e227:Line3>
|
||||
<e227:Line4 d4p1:nil="false">Test Line</e227:Line4>
|
||||
<e227:PostalCode d4p1:nil="false">0671</e227:PostalCode>
|
||||
<e227:StateOrProvince d4p1:nil="false">State</e227:StateOrProvince>
|
||||
<e227:TimeStamp d4p1:nil="false">12327485</e227:TimeStamp>
|
||||
<e227:BusinessName d4p1:nil="false">Test</e227:BusinessName>
|
||||
</e227:Address>
|
||||
<e227:ContactByPhone d4p1:nil="false">50005</e227:ContactByPhone>
|
||||
<e227:ContactByPostalMail d4p1:nil="false">7365</e227:ContactByPostalMail>
|
||||
<e227:Email d4p1:nil="false">test@mail.com</e227:Email>
|
||||
<e227:EmailFormat d4p1:nil="false">test</e227:EmailFormat>
|
||||
<e227:Fax d4p1:nil="false">73456-343</e227:Fax>
|
||||
<e227:HomePhone d4p1:nil="false">83563</e227:HomePhone>
|
||||
<e227:Id d4p1:nil="false">1232346573</e227:Id>
|
||||
<e227:Mobile d4p1:nil="false">736537</e227:Mobile>
|
||||
<e227:Phone1 d4p1:nil="false">2645</e227:Phone1>
|
||||
<e227:Phone2 d4p1:nil="false">45353</e227:Phone2>
|
||||
</e227:ContactInfo>
|
||||
<e227:CustomerId d4p1:nil="false">234627</e227:CustomerId>
|
||||
<e227:Id d4p1:nil="false">276342574</e227:Id>
|
||||
<e227:JobTitle d4p1:nil="false">Title Job</e227:JobTitle>
|
||||
<e227:LastModifiedByUserId d4p1:nil="false">234722342</e227:LastModifiedByUserId>
|
||||
<e227:LastModifiedTime d4p1:nil="false">2024-01-01T01:01:10.327</e227:LastModifiedTime>
|
||||
<e227:Lcid d4p1:nil="false">827462346</e227:Lcid>
|
||||
<e227:Name d4p1:nil="false">
|
||||
<e227:FirstName d4p1:nil="false">Name First</e227:FirstName>
|
||||
<e227:LastName d4p1:nil="false">Name Last</e227:LastName>
|
||||
<e227:MiddleInitial d4p1:nil="false">Test</e227:MiddleInitial>
|
||||
</e227:Name>
|
||||
<e227:Password d4p1:nil="false">test</e227:Password>
|
||||
<e227:SecretAnswer d4p1:nil="false">test</e227:SecretAnswer>
|
||||
<e227:SecretQuestion>test?</e227:SecretQuestion>
|
||||
<e227:UserLifeCycleStatus d4p1:nil="false">test</e227:UserLifeCycleStatus>
|
||||
<e227:TimeStamp d4p1:nil="false">2736452</e227:TimeStamp>
|
||||
<e227:UserName d4p1:nil="false">test</e227:UserName>
|
||||
<e227:ForwardCompatibilityMap xmlns:e228="http://schemas.datacontract.org/2004/07/System.Collections.Generic" d4p1:nil="false">
|
||||
<e228:KeyValuePairOfstringstring>
|
||||
<e228:key d4p1:nil="false">key</e228:key>
|
||||
<e228:value d4p1:nil="false">value</e228:value>
|
||||
</e228:KeyValuePairOfstringstring>
|
||||
</e227:ForwardCompatibilityMap>
|
||||
<e227:AuthenticationToken d4p1:nil="false">token</e227:AuthenticationToken>
|
||||
</User>
|
||||
<CustomerRoles xmlns:e229="https://bingads.microsoft.com/Customer/v13/Entities" d4p1:nil="false" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<e229:CustomerRole>
|
||||
<e229:RoleId>8324628</e229:RoleId>
|
||||
<e229:CustomerId>726542</e229:CustomerId>
|
||||
<e229:AccountIds d4p1:nil="false" xmlns:a1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
|
||||
<a1:long>180535609</a1:long>
|
||||
</e229:AccountIds>
|
||||
<e229:LinkedAccountIds d4p1:nil="false" xmlns:a1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
|
||||
<a1:long>180535609</a1:long>
|
||||
</e229:LinkedAccountIds>
|
||||
<e229:CustomerLinkPermission d4p1:nil="false">http://link</e229:CustomerLinkPermission>
|
||||
</e229:CustomerRole>
|
||||
</CustomerRoles>
|
||||
</GetUserResponse>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
||||
"""
|
||||
|
||||
|
||||
def mock_http_authenticated_send(transport: HttpAuthenticated, request: Request) -> Reply:
|
||||
if request.headers.get('SOAPAction').decode() == '"GetUser"':
|
||||
return Reply(code=200, headers={}, message=GET_USER_RESPONSE)
|
||||
|
||||
if request.headers.get('SOAPAction').decode() == '"SearchAccounts"':
|
||||
return Reply(code=200, headers={}, message=SEARCH_ACCOUNTS_RESPONSE)
|
||||
|
||||
raise Exception(f"Unexpected SOAPAction provided for mock SOAP client: {request.headers.get('SOAPAction').decode()}")
|
||||
@@ -0,0 +1,54 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
import pendulum
|
||||
from airbyte_cdk.models import SyncMode
|
||||
from airbyte_cdk.test.mock_http import HttpMocker
|
||||
from freezegun import freeze_time
|
||||
from test_bulk_stream import TestBulkStream
|
||||
|
||||
|
||||
class TestBudgetStream(TestBulkStream):
|
||||
stream_name = "budget"
|
||||
account_id = "180535609"
|
||||
cursor_field = "Modified Time"
|
||||
|
||||
@HttpMocker()
|
||||
def test_return_records_from_given_csv_file(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(self.stream_name, SyncMode.full_refresh, self._config, "budget")
|
||||
assert len(output.records) == 1
|
||||
|
||||
@HttpMocker()
|
||||
def test_return_logged_info_for_empty_csv_file(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(self.stream_name, SyncMode.full_refresh, self._config, "budget_empty")
|
||||
assert len(output.records) == 0
|
||||
assert len(output.logs) == 10
|
||||
|
||||
@HttpMocker()
|
||||
def test_transform_records(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(self.stream_name, SyncMode.full_refresh, self._config, "budget")
|
||||
assert output.records
|
||||
for record in output.records:
|
||||
assert "Account Id" in record.record.data.keys()
|
||||
assert isinstance(record.record.data["Account Id"], int)
|
||||
|
||||
@HttpMocker()
|
||||
def test_incremental_read_cursor_value_matches_value_from_most_recent_record(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(self.stream_name, SyncMode.incremental, self._config, "budget_with_cursor_value")
|
||||
assert len(output.records) == 8
|
||||
assert output.most_recent_state.get(self.stream_name, {}).get(self.account_id, {}) == {self.cursor_field: "2024-01-01T12:54:12.028+00:00"}
|
||||
|
||||
@HttpMocker()
|
||||
@freeze_time("204-02-26") # mock current time as stream data available for 30 days only
|
||||
def test_incremental_read_with_state(self, http_mocker: HttpMocker):
|
||||
state = self._state("budget_state", self.stream_name)
|
||||
self.auth_client(http_mocker)
|
||||
output, service_call_mock = self.read_stream(self.stream_name, SyncMode.incremental, self._config, "budget_with_state", state)
|
||||
assert len(output.records) == 8
|
||||
assert output.most_recent_state.get(self.stream_name, {}).get(self.account_id, {}) == {self.cursor_field: "2024-01-30T12:54:12.028+00:00"}
|
||||
|
||||
previous_state = state[0].stream.stream_state.dict()
|
||||
# gets DownloadParams object
|
||||
assert service_call_mock.call_args.args[0].last_sync_time_in_utc == pendulum.parse(previous_state[self.account_id][self.cursor_field])
|
||||
@@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from base_test import BaseTest
|
||||
from bingads.v13.bulk.bulk_service_manager import BulkServiceManager
|
||||
|
||||
|
||||
class TestBulkStream(BaseTest):
|
||||
|
||||
@property
|
||||
def service_manager(self) -> BulkServiceManager:
|
||||
return BulkServiceManager
|
||||
|
||||
def _download_file(self, file: Optional[str] = None) -> Path:
|
||||
"""
|
||||
Returns path to temporary file of downloaded data that will be use in read.
|
||||
Base file should be named as {file_name}.cvs in resource/response folder.
|
||||
"""
|
||||
if file:
|
||||
path_to_tmp_file = Path(__file__).parent.parent / f"resource/response/{file}_tmp.csv"
|
||||
path_to_file_base = Path(__file__).parent.parent / f"resource/response/{file}.csv"
|
||||
with open(path_to_file_base, "r") as f1, open(path_to_tmp_file, "w") as f2:
|
||||
for line in f1:
|
||||
f2.write(line)
|
||||
return path_to_tmp_file
|
||||
return Path(__file__).parent.parent / "resource/response/non-existing-file.csv"
|
||||
@@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
|
||||
from test_report_stream import TestSuiteReportStream
|
||||
|
||||
|
||||
class TestProductDimensionPerformanceReportDailyStream(TestSuiteReportStream):
|
||||
stream_name = "product_dimension_performance_report_daily"
|
||||
report_file = "product_dimension_performance_report_daily"
|
||||
records_number = 8
|
||||
state_file = "product_dimension_performance_report_daily_state"
|
||||
incremental_report_file = "product_dimension_performance_report_daily_incremental"
|
||||
first_read_state = {"product_dimension_performance_report_daily": {"180535609": {"TimePeriod": "2023-12-17"}}}
|
||||
second_read_state = {"product_dimension_performance_report_daily": {"180535609": {"TimePeriod": "2023-12-25"}}}
|
||||
|
||||
|
||||
class TestProductDimensionPerformanceReportHourlyStream(TestSuiteReportStream):
|
||||
stream_name = "product_dimension_performance_report_hourly"
|
||||
report_file = "product_dimension_performance_report_hourly"
|
||||
records_number = 8
|
||||
state_file = "product_dimension_performance_report_hourly_state"
|
||||
incremental_report_file = "product_dimension_performance_report_hourly_incremental"
|
||||
first_read_state = {"product_dimension_performance_report_hourly": {"180535609": {"TimePeriod": "2023-11-11T01:00:00+00:00"}}}
|
||||
second_read_state = {"product_dimension_performance_report_hourly": {"180535609": {"TimePeriod": "2023-11-12T01:00:00+00:00"}}}
|
||||
|
||||
|
||||
class TestProductDimensionPerformanceReportWeeklyStream(TestSuiteReportStream):
|
||||
stream_name = "product_dimension_performance_report_weekly"
|
||||
report_file = "product_dimension_performance_report_weekly"
|
||||
records_number = 8
|
||||
state_file = "product_dimension_performance_report_weekly_state"
|
||||
incremental_report_file = "product_dimension_performance_report_weekly_incremental"
|
||||
first_read_state = {"product_dimension_performance_report_weekly": {"180535609": {"TimePeriod": "2023-12-17"}}}
|
||||
second_read_state = {"product_dimension_performance_report_weekly": {"180535609": {"TimePeriod": "2023-12-25"}}}
|
||||
|
||||
|
||||
class TestProductDimensionPerformanceReportMonthlyStream(TestSuiteReportStream):
|
||||
stream_name = "product_dimension_performance_report_monthly"
|
||||
report_file = "product_dimension_performance_report_monthly"
|
||||
records_number = 8
|
||||
state_file = "product_dimension_performance_report_monthly_state"
|
||||
incremental_report_file = "product_dimension_performance_report_monthly_incremental"
|
||||
first_read_state = {"product_dimension_performance_report_monthly": {"180535609": {"TimePeriod": "2023-12-01"}}}
|
||||
second_read_state = {"product_dimension_performance_report_monthly": {"180535609": {"TimePeriod": "2024-01-01"}}}
|
||||
@@ -0,0 +1,112 @@
|
||||
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any, Optional
|
||||
|
||||
import pendulum
|
||||
from airbyte_cdk.models import SyncMode
|
||||
from airbyte_cdk.test.mock_http import HttpMocker
|
||||
from base_test import BaseTest
|
||||
from bingads.v13.reporting.reporting_service_manager import ReportingServiceManager
|
||||
from config_builder import ConfigBuilder
|
||||
|
||||
|
||||
class TestReportStream(BaseTest):
|
||||
start_date = "2024-01-01"
|
||||
|
||||
@property
|
||||
def service_manager(self) -> ReportingServiceManager:
|
||||
return ReportingServiceManager
|
||||
|
||||
@property
|
||||
def _config(self) -> dict[str, Any]:
|
||||
return ConfigBuilder().with_reports_start_date(self.start_date).build()
|
||||
|
||||
def _download_file(self, file: Optional[str] = None) -> Path:
|
||||
"""
|
||||
Returns path to temporary file of downloaded data that will be use in read.
|
||||
Base file should be named as {file_name}.cvs in resource/response folder.
|
||||
"""
|
||||
if file:
|
||||
path_to_tmp_file = Path(__file__).parent.parent / f"resource/response/{file}.csv"
|
||||
return path_to_tmp_file
|
||||
return Path(__file__).parent.parent / "resource/response/non-existing-file.csv"
|
||||
|
||||
|
||||
class TestSuiteReportStream(TestReportStream):
|
||||
stream_name: str = None
|
||||
report_file: str
|
||||
records_number: int
|
||||
state_file: str
|
||||
incremental_report_file: str
|
||||
first_read_state: dict
|
||||
second_read_state: dict
|
||||
transform_field: str = "AccountId"
|
||||
account_id: str = "180535609"
|
||||
cursor_field = "TimePeriod"
|
||||
|
||||
def setUp(self):
|
||||
if not self.stream_name:
|
||||
self.skipTest("Skipping TestSuiteReportStream")
|
||||
|
||||
@HttpMocker()
|
||||
def test_return_records_from_given_csv_file(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(
|
||||
self.stream_name,
|
||||
SyncMode.full_refresh,
|
||||
self._config,
|
||||
self.report_file
|
||||
)
|
||||
assert len(output.records) == self.records_number
|
||||
|
||||
@HttpMocker()
|
||||
def test_transform_records_from_given_csv_file(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(
|
||||
self.stream_name,
|
||||
SyncMode.full_refresh,
|
||||
self._config,
|
||||
self.report_file
|
||||
)
|
||||
|
||||
assert len(output.records) == self.records_number
|
||||
for record in output.records:
|
||||
assert self.transform_field in record.record.data.keys()
|
||||
|
||||
@HttpMocker()
|
||||
def test_incremental_read_returns_records(self, http_mocker: HttpMocker):
|
||||
self.auth_client(http_mocker)
|
||||
output, _ = self.read_stream(
|
||||
self.stream_name,
|
||||
SyncMode.incremental,
|
||||
self._config,
|
||||
self.report_file
|
||||
)
|
||||
assert len(output.records) == self.records_number
|
||||
assert output.most_recent_state == self.first_read_state
|
||||
|
||||
@HttpMocker()
|
||||
def test_incremental_read_with_state_returns_records(self, http_mocker: HttpMocker):
|
||||
state = self._state(self.state_file, self.stream_name)
|
||||
self.auth_client(http_mocker)
|
||||
output, service_call_mock = self.read_stream(
|
||||
self.stream_name,
|
||||
SyncMode.incremental,
|
||||
self._config,
|
||||
self.incremental_report_file,
|
||||
state
|
||||
)
|
||||
assert len(output.records) == self.records_number
|
||||
|
||||
actual_cursor = output.most_recent_state.get(self.stream_name).get(self.account_id)
|
||||
expected_cursor = self.second_read_state.get(self.stream_name).get(self.account_id)
|
||||
assert actual_cursor == expected_cursor
|
||||
|
||||
provided_state = state[0].stream.stream_state.dict()[self.account_id][self.cursor_field]
|
||||
# gets ReportDownloadParams object
|
||||
request_start_date = service_call_mock.call_args.args[0].report_request.Time.CustomDateRangeStart
|
||||
year = request_start_date.Year
|
||||
month = request_start_date.Month
|
||||
day = request_start_date.Day
|
||||
assert pendulum.DateTime(year, month, day, tzinfo=pendulum.UTC) == pendulum.parse(provided_state)
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"access_token": "access_token",
|
||||
"expires_in": 111111,
|
||||
"refresh_token": "refresh_token"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Type,Status,Id,Parent Id,Client Id,Modified Time,Budget Id,Budget Name,Budget,Budget Type,Name
|
||||
Format Version,,,,,,,,,,6.0
|
||||
Budget,Active,-20,0,23645271,,,My Shared Budget,50,DailyBudgetStandard,
|
||||
|
|
|
@@ -0,0 +1,10 @@
|
||||
Type,Status,Id,Parent Id,Client Id,Modified Time,Budget Id,Budget Name,Budget,Budget Type,Name
|
||||
Format Version,,,,,,,,,,6.0
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:12:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:13:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:14:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:15:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:17:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:23:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:43:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/01/2024 12:54:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
|
@@ -0,0 +1,10 @@
|
||||
Type,Status,Id,Parent Id,Client Id,Modified Time,Budget Id,Budget Name,Budget,Budget Type,Name
|
||||
Format Version,,,,,,,,,,6.0
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:12:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:13:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:14:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:15:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:17:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:23:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:43:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
Budget,Active,-20,0,23645271,01/30/2024 12:54:12.02837,,My Shared Budget,50,DailyBudgetStandard,
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-18,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-19,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-20,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-21,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-22,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11T01:15:00+00:00,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-24,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-25,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-12|01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2024-01-01,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-17,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,9 @@
|
||||
TimePeriod,AccountName,AccountNumber,AdGroupName,AdGroupId,CampaignStatus,AccountStatus,AdGroupStatus,Network,AdId,CampaignId,CampaignName,CurrencyCode,DeviceType,Language,MerchantProductId,Title,Condition,Brand,Price,Impressions,Clicks,Ctr,AverageCpc,Spend,Conversions,ConversionRate,Revenue,RevenuePerConversion,SellerName,OfferLanguage,CountryOfSale,AdStatus,AdDistribution,ClickTypeId,TotalClicksOnAdElements,ClickType,ReturnOnAdSpend,BidStrategyType,LocalStoreCode,StoreId,AssistedClicks,AssistedConversions,AllConversions,AllRevenue,AllConversionRate,AllCostPerConversion,AllReturnOnAdSpend,AllRevenuePerConversion,CostPerConversion,ViewThroughConversions,Goal,GoalType,ProductBought,QuantityBought,AverageCpm,ConversionsQualified,AssistedConversionsQualified,ViewThroughConversionsQualified,ProductBoughtTitle,GTIN,MPN,ViewThroughRevenue,Sales,CostPerSale,RevenuePerSale,Installs,CostPerInstall,RevenuePerInstall,CampaignType,AssetGroupId,AssetGroupName,AssetGroupStatus,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-18,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-19,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-20,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-21,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-22,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-11-11T01:15:00+00:00,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-24,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
2023-12-25,TestAccount,123456,TestGroup,212344,Active,Active,,,12345,123456778,USD,Computer,English,123455,Title,,,45,45,0,0,0,0,0,0,0,0,0,TestName,English,USA,Active,,12124,1233,,,,,5675,0,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,234,CustomLabel0,CustomLabel1,CustomLabel2,CustomLabel3,CustomLabel4,ProductType1,ProductType2,ProductType3,ProductType4,ProductType5
|
||||
|
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"180535609": {
|
||||
"Modified Time": "2024-01-29T12:54:12.028+00:00"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"180535609": {
|
||||
"TimePeriod": "2023-11-11"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"180535609": {
|
||||
"TimePeriod": "2023-11-11"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"180535609": {
|
||||
"TimePeriod": "2023-12-01"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"180535609": {
|
||||
"TimePeriod": "2023-11-11"
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,14 @@ def test_bulk_stream_read_with_chunks_app_install_ad_labels(mocked_client, confi
|
||||
}
|
||||
|
||||
|
||||
@patch.object(source_bing_ads.source, "Client")
|
||||
def test_bulk_stream_read_with_chunks_ioe_error(mocked_client, config, caplog):
|
||||
app_install_ads = AppInstallAdLabels(mocked_client, config)
|
||||
with pytest.raises(IOError):
|
||||
list(app_install_ads.read_with_chunks(path=Path(__file__).parent / "non-existing-file.csv"))
|
||||
assert "The IO/Error occurred while reading tmp data" in caplog.text
|
||||
|
||||
|
||||
@patch.object(source_bing_ads.source, "Client")
|
||||
@freeze_time("2023-11-01T12:00:00.000+00:00")
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -16,7 +16,7 @@ from source_bing_ads.source import SourceBingAds
|
||||
@patch.object(source_bing_ads.source, "Client")
|
||||
def test_streams_config_based(mocked_client, config):
|
||||
streams = SourceBingAds().streams(config)
|
||||
assert len(streams) == 60
|
||||
assert len(streams) == 65
|
||||
|
||||
|
||||
@patch.object(source_bing_ads.source, "Client")
|
||||
|
||||
@@ -113,6 +113,7 @@ The Bing Ads source connector supports the following streams. For more informati
|
||||
- [Ads](https://docs.microsoft.com/en-us/advertising/campaign-management-service/getadsbyadgroupid?view=bingads-13)
|
||||
- [App Install Ads](https://learn.microsoft.com/en-us/advertising/bulk-service/app-install-ad?view=bingads-13)
|
||||
- [App Install Ad Labels](https://learn.microsoft.com/en-us/advertising/bulk-service/app-install-ad-label?view=bingads-13)
|
||||
- [Budget](https://learn.microsoft.com/en-us/advertising/bulk-service/budget?view=bingads-13&viewFallbackFrom=bingads-13)
|
||||
- [Campaigns](https://docs.microsoft.com/en-us/advertising/campaign-management-service/getcampaignsbyaccountid?view=bingads-13)
|
||||
- [Campaign Labels](https://learn.microsoft.com/en-us/advertising/bulk-service/campaign-label?view=bingads-13)
|
||||
- [Keywords](https://learn.microsoft.com/en-us/advertising/bulk-service/keyword?view=bingads-13)
|
||||
@@ -166,6 +167,10 @@ The Bing Ads source connector supports the following streams. For more informati
|
||||
- [User Location Performance Report Daily](https://learn.microsoft.com/en-us/advertising/reporting-service/userlocationperformancereportrequest?view=bingads-13)
|
||||
- [User Location Performance Report Weekly](https://learn.microsoft.com/en-us/advertising/reporting-service/userlocationperformancereportrequest?view=bingads-13)
|
||||
- [User Location Performance Report Monthly](https://learn.microsoft.com/en-us/advertising/reporting-service/userlocationperformancereportrequest?view=bingads-13)
|
||||
- [Product Dimension Performance Report Hourly](https://learn.microsoft.com/en-us/advertising/reporting-service/productdimensionperformancereportrequest?view=bingads-13)
|
||||
- [Product Dimension Performance Report Daily](https://learn.microsoft.com/en-us/advertising/reporting-service/productdimensionperformancereportrequest?view=bingads-13)
|
||||
- [Product Dimension Performance Report Weekly](https://learn.microsoft.com/en-us/advertising/reporting-service/productdimensionperformancereportrequest?view=bingads-13)
|
||||
- [Product Dimension Performance Report Monthly](https://learn.microsoft.com/en-us/advertising/reporting-service/productdimensionperformancereportrequest?view=bingads-13)
|
||||
- [Search Query Performance Report Hourly](https://learn.microsoft.com/en-us/advertising/reporting-service/searchqueryperformancereportrequest?view=bingads-13)
|
||||
- [Search Query Performance Report Daily](https://learn.microsoft.com/en-us/advertising/reporting-service/searchqueryperformancereportrequest?view=bingads-13)
|
||||
- [Search Query Performance Report Weekly](https://learn.microsoft.com/en-us/advertising/reporting-service/searchqueryperformancereportrequest?view=bingads-13)
|
||||
@@ -226,7 +231,8 @@ The Bing Ads API limits the number of requests for all Microsoft Advertising cli
|
||||
|
||||
| Version | Date | Pull Request | Subject |
|
||||
|:--------|:-----------|:---------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 2.1.4 | 2024-02-12 | [35179](https://github.com/airbytehq/airbyte/pull/35179) | Manage dependencies with Poetry. |
|
||||
| 2.2.0 | 2024-02-13 | [35201](https://github.com/airbytehq/airbyte/pull/35201) | New streams Budget and |
|
||||
| 2.1.4 | 2024-02-12 | [35179](https://github.com/airbytehq/airbyte/pull/35179) | Manage dependencies with Poetry. |
|
||||
| 2.1.3 | 2024-01-31 | [34712](https://github.com/airbytehq/airbyte/pull/34712) | Fix duplicated records for report-based streams |
|
||||
| 2.1.2 | 2024-01-09 | [34045](https://github.com/airbytehq/airbyte/pull/34045) | Speed up record transformation |
|
||||
| 2.1.1 | 2023-12-15 | [33500](https://github.com/airbytehq/airbyte/pull/33500) | Fix state setter when state was provided |
|
||||
|
||||
Reference in New Issue
Block a user