-
Notifications
You must be signed in to change notification settings - Fork 521
Opt asyncio #1049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Opt asyncio #1049
Conversation
Verifies that the
mutate
method is called exactly once with two operations (budget and campaign).
Checks for the correct usage of temporary resource names.
tests/examples/asyncio/async_search_stream_test.py
:
Verifies that search_stream is called with a query that does not contain LIMIT 10.
Mocks the async streaming iterator to ensure robust execution.
tests/examples/asyncio/async_search_test.py
:
Verifies that search is called with a query that does not contain LIMIT 10.
Here is the list of modifications I have made during this session:
Optimized Files
examples/asyncio/async_add_campaigns.py
:
Optimization: Implemented batch processing using GoogleAdsService.mutate and temporary resource IDs.
Benefit: Reduced network round trips from 2 to 1 and ensured atomic creation of Budget and Campaign.
examples/asyncio/async_search_stream.py
:
Optimization: Removed LIMIT 10 from the GAQL query.
Benefit: Aligned code behavior with its description ("get all campaigns") and correctly demonstrates streaming.
examples/asyncio/async_search.py
:
Optimization: Removed LIMIT 10 from the GAQL query.
Benefit: Aligned code behavior with its description ("get all campaigns").
New Unit Tests
tests/examples/asyncio/async_add_campaigns_test.py
- Replaced CampaignBudgetServiceClient and CampaignServiceClient with the unified GoogleAdsService.
- Implemented MutateOperation for both budget and campaign.
- Used temporary resource IDs (e.g., customers/{customer_id}/campaignBudgets/-1) to allow the campaign to reference the budget created in the same request.
- Executed both operations in a single mutate call.
async_search_stream.py
Query Optimization:
- Removed LIMIT 10 from the GAQL query to correctly illustrate "getting all campaigns" as per the example's purpose.`
sync_search.py
Query Optimization:
- Removed LIMIT 10 from the GAQL query to correctly illustrate "getting all campaigns" as per the example's purpose.
New Unit Tests
tests/examples/asyncio/async_add_campaigns_test.py
- Replaced CampaignBudgetServiceClient and CampaignServiceClient with the unified GoogleAdsService.
- Implemented MutateOperation for both budget and campaign.
- Used temporary resource IDs (e.g., customers/{customer_id}/campaignBudgets/-1) to allow the campaign to reference the budget created in the same request.
- Executed both operations in a single mutate call.
async_search_stream.py
Query Optimization:
- Removed LIMIT 10 from the GAQL query to correctly illustrate "getting all campaigns" as per the example's purpose.`
sync_search.py
Query Optimization:
- Removed LIMIT 10 from the GAQL query to correctly illustrate "getting all campaigns" as per the example's purpose.
Merge branch 'opt_asyncio' of https://github.com/googleads/google-ads-python into opt_asyncio
Batch Processing:
- Replaced CampaignBudgetServiceClient and CampaignServiceClient with the unified GoogleAdsService.
- Implemented MutateOperation for both budget and campaign.
- Used temporary resource IDs (e.g., customers/{customer_id}/campaignBudgets/-1) to allow the campaign to reference the budget created in the same request.
- Executed both operations in a single mutate call.
async_search_stream.py
Query Optimization:
- Removed LIMIT 10 from the GAQL query to correctly illustrate "getting all campaigns" as per the example's purpose.`
sync_search.py
Query Optimization:
- Removed LIMIT 10 from the GAQL query to correctly illustrate "getting all campaigns" as per the example's purpose.
In add_async_campaign.py I replaced the individual service clients with the unified
GoogleAdsService to enable atomic batch processing using Temporary Resource Names.
Here is the breakdown of why this was necessary for the optimization:
Single Network Request: The GoogleAdsService.mutate method allows you to bundle operations for different resource types (simultaneously creating a CampaignBudget and a
Campaign) into one single API call. The individual clients (CampaignBudgetServiceClient, etc.) can only handle their specific resource type, forcing you to make sequential network requests.
Temporary Resource Names: This is the key feature that makes 1-step creation possible. By using a temporary ID (like customers/123/campaignBudgets/-1), I could tell the API: "Create this budget, and simultaneously create this campaign that references that budget you are about to create."
If I used the individual services, I would have to await the budget creation, get the real resource name back, and then start the campaign creation request (2 round-trips).
Atomicity: This approach ensures that either both resources are created successfully, or neither is. If the campaign creation fails, the budget won't be left orphaned in your account.
| # We are creating both the budget and the campaign in the same request, so | ||
| # we need to use a temporary resource name for the budget to reference it | ||
| # in the campaign. | ||
| # Temporary resource names must be negative integers formatted as strings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want to add a link to the docs for temp IDs? https://developers.google.com/google-ads/api/docs/batch-processing/temporary-ids
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the link and pushed the change.
add_async_campaign.py
Batch Processing:
- Replaced CampaignBudgetServiceClient and CampaignServiceClient with the unified GoogleAdsService.
- Implemented MutateOperation for both budget and campaign.
- Used temporary resource IDs (e.g., customers/{customer_id}/campaignBudgets/-1) to allow the campaign to reference the budget created in the same request.
- Executed both operations in a single mutate call.
In add_async_campaign.py I replaced the individual service clients with the unified GoogleAdsService to enable atomic batch processing using Temporary Resource Names.
Here is the breakdown of why this was necessary for the optimization:
Single Network Request: The GoogleAdsService.mutate method allows you to bundle operations for different resource types (simultaneously creating a CampaignBudget and a Campaign) into one single API call. The individual clients (CampaignBudgetServiceClient, etc.) can only handle their specific resource type, forcing you to make sequential network requests.
Temporary Resource Names: This is the key feature that makes 1-step creation possible. By using a temporary ID (like customers/123/campaignBudgets/-1), I could tell the API: "Create this budget, and simultaneously create this campaign that references that budget you are about to create."
If I used the individual services, I would have to await the budget creation, get the real resource name back, and then start the campaign creation request (2 round-trips).