Skip to content

Commit f6fd017

Browse files
fix(source-google-search-console): fix request body for report streams by keyword (#45196)
1 parent 4559c75 commit f6fd017

File tree

7 files changed

+89
-75
lines changed

7 files changed

+89
-75
lines changed

airbyte-integrations/connectors/source-google-search-console/acceptance-test-config.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ acceptance_tests:
1414
tests:
1515
- config_path: "secrets/config.json"
1616
status: "succeed"
17-
- config_path: "secrets/service_account_config.json"
18-
status: "succeed"
17+
# TODO: uncomment testing on service_account_config.json when we update creds
18+
# - config_path: "secrets/service_account_config.json"
19+
# status: "succeed"
1920
- config_path: "integration_tests/invalid_config.json"
2021
status: "failed"
2122
discovery:

airbyte-integrations/connectors/source-google-search-console/integration_tests/expected_records.jsonl

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
{"stream": "search_analytics_all_fields", "data": {"clicks": 2, "impressions": 2, "ctr": 1, "position": 2, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/integrating-keycloak-iam-with-airbyte/2826", "query": "airbyte keycloak"}, "emitted_at": 1709913953146}
1616
{"stream": "custom_dimensions", "data": {"clicks": 97, "impressions": 2392, "ctr": 0.040551839464882944, "position": 24.149247491638796, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913970183}
1717
{"stream": "custom_dimensions", "data": {"clicks": 81, "impressions": 2220, "ctr": 0.03648648648648649, "position": 27.025675675675675, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913970184}
18-
{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 6, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-08", "country": "usa", "device": "DESKTOP", "query": "fatal: not a dbt project (or any of the parent directories). missing dbt_project.yml file", "page": "https://discuss.airbyte.io/t/how-to-set-workspace-folder-job-id-in-entrypoint-arguments-for-custom-dbt-transformation/2805"}, "emitted_at": 1709913956708}
19-
{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 4, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-09", "country": "usa", "device": "DESKTOP", "query": "could not find a version that satisfies the requirement comm>=0.1.3", "page": "https://discuss.airbyte.io/t/error-could-not-find-a-version-that-satisfies-the-requirement-airbyte-cdk-0-1-56/1397"}, "emitted_at": 1709913956709}
18+
{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 4, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-01", "country": "ind", "device": "DESKTOP", "query": "airbyte octavia", "page": "https://discuss.airbyte.io/t/airbyte-connectors-configuration-data-storage-using-octavia/3145"}, "emitted_at": 1725547397864}
19+
{"stream": "search_analytics_keyword_page_report", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 32, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-08-31", "country": "are", "device": "DESKTOP", "query": "database in k8s", "page": "https://discuss.airbyte.io/t/kubernetes-temporal-deployment-failling-to-connect-with-external-azure-postgres-db/2928"}, "emitted_at": 1725547398182}
2020
{"stream": "search_analytics_page_report", "data": {"clicks": 2, "impressions": 4, "ctr": 0.5, "position": 2.5, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "gbr", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/using-a-private-git-repo-for-transformations-the-selection-criterion-does-not-match-any-nodes/4170"}, "emitted_at": 1709913968085}
2121
{"stream": "search_analytics_page_report", "data": {"clicks": 2, "impressions": 3, "ctr": 0.6666666666666666, "position": 1, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "deu", "device": "DESKTOP", "page": "https://discuss.airbyte.io/t/mixpanel-connector-issue-follow-up-on-previous-case/2814"}, "emitted_at": 1709913968086}
22-
{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 6, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-08", "country": "usa", "device": "DESKTOP", "query": "fatal: not a dbt project (or any of the parent directories). missing dbt_project.yml file"}, "emitted_at": 1709913961303}
23-
{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 4, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-09", "country": "usa", "device": "DESKTOP", "query": "could not find a version that satisfies the requirement comm>=0.1.3"}, "emitted_at": 1709913961305}
24-
{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 5, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-10", "country": "usa", "device": "DESKTOP", "query": "fatal: not a dbt project (or any of the parent directories). missing dbt_project.yml file"}, "emitted_at": 1709913966177}
25-
{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 5, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-11", "country": "usa", "device": "DESKTOP", "query": "dbt_project.yml not found"}, "emitted_at": 1709913966179}
22+
{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 6, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-12", "country": "aus", "device": "DESKTOP", "query": "nothing to do. try checking your model configs and model specification args"}, "emitted_at": 1726485253585}
23+
{"stream": "search_analytics_keyword_site_report_by_page", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 3, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-12", "country": "can", "device": "DESKTOP", "query": "did not find matching node for patch with name"}, "emitted_at": 1726485254092}
24+
{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 1, "impressions": 1, "ctr": 1, "position": 4, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-06", "country": "can", "device": "DESKTOP", "query": "airbyte datadog"}, "emitted_at": 1725874488288}
25+
{"stream": "search_analytics_keyword_site_report_by_site", "data": {"clicks": 0, "impressions": 1, "ctr": 0, "position": 12, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-09-06", "country": "can", "device": "DESKTOP", "query": "error: could not find a version that satisfies the requirement pyyaml (from versions: none)"}, "emitted_at": 1725874488655}
2626
{"stream": "search_analytics_site_report_by_page", "data": {"clicks": 105, "impressions": 2905, "ctr": 0.03614457831325301, "position": 21.6447504302926, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913968684}
2727
{"stream": "search_analytics_site_report_by_page", "data": {"clicks": 87, "impressions": 2598, "ctr": 0.03348729792147806, "position": 24.50269438029253, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-02", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913968685}
2828
{"stream": "search_analytics_site_report_by_site", "data": {"clicks": 97, "impressions": 2392, "ctr": 0.040551839464882944, "position": 24.149247491638796, "site_url": "sc-domain:airbyte.io", "search_type": "web", "date": "2024-01-03", "country": "usa", "device": "DESKTOP"}, "emitted_at": 1709913969703}

airbyte-integrations/connectors/source-google-search-console/metadata.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ data:
1010
connectorSubtype: api
1111
connectorType: source
1212
definitionId: eb4c9e00-db83-4d63-a386-39cfa91012a8
13-
dockerImageTag: 1.5.3
13+
dockerImageTag: 1.5.4
1414
dockerRepository: airbyte/source-google-search-console
1515
documentationUrl: https://docs.airbyte.com/integrations/sources/google-search-console
1616
erdUrl: https://dbdocs.io/airbyteio/source-google-search-console?view=relationships

airbyte-integrations/connectors/source-google-search-console/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
33
build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
6-
version = "1.5.3"
6+
version = "1.5.4"
77
name = "source-google-search-console"
88
description = "Source implementation for Google Search Console."
99
authors = [ "Airbyte <[email protected]>",]

airbyte-integrations/connectors/source-google-search-console/source_google_search_console/streams.py

+21-10
Original file line numberDiff line numberDiff line change
@@ -374,25 +374,36 @@ class SearchByKeyword(SearchAnalytics):
374374
"""
375375
Adds searchAppearance value to dimensionFilterGroups in json body
376376
https://developers.google.com/webmaster-tools/v1/how-tos/all-your-data#search-appearance-data
377+
378+
groupType: "and" - Whether all filters in this group must return true ("and"), or one or more must return true (not yet supported).
379+
filters: {"dimension": "searchAppearance", "operator": "equals", "expression": keyword}
377380
"""
378381

382+
def stream_slices(
383+
self, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None
384+
) -> Iterable[Optional[Mapping[str, Any]]]:
385+
search_appearance_stream = SearchAppearance(self._session.auth, self._site_urls, self._start_date, self._end_date)
386+
387+
for stream_slice in super().stream_slices(sync_mode, cursor_field, stream_state):
388+
keywords_records = search_appearance_stream.read_records(
389+
sync_mode=SyncMode.full_refresh, stream_state=stream_state, stream_slice=stream_slice
390+
)
391+
keywords = {record["searchAppearance"] for record in keywords_records}
392+
393+
for keyword in keywords:
394+
filters = {"dimension": "searchAppearance", "operator": "equals", "expression": keyword}
395+
stream_slice["dimensionFilterGroups"] = [{"groupType": "and", "filters": filters}]
396+
397+
yield stream_slice
398+
379399
def request_body_json(
380400
self,
381401
stream_state: Mapping[str, Any] = None,
382402
stream_slice: Mapping[str, Any] = None,
383403
next_page_token: Mapping[str, Any] = None,
384404
) -> Optional[Union[Dict[str, Any], str]]:
385405
data = super().request_body_json(stream_state, stream_slice, next_page_token)
386-
387-
stream = SearchAppearance(self._session.auth, self._site_urls, self._start_date, self._end_date)
388-
keywords_records = stream.read_records(sync_mode=SyncMode.full_refresh, stream_state=stream_state, stream_slice=stream_slice)
389-
keywords = {record["searchAppearance"] for record in keywords_records}
390-
filters = []
391-
for keyword in keywords:
392-
filters.append({"dimension": "searchAppearance", "operator": "equals", "expression": keyword})
393-
394-
data["dimensionFilterGroups"] = [{"filters": filters}]
395-
406+
data["dimensionFilterGroups"] = stream_slice["dimensionFilterGroups"]
396407
return data
397408

398409

airbyte-integrations/connectors/source-google-search-console/unit_tests/unit_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ def test_forbidden_should_retry(requests_mock, forbidden_error_message_json):
133133

134134
def test_bad_aggregation_type_should_retry(requests_mock, bad_aggregation_type):
135135
stream = SearchAnalyticsKeywordSiteReportBySite(None, ["https://example.com"], "2021-01-01", "2021-01-02")
136+
requests_mock.post(f"{stream.url_base}sites/{stream._site_urls[0]}/searchAnalytics/query", status_code=200, json={"rows": [{"keys": ["TPF_QA"]}]})
136137
slice = list(stream.stream_slices(None))[0]
137138
url = stream.url_base + stream.path(None, slice)
138139
requests_mock.get(url, status_code=400, json=bad_aggregation_type)

0 commit comments

Comments
 (0)