Skip to content

Commit e9e91fe

Browse files
I've added type hints and annotations to the Python files in your examples/basic_operations directory. This should make the code easier to read and also help with static analysis.
Here are the files I modified: - `examples/basic_operations/add_ad_groups.py` - `examples/basic_operations/add_campaigns.py` - `examples/basic_operations/get_campaigns.py` - `examples/basic_operations/get_responsive_search_ads.py` - `examples/basic_operations/pause_ad.py` - `examples/basic_operations/remove_campaign.py` - `examples/basic_operations/search_for_google_ads_fields.py` - `examples/basic_operations/update_ad_group.py` - `examples/basic_operations/update_campaign.py` - `examples/basic_operations/update_responsive_search_ad.py`
1 parent 4f350a8 commit e9e91fe

File tree

10 files changed

+308
-109
lines changed

10 files changed

+308
-109
lines changed

examples/basic_operations/add_ad_groups.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,46 @@
2121
import argparse
2222
import sys
2323
import uuid
24+
from typing import Any, MutableSequence
2425

2526
from google.ads.googleads.client import GoogleAdsClient
2627
from google.ads.googleads.errors import GoogleAdsException
28+
from google.ads.googleads.v19.services.types.ad_group_service import (
29+
AdGroupOperation,
30+
MutateAdGroupsResponse,
31+
AdGroupServiceClient,
32+
)
33+
from google.ads.googleads.v19.services.types.campaign_service import (
34+
CampaignServiceClient,
35+
)
36+
from google.ads.googleads.v19.resources.types.ad_group import AdGroup
2737

2838

29-
def main(client, customer_id, campaign_id):
30-
ad_group_service = client.get_service("AdGroupService")
31-
campaign_service = client.get_service("CampaignService")
39+
def main(
40+
client: GoogleAdsClient, customer_id: str, campaign_id: str
41+
) -> None:
42+
ad_group_service: AdGroupServiceClient = client.get_service(
43+
"AdGroupService"
44+
)
45+
campaign_service: CampaignServiceClient = client.get_service(
46+
"CampaignService"
47+
)
3248

3349
# Create ad group.
34-
ad_group_operation = client.get_type("AdGroupOperation")
35-
ad_group = ad_group_operation.create
50+
ad_group_operation: AdGroupOperation = client.get_type("AdGroupOperation")
51+
ad_group: AdGroup = ad_group_operation.create
3652
ad_group.name = f"Earth to Mars cruises {uuid.uuid4()}"
3753
ad_group.status = client.enums.AdGroupStatusEnum.ENABLED
3854
ad_group.campaign = campaign_service.campaign_path(customer_id, campaign_id)
3955
ad_group.type_ = client.enums.AdGroupTypeEnum.SEARCH_STANDARD
4056
ad_group.cpc_bid_micros = 10000000
4157

4258
# Add the ad group.
43-
ad_group_response = ad_group_service.mutate_ad_groups(
44-
customer_id=customer_id, operations=[ad_group_operation]
59+
ad_group_response: MutateAdGroupsResponse = (
60+
ad_group_service.mutate_ad_groups(
61+
customer_id=customer_id,
62+
operations=[ad_group_operation], # type: ignore
63+
)
4564
)
4665
print(f"Created ad group {ad_group_response.results[0].resource_name}.")
4766

@@ -61,11 +80,13 @@ def main(client, customer_id, campaign_id):
6180
parser.add_argument(
6281
"-i", "--campaign_id", type=str, required=True, help="The campaign ID."
6382
)
64-
args = parser.parse_args()
83+
args: argparse.Namespace = parser.parse_args()
6584

6685
# GoogleAdsClient will read the google-ads.yaml configuration file in the
6786
# home directory if none is specified.
68-
googleads_client = GoogleAdsClient.load_from_storage(version="v19")
87+
googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage(
88+
version="v19"
89+
)
6990

7091
try:
7192
main(googleads_client, args.customer_id, args.campaign_id)

examples/basic_operations/add_campaigns.py

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,75 @@
1818
"""
1919

2020

21+
import argparse
2122
import argparse
2223
import datetime
2324
import sys
2425
import uuid
26+
from typing import MutableSequence
2527

2628
from google.ads.googleads.client import GoogleAdsClient
2729
from google.ads.googleads.errors import GoogleAdsException
28-
29-
30-
_DATE_FORMAT = "%Y%m%d"
31-
32-
33-
def main(client, customer_id):
34-
campaign_budget_service = client.get_service("CampaignBudgetService")
35-
campaign_service = client.get_service("CampaignService")
30+
from google.ads.googleads.v19.services.types.campaign_budget_service import (
31+
CampaignBudgetOperation,
32+
CampaignBudgetServiceClient,
33+
MutateCampaignBudgetsResponse,
34+
)
35+
from google.ads.googleads.v19.services.types.campaign_service import (
36+
CampaignOperation,
37+
CampaignServiceClient,
38+
MutateCampaignsResponse,
39+
)
40+
from google.ads.googleads.v19.resources.types.campaign_budget import (
41+
CampaignBudget,
42+
)
43+
from google.ads.googleads.v19.resources.types.campaign import Campaign
44+
from google.ads.googleads.v19.common.types.bidding import ManualCpc
45+
46+
47+
_DATE_FORMAT: str = "%Y%m%d"
48+
49+
50+
def main(client: GoogleAdsClient, customer_id: str) -> None:
51+
campaign_budget_service: CampaignBudgetServiceClient = client.get_service(
52+
"CampaignBudgetService"
53+
)
54+
campaign_service: CampaignServiceClient = client.get_service(
55+
"CampaignService"
56+
)
3657

3758
# [START add_campaigns]
3859
# Create a budget, which can be shared by multiple campaigns.
39-
campaign_budget_operation = client.get_type("CampaignBudgetOperation")
40-
campaign_budget = campaign_budget_operation.create
60+
campaign_budget_operation: CampaignBudgetOperation = client.get_type(
61+
"CampaignBudgetOperation"
62+
)
63+
campaign_budget: CampaignBudget = campaign_budget_operation.create
4164
campaign_budget.name = f"Interplanetary Budget {uuid.uuid4()}"
4265
campaign_budget.delivery_method = (
4366
client.enums.BudgetDeliveryMethodEnum.STANDARD
4467
)
4568
campaign_budget.amount_micros = 500000
4669

4770
# Add budget.
71+
campaign_budget_response: MutateCampaignBudgetsResponse
4872
try:
4973
campaign_budget_response = (
5074
campaign_budget_service.mutate_campaign_budgets(
51-
customer_id=customer_id, operations=[campaign_budget_operation]
75+
customer_id=customer_id,
76+
operations=[campaign_budget_operation], # type: ignore
5277
)
5378
)
5479
except GoogleAdsException as ex:
5580
handle_googleads_exception(ex)
5681
# [END add_campaigns]
82+
# We are exiting in handle_googleads_exception so this return is not
83+
# strictly necessary, but it makes static analysis happier.
84+
return
5785

5886
# [START add_campaigns_1]
5987
# Create campaign.
60-
campaign_operation = client.get_type("CampaignOperation")
61-
campaign = campaign_operation.create
88+
campaign_operation: CampaignOperation = client.get_type("CampaignOperation")
89+
campaign: Campaign = campaign_operation.create
6290
campaign.name = f"Interplanetary Cruise {uuid.uuid4()}"
6391
campaign.advertising_channel_type = (
6492
client.enums.AdvertisingChannelTypeEnum.SEARCH
@@ -70,7 +98,7 @@ def main(client, customer_id):
7098
campaign.status = client.enums.CampaignStatusEnum.PAUSED
7199

72100
# Set the bidding strategy and budget.
73-
campaign.manual_cpc = client.get_type("ManualCpc")
101+
campaign.manual_cpc = ManualCpc()
74102
campaign.campaign_budget = campaign_budget_response.results[0].resource_name
75103

76104
# Set the campaign network options.
@@ -83,24 +111,27 @@ def main(client, customer_id):
83111
# [END add_campaigns_1]
84112

85113
# Optional: Set the start date.
86-
start_time = datetime.date.today() + datetime.timedelta(days=1)
114+
start_time: datetime.date = datetime.date.today() + datetime.timedelta(
115+
days=1
116+
)
87117
campaign.start_date = datetime.date.strftime(start_time, _DATE_FORMAT)
88118

89119
# Optional: Set the end date.
90-
end_time = start_time + datetime.timedelta(weeks=4)
120+
end_time: datetime.date = start_time + datetime.timedelta(weeks=4)
91121
campaign.end_date = datetime.date.strftime(end_time, _DATE_FORMAT)
92122

93123
# Add the campaign.
124+
campaign_response: MutateCampaignsResponse
94125
try:
95126
campaign_response = campaign_service.mutate_campaigns(
96-
customer_id=customer_id, operations=[campaign_operation]
127+
customer_id=customer_id, operations=[campaign_operation] # type: ignore
97128
)
98129
print(f"Created campaign {campaign_response.results[0].resource_name}.")
99130
except GoogleAdsException as ex:
100131
handle_googleads_exception(ex)
101132

102133

103-
def handle_googleads_exception(exception):
134+
def handle_googleads_exception(exception: GoogleAdsException) -> None:
104135
print(
105136
f'Request with ID "{exception.request_id}" failed with status '
106137
f'"{exception.error.code().name}" and includes the following errors:'
@@ -125,10 +156,12 @@ def handle_googleads_exception(exception):
125156
required=True,
126157
help="The Google Ads customer ID.",
127158
)
128-
args = parser.parse_args()
159+
args: argparse.Namespace = parser.parse_args()
129160

130161
# GoogleAdsClient will read the google-ads.yaml configuration file in the
131162
# home directory if none is specified.
132-
googleads_client = GoogleAdsClient.load_from_storage(version="v19")
163+
googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage(
164+
version="v19"
165+
)
133166

134167
main(googleads_client, args.customer_id)

examples/basic_operations/get_campaigns.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,36 @@
2020

2121
import argparse
2222
import sys
23+
from typing import Iterator
2324

2425
from google.ads.googleads.client import GoogleAdsClient
2526
from google.ads.googleads.errors import GoogleAdsException
27+
from google.ads.googleads.v19.services.services.google_ads_service import (
28+
GoogleAdsServiceClient,
29+
)
30+
from google.ads.googleads.v19.services.types.google_ads_service import (
31+
SearchGoogleAdsStreamResponse,
32+
GoogleAdsRow,
33+
)
2634

2735
# [START get_campaigns]
28-
def main(client, customer_id):
29-
ga_service = client.get_service("GoogleAdsService")
36+
def main(client: GoogleAdsClient, customer_id: str) -> None:
37+
ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService")
3038

31-
query = """
39+
query: str = """
3240
SELECT
3341
campaign.id,
3442
campaign.name
3543
FROM campaign
3644
ORDER BY campaign.id"""
3745

3846
# Issues a search request using streaming.
39-
stream = ga_service.search_stream(customer_id=customer_id, query=query)
47+
stream: Iterator[SearchGoogleAdsStreamResponse] = ga_service.search_stream(
48+
customer_id=customer_id, query=query
49+
)
4050

4151
for batch in stream:
42-
for row in batch.results:
52+
for row: GoogleAdsRow in batch.results:
4353
print(
4454
f"Campaign with ID {row.campaign.id} and name "
4555
f'"{row.campaign.name}" was found.'
@@ -59,11 +69,13 @@ def main(client, customer_id):
5969
required=True,
6070
help="The Google Ads customer ID.",
6171
)
62-
args = parser.parse_args()
72+
args: argparse.Namespace = parser.parse_args()
6373

6474
# GoogleAdsClient will read the google-ads.yaml configuration file in the
6575
# home directory if none is specified.
66-
googleads_client = GoogleAdsClient.load_from_storage(version="v19")
76+
googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage(
77+
version="v19"
78+
)
6779

6880
try:
6981
main(googleads_client, args.customer_id)

examples/basic_operations/get_responsive_search_ads.py

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,46 +20,65 @@
2020

2121
import argparse
2222
import sys
23+
from typing import List, Optional, Sequence
2324

2425
from google.ads.googleads.client import GoogleAdsClient
2526
from google.ads.googleads.errors import GoogleAdsException
26-
27-
28-
def main(client, customer_id, ad_group_id=None):
29-
ga_service = client.get_service("GoogleAdsService")
30-
31-
query = '''
27+
from google.ads.googleads.v19.common.types.ad_type_infos import AdTextAsset
28+
from google.ads.googleads.v19.resources.types.ad import Ad
29+
from google.ads.googleads.v19.services.services.google_ads_service import (
30+
GoogleAdsServiceClient,
31+
)
32+
from google.ads.googleads.v19.services.types.google_ads_service import (
33+
GoogleAdsRow,
34+
SearchGoogleAdsRequest,
35+
SearchGoogleAdsResponse,
36+
)
37+
38+
39+
def main(
40+
client: GoogleAdsClient,
41+
customer_id: str,
42+
ad_group_id: Optional[str] = None,
43+
) -> None:
44+
ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService")
45+
46+
query: str = """
3247
SELECT ad_group.id, ad_group_ad.ad.id,
3348
ad_group_ad.ad.responsive_search_ad.headlines,
3449
ad_group_ad.ad.responsive_search_ad.descriptions,
3550
ad_group_ad.status FROM ad_group_ad
3651
WHERE ad_group_ad.ad.type = RESPONSIVE_SEARCH_AD
37-
AND ad_group_ad.status != "REMOVED"'''
52+
AND ad_group_ad.status != "REMOVED" """
3853

3954
# Optional: Specify an ad group ID to restrict search to only a given
4055
# ad group.
4156
if ad_group_id:
4257
query += f" AND ad_group.id = {ad_group_id}"
4358

44-
ga_search_request = client.get_type("SearchGoogleAdsRequest")
59+
ga_search_request: SearchGoogleAdsRequest = client.get_type(
60+
"SearchGoogleAdsRequest"
61+
)
4562
ga_search_request.customer_id = customer_id
4663
ga_search_request.query = query
47-
results = ga_service.search(request=ga_search_request)
64+
results: SearchGoogleAdsResponse = ga_service.search(
65+
request=ga_search_request
66+
)
4867

49-
one_found = False
68+
one_found: bool = False
5069

5170
for row in results:
5271
one_found = True
53-
ad = row.ad_group_ad.ad
72+
ad: Ad = row.ad_group_ad.ad
5473
print(
5574
"Responsive search ad with resource name "
5675
f'"{ad.resource_name}", status {row.ad_group_ad.status.name} '
5776
"was found."
5877
)
59-
headlines = "\n".join(
78+
headlines: str = "\n".join(
6079
ad_text_assets_to_strs(ad.responsive_search_ad.headlines)
6180
)
62-
descriptions = "\n".join(
81+
descriptions: str = "\n".join(
6382
ad_text_assets_to_strs(ad.responsive_search_ad.descriptions)
6483
)
6584
print(f"Headlines:\n{headlines}\nDescriptions:\n{descriptions}\n")
@@ -68,9 +87,10 @@ def main(client, customer_id, ad_group_id=None):
6887
print("No responsive search ads were found.")
6988

7089

71-
def ad_text_assets_to_strs(assets):
90+
def ad_text_assets_to_strs(assets: Sequence[AdTextAsset]) -> List[str]:
7291
"""Converts a list of AdTextAssets to a list of user-friendly strings."""
73-
s = []
92+
s: List[str] = []
93+
asset: AdTextAsset
7494
for asset in assets:
7595
s.append(f"\t {asset.text} pinned to {asset.pinned_field.name}")
7696
return s
@@ -96,11 +116,13 @@ def ad_text_assets_to_strs(assets):
96116
required=False,
97117
help="The ad group ID. ",
98118
)
99-
args = parser.parse_args()
119+
args: argparse.Namespace = parser.parse_args()
100120

101121
# GoogleAdsClient will read the google-ads.yaml configuration file in the
102122
# home directory if none is specified.
103-
googleads_client = GoogleAdsClient.load_from_storage(version="v19")
123+
googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage(
124+
version="v19"
125+
)
104126

105127
try:
106128
main(

0 commit comments

Comments
 (0)