Skip to content

Commit 21b30d6

Browse files
authored
updated docs and enchanced docstring test (#10)
1 parent 7ffb909 commit 21b30d6

26 files changed

+3104
-1268
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ Additional documentation:
107107
- To understand the logging implemementation, see [LOGGING](docs/LOGGING.md)
108108
- To understand validations and the exception hierarchy, see
109109
[VALIDATIONS_AND_EXCEPTIONS](docs/VALIDATIONS_AND_EXCEPTIONS.md)
110+
- It's work checking out
111+
[Fitbit's Best Practices](https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/)
110112
- For some general development guidelines, see
111113
[DEVELOPMENT](docs/DEVELOPMENT.md).
112114
- For style guidelines (mostly enforced through varius linters and formatters)

TODO.md

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323

2424
- Creat and Test that all methods have an alias in `Client` and that the
2525
signatures match
26-
- Make sure that `ClientValidationException` is getting used for arbitrary
27-
validations like:
2826

2927
```python
3028
if not food_id and not (food_name and calories):
@@ -45,41 +43,20 @@ if not food_id and not (food_name and calories):
4543
params[str(key)] = float(value)
4644
```
4745

48-
It needs to change to:
49-
50-
```python
51-
for key, value in nutritional_values.items():
52-
if isinstance(key, NutritionalValue):
53-
if key == NutritionalValue.CALORIES_FROM_FAT:
54-
params[key.value] = int(value)
55-
else:
56-
params[key.value] = float(value)
57-
else:
58-
params[str(key)] = float(value)
59-
```
60-
6146
see: test_create_food_calories_from_fat_must_be_integer(nutrition_resource)
6247

6348
- exceptions.py
6449

65-
- Should ClientValidationException really subclass FitbitAPIException? It
66-
doesn't need the API lookup mapping (`exception_type`) or a `status_code`,
67-
so we may just be able to simplify it. The most important thing is that the
68-
user understands that the message came from the client prior to the API
69-
call.
70-
71-
- Resource docstrings/documentation:
50+
- Should ClientValidationException really subclass FitbitAPIException? IT
51+
SHOULD SUBCLASS ValueError doesn't need the API lookup mapping
52+
(`exception_type`) or a `status_code`, so we may just be able to simplify
53+
it. The most important thing is that the user understands that the message
54+
came from the client prior to the API call.
7255

73-
- Update the list of exceptions that are raised in the doctring for
74-
`base._make_request`
75-
- Review all documentation and between **API docs, return types, and
76-
exceptions**, update the doctrings
77-
- Update "Returns" in all resource docstrings
78-
- Review and add link to
79-
https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/
80-
in README--they still apply!
56+
- Make sure we aren't using
8157

82-
- Set up CI!
58+
- Make sure that `ClientValidationException` is getting used for arbitrary
59+
validations like
8360

8461
## Longer term TODOs
8562

fitbit_client/resources/active_zone_minutes.py

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,62 @@
1414

1515

1616
class ActiveZoneMinutesResource(BaseResource):
17-
"""
18-
Handles Fitbit Active Zone Minutes (AZM) API endpoints for retrieving user's
19-
heart-pumping activity data throughout the day.
17+
"""Provides access to Fitbit Active Zone Minutes (AZM) API for heart rate-based activity metrics.
18+
19+
This resource handles endpoints for retrieving Active Zone Minutes (AZM) data, which measures
20+
the time users spend in target heart rate zones during exercise or daily activities. AZM
21+
is a scientifically-validated way to track activity intensity based on personalized heart
22+
rate zones rather than just steps.
2023
21-
Active Zone Minutes (AZM) measure the time spent in target heart rate zones.
2224
Different zones contribute differently to the total AZM count:
23-
- Fat Burn zone: 1 minute = 1 AZM
24-
- Cardio zone: 1 minute = 2 AZM
25-
- Peak zone: 1 minute = 2 AZM
25+
- Fat Burn zone: 1 minute = 1 AZM (moderate intensity)
26+
- Cardio zone: 1 minute = 2 AZM (high intensity)
27+
- Peak zone: 1 minute = 2 AZM (maximum effort)
2628
2729
API Reference: https://dev.fitbit.com/build/reference/web-api/active-zone-minutes-timeseries/
30+
31+
Required Scopes:
32+
- activity (for all AZM endpoints)
33+
34+
Note:
35+
- Heart rate zones are personalized based on the user's resting heart rate and age
36+
- The American Heart Association recommends 150 minutes of moderate (Fat Burn) or
37+
75 minutes of vigorous (Cardio/Peak) activity per week
38+
- AZM data is available from the date the user first set up their Fitbit device
39+
- Historical data older than 3 years may not be available through the API
40+
- Not all Fitbit devices support AZM tracking (requires heart rate monitoring)
41+
- The date range endpoints are useful for analyzing weekly and monthly AZM totals
2842
"""
2943

3044
@validate_date_param()
3145
def get_azm_timeseries_by_date(
3246
self, date: str, period: Period = Period.ONE_DAY, user_id: str = "-", debug: bool = False
3347
) -> JSONDict:
34-
"""
35-
Get Active Zone Minutes time series data for a period starting from the specified date.
48+
"""Returns Active Zone Minutes time series data for a period ending on the specified date.
3649
3750
API Reference: https://dev.fitbit.com/build/reference/web-api/active-zone-minutes-timeseries/get-azm-timeseries-by-date/
3851
3952
Args:
40-
date: The end date of the period in yyyy-MM-dd format or 'today'
53+
date: The end date of the period in YYYY-MM-DD format or 'today'
4154
period: The range for which data will be returned. Only Period.ONE_DAY (1d) is supported.
42-
user_id: The encoded ID of the user. Use "-" (dash) for current logged-in user.
43-
debug: If True, a prints a curl command to stdout to help with debugging (default: False)
55+
user_id: Optional user ID, defaults to current user ("-")
56+
debug: If True, prints a curl command to stdout to help with debugging (default: False)
4457
4558
Returns:
46-
Daily AZM data including:
47-
- activeZoneMinutes: Total count of active zone minutes
48-
- fatBurnActiveZoneMinutes: Minutes in fat burn zone (1 minute = 1 AZM)
49-
- cardioActiveZoneMinutes: Minutes in cardio zone (1 minute = 2 AZM)
50-
- peakActiveZoneMinutes: Minutes in peak zone (1 minute = 2 AZM)
59+
JSONDict: Daily Active Zone Minutes data
5160
5261
Raises:
5362
ValueError: If period is not Period.ONE_DAY
54-
InvalidDateException: If date format is invalid
63+
fitbit_client.exceptions.InvalidDateException: If date format is invalid
64+
65+
Note:
66+
- Only Period.ONE_DAY (1d) is currently supported by the Fitbit API
67+
- activeZoneMinutes is the sum total of all zone minutes with cardio and peak
68+
minutes counting double (fatBurn + (cardio × 2) + (peak × 2))
69+
- Fat burn zone is typically 50-69% of max heart rate (moderate intensity)
70+
- Cardio zone is typically 70-84% of max heart rate (high intensity)
71+
- Peak zone is typically 85%+ of max heart rate (maximum effort)
72+
- Days with no AZM data will show all metrics as zero
5573
"""
5674
if period != Period.ONE_DAY:
5775
raise ValueError("Only 1d period is supported for AZM time series")
@@ -67,30 +85,32 @@ def get_azm_timeseries_by_date(
6785
def get_azm_timeseries_by_interval(
6886
self, start_date: str, end_date: str, user_id: str = "-", debug: bool = False
6987
) -> JSONDict:
70-
"""
71-
Get Active Zone Minutes time series data for a specified date range.
88+
"""Returns Active Zone Minutes time series data for a specified date range.
7289
7390
API Reference: https://dev.fitbit.com/build/reference/web-api/active-zone-minutes-timeseries/get-azm-timeseries-by-interval/
7491
7592
Args:
76-
start_date: The start date in yyyy-MM-dd format or 'today'
77-
end_date: The end date in yyyy-MM-dd format or 'today'
78-
user_id: The encoded ID of the user. Use "-" (dash) for current logged-in user.
79-
debug: If True, a prints a curl command to stdout to help with debugging (default: False)
93+
start_date: The start date in YYYY-MM-DD format or 'today'
94+
end_date: The end date in YYYY-MM-DD format or 'today'
95+
user_id: Optional user ID, defaults to current user ("-")
96+
debug: If True, prints a curl command to stdout to help with debugging (default: False)
8097
8198
Returns:
82-
Daily AZM data for each date in the range including:
83-
- activeZoneMinutes: Total count of active zone minutes
84-
- fatBurnActiveZoneMinutes: Minutes in fat burn zone (1 minute = 1 AZM)
85-
- cardioActiveZoneMinutes: Minutes in cardio zone (1 minute = 2 AZM)
86-
- peakActiveZoneMinutes: Minutes in peak zone (1 minute = 2 AZM)
99+
JSONDict: Daily Active Zone Minutes data for each date in the range
87100
88101
Raises:
89-
InvalidDateException: If date format is invalid
90-
InvalidDateRangeException: If date range is invalid or exceeds 1095 days
102+
fitbit_client.exceptions.InvalidDateException: If date format is invalid
103+
fitbit_client.exceptions.InvalidDateRangeException: If date range is invalid or exceeds 1095 days
91104
92105
Note:
93-
Maximum date range is 1095 days (approximately 3 years)
106+
- Maximum date range is 1095 days (approximately 3 years)
107+
- Each day's entry includes separate counts for each heart rate zone
108+
- activeZoneMinutes is the total AZM with cardio and peak minutes counting double
109+
- This endpoint is useful for calculating weekly or monthly AZM totals
110+
- Days with no AZM data will have all metrics as zero
111+
- Active Zone Minutes does not support subscription notifications (webhooks),
112+
but can be queried after activity notifications arrive
113+
- Weekly AZM goals can be tracked by summing 7 consecutive days of data
94114
"""
95115
result = self._make_request(
96116
f"activities/active-zone-minutes/date/{start_date}/{end_date}.json",

0 commit comments

Comments
 (0)