Skip to content

Commit fa8844a

Browse files
committed
Fetch daily steps in chunks if needed
1 parent 241929d commit fa8844a

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

garminconnect/__init__.py

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import os
66
import re
77
from collections.abc import Callable
8-
from datetime import date, datetime, timezone
8+
from datetime import date, datetime, timedelta, timezone
99
from enum import Enum, auto
1010
from pathlib import Path
1111
from typing import Any
@@ -567,7 +567,12 @@ def get_floors(self, cdate: str) -> dict[str, Any]:
567567
return response
568568

569569
def get_daily_steps(self, start: str, end: str) -> list[dict[str, Any]]:
570-
"""Fetch available steps data 'start' and 'end' format 'YYYY-MM-DD'."""
570+
"""Fetch available steps data 'start' and 'end' format 'YYYY-MM-DD'.
571+
572+
Note: The Garmin Connect API has a 28-day limit per request. For date ranges
573+
exceeding 28 days, this method automatically splits the range into chunks
574+
and makes multiple API calls, then merges the results.
575+
"""
571576

572577
# Validate inputs
573578
start = _validate_date_format(start, "start")
@@ -580,10 +585,45 @@ def get_daily_steps(self, start: str, end: str) -> list[dict[str, Any]]:
580585
if start_date > end_date:
581586
raise ValueError("start date cannot be after end date")
582587

583-
url = f"{self.garmin_connect_daily_stats_steps_url}/{start}/{end}"
584-
logger.debug("Requesting daily steps data")
588+
# Calculate date range (inclusive)
589+
days_diff = (end_date - start_date).days + 1
585590

586-
return self.connectapi(url)
591+
# If range is 28 days or less, make single request
592+
if days_diff <= 28:
593+
url = f"{self.garmin_connect_daily_stats_steps_url}/{start}/{end}"
594+
logger.debug("Requesting daily steps data")
595+
return self.connectapi(url)
596+
597+
# For ranges > 28 days, split into chunks
598+
logger.debug(
599+
f"Date range ({days_diff} days) exceeds 28-day limit, " "chunking requests"
600+
)
601+
all_results = []
602+
current_start = start_date
603+
604+
while current_start <= end_date:
605+
# Calculate chunk end (max 28 days from current_start)
606+
chunk_end = min(current_start + timedelta(days=27), end_date)
607+
chunk_start_str = current_start.isoformat()
608+
chunk_end_str = chunk_end.isoformat()
609+
610+
url = (
611+
f"{self.garmin_connect_daily_stats_steps_url}/"
612+
f"{chunk_start_str}/{chunk_end_str}"
613+
)
614+
logger.debug(
615+
f"Requesting daily steps data for chunk: "
616+
f"{chunk_start_str} to {chunk_end_str}"
617+
)
618+
619+
chunk_results = self.connectapi(url)
620+
if chunk_results:
621+
all_results.extend(chunk_results)
622+
623+
# Move to next chunk
624+
current_start = chunk_end + timedelta(days=1)
625+
626+
return all_results
587627

588628
def get_heart_rates(self, cdate: str) -> dict[str, Any]:
589629
"""Fetch available heart rates data 'cDate' format 'YYYY-MM-DD'.

0 commit comments

Comments
 (0)