2424
2525import argparse
2626import sys
27+ from typing import Optional , List , Dict
2728
2829from google .ads .googleads .client import GoogleAdsClient
2930from google .ads .googleads .errors import GoogleAdsException
30-
31-
32- def main (client , login_customer_id = None ):
31+ from google .ads .googleads .v20 .services .services .google_ads_service .client import (
32+ GoogleAdsServiceClient ,
33+ )
34+ from google .ads .googleads .v20 .services .services .customer_service .client import (
35+ CustomerServiceClient ,
36+ )
37+ from google .ads .googleads .v20 .resources .types .customer_client import (
38+ CustomerClient ,
39+ )
40+ from google .ads .googleads .v20 .services .types .google_ads_service import (
41+ SearchPagedResponse ,
42+ GoogleAdsRow ,
43+ )
44+
45+ # ListAccessibleCustomersResponse is not directly used for a variable type,
46+ # but its attribute .resource_names is used, which is List[str].
47+
48+
49+ def main (
50+ client : GoogleAdsClient , login_customer_id : Optional [str ] = None
51+ ) -> None :
3352 """Gets the account hierarchy of the given MCC and login customer ID.
3453
3554 Args:
@@ -38,13 +57,16 @@ def main(client, login_customer_id=None):
3857 method will instead list the accounts accessible from the
3958 authenticated Google Ads account.
4059 """
41-
4260 # Gets instances of the GoogleAdsService and CustomerService clients.
43- googleads_service = client .get_service ("GoogleAdsService" )
44- customer_service = client .get_service ("CustomerService" )
61+ googleads_service : GoogleAdsServiceClient = client .get_service (
62+ "GoogleAdsService"
63+ )
64+ customer_service : CustomerServiceClient = client .get_service (
65+ "CustomerService"
66+ )
4567
4668 # A collection of customer IDs to handle.
47- seed_customer_ids = []
69+ seed_customer_ids : List [ str ] = []
4870
4971 # Creates a query that retrieves all child accounts of the manager
5072 # specified in search calls below.
@@ -64,69 +86,84 @@ def main(client, login_customer_id=None):
6486 # the only ID in the list. Otherwise, we will issue a request for all
6587 # customers accessible by this authenticated Google account.
6688 if login_customer_id is not None :
89+ # Ensure login_customer_id is treated as a string for this list.
6790 seed_customer_ids = [login_customer_id ]
6891 else :
6992 print (
7093 "No manager ID is specified. The example will print the "
7194 "hierarchies of all accessible customer IDs."
7295 )
7396
74- customer_resource_names = (
97+ customer_resource_names : List [ str ] = (
7598 customer_service .list_accessible_customers ().resource_names
7699 )
77100
78101 for customer_resource_name in customer_resource_names :
79- customer_id = googleads_service .parse_customer_path (
102+ # customer_id here is a string as returned by parse_customer_path
103+ customer_id_from_parse : str = googleads_service .parse_customer_path (
80104 customer_resource_name
81105 )["customer_id" ]
82- print (customer_id )
83- seed_customer_ids .append (customer_id )
106+ print (customer_id_from_parse )
107+ seed_customer_ids .append (customer_id_from_parse )
84108
85- for seed_customer_id in seed_customer_ids :
109+ for (
110+ seed_customer_id_str
111+ ) in seed_customer_ids : # seed_customer_id_str is a string
86112 # Performs a breadth-first search to build a Dictionary that maps
87113 # managers to their child accounts (customerIdsToChildAccounts).
88- unprocessed_customer_ids = [seed_customer_id ]
89- customer_ids_to_child_accounts = dict ()
90- root_customer_client = None
114+ # unprocessed_customer_ids should store integers.
115+ unprocessed_customer_ids : List [int ] = [int (seed_customer_id_str )]
116+ customer_ids_to_child_accounts : Dict [int , List [CustomerClient ]] = dict ()
117+ root_customer_client : CustomerClient | None = None
91118
92119 while unprocessed_customer_ids :
93- customer_id = int (unprocessed_customer_ids .pop (0 ))
94- response = googleads_service .search (
95- customer_id = str (customer_id ), query = query
120+ customer_id_loop : int = unprocessed_customer_ids .pop (
121+ 0
122+ ) # customer_id_loop is an int
123+ # The search method expects customer_id to be a string.
124+ response : SearchPagedResponse = googleads_service .search (
125+ customer_id = str (customer_id_loop ), query = query
96126 )
97127
98128 # Iterates over all rows in all pages to get all customer
99129 # clients under the specified customer's hierarchy.
130+ googleads_row : GoogleAdsRow
100131 for googleads_row in response :
101- customer_client = googleads_row .customer_client
132+ customer_client_loop_var : CustomerClient = (
133+ googleads_row .customer_client
134+ )
102135
103136 # The customer client that with level 0 is the specified
104137 # customer.
105- if customer_client .level == 0 :
138+ if customer_client_loop_var .level == 0 :
106139 if root_customer_client is None :
107- root_customer_client = customer_client
140+ root_customer_client = customer_client_loop_var
108141 continue
109142
110143 # For all level-1 (direct child) accounts that are a
111144 # manager account, the above query will be run against them
112145 # to create a Dictionary of managers mapped to their child
113146 # accounts for printing the hierarchy afterwards.
114- if customer_id not in customer_ids_to_child_accounts :
115- customer_ids_to_child_accounts [customer_id ] = []
147+ if customer_id_loop not in customer_ids_to_child_accounts :
148+ customer_ids_to_child_accounts [customer_id_loop ] = []
116149
117- customer_ids_to_child_accounts [customer_id ].append (
118- customer_client
150+ customer_ids_to_child_accounts [customer_id_loop ].append (
151+ customer_client_loop_var
119152 )
120153
121- if customer_client .manager :
154+ if customer_client_loop_var .manager :
122155 # A customer can be managed by multiple managers, so to
123156 # prevent visiting the same customer many times, we
124157 # need to check if it's already in the Dictionary.
158+ # Assuming customer_client_loop_var.id is an int
125159 if (
126- customer_client .id not in customer_ids_to_child_accounts
127- and customer_client .level == 1
160+ customer_client_loop_var .id
161+ not in customer_ids_to_child_accounts
162+ and customer_client_loop_var .level == 1
128163 ):
129- unprocessed_customer_ids .append (customer_client .id )
164+ unprocessed_customer_ids .append (
165+ customer_client_loop_var .id
166+ )
130167
131168 if root_customer_client is not None :
132169 print (
@@ -145,8 +182,10 @@ def main(client, login_customer_id=None):
145182
146183
147184def print_account_hierarchy (
148- customer_client , customer_ids_to_child_accounts , depth
149- ):
185+ customer_client : CustomerClient ,
186+ customer_ids_to_child_accounts : Dict [int , List [CustomerClient ]],
187+ depth : int ,
188+ ) -> None :
150189 """Prints the specified account's hierarchy using recursion.
151190
152191 Args:
@@ -160,17 +199,19 @@ def print_account_hierarchy(
160199 if depth == 0 :
161200 print ("Customer ID (Descriptive Name, Currency Code, Time Zone)" )
162201
163- customer_id = customer_client .id
202+ # Assuming customer_client.id is an int based on previous analysis for keys in customer_ids_to_child_accounts
203+ customer_id_print : int = customer_client .id
164204 print ("-" * (depth * 2 ), end = "" )
165205 print (
166- f"{ customer_id } ({ customer_client .descriptive_name } , "
206+ f"{ customer_id_print } ({ customer_client .descriptive_name } , "
167207 f"{ customer_client .currency_code } , "
168208 f"{ customer_client .time_zone } )"
169209 )
170210
171211 # Recursively call this function for all child accounts of customer_client.
172- if customer_id in customer_ids_to_child_accounts :
173- for child_account in customer_ids_to_child_accounts [customer_id ]:
212+ if customer_id_print in customer_ids_to_child_accounts :
213+ child_account : CustomerClient
214+ for child_account in customer_ids_to_child_accounts [customer_id_print ]:
174215 print_account_hierarchy (
175216 child_account , customer_ids_to_child_accounts , depth + 1
176217 )
0 commit comments