diff --git a/airbyte-integrations/connectors/source-google-ads/metadata.yaml b/airbyte-integrations/connectors/source-google-ads/metadata.yaml index 8b95192dcb09..5a940f543ff5 100644 --- a/airbyte-integrations/connectors/source-google-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-ads/metadata.yaml @@ -11,7 +11,7 @@ data: connectorSubtype: api connectorType: source definitionId: 253487c0-2246-43ba-a21f-5116b20a2c50 - dockerImageTag: 3.7.8 + dockerImageTag: 3.7.9 dockerRepository: airbyte/source-google-ads documentationUrl: https://docs.airbyte.com/integrations/sources/google-ads githubIssueLabel: source-google-ads diff --git a/airbyte-integrations/connectors/source-google-ads/pyproject.toml b/airbyte-integrations/connectors/source-google-ads/pyproject.toml index e233d58ac56f..431e6ffefcf2 100644 --- a/airbyte-integrations/connectors/source-google-ads/pyproject.toml +++ b/airbyte-integrations/connectors/source-google-ads/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "3.7.8" +version = "3.7.9" name = "source-google-ads" description = "Source implementation for Google Ads." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/models.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/models.py index 7da4ed7c2b9c..269448ff25f9 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/models.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/models.py @@ -4,7 +4,7 @@ from dataclasses import dataclass -from typing import Any, Iterable, Mapping +from typing import Any, Iterable, List, Mapping from pendulum import local_timezone, timezone from pendulum.tz.timezone import Timezone @@ -18,18 +18,31 @@ class CustomerModel: login_customer_id: str = None @classmethod - def from_accounts(cls, accounts: Iterable[Mapping[str, Any]]) -> Iterable["CustomerModel"]: - data_objects = [] + def _unique_from_accounts(cls, accounts: Iterable[Mapping[str, Any]]) -> Iterable["CustomerModel"]: + seen_ids = set() + for account in accounts: time_zone_name = account.get("customer_client.time_zone") tz = Timezone(time_zone_name) if time_zone_name else local_timezone() + customer_id = str(account["customer_client.id"]) + + # filter duplicates as one customer can be accessible from multiple connected accounts + if customer_id in seen_ids: + continue - data_objects.append( - cls( - id=str(account["customer_client.id"]), - time_zone=tz, - is_manager_account=bool(account.get("customer_client.manager")), - login_customer_id=account.get("login_customer_id"), - ) + yield cls( + id=customer_id, + time_zone=tz, + is_manager_account=bool(account.get("customer_client.manager")), + login_customer_id=account.get("login_customer_id"), ) - return data_objects + + seen_ids.add(customer_id) + + @classmethod + def from_accounts(cls, accounts: Iterable[Mapping[str, Any]]) -> List["CustomerModel"]: + return list(cls._unique_from_accounts(accounts)) + + @classmethod + def from_accounts_by_id(cls, accounts: Iterable[Mapping[str, Any]], customer_ids: List[str]) -> List["CustomerModel"]: + return [customer for customer in cls._unique_from_accounts(accounts) if customer.id in customer_ids] diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py index 8f1acf2ecfbd..562dacf6f899 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py @@ -116,28 +116,13 @@ def _get_all_connected_accounts( def get_customers(self, google_api: GoogleAds, config: Mapping[str, Any]) -> List[CustomerModel]: customer_status_filter = config.get("customer_status_filter", []) accounts = self._get_all_connected_accounts(google_api, customer_status_filter) - customers = CustomerModel.from_accounts(accounts) - - # filter duplicates as one customer can be accessible from mutiple connected accounts - unique_customers = [] - seen_ids = set() - for customer in customers: - if customer.id in seen_ids: - continue - seen_ids.add(customer.id) - unique_customers.append(customer) - customers = unique_customers - customers_dict = {customer.id: customer for customer in customers} # filter only selected accounts if config.get("customer_ids"): - customers = [] - for customer_id in config["customer_ids"]: - if customer_id not in customers_dict: - logging.warning(f"Customer with id {customer_id} is not accessible. Skipping it.") - else: - customers.append(customers_dict[customer_id]) - return customers + return CustomerModel.from_accounts_by_id(accounts, config["customer_ids"]) + + # all unique accounts + return CustomerModel.from_accounts(accounts) @staticmethod def is_metrics_in_custom_query(query: GAQL) -> bool: diff --git a/docs/integrations/sources/google-ads.md b/docs/integrations/sources/google-ads.md index bb981b4a26bd..9e1786657280 100644 --- a/docs/integrations/sources/google-ads.md +++ b/docs/integrations/sources/google-ads.md @@ -335,14 +335,15 @@ Due to a limitation in the Google Ads API which does not allow getting performan | Version | Date | Pull Request | Subject | |:----------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| -| 3.7.8 | 2024-10-12 | [46120](https://github.com/airbytehq/airbyte/pull/46120) | Update dependencies | -| 3.7.7 | 2024-10-07 | [45852](https://github.com/airbytehq/airbyte/pull/45852) | Change to the objects serialization in lists to JSON | -| 3.7.6 | 2024-09-21 | [46543](https://github.com/airbytehq/airbyte/pull/46543) | Raise exception on missing stream | -| 3.7.5 | 2024-09-21 | [45801](https://github.com/airbytehq/airbyte/pull/45801) | Update dependencies | -| 3.7.4 | 2024-09-20 | [44600](https://github.com/airbytehq/airbyte/pull/44600) | Update API documentation URLs | -| 3.7.3 | 2024-09-14 | [45497](https://github.com/airbytehq/airbyte/pull/45497) | Update dependencies | -| 3.7.2 | 2024-09-07 | [45263](https://github.com/airbytehq/airbyte/pull/45263) | Update dependencies | -| 3.7.1 | 2024-08-31 | [44326](https://github.com/airbytehq/airbyte/pull/44326) | Update dependencies | +| 3.7.9 | 2024-10-14 | [46893](https://github.com/airbytehq/airbyte/pull/46893) | Update getting customers logic | +| 3.7.8 | 2024-10-12 | [46120](https://github.com/airbytehq/airbyte/pull/46120) | Update dependencies | +| 3.7.7 | 2024-10-07 | [45852](https://github.com/airbytehq/airbyte/pull/45852) | Change to the objects serialization in lists to JSON | +| 3.7.6 | 2024-09-21 | [46543](https://github.com/airbytehq/airbyte/pull/46543) | Raise exception on missing stream | +| 3.7.5 | 2024-09-21 | [45801](https://github.com/airbytehq/airbyte/pull/45801) | Update dependencies | +| 3.7.4 | 2024-09-20 | [44600](https://github.com/airbytehq/airbyte/pull/44600) | Update API documentation URLs | +| 3.7.3 | 2024-09-14 | [45497](https://github.com/airbytehq/airbyte/pull/45497) | Update dependencies | +| 3.7.2 | 2024-09-07 | [45263](https://github.com/airbytehq/airbyte/pull/45263) | Update dependencies | +| 3.7.1 | 2024-08-31 | [44326](https://github.com/airbytehq/airbyte/pull/44326) | Update dependencies | | `3.7.0 ` | 2024-08-15 | [44095](https://github.com/airbytehq/airbyte/pull/44095) | Migrate to google-ads v17 | | `3.6.5 ` | 2024-08-12 | [43882](https://github.com/airbytehq/airbyte/pull/43882) | Update dependencies | | `3.6.4` | 2024-08-10 | [43628](https://github.com/airbytehq/airbyte/pull/43628) | Update dependencies |