airbyte-source-google-search-console 1.6.0.dev202503282247__py3-none-any.whl → 1.7.0__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.
- {airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info → airbyte_source_google_search_console-1.7.0.dist-info}/METADATA +4 -4
- airbyte_source_google_search_console-1.7.0.dist-info/RECORD +22 -0
- {airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info → airbyte_source_google_search_console-1.7.0.dist-info}/WHEEL +1 -1
- source_google_search_console/components.py +81 -0
- source_google_search_console/config_migrations.py +4 -1
- source_google_search_console/manifest.yaml +828 -0
- source_google_search_console/run.py +47 -9
- source_google_search_console/service_account_authenticator.py +3 -1
- source_google_search_console/source.py +23 -59
- source_google_search_console/spec.json +7 -0
- source_google_search_console/streams.py +1 -121
- airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info/RECORD +0 -29
- source_google_search_console/schemas/search_analytics_by_country.json +0 -41
- source_google_search_console/schemas/search_analytics_keyword_page_report.json +0 -54
- source_google_search_console/schemas/search_analytics_keyword_page_report_minimal_dimensions.json +0 -54
- source_google_search_console/schemas/search_analytics_keyword_site_report_by_page.json +0 -50
- source_google_search_console/schemas/search_analytics_keyword_site_report_by_page_minimal_dimensions.json +0 -50
- source_google_search_console/schemas/search_analytics_keyword_site_report_by_site.json +0 -50
- source_google_search_console/schemas/search_analytics_keyword_site_report_by_site_minimal_dimensions.json +0 -50
- source_google_search_console/schemas/sitemaps.json +0 -61
- source_google_search_console/schemas/sites.json +0 -14
- {airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info → airbyte_source_google_search_console-1.7.0.dist-info}/entry_points.txt +0 -0
@@ -1,18 +1,56 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c)
|
2
|
+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
|
3
3
|
#
|
4
4
|
|
5
|
-
|
6
5
|
import sys
|
6
|
+
import traceback
|
7
|
+
from datetime import datetime
|
8
|
+
from typing import List
|
9
|
+
|
10
|
+
from orjson import orjson
|
7
11
|
|
8
|
-
from airbyte_cdk.entrypoint import launch
|
12
|
+
from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch, logger
|
13
|
+
from airbyte_cdk.exception_handler import init_uncaught_exception_handler
|
14
|
+
from airbyte_cdk.models import AirbyteErrorTraceMessage, AirbyteMessage, AirbyteMessageSerializer, AirbyteTraceMessage, TraceType, Type
|
9
15
|
from source_google_search_console import SourceGoogleSearchConsole
|
10
16
|
from source_google_search_console.config_migrations import MigrateCustomReports
|
11
17
|
|
12
18
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
+
def _get_source(args: List[str]):
|
20
|
+
catalog_path = AirbyteEntrypoint.extract_catalog(args)
|
21
|
+
config_path = AirbyteEntrypoint.extract_config(args)
|
22
|
+
state_path = AirbyteEntrypoint.extract_state(args)
|
23
|
+
try:
|
24
|
+
return SourceGoogleSearchConsole(
|
25
|
+
SourceGoogleSearchConsole.read_catalog(catalog_path) if catalog_path else None,
|
26
|
+
SourceGoogleSearchConsole.read_config(config_path) if config_path else None,
|
27
|
+
SourceGoogleSearchConsole.read_state(state_path) if state_path else None,
|
28
|
+
)
|
29
|
+
except Exception as error:
|
30
|
+
print(
|
31
|
+
orjson.dumps(
|
32
|
+
AirbyteMessageSerializer.dump(
|
33
|
+
AirbyteMessage(
|
34
|
+
type=Type.TRACE,
|
35
|
+
trace=AirbyteTraceMessage(
|
36
|
+
type=TraceType.ERROR,
|
37
|
+
emitted_at=int(datetime.now().timestamp() * 1000),
|
38
|
+
error=AirbyteErrorTraceMessage(
|
39
|
+
message=f"Error starting the sync. This could be due to an invalid configuration or catalog. Please contact Support for assistance. Error: {error}",
|
40
|
+
stack_trace=traceback.format_exc(),
|
41
|
+
),
|
42
|
+
),
|
43
|
+
)
|
44
|
+
)
|
45
|
+
).decode()
|
46
|
+
)
|
47
|
+
return None
|
48
|
+
|
49
|
+
|
50
|
+
def run() -> None:
|
51
|
+
init_uncaught_exception_handler(logger)
|
52
|
+
_args = sys.argv[1:]
|
53
|
+
source = _get_source(_args)
|
54
|
+
if source:
|
55
|
+
MigrateCustomReports.migrate(sys.argv[1:], source)
|
56
|
+
launch(source, _args)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
3
|
#
|
4
|
+
import json
|
4
5
|
|
5
6
|
import requests
|
6
7
|
from google.auth.transport.requests import Request
|
@@ -21,7 +22,8 @@ class ServiceAccountAuthenticator(AuthBase):
|
|
21
22
|
|
22
23
|
def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
|
23
24
|
try:
|
24
|
-
|
25
|
+
service_account_info = json.loads(self.service_account_info)
|
26
|
+
credentials: Credentials = Credentials.from_service_account_info(service_account_info, scopes=self.scopes).with_subject(
|
25
27
|
self.email
|
26
28
|
)
|
27
29
|
if not credentials.valid:
|
@@ -3,7 +3,6 @@
|
|
3
3
|
#
|
4
4
|
|
5
5
|
import json
|
6
|
-
import logging
|
7
6
|
from typing import Any, List, Mapping, Optional, Tuple, Union
|
8
7
|
from urllib.parse import urlparse
|
9
8
|
|
@@ -11,37 +10,28 @@ import jsonschema
|
|
11
10
|
import pendulum
|
12
11
|
import requests
|
13
12
|
|
14
|
-
from airbyte_cdk.models import FailureType, SyncMode
|
15
|
-
from airbyte_cdk.sources import
|
13
|
+
from airbyte_cdk.models import ConfiguredAirbyteCatalog, FailureType, SyncMode
|
14
|
+
from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource
|
15
|
+
from airbyte_cdk.sources.source import TState
|
16
16
|
from airbyte_cdk.sources.streams import Stream
|
17
17
|
from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator
|
18
18
|
from airbyte_cdk.utils import AirbyteTracedException
|
19
19
|
from source_google_search_console.exceptions import (
|
20
20
|
InvalidSiteURLValidationError,
|
21
21
|
UnauthorizedOauthError,
|
22
|
-
UnauthorizedServiceAccountError,
|
23
22
|
UnidentifiedError,
|
24
23
|
)
|
25
24
|
from source_google_search_console.service_account_authenticator import ServiceAccountAuthenticator
|
26
25
|
from source_google_search_console.streams import (
|
27
26
|
SearchAnalyticsAllFields,
|
28
|
-
SearchAnalyticsByCountry,
|
29
27
|
SearchAnalyticsByCustomDimensions,
|
30
28
|
SearchAnalyticsByDate,
|
31
29
|
SearchAnalyticsByDevice,
|
32
30
|
SearchAnalyticsByPage,
|
33
31
|
SearchAnalyticsByQuery,
|
34
|
-
SearchAnalyticsKeywordPageReport,
|
35
|
-
SearchAnalyticsKeywordPageReportMinimalDimensions,
|
36
|
-
SearchAnalyticsKeywordSiteReportByPage,
|
37
|
-
SearchAnalyticsKeywordSiteReportByPageMinimalDimensions,
|
38
|
-
SearchAnalyticsKeywordSiteReportBySite,
|
39
|
-
SearchAnalyticsKeywordSiteReportBySiteMinimalDimensions,
|
40
32
|
SearchAnalyticsPageReport,
|
41
33
|
SearchAnalyticsSiteReportByPage,
|
42
34
|
SearchAnalyticsSiteReportBySite,
|
43
|
-
Sitemaps,
|
44
|
-
Sites,
|
45
35
|
)
|
46
36
|
|
47
37
|
|
@@ -58,7 +48,10 @@ custom_reports_schema = {
|
|
58
48
|
}
|
59
49
|
|
60
50
|
|
61
|
-
class SourceGoogleSearchConsole(
|
51
|
+
class SourceGoogleSearchConsole(YamlDeclarativeSource):
|
52
|
+
def __init__(self, catalog: Optional[ConfiguredAirbyteCatalog], config: Optional[Mapping[str, Any]], state: TState, **kwargs):
|
53
|
+
super().__init__(catalog=catalog, config=config, state=state, **{"path_to_yaml": "manifest.yaml"})
|
54
|
+
|
62
55
|
@staticmethod
|
63
56
|
def normalize_url(url):
|
64
57
|
parse_result = urlparse(url)
|
@@ -71,7 +64,7 @@ class SourceGoogleSearchConsole(AbstractSource):
|
|
71
64
|
authorization = config["authorization"]
|
72
65
|
if authorization["auth_type"] == "Service":
|
73
66
|
try:
|
74
|
-
|
67
|
+
json.loads(authorization["service_account_info"])
|
75
68
|
except ValueError:
|
76
69
|
message = "authorization.service_account_info is not valid JSON"
|
77
70
|
raise AirbyteTracedException(message=message, internal_message=message, failure_type=FailureType.config_error)
|
@@ -113,29 +106,6 @@ class SourceGoogleSearchConsole(AbstractSource):
|
|
113
106
|
raise AirbyteTracedException(message=message, internal_message=message, failure_type=FailureType.config_error)
|
114
107
|
return config
|
115
108
|
|
116
|
-
def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Any]:
|
117
|
-
try:
|
118
|
-
config = self._validate_and_transform(config)
|
119
|
-
stream_kwargs = self.get_stream_kwargs(config)
|
120
|
-
self.validate_site_urls(config["site_urls"], stream_kwargs["authenticator"])
|
121
|
-
sites = Sites(**stream_kwargs)
|
122
|
-
stream_slice = sites.stream_slices(SyncMode.full_refresh)
|
123
|
-
|
124
|
-
# stream_slice returns all site_urls and we need to make sure that
|
125
|
-
# the connection is successful for all of them
|
126
|
-
for _slice in stream_slice:
|
127
|
-
sites_gen = sites.read_records(sync_mode=SyncMode.full_refresh, stream_slice=_slice)
|
128
|
-
next(sites_gen)
|
129
|
-
return True, None
|
130
|
-
|
131
|
-
except (InvalidSiteURLValidationError, UnauthorizedOauthError, UnauthorizedServiceAccountError, jsonschema.ValidationError) as e:
|
132
|
-
return False, repr(e)
|
133
|
-
except (Exception, UnidentifiedError) as error:
|
134
|
-
return (
|
135
|
-
False,
|
136
|
-
f"Unable to check connectivity to Google Search Console API - {repr(error)}",
|
137
|
-
)
|
138
|
-
|
139
109
|
def validate_site_urls(self, site_urls: List[str], auth: Union[ServiceAccountAuthenticator, Oauth2Authenticator]):
|
140
110
|
if isinstance(auth, ServiceAccountAuthenticator):
|
141
111
|
request = auth(requests.Request(method="GET", url="https://www.googleapis.com/webmasters/v3/sites"))
|
@@ -154,7 +124,7 @@ class SourceGoogleSearchConsole(AbstractSource):
|
|
154
124
|
if response.status_code != 200:
|
155
125
|
raise UnidentifiedError(response.json())
|
156
126
|
|
157
|
-
remote_site_urls = {s["siteUrl"] for s in response.json()
|
127
|
+
remote_site_urls = {s["siteUrl"] for s in response.json().get("siteEntry", [])}
|
158
128
|
invalid_site_url = set(site_urls) - remote_site_urls
|
159
129
|
if invalid_site_url:
|
160
130
|
raise InvalidSiteURLValidationError(invalid_site_url)
|
@@ -175,26 +145,20 @@ class SourceGoogleSearchConsole(AbstractSource):
|
|
175
145
|
config = self._validate_and_transform(config)
|
176
146
|
stream_config = self.get_stream_kwargs(config)
|
177
147
|
|
178
|
-
streams =
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
SearchAnalyticsKeywordSiteReportByPage(**stream_config),
|
193
|
-
SearchAnalyticsKeywordSiteReportByPageMinimalDimensions(**stream_config),
|
194
|
-
SearchAnalyticsKeywordSiteReportBySite(**stream_config),
|
195
|
-
SearchAnalyticsKeywordSiteReportBySiteMinimalDimensions(**stream_config),
|
196
|
-
]
|
197
|
-
|
148
|
+
streams = super().streams(config=config)
|
149
|
+
|
150
|
+
streams.extend(
|
151
|
+
[
|
152
|
+
SearchAnalyticsByDevice(**stream_config),
|
153
|
+
SearchAnalyticsByDate(**stream_config),
|
154
|
+
SearchAnalyticsByQuery(**stream_config),
|
155
|
+
SearchAnalyticsByPage(**stream_config),
|
156
|
+
SearchAnalyticsAllFields(**stream_config),
|
157
|
+
SearchAnalyticsPageReport(**stream_config),
|
158
|
+
SearchAnalyticsSiteReportBySite(**stream_config),
|
159
|
+
SearchAnalyticsSiteReportByPage(**stream_config),
|
160
|
+
]
|
161
|
+
)
|
198
162
|
streams = streams + self.get_custom_reports(config=config, stream_config=stream_config)
|
199
163
|
|
200
164
|
return streams
|
@@ -157,6 +157,13 @@
|
|
157
157
|
"examples": ["final", "all"],
|
158
158
|
"default": "final",
|
159
159
|
"order": 6
|
160
|
+
},
|
161
|
+
"always_use_aggregation_type_auto": {
|
162
|
+
"type": "boolean",
|
163
|
+
"title": "Always Use Aggregation Type Auto",
|
164
|
+
"description": "Some search analytics streams fail with a 400 error if the specified `aggregationType` is not supported. This is customer implementation dependent and if this error is encountered, enable this setting which will override the existing `aggregationType` to use `auto` which should resolve the stream errors.",
|
165
|
+
"default": false,
|
166
|
+
"order": 7
|
160
167
|
}
|
161
168
|
}
|
162
169
|
},
|
@@ -81,40 +81,7 @@ class GoogleSearchConsole(HttpStream, ABC):
|
|
81
81
|
self.logger.error(f"Stream `{self.name}`. {error.get('message')}. Trying with `aggregationType = auto` instead.")
|
82
82
|
self.aggregation_type = QueryAggregationType.auto
|
83
83
|
setattr(self, "raise_on_http_errors", False)
|
84
|
-
return
|
85
|
-
|
86
|
-
|
87
|
-
class Sites(GoogleSearchConsole):
|
88
|
-
"""
|
89
|
-
API docs: https://developers.google.com/webmaster-tools/search-console-api-original/v3/sites
|
90
|
-
"""
|
91
|
-
|
92
|
-
primary_key = None
|
93
|
-
|
94
|
-
def path(
|
95
|
-
self,
|
96
|
-
stream_state: Mapping[str, Any] = None,
|
97
|
-
stream_slice: Mapping[str, Any] = None,
|
98
|
-
next_page_token: Mapping[str, Any] = None,
|
99
|
-
) -> str:
|
100
|
-
return f"sites/{stream_slice.get('site_url')}"
|
101
|
-
|
102
|
-
|
103
|
-
class Sitemaps(GoogleSearchConsole):
|
104
|
-
"""
|
105
|
-
API docs: https://developers.google.com/webmaster-tools/search-console-api-original/v3/sitemaps
|
106
|
-
"""
|
107
|
-
|
108
|
-
primary_key = None
|
109
|
-
data_field = "sitemap"
|
110
|
-
|
111
|
-
def path(
|
112
|
-
self,
|
113
|
-
stream_state: Mapping[str, Any] = None,
|
114
|
-
stream_slice: Mapping[str, Any] = None,
|
115
|
-
next_page_token: Mapping[str, Any] = None,
|
116
|
-
) -> str:
|
117
|
-
return f"sites/{stream_slice.get('site_url')}/sitemaps"
|
84
|
+
return response.status_code == 429 or 500 <= response.status_code < 600
|
118
85
|
|
119
86
|
|
120
87
|
class SearchAnalytics(GoogleSearchConsole, CheckpointMixin, ABC):
|
@@ -333,12 +300,6 @@ class SearchAnalyticsByDate(SearchAnalytics):
|
|
333
300
|
dimensions = ["date"]
|
334
301
|
|
335
302
|
|
336
|
-
class SearchAnalyticsByCountry(SearchAnalytics):
|
337
|
-
primary_key = ["site_url", "date", "country", "search_type"]
|
338
|
-
search_types = ["web", "news", "image", "video", "discover", "googleNews"]
|
339
|
-
dimensions = ["date", "country"]
|
340
|
-
|
341
|
-
|
342
303
|
class SearchAnalyticsByDevice(SearchAnalytics):
|
343
304
|
primary_key = ["site_url", "date", "device", "search_type"]
|
344
305
|
search_types = ["web", "news", "image", "video", "googleNews"]
|
@@ -361,87 +322,6 @@ class SearchAnalyticsAllFields(SearchAnalytics):
|
|
361
322
|
dimensions = ["date", "country", "device", "page", "query"]
|
362
323
|
|
363
324
|
|
364
|
-
class SearchAppearance(SearchAnalytics):
|
365
|
-
"""
|
366
|
-
Dimension searchAppearance can't be used with other dimension.
|
367
|
-
search appearance data (AMP, blue link, rich result, and so on) must be queried using a two-step process.
|
368
|
-
https://developers.google.com/webmaster-tools/v1/how-tos/all-your-data#search-appearance-data
|
369
|
-
"""
|
370
|
-
|
371
|
-
primary_key = None
|
372
|
-
dimensions = ["searchAppearance"]
|
373
|
-
|
374
|
-
|
375
|
-
class SearchByKeyword(SearchAnalytics):
|
376
|
-
"""
|
377
|
-
Adds searchAppearance value to dimensionFilterGroups in json body
|
378
|
-
https://developers.google.com/webmaster-tools/v1/how-tos/all-your-data#search-appearance-data
|
379
|
-
|
380
|
-
groupType: "and" - Whether all filters in this group must return true ("and"), or one or more must return true (not yet supported).
|
381
|
-
filters: {"dimension": "searchAppearance", "operator": "equals", "expression": keyword}
|
382
|
-
"""
|
383
|
-
|
384
|
-
def stream_slices(
|
385
|
-
self, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None
|
386
|
-
) -> Iterable[Optional[Mapping[str, Any]]]:
|
387
|
-
search_appearance_stream = SearchAppearance(self._session.auth, self._site_urls, self._start_date, self._end_date)
|
388
|
-
|
389
|
-
for stream_slice in super().stream_slices(sync_mode, cursor_field, stream_state):
|
390
|
-
keywords_records = search_appearance_stream.read_records(
|
391
|
-
sync_mode=SyncMode.full_refresh, stream_state=stream_state, stream_slice=stream_slice
|
392
|
-
)
|
393
|
-
keywords = {record["searchAppearance"] for record in keywords_records}
|
394
|
-
|
395
|
-
for keyword in keywords:
|
396
|
-
filters = {"dimension": "searchAppearance", "operator": "equals", "expression": keyword}
|
397
|
-
stream_slice["dimensionFilterGroups"] = [{"groupType": "and", "filters": filters}]
|
398
|
-
yield stream_slice
|
399
|
-
|
400
|
-
def request_body_json(
|
401
|
-
self,
|
402
|
-
stream_state: Mapping[str, Any] = None,
|
403
|
-
stream_slice: Mapping[str, Any] = None,
|
404
|
-
next_page_token: Mapping[str, Any] = None,
|
405
|
-
) -> Optional[Union[Dict[str, Any], str]]:
|
406
|
-
data = super().request_body_json(stream_state, stream_slice, next_page_token)
|
407
|
-
data["dimensionFilterGroups"] = stream_slice["dimensionFilterGroups"]
|
408
|
-
return data
|
409
|
-
|
410
|
-
|
411
|
-
class SearchAnalyticsKeywordPageReport(SearchByKeyword):
|
412
|
-
primary_key = ["site_url", "date", "country", "device", "query", "page", "search_type"]
|
413
|
-
dimensions = ["date", "country", "device", "query", "page"]
|
414
|
-
|
415
|
-
|
416
|
-
class SearchAnalyticsKeywordPageReportMinimalDimensions(SearchByKeyword):
|
417
|
-
primary_key = ["site_url", "date", "country", "device", "query", "page", "search_type"]
|
418
|
-
dimensions = ["date"]
|
419
|
-
|
420
|
-
|
421
|
-
class SearchAnalyticsKeywordSiteReportByPage(SearchByKeyword):
|
422
|
-
primary_key = ["site_url", "date", "country", "device", "query", "search_type"]
|
423
|
-
dimensions = ["date", "country", "device", "query"]
|
424
|
-
aggregation_type = QueryAggregationType.by_page
|
425
|
-
|
426
|
-
|
427
|
-
class SearchAnalyticsKeywordSiteReportByPageMinimalDimensions(SearchByKeyword):
|
428
|
-
primary_key = ["site_url", "date", "country", "device", "query", "search_type"]
|
429
|
-
dimensions = ["date"]
|
430
|
-
aggregation_type = QueryAggregationType.by_page
|
431
|
-
|
432
|
-
|
433
|
-
class SearchAnalyticsKeywordSiteReportBySite(SearchByKeyword):
|
434
|
-
primary_key = ["site_url", "date", "country", "device", "query", "search_type"]
|
435
|
-
dimensions = ["date", "country", "device", "query"]
|
436
|
-
aggregation_type = QueryAggregationType.by_property
|
437
|
-
|
438
|
-
|
439
|
-
class SearchAnalyticsKeywordSiteReportBySiteMinimalDimensions(SearchByKeyword):
|
440
|
-
primary_key = ["site_url", "date", "country", "device", "query", "search_type"]
|
441
|
-
dimensions = ["date"]
|
442
|
-
aggregation_type = QueryAggregationType.by_property
|
443
|
-
|
444
|
-
|
445
325
|
class SearchAnalyticsSiteReportBySite(SearchAnalytics):
|
446
326
|
primary_key = ["site_url", "date", "country", "device", "search_type"]
|
447
327
|
dimensions = ["date", "country", "device"]
|
@@ -1,29 +0,0 @@
|
|
1
|
-
source_google_search_console/__init__.py,sha256=HQCPu-CK7XmVDtP9rmTdB2XyraVCc6pv9pw38-O8y48,1191
|
2
|
-
source_google_search_console/config_migrations.py,sha256=9C8QoELMAxt8NHiEY4fZMCYy5PwoOSUd6vSwoC1B3FM,4135
|
3
|
-
source_google_search_console/exceptions.py,sha256=iD3jYC4WxVCEKGsqQ7Vaj1tbjhJZ4S5mnSDnwFJdsIQ,1097
|
4
|
-
source_google_search_console/run.py,sha256=q6O2iXoxtrdgtodCaanqTO2eKzUvXF2iDCfmCxaPE24,462
|
5
|
-
source_google_search_console/schemas/search_analytics_all_fields.json,sha256=iQxRh_c_yz3uGofqpo1KX571TMmzYjKScb0PtI6SN_Q,1729
|
6
|
-
source_google_search_console/schemas/search_analytics_by_country.json,sha256=xvUVjGRy63dsc7c0O-Kg7DUzybRpD-r_-VYhPmDBw_o,1491
|
7
|
-
source_google_search_console/schemas/search_analytics_by_date.json,sha256=meCbWDayc1y0q-Lu-CAdjQVnsM8xZBX3BdF129UC1P8,1388
|
8
|
-
source_google_search_console/schemas/search_analytics_by_device.json,sha256=VtoFjmmv9rx-uhSFaRn0wm4LeSxRIaexrxg2Spvbneo,1525
|
9
|
-
source_google_search_console/schemas/search_analytics_by_page.json,sha256=KyUojZc4Lv3hPswxIJzUL5QDNsbvSugGjl_uHGF7Am4,1473
|
10
|
-
source_google_search_console/schemas/search_analytics_by_query.json,sha256=mYc1Fu1A5TWLZCApZSjjfs_urW5BRUCPQI3rw3yQjt4,1439
|
11
|
-
source_google_search_console/schemas/search_analytics_keyword_page_report.json,sha256=hCQZbpW9UNiCOrnUMkj4oQdzY0k8Hqoh1XkuKHvyvZw,1681
|
12
|
-
source_google_search_console/schemas/search_analytics_keyword_page_report_minimal_dimensions.json,sha256=hCQZbpW9UNiCOrnUMkj4oQdzY0k8Hqoh1XkuKHvyvZw,1681
|
13
|
-
source_google_search_console/schemas/search_analytics_keyword_site_report_by_page.json,sha256=lFpbShmTQhFyySc_JCdIOqMP9RfOIA15fpQN9xNXtTI,1626
|
14
|
-
source_google_search_console/schemas/search_analytics_keyword_site_report_by_page_minimal_dimensions.json,sha256=lFpbShmTQhFyySc_JCdIOqMP9RfOIA15fpQN9xNXtTI,1626
|
15
|
-
source_google_search_console/schemas/search_analytics_keyword_site_report_by_site.json,sha256=AVUl5x9jLL0FcStbTR-FMy-_A7uM-VlrJ-kdCBXWz_g,1755
|
16
|
-
source_google_search_console/schemas/search_analytics_keyword_site_report_by_site_minimal_dimensions.json,sha256=AVUl5x9jLL0FcStbTR-FMy-_A7uM-VlrJ-kdCBXWz_g,1755
|
17
|
-
source_google_search_console/schemas/search_analytics_page_report.json,sha256=-b0Y0LenTchS0q9A2aQ4hIjUjXkYF8erOtyrTMhf6MM,1776
|
18
|
-
source_google_search_console/schemas/search_analytics_site_report_by_page.json,sha256=hWKHkm1reqGGu1dNcWBe6_XkZ5tK-UaiymrYRVgxRxI,1515
|
19
|
-
source_google_search_console/schemas/search_analytics_site_report_by_site.json,sha256=rAh6LuNy7nCrrNM9MTd0qxAVc886ecQaqWRgV63OfyA,1408
|
20
|
-
source_google_search_console/schemas/sitemaps.json,sha256=coyPSZCAfzMheybfRp4WPAZCp5JF2KGRF2rWK8oC080,1775
|
21
|
-
source_google_search_console/schemas/sites.json,sha256=WNiCRuStPL1YkJiFa8FEbNJmqaERAOf9Yow6ygIumvo,383
|
22
|
-
source_google_search_console/service_account_authenticator.py,sha256=gjUxt0xFxj82uviCQNTsA1Jlee__UDhYNjE7bRO1G0U,1227
|
23
|
-
source_google_search_console/source.py,sha256=4UJW4KUVGo5WxH9ewWBVSemXH17Iqp-eaNRtUfLNET8,10431
|
24
|
-
source_google_search_console/spec.json,sha256=WYtFvaSqWYGm1Dt2yV9G92U78Q94rh9oarbxJe3H7xo,8470
|
25
|
-
source_google_search_console/streams.py,sha256=1rgtlcVUyAP3oKRNQ34qIh6rwTzvlr636GiEy0RPQLs,20508
|
26
|
-
airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info/METADATA,sha256=YyTR_gsHe3OcxaiSStl2wtO8Wa5Vsfm16QJ6miZG8JA,5645
|
27
|
-
airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
28
|
-
airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info/entry_points.txt,sha256=DMcgc9bCX-Vt6hm_68pa77qS3eGdeMhg-UdlFc-XKUM,85
|
29
|
-
airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info/RECORD,,
|
@@ -1,41 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
3
|
-
"type": "object",
|
4
|
-
"properties": {
|
5
|
-
"site_url": {
|
6
|
-
"description": "The URL of the site for which the search analytics data is being reported.",
|
7
|
-
"type": ["null", "string"]
|
8
|
-
},
|
9
|
-
"search_type": {
|
10
|
-
"description": "The type of search (web search, image search, video search, etc.) for which the data is being reported.",
|
11
|
-
"type": ["null", "string"]
|
12
|
-
},
|
13
|
-
"date": {
|
14
|
-
"description": "The date for which the search analytics data is being reported.",
|
15
|
-
"type": ["null", "string"],
|
16
|
-
"format": "date"
|
17
|
-
},
|
18
|
-
"country": {
|
19
|
-
"description": "The country for which the search analytics data is being reported.",
|
20
|
-
"type": ["null", "string"]
|
21
|
-
},
|
22
|
-
"clicks": {
|
23
|
-
"description": "The number of times users clicked on the search result for a specific country.",
|
24
|
-
"type": ["null", "integer"]
|
25
|
-
},
|
26
|
-
"impressions": {
|
27
|
-
"description": "The total number of times a search result was shown in search results for a specific country.",
|
28
|
-
"type": ["null", "integer"]
|
29
|
-
},
|
30
|
-
"ctr": {
|
31
|
-
"description": "The click-through rate, i.e., the ratio of clicks to impressions for a specific country.",
|
32
|
-
"type": ["null", "number"],
|
33
|
-
"multipleOf": 1e-25
|
34
|
-
},
|
35
|
-
"position": {
|
36
|
-
"description": "The average position at which the site's search result appeared for a specific country.",
|
37
|
-
"type": ["null", "number"],
|
38
|
-
"multipleOf": 1e-25
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
@@ -1,54 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
-
"type": "object",
|
4
|
-
"additionalProperties": true,
|
5
|
-
"properties": {
|
6
|
-
"site_url": {
|
7
|
-
"description": "The URL of the website being monitored.",
|
8
|
-
"type": ["null", "string"]
|
9
|
-
},
|
10
|
-
"search_type": {
|
11
|
-
"description": "The type of search (e.g., web, image, video).",
|
12
|
-
"type": ["null", "string"]
|
13
|
-
},
|
14
|
-
"date": {
|
15
|
-
"description": "The date of the search data collected.",
|
16
|
-
"type": ["null", "string"],
|
17
|
-
"format": "date"
|
18
|
-
},
|
19
|
-
"country": {
|
20
|
-
"description": "The country where the search is made.",
|
21
|
-
"type": ["null", "string"]
|
22
|
-
},
|
23
|
-
"device": {
|
24
|
-
"description": "The device type used for the search (e.g., desktop, mobile).",
|
25
|
-
"type": ["null", "string"]
|
26
|
-
},
|
27
|
-
"page": {
|
28
|
-
"description": "The page URL on which the keyword appears in search results.",
|
29
|
-
"type": ["null", "string"]
|
30
|
-
},
|
31
|
-
"query": {
|
32
|
-
"description": "The search query used to find the site.",
|
33
|
-
"type": ["null", "string"]
|
34
|
-
},
|
35
|
-
"clicks": {
|
36
|
-
"description": "The number of clicks for the keyword on a specific page.",
|
37
|
-
"type": ["null", "integer"]
|
38
|
-
},
|
39
|
-
"impressions": {
|
40
|
-
"description": "The number of times the keyword appeared in search results.",
|
41
|
-
"type": ["null", "integer"]
|
42
|
-
},
|
43
|
-
"ctr": {
|
44
|
-
"description": "Click-through rate which is the percentage of clicks divided by impressions.",
|
45
|
-
"type": ["null", "number"],
|
46
|
-
"multipleOf": 1e-25
|
47
|
-
},
|
48
|
-
"position": {
|
49
|
-
"description": "The average position of the keyword on search results pages.",
|
50
|
-
"type": ["null", "number"],
|
51
|
-
"multipleOf": 1e-25
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
source_google_search_console/schemas/search_analytics_keyword_page_report_minimal_dimensions.json
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
-
"type": "object",
|
4
|
-
"additionalProperties": true,
|
5
|
-
"properties": {
|
6
|
-
"site_url": {
|
7
|
-
"description": "The URL of the website being monitored.",
|
8
|
-
"type": ["null", "string"]
|
9
|
-
},
|
10
|
-
"search_type": {
|
11
|
-
"description": "The type of search (e.g., web, image, video).",
|
12
|
-
"type": ["null", "string"]
|
13
|
-
},
|
14
|
-
"date": {
|
15
|
-
"description": "The date of the search data collected.",
|
16
|
-
"type": ["null", "string"],
|
17
|
-
"format": "date"
|
18
|
-
},
|
19
|
-
"country": {
|
20
|
-
"description": "The country where the search is made.",
|
21
|
-
"type": ["null", "string"]
|
22
|
-
},
|
23
|
-
"device": {
|
24
|
-
"description": "The device type used for the search (e.g., desktop, mobile).",
|
25
|
-
"type": ["null", "string"]
|
26
|
-
},
|
27
|
-
"page": {
|
28
|
-
"description": "The page URL on which the keyword appears in search results.",
|
29
|
-
"type": ["null", "string"]
|
30
|
-
},
|
31
|
-
"query": {
|
32
|
-
"description": "The search query used to find the site.",
|
33
|
-
"type": ["null", "string"]
|
34
|
-
},
|
35
|
-
"clicks": {
|
36
|
-
"description": "The number of clicks for the keyword on a specific page.",
|
37
|
-
"type": ["null", "integer"]
|
38
|
-
},
|
39
|
-
"impressions": {
|
40
|
-
"description": "The number of times the keyword appeared in search results.",
|
41
|
-
"type": ["null", "integer"]
|
42
|
-
},
|
43
|
-
"ctr": {
|
44
|
-
"description": "Click-through rate which is the percentage of clicks divided by impressions.",
|
45
|
-
"type": ["null", "number"],
|
46
|
-
"multipleOf": 1e-25
|
47
|
-
},
|
48
|
-
"position": {
|
49
|
-
"description": "The average position of the keyword on search results pages.",
|
50
|
-
"type": ["null", "number"],
|
51
|
-
"multipleOf": 1e-25
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
@@ -1,50 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"$schema": "https://json-schema.org/draft-07/schema#",
|
3
|
-
"type": "object",
|
4
|
-
"additionalProperties": true,
|
5
|
-
"properties": {
|
6
|
-
"site_url": {
|
7
|
-
"description": "The URL of the website for which the search analytics data is retrieved.",
|
8
|
-
"type": ["null", "string"]
|
9
|
-
},
|
10
|
-
"search_type": {
|
11
|
-
"description": "The type of search conducted (e.g., web, image, video).",
|
12
|
-
"type": ["null", "string"]
|
13
|
-
},
|
14
|
-
"date": {
|
15
|
-
"description": "The date when the search data was recorded.",
|
16
|
-
"type": ["null", "string"],
|
17
|
-
"format": "date"
|
18
|
-
},
|
19
|
-
"country": {
|
20
|
-
"description": "The country from which the search query originated.",
|
21
|
-
"type": ["null", "string"]
|
22
|
-
},
|
23
|
-
"device": {
|
24
|
-
"description": "The device type used for the search query (e.g., desktop, mobile).",
|
25
|
-
"type": ["null", "string"]
|
26
|
-
},
|
27
|
-
"query": {
|
28
|
-
"description": "The search query used by the user.",
|
29
|
-
"type": ["null", "string"]
|
30
|
-
},
|
31
|
-
"clicks": {
|
32
|
-
"description": "The number of times users clicked on your website link in search results.",
|
33
|
-
"type": ["null", "integer"]
|
34
|
-
},
|
35
|
-
"impressions": {
|
36
|
-
"description": "The number of times your website link appeared in search results.",
|
37
|
-
"type": ["null", "integer"]
|
38
|
-
},
|
39
|
-
"ctr": {
|
40
|
-
"description": "Click-through rate: Number of clicks divided by the number of impressions.",
|
41
|
-
"type": ["null", "number"],
|
42
|
-
"multipleOf": 1e-25
|
43
|
-
},
|
44
|
-
"position": {
|
45
|
-
"description": "The average position of your website link in search results.",
|
46
|
-
"type": ["null", "number"],
|
47
|
-
"multipleOf": 1e-25
|
48
|
-
}
|
49
|
-
}
|
50
|
-
}
|