Report Streaming

There are two methods for retrieving entities and reporting data with the Search Ads 360 Reporting API.

This guide primarily focuses on streaming data from SearchAds360Service . Here are high-level distinctions for the two data retrieval methods:

SearchAds360Service.SearchStream SearchAds360Service.Search
Suitable for production code
Yes Yes
Service
SearchAds360Service SearchAds360Service
Scenario
Fetching objects and reports Fetching objects and reports
Response
Stream of SearchAds360Row objects Pages of SearchAds360Row objects
Response's fields
Only those specified in the query Only those specified in the query
Daily limits
See API limits and quotas. See API limits and quotas.

While Search can send multiple paginated requests to download the entire report, SearchStream sends a single request and initiates a persistent connection with the Search Ads 360 Reporting API regardless of report size.

For SearchStream , data packets start to download immediately with the entire result cached in a data buffer. Your code can start reading the buffered data without having to wait for the entire stream to finish.

By eliminating the round-trip network time required to request each individual page of a Search response, depending on your app, SearchStream can offer improved performance over paging, especially for bigger reports.

Example

Take a report that consists of 100,000 rows for example. The following table breaks down the accounting differences between the two methods.

* SearchStream Search
Page size Not Applicable 10,000 rows per page
Number of API requests 1 request 10 requests
Number of API responses 1 continuous stream 10 responses

Performance factors

In general, we recommend SearchStream over Search for the following reasons.

  • For single page reports (under 10,000 rows): No significant performance differences between the two methods.

  • For multiple page reports: SearchStream is typically faster since multiple roundtrips are avoided and reading/writing from disk cache is less of a factor.

Rate limits

Daily limits for both methods adhere to the standard API limits and quotas . A single query or report is counted as one operation regardless of the result being paged or streamed.

Streaming example

Java

 // Copyright 2022 Google LLC 
 // 
 // Licensed under the Apache License, Version 2.0 (the "License"); 
 // you may not use this file except in compliance with the License. 
 // You may obtain a copy of the License at 
 // 
 //     https://www.apache.org/licenses/LICENSE-2.0 
 // 
 // Unless required by applicable law or agreed to in writing, software 
 // distributed under the License is distributed on an "AS IS" BASIS, 
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 // See the License for the specific language governing permissions and 
 // limitations under the License. 
 package 
  
 sample 
 ; 
 import 
  
 com.beust.jcommander.Parameter 
 ; 
 import 
  
 com.google.ads.searchads360.v0.lib.SearchAds360Client 
 ; 
 import 
  
 com.google.ads.searchads360.v0.services.SearchAds360Row 
 ; 
 import 
  
 com.google.ads.searchads360.v0.services.SearchAds360ServiceClient 
 ; 
 import 
  
 com.google.ads.searchads360.v0.services.SearchSearchAds360StreamRequest 
 ; 
 import 
  
 com.google.ads.searchads360.v0.services.SearchSearchAds360StreamResponse 
 ; 
 import 
  
 com.google.api.gax.rpc.ServerStream 
 ; 
 /** Get campaign details using SearchStream. */ 
 public 
  
 class 
 GetCampaignsStream 
  
 { 
  
 private 
  
 static 
  
 class 
 GetCampaignsStreamParams 
  
 extends 
  
 CodeSampleParams 
  
 { 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 "--customerId" 
 , 
  
 required 
  
 = 
  
 true 
 ) 
  
 private 
  
 String 
  
 customerId 
 ; 
  
 @Parameter 
 ( 
 names 
  
 = 
  
 "--loginCustomerId" 
 ) 
  
 private 
  
 String 
  
 loginCustomerId 
 ; 
  
 } 
  
 public 
  
 static 
  
 void 
  
 main 
 ( 
 String 
 [] 
  
 args 
 ) 
  
 { 
  
 GetCampaignsStreamParams 
  
 params 
  
 = 
  
 new 
  
 GetCampaignsStreamParams 
 (); 
  
 if 
  
 ( 
 ! 
 params 
 . 
 parseArguments 
 ( 
 args 
 )) 
  
 { 
  
 // Optional: You may pass the loginCustomerId on the command line or specify a loginCustomerId 
  
 // here (10 digits, no dashes). If neither are set, customerId will be used as 
  
 // loginCustomerId. 
  
 // params.loginCustomerId = Long.parseLong("INSERT_LOGIN_CUSTOMER_ID_HERE"); 
  
 } 
  
 final 
  
 String 
  
 loginCustomerId 
  
 = 
  
 params 
 . 
 loginCustomerId 
 ; 
  
 final 
  
 String 
  
 customerId 
  
 = 
  
 params 
 . 
 customerId 
 ; 
  
 try 
  
 { 
  
 // Creates a SearchAds360Client with the specified loginCustomerId. If there's 
  
 // no loginCustomerId, customerId will be used instead. 
  
 final 
  
 SearchAds360Client 
  
 searchAds360Client 
  
 = 
  
 SearchAds360Client 
 . 
 newBuilder 
 () 
  
 . 
 setLoginCustomerId 
 ( 
 loginCustomerId 
  
 == 
  
 null 
  
 ? 
  
 customerId 
  
 : 
  
 loginCustomerId 
 ) 
  
 . 
 fromPropertiesFile 
 () 
  
 . 
 build 
 (); 
  
 // Creates the Search Ads 360 Service client. 
  
 SearchAds360ServiceClient 
  
 client 
  
 = 
  
 searchAds360Client 
 . 
 create 
 (); 
  
 new 
  
 GetCampaignsStream 
 (). 
 runExample 
 ( 
 client 
 , 
  
 customerId 
 ); 
  
 } 
  
 catch 
  
 ( 
 Exception 
  
 exception 
 ) 
  
 { 
  
 System 
 . 
 err 
 . 
 printf 
 ( 
 "Failed with exception: %s%n" 
 , 
  
 exception 
 ); 
  
 exception 
 . 
 printStackTrace 
 (); 
  
 System 
 . 
 exit 
 ( 
 1 
 ); 
  
 } 
  
 } 
  
 private 
  
 void 
  
 runExample 
 ( 
 SearchAds360ServiceClient 
  
 searchAds360ServiceClient 
 , 
  
 String 
  
 customerId 
 ) 
  
 { 
  
 // Creates a query that retrieves all campaigns under the customerId. 
  
 String 
  
 query 
  
 = 
  
 """ 
 SELECT campaign.name, campaign.id, campaign.status FROM campaign 
 """ 
 ; 
  
 SearchSearchAds360StreamRequest 
  
 request 
  
 = 
  
 SearchSearchAds360StreamRequest 
 . 
 newBuilder 
 () 
  
 . 
 setCustomerId 
 ( 
 customerId 
 ) 
  
 . 
 setQuery 
 ( 
 query 
 ) 
  
 . 
 build 
 (); 
  
 // Issues a search stream request. 
  
 ServerStream<SearchSearchAds360StreamResponse> 
  
 stream 
  
 = 
  
 searchAds360ServiceClient 
 . 
 searchStreamCallable 
 (). 
 call 
 ( 
 request 
 ); 
  
 for 
  
 ( 
 SearchSearchAds360StreamResponse 
  
 response 
  
 : 
  
 stream 
 ) 
  
 { 
  
 for 
  
 ( 
 SearchAds360Row 
  
 element 
  
 : 
  
 response 
 . 
 getResultsList 
 ()) 
  
 { 
  
 System 
 . 
 out 
 . 
 printf 
 ( 
  
 "Campaign found with name '%s', ID %d, and status: %s.%n" 
 , 
  
 element 
 . 
 getCampaign 
 (). 
 getName 
 (), 
  
 element 
 . 
 getCampaign 
 (). 
 getId 
 (), 
  
 element 
 . 
 getCampaign 
 (). 
 getStatus 
 ()); 
  
 } 
  
 } 
  
 } 
 } 

Download GetCampaignsStream.java

Python

 #!/usr/bin/env python 
 # Copyright 2022 Google LLC 
 # 
 # Licensed under the Apache License, Version 2.0 (the "License"); 
 # you may not use this file except in compliance with the License. 
 # You may obtain a copy of the License at 
 # 
 #     https://www.apache.org/licenses/LICENSE-2.0 
 # 
 # Unless required by applicable law or agreed to in writing, software 
 # distributed under the License is distributed on an "AS IS" BASIS, 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 # See the License for the specific language governing permissions and 
 # limitations under the License. 
 """Retrieves campaigns for a customer using a stream request.""" 
 import 
  
 argparse 
 import 
  
 traceback 
 from 
  
 google.ads.searchads360.v0.services.types.search_ads360_service 
  
 import 
 SearchSearchAds360StreamRequest 
 from 
  
 util_searchads360 
  
 import 
 SearchAds360Client 
 def 
  
 main 
 ( 
 client 
 , 
 customer_id 
 ) 
 - 
> None 
 : 
 search_ads_360_service 
 = 
 client 
 . 
 get_service 
 () 
 query 
 = 
 """ 
 SELECT 
 campaign.name, 
 campaign.id, 
 campaign.status 
 FROM campaign""" 
 request 
 = 
 SearchSearchAds360StreamRequest 
 () 
 request 
 . 
 customer_id 
 = 
 customer_id 
 request 
 . 
 query 
 = 
 query 
 # Issues a search stream request. 
 results 
 = 
 search_ads_360_service 
 . 
 search_stream 
 ( 
 request 
 = 
 request 
 ) 
 for 
 response 
 in 
 results 
 : 
 for 
 result 
 in 
 response 
 . 
 results 
 : 
 campaign 
 = 
 result 
 . 
 campaign 
 print 
 ( 
 f 
 'campaign " 
 { 
 campaign 
 . 
 name 
 } 
 " has id 
 { 
 campaign 
 . 
 id 
 } 
 and status 
 { 
 campaign 
 . 
 status 
 . 
 name 
 } 
 ' 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 # SearchAds360Client will read the search-ads-360.yaml configuration file in 
 # the home directory if none is specified. 
 search_ads_360_client 
 = 
 SearchAds360Client 
 . 
 load_from_file 
 () 
 parser 
 = 
 argparse 
 . 
 ArgumentParser 
 ( 
 description 
 = 
 ( 
 "Retrieves campaigns for a customer." 
 )) 
 # Arguments to provide to run the example. 
 parser 
 . 
 add_argument 
 ( 
 "-c" 
 , 
 "--customer_id" 
 , 
 type 
 = 
 str 
 , 
 required 
 = 
 True 
 , 
 help 
 = 
 "The Search Ads 360 customer ID (10 digits, no dashes)." 
 , 
 ) 
 parser 
 . 
 add_argument 
 ( 
 "-l" 
 , 
 "--login_customer_id" 
 , 
 type 
 = 
 str 
 , 
 required 
 = 
 False 
 , 
 help 
 = 
 "The Search Ads 360 login customer ID (10 digits, no dashes)." 
 , 
 ) 
 args 
 = 
 parser 
 . 
 parse_args 
 () 
 search_ads_360_client 
 . 
 set_ids 
 ( 
 args 
 . 
 customer_id 
 , 
 args 
 . 
 login_customer_id 
 ) 
 try 
 : 
 main 
 ( 
 search_ads_360_client 
 , 
 args 
 . 
 customer_id 
 ) 
 except 
 Exception 
 : 
 # pylint: disable=broad-except 
 traceback 
 . 
 print_exc 
 () 

Download get_campaigns_stream.py

Design a Mobile Site
View Site in Mobile | Classic
Share by: