55import os
66import re
77from collections .abc import Callable
8- from datetime import date , datetime , timezone
8+ from datetime import date , datetime , timedelta , timezone
99from enum import Enum , auto
1010from pathlib import Path
1111from 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