The AdWords API will sunset on April 27, 2022. Migrate to the Google Ads API to take advantage of the latest Google Ads features.

Reporting Samples

The code samples below provide examples of common reporting functions using the AdWords API. Client Library.

Download a criteria performance report with AWQL

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.Reports;
using Google.Api.Ads.AdWords.Util.Reports.v201809;
using Google.Api.Ads.AdWords.v201809;
using Google.Api.Ads.Common.Util.Reports;

using System;
using System.IO;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// This code example gets and downloads a criteria Ad Hoc report from an AWQL
    /// query. See https://developers.google.com/adwords/api/docs/guides/awql for
    /// AWQL documentation.
    /// </summary>
    public class DownloadCriteriaReportWithAwql : ExampleBase
    {
        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            DownloadCriteriaReportWithAwql codeExample = new DownloadCriteriaReportWithAwql();
            Console.WriteLine(codeExample.Description);
            try
            {
                string fileName = "INSERT_FILE_NAME_HERE";
                codeExample.Run(new AdWordsUser(), fileName);
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example gets and downloads a criteria Ad Hoc report from an " +
                    "AWQL query. See " +
                    "https://developers.google.com/adwords/api/docs/guides/awql for AWQL " +
                    "documentation.";
            }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="fileName">The file to which the report is downloaded.
        /// </param>
        public void Run(AdWordsUser user, string fileName)
        {
            ReportQuery query = new ReportQueryBuilder()
                .Select("CampaignId", "AdGroupId", "Id", "Criteria", "CriteriaType",
                    "Impressions", "Clicks", "Cost")
                .From(ReportDefinitionReportType.CRITERIA_PERFORMANCE_REPORT)
                .Where("Status").In("ENABLED", "PAUSED")
                .During(ReportDefinitionDateRangeType.LAST_7_DAYS)
                .Build();

            string filePath =
                ExampleUtilities.GetHomeDir() + Path.DirectorySeparatorChar + fileName;

            try
            {
                ReportUtilities utilities = new ReportUtilities(user, "v201809", query,
                    DownloadFormat.GZIPPED_CSV.ToString());
                using (ReportResponse response = utilities.GetResponse())
                {
                    response.Save(filePath);
                }

                Console.WriteLine("Report was downloaded to '{0}'.", filePath);
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to download report.", e);
            }
        }
    }
}

Download a criteria performance report using selectors

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.Reports;
using Google.Api.Ads.AdWords.v201809;
using Google.Api.Ads.Common.Util.Reports;

using System;
using System.IO;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// This code example gets and downloads a criteria Ad Hoc report from an XML
    /// report definition.
    /// </summary>
    public class DownloadCriteriaReportWithSelector : ExampleBase
    {
        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            DownloadCriteriaReportWithSelector codeExample =
                new DownloadCriteriaReportWithSelector();
            Console.WriteLine(codeExample.Description);
            try
            {
                string fileName = "INSERT_FILE_NAME_HERE";
                codeExample.Run(new AdWordsUser(), fileName);
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example gets and downloads a criteria Ad Hoc report from an " +
                    "XML report definition.";
            }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="fileName">The file to which the report is downloaded.
        /// </param>
        public void Run(AdWordsUser user, string fileName)
        {
            ReportDefinition definition = new ReportDefinition()
            {
                reportName = "Last 7 days CRITERIA_PERFORMANCE_REPORT",
                reportType = ReportDefinitionReportType.CRITERIA_PERFORMANCE_REPORT,
                downloadFormat = DownloadFormat.GZIPPED_CSV,
                dateRangeType = ReportDefinitionDateRangeType.LAST_7_DAYS,

                selector = new Selector()
                {
                    fields = new string[]
                    {
                        "CampaignId",
                        "AdGroupId",
                        "Id",
                        "CriteriaType",
                        "Criteria",
                        "FinalUrls",
                        "Clicks",
                        "Impressions",
                        "Cost"
                    },
                    predicates = new Predicate[]
                    {
                        Predicate.In("Status", new string[]
                        {
                            "ENABLED",
                            "PAUSED"
                        })
                    }
                },
            };

            // Optional: Include zero impression rows.
            (user.Config as AdWordsAppConfig).IncludeZeroImpressions = true;

            // Optional: You can also skip the report headers, column headers and
            // report summary etc. to make the report parsing simpler.
            // (user.Config as AdWordsAppConfig).SkipColumnHeader = true;
            // (user.Config as AdWordsAppConfig).SkipReportHeader = true;
            // (user.Config as AdWordsAppConfig).SkipReportSummary = true;

            string filePath =
                ExampleUtilities.GetHomeDir() + Path.DirectorySeparatorChar + fileName;

            try
            {
                ReportUtilities utilities = new ReportUtilities(user, "v201809", definition);
                using (ReportResponse response = utilities.GetResponse())
                {
                    response.Save(filePath);
                }

                Console.WriteLine("Report was downloaded to '{0}'.", filePath);
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to download report.", e);
            }
        }
    }
}

Get the report fields from a report

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.v201809;

using System;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// This code example gets report fields.
    /// </summary>
    public class GetReportFields : ExampleBase
    {
        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            GetReportFields codeExample = new GetReportFields();
            Console.WriteLine(codeExample.Description);
            try
            {
                ReportDefinitionReportType reportType =
                    (ReportDefinitionReportType) Enum.Parse(typeof(ReportDefinitionReportType),
                        "INSERT_REPORT_TYPE_HERE");
                codeExample.Run(new AdWordsUser(), reportType);
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get { return "This code example gets report fields."; }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="reportType">The report type to be run.</param>
        public void Run(AdWordsUser user, ReportDefinitionReportType reportType)
        {
            using (ReportDefinitionService reportDefinitionService =
                (ReportDefinitionService) user.GetService(AdWordsService.v201809
                    .ReportDefinitionService))
            {
                try
                {
                    // Get the report fields.
                    ReportDefinitionField[] reportDefinitionFields =
                        reportDefinitionService.getReportFields(reportType);
                    if (reportDefinitionFields != null && reportDefinitionFields.Length > 0)
                    {
                        // Display report fields.
                        Console.WriteLine("The report type '{0}' contains the following fields:",
                            reportType);

                        foreach (ReportDefinitionField reportDefinitionField in
                            reportDefinitionFields)
                        {
                            Console.Write("- {0} ({1})", reportDefinitionField.fieldName,
                                reportDefinitionField.fieldType);
                            if (reportDefinitionField.enumValues != null)
                            {
                                Console.Write(" := [{0}]",
                                    string.Join(", ", reportDefinitionField.enumValues));
                            }

                            Console.WriteLine();
                        }
                    }
                    else
                    {
                        Console.WriteLine("This report type has no fields.");
                    }
                }
                catch (Exception e)
                {
                    throw new System.ApplicationException(
                        "Failed to retrieve fields for report type.", e);
                }
            }
        }
    }
}

Download a report for multiple accounts

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.Reports;
using Google.Api.Ads.AdWords.Util.Reports.v201809;
using Google.Api.Ads.AdWords.v201809;
using Google.Api.Ads.Common.Util.Reports;

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// This code example runs a report for every advertiser account under a
    /// given manager account, using multiple parallel threads. This code example
    /// needs to be run against an AdWords manager account.
    /// </summary>
    public class ParallelReportDownload : ExampleBase
    {
        /// <summary>
        /// The maximum number of reports to download in parallel. This number should
        /// be less than or equal to <see cref="MAX_NUMBER_OF_THREADS"/>.
        /// </summary>
        private const int MAX_REPORT_DOWNLOADS_IN_PARALLEL = 3;

        /// <summary>
        /// The maximum number of threads to initialize for report downloads.
        /// Normally, you would set this to <see cref="MAX_REPORT_DOWNLOADS_IN_PARALLEL"/>.
        /// However, a more dynamic strategy involves changing
        /// MAX_REPORT_DOWNLOADS_IN_PARALLEL at runtime depending on the AdWords
        /// API server loads.
        /// </summary>
        private const int MAX_NUMBER_OF_THREADS = 10;

        /// <summary>
        /// Represents a report that was successfully downloaded.
        /// </summary>
        public class SuccessfulReportDownload
        {
            /// <summary>
            /// Gets or sets the customer ID for the report.
            /// </summary>
            public long CustomerId { get; set; }

            /// <summary>
            /// Gets or sets the path to which report was downloaded.
            /// </summary>
            public string Path { get; set; }
        }

        /// <summary>
        /// Represents a report download that failed.
        /// </summary>
        public class FailedReportDownload
        {
            /// <summary>
            /// Gets or sets the customer ID for the report.
            /// </summary>
            public long CustomerId { get; set; }

            /// <summary>
            /// Gets or sets the exception that was thrown..
            /// </summary>
            public AdWordsReportsException Exception { get; set; }
        }

        /// <summary>
        /// A data structure to hold data specific for a particular report download
        /// thread.
        /// </summary>
        public class ReportDownloadData
        {
            /// <summary>
            /// Gets or sets the application configuration.
            /// </summary>
            public AdWordsAppConfig Config { get; set; }

            /// <summary>
            /// Gets or sets the index of the thread that identifies it.
            /// </summary>
            public int ThreadIndex { get; set; }

            /// <summary>
            /// Gets or sets the folder to which reports are downloaded.
            /// </summary>
            public string DownloadFolder { get; set; }

            /// <summary>
            /// Gets or sets the event that signals the main thread that this thread
            /// is finished with its job.
            /// </summary>
            public ManualResetEvent SignalEvent { get; set; }

            /// <summary>
            /// Gets or sets the queue that holds the list of all customerIDs to be
            /// processed.
            /// </summary>
            public IProducerConsumerCollection<long> CustomerIdQueue { get; set; }

            /// <summary>
            /// Gets or sets the queue that holds the list of successful report
            /// downloads.
            /// </summary>
            public IProducerConsumerCollection<SuccessfulReportDownload> SuccessfulReports
            {
                get;
                set;
            }

            /// <summary>
            /// Gets or sets the queue that holds the list of failed report downloads.
            /// </summary>
            public IProducerConsumerCollection<FailedReportDownload> FailedReports { get; set; }

            /// <summary>
            /// Gets or sets the lock that ensures only a fixed number of report
            /// downloads happen simultaneously.
            /// </summary>
            public Semaphore QuotaLock { get; set; }

            /// <summary>
            /// The callback method for the report download thread.
            /// </summary>
            public void ThreadCallback(object arg)
            {
                string query = (string) arg;

                AdWordsUser user = new AdWordsUser(this.Config);

                while (true)
                {
                    // Wait to acquire a lock on the quota lock.
                    QuotaLock.WaitOne();

                    // Try to get a customer ID from the queue.
                    long customerId = 0;
                    bool hasMoreCustomers = CustomerIdQueue.TryTake(out customerId);

                    if (!hasMoreCustomers)
                    {
                        // Nothing more to do, break the loop.
                        QuotaLock.Release();
                        break;
                    }

                    try
                    {
                        ProcessCustomer(user, customerId, query);
                    }
                    finally
                    {
                        // Release the quota lock once we have downloaded the report for the
                        // customer ID.
                        QuotaLock.Release();
                    }
                }

                // Mark the download as finished.
                this.SignalEvent.Set();
            }

            /// <summary>
            /// Processes the customer.
            /// </summary>
            /// <param name="user">The AdWords user.</param>
            /// <param name="customerId">The customer ID.</param>
            /// <param name="query">The report query.</param>
            private void ProcessCustomer(AdWordsUser user, long customerId, string query)
            {
                // Set the customer ID to the current customer.
                this.Config.ClientCustomerId = customerId.ToString();

                string downloadFile = string.Format("{0}{1}adgroup_{2:D10}.gz", this.DownloadFolder,
                    Path.DirectorySeparatorChar, customerId);

                // Download the report.
                Console.WriteLine("[Thread #{0}]: Downloading report for customer: {1} into {2}...",
                    this.ThreadIndex, customerId, downloadFile);

                try
                {
                    ReportUtilities utilities = new ReportUtilities(user, "v201809", query,
                        DownloadFormat.GZIPPED_CSV.ToString());
                    using (ReportResponse response = utilities.GetResponse())
                    {
                        response.Save(downloadFile);
                    }

                    // Mark this report download as success.
                    SuccessfulReportDownload success = new SuccessfulReportDownload
                    {
                        CustomerId = customerId,
                        Path = downloadFile
                    };
                    SuccessfulReports.TryAdd(success);

                    Console.WriteLine("Report was downloaded to '{0}'.", downloadFile);
                }
                catch (AdWordsReportsException e)
                {
                    // Mark this report download as failure.
                    FailedReportDownload failure = new FailedReportDownload
                    {
                        CustomerId = customerId,
                        Exception = e
                    };
                    FailedReports.TryAdd(failure);

                    Console.WriteLine(
                        "Failed to download report for customer: {0}. Exception says {1}",
                        customerId, e.Message);
                }
            }
        }

        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            ParallelReportDownload codeExample = new ParallelReportDownload();
            Console.WriteLine(codeExample.Description);
            try
            {
                string fileName = "INSERT_FOLDER_NAME_HERE";
                codeExample.Run(new AdWordsUser(), fileName);
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example runs a report for every advertiser account under a " +
                    "given manager account, using multiple parallel threads. This code example " +
                    "needs to be run against an AdWords manager account.";
            }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="downloadFolder">The file to which the report is downloaded.
        /// </param>
        public void Run(AdWordsUser user, string downloadFolder)
        {
            // Increase the number of HTTP connections we can do in parallel.
            System.Net.ServicePointManager.DefaultConnectionLimit = 100;

            try
            {
                // Start the rate limiter with an initial value of zero, so that all
                // threads block immediately.
                Semaphore rateLimiter = new Semaphore(0, MAX_REPORT_DOWNLOADS_IN_PARALLEL);

                // Get all the advertiser accounts under this manager account.
                List<long> allCustomerIds = GetDescendantAdvertiserAccounts(user);

                // Create a concurrent queue of customers so that all threads can work
                // on the collection in parallel.
                ConcurrentQueue<long> customerQueue = new ConcurrentQueue<long>(allCustomerIds);

                // Create queues to keep track of successful and failed report downloads.
                ConcurrentQueue<SuccessfulReportDownload> reportsSucceeeded =
                    new ConcurrentQueue<SuccessfulReportDownload>();
                ConcurrentQueue<FailedReportDownload> reportsFailed =
                    new ConcurrentQueue<FailedReportDownload>();

                // Keep an array of events. This is used by the main thread to wait for
                // all worker threads to join.
                ManualResetEvent[] doneEvents = new ManualResetEvent[MAX_NUMBER_OF_THREADS];

                // The list of threads to download reports.
                Thread[] threads = new Thread[MAX_NUMBER_OF_THREADS];

                // The data for each thread.
                ReportDownloadData[] threadData = new ReportDownloadData[MAX_NUMBER_OF_THREADS];

                // The query to be run on each account.
                ReportQuery query = new ReportQueryBuilder()
                    .Select("CampaignId", "AdGroupId", "Impressions", "Clicks", "Cost")
                    .From(ReportDefinitionReportType.ADGROUP_PERFORMANCE_REPORT)
                    .Where("AdGroupStatus").In("ENABLED", "PAUSED")
                    .During(ReportDefinitionDateRangeType.LAST_7_DAYS).Build();

                // Initialize the threads and their data.
                for (int i = 0; i < MAX_NUMBER_OF_THREADS; i++)
                {
                    doneEvents[i] = new ManualResetEvent(false);
                    threadData[i] = new ReportDownloadData()
                    {
                        Config = (AdWordsAppConfig) (user.Config.Clone()),
                        DownloadFolder = downloadFolder,
                        SignalEvent = doneEvents[i],
                        ThreadIndex = i,
                        QuotaLock = rateLimiter,
                        CustomerIdQueue = customerQueue,
                        SuccessfulReports = reportsSucceeeded,
                        FailedReports = reportsFailed
                    };

                    threads[i] = new Thread(threadData[i].ThreadCallback);
                }

                // Start the threads. Since the initial value of rate limiter is zero,
                // all threads will block immediately.
                for (int i = 0; i < threads.Length; i++)
                {
                    threads[i].Start(query);
                }

                // Now reset the rate limiter so all threads can start downloading reports.
                rateLimiter.Release(MAX_REPORT_DOWNLOADS_IN_PARALLEL);

                // Wait for all threads in pool to complete.
                WaitHandle.WaitAll(doneEvents);
                Console.WriteLine("Download completed, results:");

                Console.WriteLine("Successful reports:");
                while (!reportsSucceeeded.IsEmpty)
                {
                    SuccessfulReportDownload success = null;
                    if (reportsSucceeeded.TryDequeue(out success))
                    {
                        Console.WriteLine("Client ID: {0}, Path: {1}", success.CustomerId,
                            success.Path);
                    }
                }

                Console.WriteLine("Failed reports:");
                while (!reportsFailed.IsEmpty)
                {
                    FailedReportDownload failure = null;
                    if (reportsFailed.TryDequeue(out failure))
                    {
                        Console.WriteLine("Client ID: {0}, Cause: {1}", failure.CustomerId,
                            failure.Exception.Message);
                    }
                }

                Console.WriteLine("All reports are downloaded.");
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to download reports.", e);
            }
        }

        /// <summary>
        /// Gets the list of all descendant advertiser accounts under the manager
        /// account.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <returns>A list of customer IDs for descendant advertiser accounts.</returns>
        public static List<long> GetDescendantAdvertiserAccounts(AdWordsUser user)
        {
            List<long> retval = new List<long>();

            // Get the ManagedCustomerService.
            ManagedCustomerService managedCustomerService =
                (ManagedCustomerService) user.GetService(AdWordsService.v201809
                    .ManagedCustomerService);

            // Create selector.
            Selector selector = new Selector()
            {
                fields = new string[]
                {
                    ManagedCustomer.Fields.CustomerId
                },
                predicates = new Predicate[]
                {
                    // Select only advertiser accounts.
                    Predicate.Equals(ManagedCustomer.Fields.CanManageClients, false.ToString())
                },
                paging = Paging.Default
            };

            ManagedCustomerPage page = null;
            try
            {
                do
                {
                    page = managedCustomerService.get(selector);

                    if (page.entries != null)
                    {
                        foreach (ManagedCustomer customer in page.entries)
                        {
                            retval.Add(customer.customerId);
                        }
                    }

                    selector.paging.IncreaseOffset();
                } while (selector.paging.startIndex < page.totalNumEntries);
            }
            catch (Exception)
            {
                Console.WriteLine(
                    "Failed to retrieve advertiser accounts under the manager account.");
                throw;
            }

            return retval;
        }
    }
}

Stream results from a report

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.Reports;
using Google.Api.Ads.AdWords.Util.Reports.v201809;
using Google.Api.Ads.AdWords.v201809;
using Google.Api.Ads.Common.Util.Reports;

using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Xml;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// This code example streams the results of an ad hoc report, collecting
    /// total impressions by network from each line. This demonstrates how you
    /// can extract data from a large report without holding the entire result
    /// set in memory or using files.
    /// </summary>
    public class StreamCriteriaReportResults : ExampleBase
    {
        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            StreamCriteriaReportResults codeExample = new StreamCriteriaReportResults();
            Console.WriteLine(codeExample.Description);
            try
            {
                codeExample.Run(new AdWordsUser());
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example streams the results of an ad hoc report, collecting " +
                    "total impressions by network from each line. This demonstrates how you can " +
                    "extract data from a large report without holding the entire result set in " +
                    "memory or using files.";
            }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            // Create the query.
            ReportQuery query = new ReportQueryBuilder()
                .Select("Id", "AdNetworkType1", "Impressions")
                .From(ReportDefinitionReportType.CRITERIA_PERFORMANCE_REPORT)
                .Where("Status").In("ENABLED", "PAUSED")
                .During(ReportDefinitionDateRangeType.LAST_7_DAYS)
                .Build();

            ReportUtilities reportUtilities = new ReportUtilities(user, "v201809", query,
                DownloadFormat.GZIPPED_XML.ToString());

            Dictionary<string, long> impressionsByAdNetworkType1 = new Dictionary<string, long>();

            try
            {
                using (ReportResponse response = reportUtilities.GetResponse())
                {
                    using (GZipStream gzipStream =
                        new GZipStream(response.Stream, CompressionMode.Decompress))
                    {
                        using (XmlTextReader reader = new XmlTextReader(gzipStream))
                        {
                            while (reader.Read())
                            {
                                switch (reader.NodeType)
                                {
                                    case XmlNodeType.Element: // The node is an Element.
                                        if (reader.Name == "row")
                                        {
                                            ParseRow(impressionsByAdNetworkType1, reader);
                                        }

                                        break;
                                }
                            }
                        }
                    }
                }

                Console.WriteLine("Network, Impressions");
                foreach (string network in impressionsByAdNetworkType1.Keys)
                {
                    Console.WriteLine("{0}, {1}", network, impressionsByAdNetworkType1[network]);
                }
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to download report.", e);
            }
        }

        /// <summary>
        /// Parses a report row.
        /// </summary>
        /// <param name="impressionsByAdNetworkType1">The map that keeps track of
        /// the impressions grouped by by ad network type1.</param>
        /// <param name="reader">The XML reader that parses the report.</param>
        private static void ParseRow(Dictionary<string, long> impressionsByAdNetworkType1,
            XmlTextReader reader)
        {
            string network = null;
            long impressions = 0;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.Name)
                {
                    case "network":
                        network = reader.Value;
                        break;

                    case "impressions":
                        impressions = long.Parse(reader.Value);
                        break;
                }
            }

            if (network != null)
            {
                if (!impressionsByAdNetworkType1.ContainsKey(network))
                {
                    impressionsByAdNetworkType1[network] = 0;
                }

                impressionsByAdNetworkType1[network] += impressions;
            }
        }
    }
}

Stream results from a report as objects

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.Reports;
using Google.Api.Ads.AdWords.Util.Reports.v201809;
using Google.Api.Ads.AdWords.v201809;
using Google.Api.Ads.Common.Util.Reports;

using System;
using System.IO.Compression;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// The class that holds the data of one row of the report.
    /// </summary>
    public class CriteriaReportRow
    {
        /// <summary>
        /// The Keyword ID column.
        /// </summary>
        [ReportColumn("keywordID")]
        public long KeywordID { get; set; }

        /// <summary>
        /// The impressions column.
        /// </summary>
        [ReportColumn("impressions")]
        public long Impressions { get; set; }

        /// <summary>
        /// The network column.
        /// </summary>
        [ReportColumn("network")]
        public string NetworkType { get; set; }

        /// <summary>
        /// Returns a string that represents the current report row.
        /// </summary>
        override public string ToString()
        {
            return "Id: " + KeywordID + " Impressions: " + Impressions + " NetworkType: " +
                NetworkType;
        }
    }

    /// <summary>
    /// This code example streams the results of an ad hoc report, and
    /// returns the data in the report as objects of a given type.
    /// </summary>
    public class StreamCriteriaReportToPoco : ExampleBase
    {
        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            StreamCriteriaReportToPoco codeExample = new StreamCriteriaReportToPoco();
            Console.WriteLine(codeExample.Description);
            try
            {
                codeExample.Run(new AdWordsUser());
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }

            Console.ReadLine();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example streams the results of an ad hoc report, and " +
                    "returns the data in the report as objects of a given type.";
            }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            // Create the query.
            ReportQuery query = new ReportQueryBuilder()
                .Select("Id", "AdNetworkType1", "Impressions")
                .From(ReportDefinitionReportType.CRITERIA_PERFORMANCE_REPORT)
                .Where("Status").In("ENABLED", "PAUSED")
                .During(ReportDefinitionDateRangeType.LAST_7_DAYS)
                .Build();

            ReportUtilities reportUtilities = new ReportUtilities(user, "v201809", query,
                DownloadFormat.GZIPPED_XML.ToString());

            try
            {
                using (ReportResponse response = reportUtilities.GetResponse())
                {
                    using (GZipStream gzipStream =
                        new GZipStream(response.Stream, CompressionMode.Decompress))
                    {
                        // Deserialize the report into a list of CriteriaReportRow.
                        // You can also deserialize the list into your own POCOs as follows.
                        // 1. Annotate your class properties with ReportRow annotation.
                        //
                        //  public class MyCriteriaReportRow {
                        //
                        //    [ReportColumn]
                        //    public long KeywordID { get; set; }
                        //
                        //    [ReportColumn]
                        //    public long Impressions { get; set; }
                        //  }
                        //
                        // 2. Deserialize into your own report rows.
                        //
                        // var report = new AwReport<MyCriteriaReportRow>(
                        //                new AwXmlTextReader(gzipStream), "Example");
                        using (var report =
                            new AwReport<CriteriaReportRow>(new AwXmlTextReader(gzipStream),
                                "Example"))
                        {
                            // Print the contents of each row object.
                            foreach (var record in report.Rows)
                            {
                                Console.WriteLine(record);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to download and parse report.", e);
            }
        }
    }
}

Stream results from a report as objects of a predefined report row type

// Copyright 2018 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
//
//     http://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.

using Google.Api.Ads.AdWords.Lib;
using Google.Api.Ads.AdWords.Util.Reports;
using Google.Api.Ads.AdWords.Util.Reports.v201809;
using Google.Api.Ads.AdWords.v201809;
using Google.Api.Ads.Common.Util.Reports;

using System;
using System.IO.Compression;

namespace Google.Api.Ads.AdWords.Examples.CSharp.v201809
{
    /// <summary>
    /// This code example streams the results of an ad hoc report, and
    /// returns the data in the report as objects of a predefined report row type.
    /// </summary>
    public class StreamReportToPredefinedReportRowType : ExampleBase
    {
        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            StreamReportToPredefinedReportRowType codeExample =
                new StreamReportToPredefinedReportRowType();
            Console.WriteLine(codeExample.Description);
            try
            {
                codeExample.Run(new AdWordsUser());
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception occurred while running this code example. {0}",
                    ExampleUtilities.FormatException(e));
            }

            Console.ReadLine();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example streams the results of an ad hoc report, and " +
                    "returns the data in the report as objects of a predefined report row type.";
            }
        }

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        public void Run(AdWordsUser user)
        {
            // Retreiving the raw values of enum-type fields instead of display values
            (user.Config as AdWordsAppConfig).UseRawEnumValues = true;

            // Create the query.
            string query =
                "SELECT AccountCurrencyCode, AccountDescriptiveName FROM FINAL_URL_REPORT " +
                "DURING LAST_7_DAYS";

            ReportUtilities reportUtilities = new ReportUtilities(user, "v201809", query,
                DownloadFormat.GZIPPED_XML.ToString());

            try
            {
                using (ReportResponse response = reportUtilities.GetResponse())
                {
                    using (GZipStream gzipStream =
                        new GZipStream(response.Stream, CompressionMode.Decompress))
                    {
                        // Create the report object using the stream.
                        using (var report =
                            new AwReport<FinalUrlReportReportRow>(new AwXmlTextReader(gzipStream),
                                "Example"))
                        {
                            // Print the contents of each row object.
                            while (report.MoveNext())
                            {
                                Console.WriteLine(report.Current.accountCurrencyCode + " " +
                                    report.Current.accountDescriptiveName);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new System.ApplicationException("Failed to download and parse report.", e);
            }
        }
    }
}