airbyte-source-google-ads 4.1.3.dev202511242224__tar.gz → 4.1.4__tar.gz
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.
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/PKG-INFO +2 -2
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/pyproject.toml +2 -2
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/components.py +12 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/manifest.yaml +129 -45
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/README.md +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/__init__.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/config_migrations.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/google_ads.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/models.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/run.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/schemas/customer_client.json +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/schemas/service_accounts.json +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/source.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/spec.json +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/streams.py +0 -0
- {airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/source_google_ads/utils.py +0 -0
{airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: airbyte-source-google-ads
|
|
3
|
-
Version: 4.1.
|
|
3
|
+
Version: 4.1.4
|
|
4
4
|
Summary: Source implementation for Google Ads.
|
|
5
5
|
Home-page: https://airbyte.com
|
|
6
6
|
License: Elv2
|
|
@@ -11,7 +11,7 @@ Classifier: License :: Other/Proprietary License
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
-
Requires-Dist: airbyte-cdk (>=7.
|
|
14
|
+
Requires-Dist: airbyte-cdk (>=7.5.1.post3.dev19705070276,<8.0.0)
|
|
15
15
|
Requires-Dist: google-ads (==27.0.0)
|
|
16
16
|
Requires-Dist: pendulum (<3.0.0)
|
|
17
17
|
Requires-Dist: protobuf (==4.25.2)
|
{airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/pyproject.toml
RENAMED
|
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
|
|
|
3
3
|
build-backend = "poetry.core.masonry.api"
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
|
-
version = "4.1.
|
|
6
|
+
version = "4.1.4"
|
|
7
7
|
name = "airbyte-source-google-ads"
|
|
8
8
|
description = "Source implementation for Google Ads."
|
|
9
9
|
authors = [ "Airbyte <contact@airbyte.io>",]
|
|
@@ -20,7 +20,7 @@ python = "^3.10,<3.12"
|
|
|
20
20
|
google-ads = "==27.0.0"
|
|
21
21
|
protobuf = "==4.25.2"
|
|
22
22
|
pendulum = "<3.0.0"
|
|
23
|
-
airbyte-cdk = "^7.
|
|
23
|
+
airbyte-cdk = "^7.5.1.post3.dev19705070276"
|
|
24
24
|
|
|
25
25
|
[tool.poetry.scripts]
|
|
26
26
|
source-google-ads = "source_google_ads.run:run"
|
|
@@ -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:
|
|
75
|
+
type: CustomDecoder
|
|
76
|
+
class_name: "source_google_ads.components.GoogleAdsStreamingDecoder"
|
|
89
77
|
|
|
90
78
|
stream_base:
|
|
91
79
|
type: DeclarativeStream
|
|
@@ -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:
|
|
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:
|
|
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:
|
|
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
|
|
@@ -1030,14 +998,6 @@ definitions:
|
|
|
1030
998
|
)
|
|
1031
999
|
}}
|
|
1032
1000
|
create_or_update: true
|
|
1033
|
-
- type: ComponentMappingDefinition
|
|
1034
|
-
field_path:
|
|
1035
|
-
- retriever
|
|
1036
|
-
- requester
|
|
1037
|
-
- $parameters
|
|
1038
|
-
- query
|
|
1039
|
-
value: "{{ components_values.get('query', None) }}"
|
|
1040
|
-
create_or_update: true
|
|
1041
1001
|
- type: ComponentMappingDefinition
|
|
1042
1002
|
field_path:
|
|
1043
1003
|
- retriever
|
|
@@ -1085,6 +1045,130 @@ definitions:
|
|
|
1085
1045
|
)
|
|
1086
1046
|
}}
|
|
1087
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
|
|
1088
1172
|
- type: ComponentMappingDefinition
|
|
1089
1173
|
field_path:
|
|
1090
1174
|
- retriever
|
{airbyte_source_google_ads-4.1.3.dev202511242224 → airbyte_source_google_ads-4.1.4}/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|