Skip to content

Commit e26e566

Browse files
Trying new things
Change-Id: I78b5fceb7e6dfb88306d5521176e7ae55d6ddba9
1 parent 8ba1f42 commit e26e566

1 file changed

Lines changed: 134 additions & 78 deletions

File tree

examples/experiments/create_asset_optimization_experiment.py

Lines changed: 134 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@
2525
from examples.utils.example_helpers import get_image_bytes_from_url
2626
from google.ads.googleads.client import GoogleAdsClient
2727
from google.ads.googleads.errors import GoogleAdsException
28+
from google.ads.googleads.v24.services.types.experiment_service import (
29+
ExperimentOperation,
30+
MutateExperimentsResponse,
31+
)
32+
from google.ads.googleads.v24.services.types.experiment_arm_service import (
33+
ExperimentArmOperation,
34+
MutateExperimentArmsRequest,
35+
MutateExperimentArmsResponse,
36+
)
37+
from google.ads.googleads.v24.resources.types.experiment import Experiment
38+
from google.ads.googleads.v24.resources.types.experiment_arm import (
39+
ExperimentArm,
40+
)
41+
from google.ads.googleads.v24.services.services.experiment_service import (
42+
ExperimentServiceClient,
43+
)
44+
from google.ads.googleads.v24.services.services.experiment_arm_service import (
45+
ExperimentArmServiceClient,
46+
)
2847
from google.ads.googleads.v24.services.types.google_ads_service import (
2948
MutateOperation,
3049
)
@@ -42,14 +61,32 @@ def main(
4261
"""
4362
googleads_service = client.get_service("GoogleAdsService")
4463

45-
# Temp IDs
64+
# Query the asset group to find the associated campaign resource name.
65+
query = f"""
66+
SELECT asset_group.campaign
67+
FROM asset_group
68+
WHERE asset_group.id = {asset_group_id}
69+
"""
70+
search_response = googleads_service.search(
71+
customer_id=customer_id, query=query
72+
)
73+
campaign_resource_name = None
74+
for row in search_response:
75+
campaign_resource_name = row.asset_group.campaign
76+
break
77+
78+
if not campaign_resource_name:
79+
print(f"Asset group with ID {asset_group_id} not found.")
80+
sys.exit(1)
81+
82+
# Temp IDs for asset creation
4683
ASSET_1_TEMP_ID = "-1"
47-
EXPERIMENT_TEMP_ID = "-2"
48-
ASSET_2_TEMP_ID = "-3"
84+
ASSET_2_TEMP_ID = "-2"
4985

5086
# [START create_asset_optimization_experiment_1]
51-
# 1. Create Assets with temporary resource names.
87+
# 1. Create Assets.
5288
# We create a text asset and an image asset to showcase different types.
89+
# We execute the asset creation first to get real resource names.
5390
asset_operation_1 = create_text_asset_operation(
5491
client,
5592
customer_id,
@@ -64,93 +101,114 @@ def main(
64101
"Mars Landscape View",
65102
)
66103

67-
# 2. Create an Experiment with a temporary resource name.
68-
experiment_operation = client.get_type("MutateOperation")
69-
experiment = experiment_operation.experiment_operation.create
70-
experiment.resource_name = googleads_service.experiment_path(
71-
customer_id, EXPERIMENT_TEMP_ID
104+
asset_response = googleads_service.mutate(
105+
customer_id=customer_id,
106+
mutate_operations=[asset_operation_1, asset_operation_2],
107+
)
108+
headline_asset_resource_name = (
109+
asset_response.mutate_operation_responses[0].asset_result.resource_name
110+
)
111+
image_asset_resource_name = (
112+
asset_response.mutate_operation_responses[1].asset_result.resource_name
113+
)
114+
115+
# 2. Create an Experiment using ExperimentService.
116+
experiment_operation: ExperimentOperation = client.get_type(
117+
"ExperimentOperation"
72118
)
119+
experiment: Experiment = experiment_operation.create
73120
experiment.name = f"Interstellar Asset Experiment #{uuid4()}"
74121
experiment.type_ = client.enums.ExperimentTypeEnum.OPTIMIZE_ASSETS
75122
# Set the optimize assets experiment subtype to COMPARE_ASSETS.
76123
experiment.optimize_assets_experiment.optimize_assets_experiment_subtype = (
77124
client.enums.OptimizeAssetsExperimentSubtypeEnum.COMPARE_ASSETS
78125
)
79126

80-
# 3. Create two ExperimentArm resources.
127+
experiment_service: ExperimentServiceClient = client.get_service(
128+
"ExperimentService"
129+
)
130+
experiment_response: MutateExperimentsResponse = (
131+
experiment_service.mutate_experiments(
132+
customer_id=customer_id, operations=[experiment_operation]
133+
)
134+
)
135+
experiment_resource_name: str = (
136+
experiment_response.results[0].resource_name
137+
)
138+
139+
# 3. Create two ExperimentArm resources using ExperimentArmService.
81140
treatment_assets = [
82-
(ASSET_1_TEMP_ID, client.enums.AssetFieldTypeEnum.HEADLINE),
83-
(ASSET_2_TEMP_ID, client.enums.AssetFieldTypeEnum.MARKETING_IMAGE),
141+
(headline_asset_resource_name, client.enums.AssetFieldTypeEnum.HEADLINE),
142+
(image_asset_resource_name, client.enums.AssetFieldTypeEnum.MARKETING_IMAGE),
84143
]
85144
arm_operations = create_arms_operations(
86145
client,
87146
customer_id,
88-
EXPERIMENT_TEMP_ID,
147+
experiment_resource_name,
148+
campaign_resource_name,
89149
asset_group_id,
90150
treatment_assets,
91151
)
92152

93-
# 4. Create AssetGroupAssets linking the assets to the asset group.
153+
experiment_arm_service: ExperimentArmServiceClient = client.get_service(
154+
"ExperimentArmService"
155+
)
156+
request: MutateExperimentArmsRequest = client.get_type(
157+
"MutateExperimentArmsRequest"
158+
)
159+
request.customer_id = customer_id
160+
request.operations = arm_operations
161+
# We want to fetch the generated asset group IDs from the treatment arm, so the
162+
# easiest way to do that is to have the response return the newly created entities.
163+
request.response_content_type = (
164+
client.enums.ResponseContentTypeEnum.MUTABLE_RESOURCE
165+
)
166+
arm_response: MutateExperimentArmsResponse = (
167+
experiment_arm_service.mutate_experiment_arms(request=request)
168+
)
169+
170+
control_arm_result = arm_response.results[0]
171+
treatment_arm_result = arm_response.results[1]
172+
treatment_asset_group_resource_name = (
173+
treatment_arm_result.experiment_arm.asset_groups[0].asset_group
174+
)
175+
176+
# 4. Create AssetGroupAssets linking the assets to the treatment experiment arm's asset group.
94177
asset_group_asset_operation_1 = create_asset_group_asset_operation(
95178
client,
96-
customer_id,
97-
asset_group_id,
98-
ASSET_1_TEMP_ID,
179+
treatment_asset_group_resource_name,
180+
headline_asset_resource_name,
99181
client.enums.AssetFieldTypeEnum.HEADLINE,
100182
)
101183
asset_group_asset_operation_2 = create_asset_group_asset_operation(
102184
client,
103-
customer_id,
104-
asset_group_id,
105-
ASSET_2_TEMP_ID,
185+
treatment_asset_group_resource_name,
186+
image_asset_resource_name,
106187
client.enums.AssetFieldTypeEnum.MARKETING_IMAGE,
107188
)
108189

109-
# Send all operations in a single Mutate request.
110-
# The operations must be in this specific order.
111-
mutate_operations = [
112-
asset_operation_1,
113-
asset_operation_2,
114-
experiment_operation,
115-
*arm_operations,
116-
asset_group_asset_operation_1,
117-
asset_group_asset_operation_2,
118-
]
119-
120-
response = googleads_service.mutate(
190+
aga_response = googleads_service.mutate(
121191
customer_id=customer_id,
122-
mutate_operations=mutate_operations,
192+
mutate_operations=[
193+
asset_group_asset_operation_1,
194+
asset_group_asset_operation_2,
195+
],
123196
)
124197
# [END create_asset_optimization_experiment_1]
125198

126199
# Print the results.
127-
print(
128-
"Created headline asset:"
129-
f" {response.mutate_operation_responses[0].asset_result.resource_name}"
130-
)
131-
print(
132-
"Created image asset:"
133-
f" {response.mutate_operation_responses[1].asset_result.resource_name}"
134-
)
135-
print(
136-
"Created experiment:"
137-
f" {response.mutate_operation_responses[2].experiment_result.resource_name}"
138-
)
139-
print(
140-
"Created control arm:"
141-
f" {response.mutate_operation_responses[3].experiment_arm_result.resource_name}"
142-
)
143-
print(
144-
"Created treatment arm:"
145-
f" {response.mutate_operation_responses[4].experiment_arm_result.resource_name}"
146-
)
200+
print(f"Created headline asset: {headline_asset_resource_name}")
201+
print(f"Created image asset: {image_asset_resource_name}")
202+
print(f"Created experiment: {experiment_resource_name}")
203+
print(f"Created control arm: {control_arm_result.resource_name}")
204+
print(f"Created treatment arm: {treatment_arm_result.resource_name}")
147205
print(
148206
"Created asset group asset for headline:"
149-
f" {response.mutate_operation_responses[5].asset_group_asset_result.resource_name}"
207+
f" {aga_response.mutate_operation_responses[0].asset_group_asset_result.resource_name}"
150208
)
151209
print(
152210
"Created asset group asset for image:"
153-
f" {response.mutate_operation_responses[6].asset_group_asset_result.resource_name}"
211+
f" {aga_response.mutate_operation_responses[1].asset_group_asset_result.resource_name}"
154212
)
155213

156214

@@ -187,24 +245,26 @@ def create_image_asset_operation(
187245
def create_arms_operations(
188246
client: GoogleAdsClient,
189247
customer_id: str,
190-
experiment_temp_id: str,
248+
experiment_resource_name: str,
249+
campaign_resource_name: str,
191250
asset_group_id: str,
192251
treatment_assets: List[Tuple[str, Any]],
193-
) -> List[MutateOperation]:
252+
) -> List[ExperimentArmOperation]:
194253
"""Creates mutate operations for control and treatment arms."""
195254
googleads_service = client.get_service("GoogleAdsService")
196255
experiment_arm_type = client.get_type("ExperimentArm")
197-
operations = []
256+
operations: List[ExperimentArmOperation] = []
198257

199258
# Control arm
200-
control_operation = client.get_type("MutateOperation")
201-
control = control_operation.experiment_arm_operation.create
202-
control.experiment = googleads_service.experiment_path(
203-
customer_id, experiment_temp_id
259+
control_operation: ExperimentArmOperation = client.get_type(
260+
"ExperimentArmOperation"
204261
)
262+
control: ExperimentArm = control_operation.create
263+
control.experiment = experiment_resource_name
205264
control.name = "Base Assets (Control)"
206265
control.control = True
207266
control.traffic_split = 50
267+
control.campaigns.append(campaign_resource_name)
208268

209269
asset_group_info_control = experiment_arm_type.AssetGroupInfo()
210270
asset_group_info_control.asset_group = googleads_service.asset_group_path(
@@ -214,25 +274,25 @@ def create_arms_operations(
214274
operations.append(control_operation)
215275

216276
# Treatment arm
217-
treatment_operation = client.get_type("MutateOperation")
218-
treatment = treatment_operation.experiment_arm_operation.create
219-
treatment.experiment = googleads_service.experiment_path(
220-
customer_id, experiment_temp_id
277+
treatment_operation: ExperimentArmOperation = client.get_type(
278+
"ExperimentArmOperation"
221279
)
280+
treatment: ExperimentArm = treatment_operation.create
281+
treatment.experiment = experiment_resource_name
222282
treatment.name = "New Assets (Treatment)"
223283
treatment.control = False
224284
treatment.traffic_split = 50
285+
# NOTE: Do not set treatment.campaigns, as the backend automatically creates
286+
# the treatment campaign for Performance Max / OPTIMIZE_ASSETS experiments.
225287

226288
asset_group_info_treatment = experiment_arm_type.AssetGroupInfo()
227289
asset_group_info_treatment.asset_group = googleads_service.asset_group_path(
228290
customer_id, asset_group_id
229291
)
230292

231-
for asset_temp_id, field_type in treatment_assets:
293+
for asset_resource_name, field_type in treatment_assets:
232294
asset_group_asset_info = experiment_arm_type.AssetGroupAssetInfo()
233-
asset_group_asset_info.asset = googleads_service.asset_path(
234-
customer_id, asset_temp_id
235-
)
295+
asset_group_asset_info.asset = asset_resource_name
236296
asset_group_asset_info.field_type = field_type
237297
asset_group_info_treatment.asset_group_assets.append(
238298
asset_group_asset_info
@@ -246,19 +306,15 @@ def create_arms_operations(
246306

247307
def create_asset_group_asset_operation(
248308
client: GoogleAdsClient,
249-
customer_id: str,
250-
asset_group_id: str,
251-
asset_temp_id: str,
309+
asset_group_resource_name: str,
310+
asset_resource_name: str,
252311
field_type: Any,
253312
) -> MutateOperation:
254313
"""Creates a mutate operation for an asset group asset."""
255-
googleads_service = client.get_service("GoogleAdsService")
256314
operation = client.get_type("MutateOperation")
257315
aga = operation.asset_group_asset_operation.create
258-
aga.asset_group = googleads_service.asset_group_path(
259-
customer_id, asset_group_id
260-
)
261-
aga.asset = googleads_service.asset_path(customer_id, asset_temp_id)
316+
aga.asset_group = asset_group_resource_name
317+
aga.asset = asset_resource_name
262318
aga.field_type = field_type
263319
return operation
264320

0 commit comments

Comments
 (0)