airbyte-source-google-ads 4.1.4.dev202511261630__py3-none-any.whl → 4.1.4.dev202602051752__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-source-google-ads
3
- Version: 4.1.4.dev202511261630
3
+ Version: 4.1.4.dev202602051752
4
4
  Summary: Source implementation for Google Ads.
5
5
  Home-page: https://airbyte.com
6
6
  License: Elv2
@@ -1,17 +1,17 @@
1
1
  source_google_ads/__init__.py,sha256=Nlo5H6LlaSgg7tx_LyqMIy3MXiAagfk3izZ9o44VvSE,1201
2
- source_google_ads/components.py,sha256=_Jku4_NHRg4OzYSmtk23H0LfYo0bbqfx1navUoUztug,40970
2
+ source_google_ads/components.py,sha256=hzd6hgBuE0HvHVO71r3gdHsbM5sApQKpzW_QWKEAv8g,41479
3
3
  source_google_ads/config_migrations.py,sha256=oBi_qNqBpLS8GNCaIOBo0stNdYuyqVl6lkrhdXRwMX8,4405
4
4
  source_google_ads/google_ads.py,sha256=cxS18tz0fFJjmIhlhFQ3Zvu2K8bhDtmsl1kFeO7nNhk,11595
5
- source_google_ads/manifest.yaml,sha256=lloZo6cDdrkE-HXn66cRfNi0MwvK80lGCjFdmsiqLto,220336
5
+ source_google_ads/manifest.yaml,sha256=cQEztJxh_H5Xn1ZMRGNYwgR48xrW3gEWUb2LCJY85sI,224080
6
6
  source_google_ads/models.py,sha256=ZmdS3z_2roaEQgV2Mx1CDm33MztpQ66SfHDzP8XwZog,1658
7
7
  source_google_ads/run.py,sha256=ydIyq_vSNV5Z4mJYnsO5GyNDsLDd0qibBsq6wnvuFAo,2002
8
8
  source_google_ads/schemas/customer_client.json,sha256=oThcyUDO1yWpxtWPWdoAFqTXEIweF8N4q6mRI73Q6yU,984
9
9
  source_google_ads/schemas/service_accounts.json,sha256=HVSyzbEoxzB4rntRHOjAh0ZYgbR584ew0W0CdJH7ECU,3485
10
10
  source_google_ads/source.py,sha256=hz5ep6stMWHNvD73PIF_7bjnee49sY9YHHjaYNAPnOQ,1425
11
- source_google_ads/spec.json,sha256=8hbc7smbaffIkYCkX2BYJLB9kgaH8vYKCg-H0y1FvUs,7810
11
+ source_google_ads/spec.json,sha256=VHY8VTBxdu41VbsrSSOCUOd1ea0N2XxOUOU5CfdaRO0,8270
12
12
  source_google_ads/streams.py,sha256=FB-DNJlXhjQADptT-wrv3iGWoliyRuvDuHGeqiN9HsY,13349
13
13
  source_google_ads/utils.py,sha256=-KpgGv2W8WueXvGRC3xbVreDl5-5-vU9OwzC5SZDKVc,21409
14
- airbyte_source_google_ads-4.1.4.dev202511261630.dist-info/METADATA,sha256=nQGZU1vv_9_Qg5bWxpUISh8hpCyRDytlAb8CgGUP_l8,5397
15
- airbyte_source_google_ads-4.1.4.dev202511261630.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
16
- airbyte_source_google_ads-4.1.4.dev202511261630.dist-info/entry_points.txt,sha256=pP4Llir93XGkHFDZfXXxK7qOWo9_U1ssCJToyxEUB4w,63
17
- airbyte_source_google_ads-4.1.4.dev202511261630.dist-info/RECORD,,
14
+ airbyte_source_google_ads-4.1.4.dev202602051752.dist-info/METADATA,sha256=YKe67P_vROUfCM6-WivfteI7oY-OCu0wXmFADIflR4o,5397
15
+ airbyte_source_google_ads-4.1.4.dev202602051752.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
16
+ airbyte_source_google_ads-4.1.4.dev202602051752.dist-info/entry_points.txt,sha256=pP4Llir93XGkHFDZfXXxK7qOWo9_U1ssCJToyxEUB4w,63
17
+ airbyte_source_google_ads-4.1.4.dev202602051752.dist-info/RECORD,,
@@ -697,6 +697,7 @@ class CustomGAQueryHttpRequester(HttpRequester):
697
697
  def __post_init__(self, parameters: Mapping[str, Any]):
698
698
  super().__post_init__(parameters=parameters)
699
699
  self.query = GAQL.parse(parameters.get("query"))
700
+ self.stream_response = True
700
701
 
701
702
  @staticmethod
702
703
  def is_metrics_in_custom_query(query: GAQL) -> bool:
@@ -761,6 +762,17 @@ class CustomGAQueryHttpRequester(HttpRequester):
761
762
  return self.query[from_index + 4 :].strip()
762
763
 
763
764
 
765
+ class CustomGAQueryClickViewHttpRequester(CustomGAQueryHttpRequester):
766
+ @staticmethod
767
+ def _insert_segments_date_expr(query: GAQL, start_date: str, end_date: str) -> GAQL:
768
+ if "segments.date" not in query.fields:
769
+ query = query.append_field("segments.date")
770
+ condition = f"segments.date ='{start_date}'"
771
+ if query.where:
772
+ return query.set_where(query.where + " AND " + condition)
773
+ return query.set_where(condition)
774
+
775
+
764
776
  @dataclass()
765
777
  class CustomGAQuerySchemaLoader(SchemaLoader):
766
778
  """
@@ -65,27 +65,15 @@ definitions:
65
65
  field_path:
66
66
  - results
67
67
 
68
- cursor_paginator:
69
- type: DefaultPaginator
70
- pagination_strategy:
71
- type: CursorPagination
72
- cursor_value: "{{ response.get('nextPageToken', '') }}"
73
- stop_condition: "{{ response.get('nextPageToken', '') is none }}"
74
- page_token_option:
75
- type: RequestOption
76
- inject_into: body_json
77
- field_path: ["page_token"]
78
-
79
68
  base_retriever:
80
69
  type: SimpleRetriever
81
70
  requester:
82
71
  $ref: "#/definitions/stream_requester"
83
72
  record_selector:
84
73
  $ref: "#/definitions/base_selector"
85
- paginator:
86
- $ref: "#/definitions/cursor_paginator"
87
74
  decoder:
88
- type: JsonDecoder
75
+ type: CustomDecoder
76
+ class_name: "source_google_ads.components.GoogleAdsStreamingDecoder"
89
77
 
90
78
  stream_base:
91
79
  type: DeclarativeStream
@@ -158,7 +146,7 @@ definitions:
158
146
  datetime_format: "%Y-%m-%d"
159
147
  lookback_window: P{{ config.get('conversion_window_days', 14) }}D
160
148
  cursor_granularity: P1D
161
- step: P14D
149
+ step: P{{ config.get('step_days', 14) }}D
162
150
  start_datetime:
163
151
  type: MinMaxDatetime
164
152
  datetime: "{{ config.get('start_date', day_delta(-365 * 2, format='%Y-%m-%d')) }}"
@@ -199,7 +187,7 @@ definitions:
199
187
  $ref: "#/schemas"
200
188
  authenticator:
201
189
  $ref: "#/definitions/authenticator"
202
- url_base: "https://googleads.googleapis.com/v20/{{ stream_partition['customer_id'] }}/googleAds:search"
190
+ url_base: "https://googleads.googleapis.com/v20/{{ stream_partition['customer_id'] }}/googleAds:searchStream"
203
191
  http_method: POST
204
192
  error_handler:
205
193
  $ref: "#/definitions/base_error_handler"
@@ -224,7 +212,7 @@ definitions:
224
212
  incremental_stream:
225
213
  $ref: "#/definitions/incremental_stream_base"
226
214
  $parameters:
227
- url_base: "https://googleads.googleapis.com/v20/{{ stream_partition['parent_slice']['customer_id'] }}/googleAds:search"
215
+ url_base: "https://googleads.googleapis.com/v20/{{ stream_partition['parent_slice']['customer_id'] }}/googleAds:searchStream"
228
216
  retriever:
229
217
  type: CustomRetriever
230
218
  class_name: "source_google_ads.components.CriterionRetriever"
@@ -240,8 +228,6 @@ definitions:
240
228
  http_method: POST
241
229
  error_handler:
242
230
  $ref: "#/definitions/base_error_handler"
243
- paginator:
244
- $ref: "#/definitions/cursor_paginator"
245
231
  record_selector:
246
232
  type: RecordSelector
247
233
  extractor:
@@ -297,8 +283,6 @@ definitions:
297
283
  $ref: "#/definitions/base_requester"
298
284
  url_base: "https://googleads.googleapis.com/v20/customers:listAccessibleCustomers"
299
285
  http_method: GET
300
- paginator:
301
- type: NoPagination
302
286
  record_selector:
303
287
  extractor:
304
288
  type: CustomRecordExtractor
@@ -422,11 +406,6 @@ definitions:
422
406
  parent_key: "clientCustomer"
423
407
  partition_field: "customer_id"
424
408
  stream: "#/definitions/customer_client"
425
- decoder:
426
- type: CustomDecoder
427
- class_name: "source_google_ads.components.GoogleAdsStreamingDecoder"
428
- paginator:
429
- type: NoPagination
430
409
  transformations:
431
410
  - type: CustomTransformation
432
411
  class_name: "source_google_ads.components.KeysToSnakeCaseGoogleAdsTransformation"
@@ -487,13 +466,6 @@ definitions:
487
466
 
488
467
  ad_group_ad_stream:
489
468
  $ref: "#/definitions/incremental_stream_base"
490
- retriever:
491
- $ref: "#/definitions/incremental_stream_base/retriever"
492
- paginator:
493
- type: NoPagination
494
- decoder:
495
- type: CustomDecoder
496
- class_name: "source_google_ads.components.GoogleAdsStreamingDecoder"
497
469
  name: ad_group_ad
498
470
  primary_key:
499
471
  - ad_group.id
@@ -665,12 +637,10 @@ definitions:
665
637
  $ref: "#/schemas/click_view"
666
638
  authenticator:
667
639
  $ref: "#/definitions/authenticator"
668
- url_base: "https://googleads.googleapis.com/v20/{{ stream_partition['customer_id'] }}/googleAds:search"
640
+ url_base: "https://googleads.googleapis.com/v20/{{ stream_partition['customer_id'] }}/googleAds:searchStream"
669
641
  http_method: POST
670
642
  error_handler:
671
643
  $ref: "#/definitions/base_error_handler"
672
- paginator:
673
- $ref: "#/definitions/cursor_paginator"
674
644
  incremental_sync:
675
645
  type: DatetimeBasedCursor
676
646
  cursor_field: segments.date
@@ -859,8 +829,6 @@ definitions:
859
829
  error_handler:
860
830
  $ref: "#/definitions/base_error_handler"
861
831
  name: change_status
862
- paginator:
863
- $ref: "#/definitions/cursor_paginator"
864
832
  pagination_reset:
865
833
  type: PaginationReset
866
834
  action: SPLIT_USING_CURSOR
@@ -896,7 +864,7 @@ definitions:
896
864
  cursor_field: change_status.last_change_date_time
897
865
  datetime_format: "%Y-%m-%d %H:%M:%S.%f"
898
866
  cursor_granularity: PT0.000001S
899
- step: P14D
867
+ step: P{{ config.get('step_days', 14) }}D
900
868
  start_datetime:
901
869
  type: MinMaxDatetime
902
870
  datetime: "{{ day_delta(-90, format='%Y-%m-%d %H:%M:%S.%f') }}"
@@ -1004,7 +972,7 @@ definitions:
1004
972
  "datetime_format": "%Y-%m-%d",
1005
973
  "lookback_window": "P{{ config.get('conversion_window_days', 14) }}D",
1006
974
  "cursor_granularity": "P1D",
1007
- "step": "P14D",
975
+ "step": "P{{ config.get('step_days', 14) }}D",
1008
976
  "start_datetime": {
1009
977
  "type": "MinMaxDatetime",
1010
978
  "datetime": "{{ config.get('start_date', day_delta(-365 * 2, format='%Y-%m-%d')) }}",
@@ -1030,35 +998,6 @@ definitions:
1030
998
  )
1031
999
  }}
1032
1000
  create_or_update: true
1033
- - type: ComponentMappingDefinition
1034
- field_path:
1035
- - incremental_sync
1036
- - step
1037
- value: "P1D"
1038
- condition: >-
1039
- {{
1040
- (
1041
- (
1042
- components_values.get('query', '').count('segments.date') == 1
1043
- and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1044
- )
1045
- or
1046
- (
1047
- components_values.get('query', '').count('segments.date') == 2
1048
- and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1049
- and (components_values.get('query') | regex_search('(?i)(\\bORDER\\s+BY\\b[\\s\\S]*?segments\\.date)'))
1050
- )
1051
- ) and components_values.get('query', '') | regex_search('(?i)(\\bFROM\\s+click_view\\b)')
1052
- }}
1053
- create_or_update: true
1054
- - type: ComponentMappingDefinition
1055
- field_path:
1056
- - retriever
1057
- - requester
1058
- - $parameters
1059
- - query
1060
- value: "{{ components_values.get('query', None) }}"
1061
- create_or_update: true
1062
1001
  - type: ComponentMappingDefinition
1063
1002
  field_path:
1064
1003
  - retriever
@@ -1106,6 +1045,130 @@ definitions:
1106
1045
  )
1107
1046
  }}
1108
1047
  create_or_update: true
1048
+ - type: ComponentMappingDefinition
1049
+ field_path:
1050
+ - incremental_sync
1051
+ - step
1052
+ value: "P1D"
1053
+ condition: >-
1054
+ {{
1055
+ (
1056
+ (
1057
+ components_values.get('query', '').count('segments.date') == 1
1058
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1059
+ )
1060
+ or
1061
+ (
1062
+ components_values.get('query', '').count('segments.date') == 2
1063
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1064
+ and (components_values.get('query') | regex_search('(?i)(\\bORDER\\s+BY\\b[\\s\\S]*?segments\\.date)'))
1065
+ )
1066
+ ) and components_values.get('query', '') | regex_search('(?i)(\\bFROM\\s+click_view\\b)')
1067
+ }}
1068
+ create_or_update: true
1069
+ - type: ComponentMappingDefinition
1070
+ field_path:
1071
+ - incremental_sync
1072
+ - start_datetime
1073
+ value: >-
1074
+ {
1075
+ "type": "MinMaxDatetime",
1076
+ "datetime": "{{ max(config.get('start_date', day_delta(-90, format='%Y-%m-%d')), day_delta(-90, format='%Y-%m-%d')) }}",
1077
+ "datetime_format": "%Y-%m-%d"
1078
+ }
1079
+ condition: >-
1080
+ {{
1081
+ (
1082
+ (
1083
+ components_values.get('query', '').count('segments.date') == 1
1084
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1085
+ )
1086
+ or
1087
+ (
1088
+ components_values.get('query', '').count('segments.date') == 2
1089
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1090
+ and (components_values.get('query') | regex_search('(?i)(\\bORDER\\s+BY\\b[\\s\\S]*?segments\\.date)'))
1091
+ )
1092
+ ) and components_values.get('query', '') | regex_search('(?i)(\\bFROM\\s+click_view\\b)')
1093
+ }}
1094
+ create_or_update: true
1095
+ - type: ComponentMappingDefinition
1096
+ field_path:
1097
+ - incremental_sync
1098
+ - end_datetime
1099
+ value: >-
1100
+ {
1101
+ "type": "MinMaxDatetime",
1102
+ "datetime": "{{ format_datetime((str_to_datetime(config.get('end_date')) if config.get('end_date') else now_utc()) + duration('P1D'), '%Y-%m-%d') }}",
1103
+ "datetime_format": "%Y-%m-%d"
1104
+ }
1105
+ condition: >-
1106
+ {{
1107
+ (
1108
+ (
1109
+ components_values.get('query', '').count('segments.date') == 1
1110
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1111
+ )
1112
+ or
1113
+ (
1114
+ components_values.get('query', '').count('segments.date') == 2
1115
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1116
+ and (components_values.get('query') | regex_search('(?i)(\\bORDER\\s+BY\\b[\\s\\S]*?segments\\.date)'))
1117
+ )
1118
+ ) and components_values.get('query', '') | regex_search('(?i)(\\bFROM\\s+click_view\\b)')
1119
+ }}
1120
+ create_or_update: true
1121
+ - type: ComponentMappingDefinition
1122
+ field_path:
1123
+ - incremental_sync
1124
+ - cursor_granularity
1125
+ value: P1D
1126
+ condition: >-
1127
+ {{
1128
+ (
1129
+ (
1130
+ components_values.get('query', '').count('segments.date') == 1
1131
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1132
+ )
1133
+ or
1134
+ (
1135
+ components_values.get('query', '').count('segments.date') == 2
1136
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1137
+ and (components_values.get('query') | regex_search('(?i)(\\bORDER\\s+BY\\b[\\s\\S]*?segments\\.date)'))
1138
+ )
1139
+ ) and components_values.get('query', '') | regex_search('(?i)(\\bFROM\\s+click_view\\b)')
1140
+ }}
1141
+ create_or_update: true
1142
+ - type: ComponentMappingDefinition
1143
+ field_path:
1144
+ - retriever
1145
+ - requester
1146
+ - class_name
1147
+ value: "source_google_ads.components.CustomGAQueryClickViewHttpRequester"
1148
+ condition: >-
1149
+ {{
1150
+ (
1151
+ (
1152
+ components_values.get('query', '').count('segments.date') == 1
1153
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1154
+ )
1155
+ or
1156
+ (
1157
+ components_values.get('query', '').count('segments.date') == 2
1158
+ and (components_values.get('query') | regex_search('(?i)(\\bSELECT\\b[\\s\\S]*?segments\\.date[\\s\\S]*?\\bFROM\\b)'))
1159
+ and (components_values.get('query') | regex_search('(?i)(\\bORDER\\s+BY\\b[\\s\\S]*?segments\\.date)'))
1160
+ )
1161
+ ) and components_values.get('query', '') | regex_search('(?i)(\\bFROM\\s+click_view\\b)')
1162
+ }}
1163
+ create_or_update: true
1164
+ - type: ComponentMappingDefinition
1165
+ field_path:
1166
+ - retriever
1167
+ - requester
1168
+ - $parameters
1169
+ - query
1170
+ value: "{{ components_values.get('query', None) }}"
1171
+ create_or_update: true
1109
1172
  - type: ComponentMappingDefinition
1110
1173
  field_path:
1111
1174
  - retriever
@@ -131,6 +131,16 @@
131
131
  "default": 14,
132
132
  "examples": [14],
133
133
  "order": 6
134
+ },
135
+ "step_days": {
136
+ "title": "Step (Days)",
137
+ "type": "integer",
138
+ "description": "The number of days per request slice for incremental streams. Smaller values reduce the amount of data per request, which can help avoid timeouts and connection errors for accounts with large data volumes. Default is 14 days.",
139
+ "minimum": 1,
140
+ "maximum": 30,
141
+ "default": 14,
142
+ "examples": [1, 7, 14],
143
+ "order": 7
134
144
  }
135
145
  }
136
146
  },