From 87336623255b7d99614eb9f4e1b003d1f143ed7d Mon Sep 17 00:00:00 2001 From: indiviedualis-ui Date: Wed, 23 Sep 2026 22:45:38 +0800 Subject: [PATCH] Complete GA4 report pagination Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../run_report_with_pagination.py | 68 +++++++------------ .../run_report_with_pagination_test.py | 20 ++++++ 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/google-analytics-data/run_report_with_pagination.py b/google-analytics-data/run_report_with_pagination.py index f8af1cd..7c869c0 100644 --- a/google-analytics-data/run_report_with_pagination.py +++ b/google-analytics-data/run_report_with_pagination.py @@ -44,50 +44,34 @@ def run_report_with_pagination(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report several times, each time retrieving a portion of result using pagination.""" client = BetaAnalyticsDataClient() + limit = 100000 + offset = 0 - # [START analyticsdata_run_report_with_pagination_page1] - request = RunReportRequest( - property=f"properties/{property_id}", - date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")], - dimensions=[ - Dimension(name="firstUserSource"), - Dimension(name="firstUserMedium"), - Dimension(name="firstUserCampaignName"), - ], - metrics=[ - Metric(name="sessions"), - Metric(name="keyEvents"), - Metric(name="totalRevenue"), - ], - limit=100000, - offset=0, - ) - response = client.run_report(request) - # [END analyticsdata_run_report_with_pagination_page1] - print_run_report_response(response) + while True: + request = RunReportRequest( + property=f"properties/{property_id}", + date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")], + dimensions=[ + Dimension(name="firstUserSource"), + Dimension(name="firstUserMedium"), + Dimension(name="firstUserCampaignName"), + ], + metrics=[ + Metric(name="sessions"), + Metric(name="keyEvents"), + Metric(name="totalRevenue"), + ], + limit=limit, + offset=offset, + ) + response = client.run_report(request) + print_run_report_response(response) - # Run the same report with a different offset value to retrieve the second - # page of a response. - # [START analyticsdata_run_report_with_pagination_page2] - request = RunReportRequest( - property=f"properties/{property_id}", - date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")], - dimensions=[ - Dimension(name="firstUserSource"), - Dimension(name="firstUserMedium"), - Dimension(name="firstUserCampaignName"), - ], - metrics=[ - Metric(name="sessions"), - Metric(name="keyEvents"), - Metric(name="totalRevenue"), - ], - limit=100000, - offset=100000, - ) - response = client.run_report(request) - # [END analyticsdata_run_report_with_pagination_page2] - print_run_report_response(response) + # row_count is the total number of rows matching the request. Request + # another page only when the current page does not reach that total. + if offset + limit >= response.row_count: + break + offset += limit # [END analyticsdata_run_report_with_pagination] diff --git a/google-analytics-data/run_report_with_pagination_test.py b/google-analytics-data/run_report_with_pagination_test.py index b9b65e7..1f66713 100644 --- a/google-analytics-data/run_report_with_pagination_test.py +++ b/google-analytics-data/run_report_with_pagination_test.py @@ -13,6 +13,8 @@ # limitations under the License. import os +from types import SimpleNamespace +from unittest import mock import run_report_with_pagination @@ -23,3 +25,21 @@ def test_run_report_with_pagination(capsys): run_report_with_pagination.run_report_with_pagination(TEST_PROPERTY_ID) out, _ = capsys.readouterr() assert "Report result" in out + + +def test_run_report_with_pagination_requests_pages_until_row_count(): + responses = [ + SimpleNamespace(row_count=250001, rows=[]), + SimpleNamespace(row_count=250001, rows=[]), + SimpleNamespace(row_count=250001, rows=[]), + ] + client = mock.Mock() + client.run_report.side_effect = responses + + with mock.patch.object( + run_report_with_pagination, "BetaAnalyticsDataClient", return_value=client + ), mock.patch.object(run_report_with_pagination, "print_run_report_response"): + run_report_with_pagination.run_report_with_pagination("123") + + offsets = [request.offset for (request,) in client.run_report.call_args_list] + assert offsets == [0, 100000, 200000]