Client library for the Google Ads API providing comprehensive access to advertising management, reporting, and analytics capabilities.
—
Comprehensive campaign lifecycle management including campaign creation, budget management, campaign settings, and campaign-level targeting and bidding strategies. This covers all aspects of managing Google Ads campaigns from creation to optimization.
Core campaign management operations for creating, updating, and managing Google Ads campaigns.
class CampaignService:
"""Service for managing campaigns."""
def mutate_campaigns(
self,
customer_id: str,
operations: list,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: str = None
) -> MutateCampaignsResponse:
"""
Create, update, or delete campaigns.
Parameters:
- customer_id: Customer ID for campaign operations
- operations: List of CampaignOperation objects
- partial_failure: Continue on individual operation failures
- validate_only: Validate operations without executing
- response_content_type: Response content type (MUTABLE_RESOURCE, RESOURCE_NAME_ONLY)
Returns:
MutateCampaignsResponse with operation results
Raises:
- GoogleAdsException: If operations fail
"""Budget management for campaigns including shared budgets and budget allocation.
class CampaignBudgetService:
"""Service for managing campaign budgets."""
def mutate_campaign_budgets(
self,
customer_id: str,
operations: list,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: str = None
) -> MutateCampaignBudgetsResponse:
"""
Create, update, or delete campaign budgets.
Parameters:
- customer_id: Customer ID for budget operations
- operations: List of CampaignBudgetOperation objects
- partial_failure: Continue on individual operation failures
- validate_only: Validate operations without executing
- response_content_type: Response content type
Returns:
MutateCampaignBudgetsResponse with operation results
Raises:
- GoogleAdsException: If operations fail
"""Campaign-level targeting criteria including locations, languages, devices, and negative keywords.
class CampaignCriterionService:
"""Service for managing campaign criteria."""
def mutate_campaign_criteria(
self,
customer_id: str,
operations: list,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: str = None
) -> MutateCampaignCriteriaResponse:
"""
Create, update, or delete campaign criteria.
Parameters:
- customer_id: Customer ID for criteria operations
- operations: List of CampaignCriterionOperation objects
- partial_failure: Continue on individual operation failures
- validate_only: Validate operations without executing
- response_content_type: Response content type
Returns:
MutateCampaignCriteriaResponse with operation results
Raises:
- GoogleAdsException: If operations fail
"""Campaign-level asset associations for sitelinks, callouts, structured snippets, and other extensions.
class CampaignAssetService:
"""Service for managing campaign assets."""
def mutate_campaign_assets(
self,
customer_id: str,
operations: list,
partial_failure: bool = False,
validate_only: bool = False,
response_content_type: str = None
) -> MutateCampaignAssetsResponse:
"""
Create, update, or delete campaign assets.
Parameters:
- customer_id: Customer ID for asset operations
- operations: List of CampaignAssetOperation objects
- partial_failure: Continue on individual operation failures
- validate_only: Validate operations without executing
- response_content_type: Response content type
Returns:
MutateCampaignAssetsResponse with operation results
Raises:
- GoogleAdsException: If operations fail
"""from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException
client = GoogleAdsClient.load_from_storage("google-ads.yaml")
campaign_service = client.get_service("CampaignService")
campaign_budget_service = client.get_service("CampaignBudgetService")
# First create a campaign budget
budget_operation = client.get_type("CampaignBudgetOperation")
budget = budget_operation.create
budget.name = "My Campaign Budget"
budget.amount_micros = 50000000 # $50 in micros
budget.delivery_method = client.enums.BudgetDeliveryMethodEnum.STANDARD
budget.explicitly_shared = False
try:
budget_response = campaign_budget_service.mutate_campaign_budgets(
customer_id="1234567890",
operations=[budget_operation]
)
budget_resource_name = budget_response.results[0].resource_name
print(f"Created budget: {budget_resource_name}")
# Now create the campaign
campaign_operation = client.get_type("CampaignOperation")
campaign = campaign_operation.create
campaign.name = "My Search Campaign"
campaign.advertising_channel_type = client.enums.AdvertisingChannelTypeEnum.SEARCH
campaign.status = client.enums.CampaignStatusEnum.ENABLED
campaign.campaign_budget = budget_resource_name
# Set bidding strategy
campaign.manual_cpc.enhanced_cpc_enabled = True
# Set campaign settings
campaign.start_date = "2024-01-01"
campaign.end_date = "2024-12-31"
# Network settings
campaign.network_settings.target_google_search = True
campaign.network_settings.target_search_network = True
campaign.network_settings.target_content_network = False
campaign.network_settings.target_partner_search_network = False
campaign_response = campaign_service.mutate_campaigns(
customer_id="1234567890",
operations=[campaign_operation]
)
campaign_resource_name = campaign_response.results[0].resource_name
print(f"Created campaign: {campaign_resource_name}")
except GoogleAdsException as ex:
print(f"Campaign creation failed: {ex.error.code().name}")
for error in ex.error.details:
print(f"Error: {error.message}")# Add location targeting to campaign
campaign_criterion_service = client.get_service("CampaignCriterionService")
# Target United States
location_operation = client.get_type("CampaignCriterionOperation")
location_criterion = location_operation.create
location_criterion.campaign = campaign_resource_name
location_criterion.type_ = client.enums.CriterionTypeEnum.LOCATION
location_criterion.location.geo_target_constant = "geoTargetConstants/2840" # USA
# Add language targeting
language_operation = client.get_type("CampaignCriterionOperation")
language_criterion = language_operation.create
language_criterion.campaign = campaign_resource_name
language_criterion.type_ = client.enums.CriterionTypeEnum.LANGUAGE
language_criterion.language.language_constant = "languageConstants/1000" # English
# Add negative keyword
negative_keyword_operation = client.get_type("CampaignCriterionOperation")
negative_keyword = negative_keyword_operation.create
negative_keyword.campaign = campaign_resource_name
negative_keyword.negative = True
negative_keyword.type_ = client.enums.CriterionTypeEnum.KEYWORD
negative_keyword.keyword.text = "free"
negative_keyword.keyword.match_type = client.enums.KeywordMatchTypeEnum.BROAD
try:
criterion_response = campaign_criterion_service.mutate_campaign_criteria(
customer_id="1234567890",
operations=[location_operation, language_operation, negative_keyword_operation]
)
for result in criterion_response.results:
print(f"Created criterion: {result.resource_name}")
except GoogleAdsException as ex:
print(f"Targeting setup failed: {ex.error.code().name}")# Add sitelink extensions to campaign
campaign_asset_service = client.get_service("CampaignAssetService")
asset_service = client.get_service("AssetService")
# First create sitelink assets
sitelinks = [
{"text": "Contact Us", "url": "https://example.com/contact"},
{"text": "About Us", "url": "https://example.com/about"},
{"text": "Products", "url": "https://example.com/products"},
{"text": "Support", "url": "https://example.com/support"}
]
asset_operations = []
for sitelink in sitelinks:
asset_operation = client.get_type("AssetOperation")
asset = asset_operation.create
asset.type_ = client.enums.AssetTypeEnum.SITELINK
asset.sitelink_asset.link_text = sitelink["text"]
asset.sitelink_asset.final_urls.append(sitelink["url"])
asset_operations.append(asset_operation)
# Create the assets
asset_response = asset_service.mutate_assets(
customer_id="1234567890",
operations=asset_operations
)
# Associate assets with campaign
campaign_asset_operations = []
for result in asset_response.results:
campaign_asset_operation = client.get_type("CampaignAssetOperation")
campaign_asset = campaign_asset_operation.create
campaign_asset.campaign = campaign_resource_name
campaign_asset.asset = result.resource_name
campaign_asset.field_type = client.enums.AssetFieldTypeEnum.SITELINK
campaign_asset_operations.append(campaign_asset_operation)
campaign_asset_response = campaign_asset_service.mutate_campaign_assets(
customer_id="1234567890",
operations=campaign_asset_operations
)
print(f"Added {len(campaign_asset_response.results)} sitelinks to campaign")# Update campaign bidding strategy and settings
update_operation = client.get_type("CampaignOperation")
update_campaign = update_operation.update
update_campaign.resource_name = campaign_resource_name
# Switch to Target CPA bidding
update_campaign.target_cpa.target_cpa_micros = 5000000 # $5.00 target CPA
# Update ad schedule (Monday-Friday, 9 AM - 6 PM)
ad_schedule = client.get_type("CampaignCriterionOperation")
schedule_criterion = ad_schedule.create
schedule_criterion.campaign = campaign_resource_name
schedule_criterion.type_ = client.enums.CriterionTypeEnum.AD_SCHEDULE
schedule_criterion.ad_schedule.minute_of_hour = client.enums.MinuteOfHourEnum.ZERO
schedule_criterion.ad_schedule.start_hour = 9
schedule_criterion.ad_schedule.end_hour = 18
schedule_criterion.ad_schedule.day_of_week = client.enums.DayOfWeekEnum.MONDAY
# Set update mask to specify which fields to update
field_mask = client.get_type("FieldMask")
field_mask.paths.extend(["target_cpa.target_cpa_micros"])
update_operation.update_mask = field_mask
try:
# Update campaign
update_response = campaign_service.mutate_campaigns(
customer_id="1234567890",
operations=[update_operation]
)
# Add ad schedule
schedule_response = campaign_criterion_service.mutate_campaign_criteria(
customer_id="1234567890",
operations=[ad_schedule]
)
print("Campaign optimization completed")
except GoogleAdsException as ex:
print(f"Campaign update failed: {ex.error.code().name}")# Get campaign performance data
googleads_service = client.get_service("GoogleAdsService")
campaign_query = """
SELECT
campaign.id,
campaign.name,
campaign.status,
campaign.advertising_channel_type,
campaign.bidding_strategy_type,
campaign_budget.amount_micros,
metrics.impressions,
metrics.clicks,
metrics.cost_micros,
metrics.ctr,
metrics.average_cpc,
metrics.conversions,
metrics.conversions_value,
metrics.cost_per_conversion
FROM campaign
WHERE campaign.status IN ('ENABLED', 'PAUSED')
AND segments.date DURING LAST_30_DAYS
ORDER BY metrics.cost_micros DESC
"""
try:
response = googleads_service.search(
customer_id="1234567890",
query=campaign_query
)
print("Campaign Performance Report")
print("=" * 50)
for row in response:
c = row.campaign
m = row.metrics
b = row.campaign_budget
print(f"Campaign: {c.name} (ID: {c.id})")
print(f"Status: {c.status.name}")
print(f"Type: {c.advertising_channel_type.name}")
print(f"Bidding: {c.bidding_strategy_type.name}")
print(f"Budget: ${b.amount_micros / 1_000_000:.2f}")
print(f"Impressions: {m.impressions:,}")
print(f"Clicks: {m.clicks:,}")
print(f"Cost: ${m.cost_micros / 1_000_000:.2f}")
print(f"CTR: {m.ctr:.2%}")
print(f"Avg CPC: ${m.average_cpc / 1_000_000:.2f}")
print(f"Conversions: {m.conversions}")
print(f"Conv. Value: ${m.conversions_value:.2f}")
if m.conversions > 0:
print(f"Cost/Conv: ${m.cost_per_conversion / 1_000_000:.2f}")
print("-" * 30)
except GoogleAdsException as ex:
print(f"Report generation failed: {ex.error.code().name}")class CampaignOperation:
"""Operation for campaign mutations."""
create: Campaign # Create new campaign
update: Campaign # Update existing campaign
remove: str # Remove campaign by resource name
update_mask: FieldMask # Fields to update
class CampaignBudgetOperation:
"""Operation for campaign budget mutations."""
create: CampaignBudget # Create new budget
update: CampaignBudget # Update existing budget
remove: str # Remove budget by resource name
update_mask: FieldMask # Fields to update
class CampaignCriterionOperation:
"""Operation for campaign criterion mutations."""
create: CampaignCriterion # Create new criterion
update: CampaignCriterion # Update existing criterion
remove: str # Remove criterion by resource name
update_mask: FieldMask # Fields to updateclass Campaign:
"""Campaign resource."""
resource_name: str # Campaign resource name
name: str # Campaign name
status: CampaignStatusEnum # Campaign status
advertising_channel_type: AdvertisingChannelTypeEnum # Channel type
advertising_channel_sub_type: AdvertisingChannelSubTypeEnum # Sub type
campaign_budget: str # Budget resource name
bidding_strategy_type: BiddingStrategyTypeEnum # Bidding strategy
start_date: str # Start date (YYYY-MM-DD)
end_date: str # End date (YYYY-MM-DD)
network_settings: NetworkSettings # Network targeting
manual_cpc: ManualCpc # Manual CPC settings
target_cpa: TargetCpa # Target CPA settings
target_roas: TargetRoas # Target ROAS settings
maximize_clicks: MaximizeClicks # Maximize clicks settings
maximize_conversions: MaximizeConversions # Maximize conversions settings
class CampaignBudget:
"""Campaign budget resource."""
resource_name: str # Budget resource name
name: str # Budget name
amount_micros: int # Budget amount in micros
delivery_method: BudgetDeliveryMethodEnum # Delivery method
explicitly_shared: bool # Whether budget is shared
status: BudgetStatusEnum # Budget status
type_: BudgetTypeEnum # Budget type
class CampaignCriterion:
"""Campaign criterion resource."""
resource_name: str # Criterion resource name
campaign: str # Campaign resource name
type_: CriterionTypeEnum # Criterion type
negative: bool # Whether criterion is negative
location: LocationInfo # Location targeting
language: LanguageInfo # Language targeting
keyword: KeywordInfo # Keyword targeting
ad_schedule: AdScheduleInfo # Ad schedule
device: DeviceInfo # Device targeting# Campaign status values
class CampaignStatusEnum:
UNKNOWN = 0
ENABLED = 2
PAUSED = 3
REMOVED = 4
# Advertising channel types
class AdvertisingChannelTypeEnum:
UNKNOWN = 0
SEARCH = 2
DISPLAY = 3
SHOPPING = 4
VIDEO = 6
MULTI_CHANNEL = 7
LOCAL = 8
SMART = 9
PERFORMANCE_MAX = 13
# Bidding strategy types
class BiddingStrategyTypeEnum:
UNKNOWN = 0
MANUAL_CPC = 2
MANUAL_CPM = 3
MANUAL_CPV = 5
MAXIMIZE_CLICKS = 10
MAXIMIZE_CONVERSIONS = 11
MAXIMIZE_CONVERSION_VALUE = 12
TARGET_CPA = 13
TARGET_IMPRESSION_SHARE = 15
TARGET_ROAS = 16
TARGET_CPM = 17
# Budget delivery methods
class BudgetDeliveryMethodEnum:
UNKNOWN = 0
STANDARD = 2
ACCELERATED = 3# Micro unit conversions
MICROS_PER_UNIT = 1_000_000
# Campaign limits
MAX_CAMPAIGN_NAME_LENGTH = 255
MAX_CAMPAIGNS_PER_CUSTOMER = 10000
# Budget limits
MIN_BUDGET_AMOUNT_MICROS = 100_000 # $0.10
MAX_BUDGET_AMOUNT_MICROS = 100_000_000_000 # $100,000
# Date format
DATE_FORMAT = "YYYY-MM-DD"Install with Tessl CLI
npx tessl i tessl/pypi-google-ads