Skip to content

fix: filter activity pagination by date range#27

Open
nrvim wants to merge 3 commits intodevfrom
fix/incremental-activity-pagination
Open

fix: filter activity pagination by date range#27
nrvim wants to merge 3 commits intodevfrom
fix/incremental-activity-pagination

Conversation

@nrvim
Copy link
Copy Markdown
Owner

@nrvim nrvim commented Apr 8, 2026

Summary

  • Add startDate and endDate params to the activity search endpoint so only activities within the requested range are fetched
  • Make --latest work for regular syncs — fetches only today's data

Problem

  1. Every sync — even a 1-day incremental — paginated through all activities the user has ever recorded. For a user with 3,500+ activities (Full-range data #23), this meant 35+ API calls just for the activity list.

  2. --latest only worked with --fit-only. Running garmin-givemydata --latest ignored the flag and did a full sync, which is not what users expect.

What changed

  • endpoints.py: full_range_rest() now passes startDate/endDate to the activities search URL
  • client.py: pagination loop and activity ID fallback both include the date filter
  • garmin_givemydata.py: --latest without --fit-only now sets the date range to today only

How to test

git clone https://github.com/nrvim/garmin-givemydata.git
cd garmin-givemydata
git checkout fix/incremental-activity-pagination
bash setup.sh

If you already have a database with data:

# Quick sync — today only
garmin-givemydata --latest

# Normal incremental sync — should no longer paginate through all activities
garmin-givemydata

Before this fix you'd see dozens of Activities page: fetched 100 more (offset ...) lines. After the fix, you should see zero (or just a few if you had many activities that day).

Fixes #23

The activity search endpoint and pagination loop fetched ALL activities
on every sync regardless of date range. For a user with 3,500+
activities this meant 35+ API calls just for the activity list on a
1-day incremental sync.

Add startDate/endDate params to the activity search URL so only
activities within the requested range are fetched.

Fixes #23
Copilot AI review requested due to automatic review settings April 8, 2026 19:33
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes excessive activity-list pagination by applying the requested startDate/endDate date range filter to Garmin’s activity search endpoint, so incremental/range syncs no longer page through a user’s entire activity history.

Changes:

  • Add startDate/endDate to the initial activities search URL returned by full_range_rest().
  • Apply the same date filtering to the activities pagination loop in GarminClient.fetch_all().
  • Apply the same date filtering to the activity-ID fallback query used for per-activity detail fetching.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
garmin_client/endpoints.py Adds date-range query params to the base activities search endpoint returned for full-range fetches.
garmin_client/client.py Updates activity pagination and activity-ID fallback query to respect the same startDate/endDate filter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1036 to 1039
try:
act_data = self.api_fetch(
"/gc-api/activitylist-service/activities/search/activities?limit=1000&start=0"
f"/gc-api/activitylist-service/activities/search/activities?limit=1000&start=0&startDate={s_date}&endDate={e_date}"
)
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The activity-ID fallback query is capped at limit=1000 with no pagination. If the requested date range contains more than 1000 activities, activity_ids will be incomplete and per-activity detail endpoints (splits/HR zones/weather) won’t be fetched for activities beyond the first 1000. Consider paginating this fallback (same start += limit loop used for the main activity list) or collecting IDs during the existing pagination loop so detail fetching always covers the full range.

Copilot uses AI. Check for mistakes.
Comment on lines 933 to 939
# 2b. Paginate remaining activities within the date range
page_start = 100
while True:
act_result = self._fetch_batch(
{
f"activities_page_{page_start}": f"/gc-api/activitylist-service/activities/search/activities?limit=100&start={page_start}"
f"activities_page_{page_start}": f"/gc-api/activitylist-service/activities/search/activities?limit=100&start={page_start}&startDate={s_date}&endDate={e_date}"
},
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The activities search URL is now duplicated in multiple places (endpoints.py initial page, fetch_all pagination, and the activity-ID fallback), including repeated constants like limit=100 and the date filter params. This increases the chance of future drift (e.g., changing limit or adding params in one place but not the others). Consider factoring a small helper to build the activities search URL from start/limit/startDate/endDate and reuse it in all three call sites.

Copilot uses AI. Check for mistakes.
@nrvim nrvim mentioned this pull request Apr 8, 2026
nrvim added 2 commits April 8, 2026 21:43
--latest previously only worked with --fit-only. Now it also works as
a standalone flag to fetch only today's data, which is what users
expect when they run garmin-givemydata --latest.

Fixes #23
…cation

Single source of truth for the activities search URL with date
filtering, limit, and offset params. Used in endpoints.py,
the pagination loop, and the activity ID fallback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants