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.
Files changed (22) hide show
  1. {airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info → airbyte_source_google_search_console-1.7.0.dist-info}/METADATA +4 -4
  2. airbyte_source_google_search_console-1.7.0.dist-info/RECORD +22 -0
  3. {airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info → airbyte_source_google_search_console-1.7.0.dist-info}/WHEEL +1 -1
  4. source_google_search_console/components.py +81 -0
  5. source_google_search_console/config_migrations.py +4 -1
  6. source_google_search_console/manifest.yaml +828 -0
  7. source_google_search_console/run.py +47 -9
  8. source_google_search_console/service_account_authenticator.py +3 -1
  9. source_google_search_console/source.py +23 -59
  10. source_google_search_console/spec.json +7 -0
  11. source_google_search_console/streams.py +1 -121
  12. airbyte_source_google_search_console-1.6.0.dev202503282247.dist-info/RECORD +0 -29
  13. source_google_search_console/schemas/search_analytics_by_country.json +0 -41
  14. source_google_search_console/schemas/search_analytics_keyword_page_report.json +0 -54
  15. source_google_search_console/schemas/search_analytics_keyword_page_report_minimal_dimensions.json +0 -54
  16. source_google_search_console/schemas/search_analytics_keyword_site_report_by_page.json +0 -50
  17. source_google_search_console/schemas/search_analytics_keyword_site_report_by_page_minimal_dimensions.json +0 -50
  18. source_google_search_console/schemas/search_analytics_keyword_site_report_by_site.json +0 -50
  19. source_google_search_console/schemas/search_analytics_keyword_site_report_by_site_minimal_dimensions.json +0 -50
  20. source_google_search_console/schemas/sitemaps.json +0 -61
  21. source_google_search_console/schemas/sites.json +0 -14
  22. {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) 2023 Airbyte, Inc., all rights reserved.
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 run():
14
- source = SourceGoogleSearchConsole()
15
- # migrate config at runtime
16
- MigrateCustomReports.migrate(sys.argv[1:], source)
17
- # run the connector
18
- launch(source, sys.argv[1:])
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
- credentials: Credentials = Credentials.from_service_account_info(self.service_account_info, scopes=self.scopes).with_subject(
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 AbstractSource
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(AbstractSource):
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
- authorization["service_account_info"] = json.loads(authorization["service_account_info"])
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()["siteEntry"]}
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
- Sites(**stream_config),
180
- Sitemaps(**stream_config),
181
- SearchAnalyticsByCountry(**stream_config),
182
- SearchAnalyticsByDevice(**stream_config),
183
- SearchAnalyticsByDate(**stream_config),
184
- SearchAnalyticsByQuery(**stream_config),
185
- SearchAnalyticsByPage(**stream_config),
186
- SearchAnalyticsAllFields(**stream_config),
187
- SearchAnalyticsKeywordPageReport(**stream_config),
188
- SearchAnalyticsKeywordPageReportMinimalDimensions(**stream_config),
189
- SearchAnalyticsPageReport(**stream_config),
190
- SearchAnalyticsSiteReportBySite(**stream_config),
191
- SearchAnalyticsSiteReportByPage(**stream_config),
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 super().should_retry(response)
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
- }
@@ -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
- }