Skip to content

Commit 4cb2e8f

Browse files
committed
Corruption cleanup; merges a few commits:
- Ignore TODO - Bring back resource method aliases - Streamline README - Improve documentation organization and readability: - Split NAMING_AND_TYPING.md into TYPES.md and NAMING.md - Split VALIDATIONS_AND_EXCEPTIONS.md into VALIDATIONS.md and ERROR_HANDLING.md - Update README.md with organized documentation links - Fix intraday data support information in DEVELOPMENT.md - Add information about disabling data logging to LOGGING.md - Update TODO.md to reflect completed documentation work
1 parent 083ecf7 commit 4cb2e8f

25 files changed

+1212
-594
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ coverage.xml
4444
htmlcov/
4545
.pytest_cache/
4646
.mypy_cache/
47+
*,cover
4748

4849
# Mac
4950
.DS_Store
@@ -57,3 +58,5 @@ _scripts
5758
_cov_html
5859
secrets.json
5960
tokens.json
61+
TODO.mdø
62+

README.md

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ try:
4848
client.authenticate()
4949

5050
# Make a request (e.g., get user profile)
51+
# You can access resources directly:
5152
profile = client.user.get_profile()
53+
# Or use method aliases for shorter syntax:
54+
profile = client.get_profile()
5255
print(dumps(profile, indent=2))
5356

5457
except Exception as e:
@@ -59,63 +62,109 @@ The response will always be the body of the API response, and is almost always a
5962
`Dict`, `List` or `None`. `nutrition.get_activity_tcx` is the exception. It
6063
returns XML (as a `str`).
6164

62-
## Authentication Methods
65+
## Method Aliases
6366

64-
### 1. Automatic (Recommended)
65-
66-
Uses a local callback server to automatically handle the OAuth2 flow:
67+
All resource methods are available directly from the client instance. This means
68+
you can use:
6769

6870
```python
69-
client = FitbitClient(
70-
client_id="YOUR_CLIENT_ID",
71-
client_secret="YOUR_CLIENT_SECRET",
72-
redirect_uri="https://localhost:8080",
73-
use_callback_server=True # default is True
74-
)
71+
# Short form with method aliases
72+
client.get_profile()
73+
client.get_daily_activity_summary(date="2025-03-06")
74+
client.get_sleep_log_by_date(date="2025-03-06")
75+
```
7576

76-
# Will open browser and handle callback automatically
77-
client.authenticate()
77+
Instead of the longer form:
78+
79+
```python
80+
# Standard resource access
81+
client.user.get_profile()
82+
client.activity.get_daily_activity_summary(date="2025-03-06")
83+
client.sleep.get_sleep_log_by_date(date="2025-03-06")
7884
```
7985

80-
### 2. Manual URL Copy/Paste
86+
Both approaches are equivalent, but aliases provide a more concise syntax.
8187

82-
If you prefer not to use a local server:
88+
## Authentication
89+
90+
Uses a local callback server to automatically handle the OAuth2 flow:
8391

8492
```python
8593
client = FitbitClient(
8694
client_id="YOUR_CLIENT_ID",
8795
client_secret="YOUR_CLIENT_SECRET",
8896
redirect_uri="YOUR_REGISTERED_REDIRECT_URI",
89-
token_cache_path="/tmp/fb_tokens.json",
90-
use_callback_server=True
97+
token_cache_path="/tmp/fb_tokens.json" # Optional: saves tokens between sessions
98+
redirect_uri="YOUR_REGISTERED_REDIRECT_URI",
99+
token_cache_path="/tmp/fb_tokens.json" # Optional: saves tokens between sessions
91100
)
92101

93-
# Will open a browser and start a server to complete the flow (default), or
94-
# prompt you on the command line to copy/paste the callback URL from the
95-
# browser (see `use_callback_server`)
102+
# Will open browser and handle callback automatically
96103
client.authenticate()
97104
```
98105

106+
The `token_cache_path` parameter allows you to persist authentication tokens
107+
between sessions. If provided, the client will:
108+
109+
1. Load existing tokens from this file if available (avoiding re-authentication)
110+
111+
2. Save new or refreshed tokens to this file automatically
112+
113+
3. Handle token refresh when expired tokens are detected The `token_cache_path`
114+
parameter allows you to persist authentication tokens between sessions. If
115+
provided, the client will:
116+
117+
4. Load existing tokens from this file if available (avoiding re-authentication)
118+
119+
5. Save new or refreshed tokens to this file automatically
120+
121+
6. Handle token refresh when expired tokens are detected
122+
99123
## Setting Up Your Fitbit App
100124

101125
1. Go to dev.fitbit.com and create a new application
102126
2. Set OAuth 2.0 Application Type to "Personal"
103-
3. Set Callback URL to:
104-
- For automatic method: "https://localhost:8080"
105-
- For manual method: Your preferred redirect URI
106-
4. Copy your Client ID and Client Secret
107-
108-
Additional documentation:
109-
110-
- To understand the logging implemementation, see [LOGGING](docs/LOGGING.md)
111-
- To understand validations and the exception hierarchy, see
112-
[VALIDATIONS_AND_EXCEPTIONS](docs/VALIDATIONS_AND_EXCEPTIONS.md)
113-
- It's work checking out
114-
[Fitbit's Best Practices](https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/)
115-
- For some general development guidelines, see
116-
[DEVELOPMENT](docs/DEVELOPMENT.md).
117-
- For style guidelines (mostly enforced through varius linters and formatters)
118-
see [STYLE](docs/STYLE.md).
127+
3. Set Callback URL to "https://localhost:8080" (or your preferred local URL)
128+
4. Set Callback URL to "https://localhost:8080" (or your preferred local URL)
129+
5. Copy your Client ID and Client Secret
130+
131+
## Additional Documentation
132+
133+
### For API Library Users
134+
135+
- [LOGGING.md](docs/LOGGING.md): Understanding the dual-logger system
136+
- [TYPES.md](docs/TYPES.md): JSON type system and method return types
137+
- [NAMING.md](docs/NAMING.md): API method naming conventions
138+
- [VALIDATIONS.md](docs/VALIDATIONS.md): Input parameter validation
139+
- [ERROR_HANDLING.md](docs/ERROR_HANDLING.md): Exception hierarchy and handling
140+
141+
It's also worth reviewing
142+
[Fitbit's Best Practices](https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/)
143+
for API usage.
144+
145+
### Project Best Practices
146+
147+
- [DEVELOPMENT.md](docs/DEVELOPMENT.md): Development environment and guidelines
148+
- [STYLE.md](docs/STYLE.md): Code style and formatting standards
149+
150+
## Additional Documentation
151+
152+
### For API Library Users
153+
154+
- [LOGGING.md](docs/LOGGING.md): Understanding the dual-logger system
155+
- [TYPES.md](docs/TYPES.md): JSON type system and method return types
156+
- [NAMING.md](docs/NAMING.md): API method naming conventions
157+
- [VALIDATIONS.md](docs/VALIDATIONS.md): Input parameter validation
158+
- [ERROR_HANDLING.md](docs/ERROR_HANDLING.md): Exception hierarchy and handling
159+
160+
It's also worth reviewing
161+
[Fitbit's Best Practices](https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/)
162+
for API usage.
163+
164+
### Project Best Practices
165+
166+
- [DEVELOPMENT.md](docs/DEVELOPMENT.md): Development environment and guidelines
167+
- [STYLE.md](docs/STYLE.md): Code style and formatting standards
119168

120169
## Important Note - Subscription Support
121170

@@ -124,9 +173,20 @@ This client does not currently support the
124173
and
125174
[deletion](https://dev.fitbit.com/build/reference/web-api/subscription/delete-subscription/)
126175
of
127-
[webhook subscrptions](https://dev.fitbit.com/build/reference/web-api/developer-guide/using-subscriptions/).
128-
The methods are implemented in comments and _should_ work, but I have not had a
129-
chance to verify a user confirm this.
176+
[webhook subscriptions](https://dev.fitbit.com/build/reference/web-api/developer-guide/using-subscriptions/).
177+
The methods are implemented in comments and should work, but I have not had a
178+
chance to verify them since this requires a publicly accessible server to
179+
receive webhook notifications.
180+
181+
If you're using this library with subscriptions and would like to help test and
182+
implement this functionality, please open an issue or pull request!
183+
[webhook subscriptions](https://dev.fitbit.com/build/reference/web-api/developer-guide/using-subscriptions/).
184+
The methods are implemented in comments and should work, but I have not had a
185+
chance to verify them since this requires a publicly accessible server to
186+
receive webhook notifications.
187+
188+
If you're using this library with subscriptions and would like to help test and
189+
implement this functionality, please open an issue or pull request!
130190

131191
## License
132192

docs/DEVELOPMENT.md

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
- [Logging System](#logging-system)
1717
- [Application Logger](#application-logger)
1818
- [Data Logger](#data-logger)
19+
- [API Design](#api-design)
20+
- [Resource-Based API](#resource-based-api)
21+
- [Method Aliases](#method-aliases)
1922
- [Testing](#testing)
2023
- [Test Organization](#test-organization)
2124
- [Standard Test Fixtures](#standard-test-fixtures)
@@ -235,6 +238,63 @@ Data log entries contain:
235238
This logging system provides both operational visibility through the application
236239
logger and structured data capture through the data logger.
237240

241+
## API Design
242+
243+
The client implements a dual-level API design pattern that balances both
244+
organization and ease-of-use.
245+
246+
### Resource-Based API
247+
248+
The primary API structure is resource-based, organizing related endpoints into
249+
dedicated resource classes:
250+
251+
- `client.user` - User profile and badges endpoints
252+
- `client.activity` - Activity tracking, goals, and summaries
253+
- `client.sleep` - Sleep logs and goals
254+
- etc.
255+
256+
This organization provides a clean separation of concerns and makes the code
257+
more maintainable by grouping related functionality.
258+
259+
### Method Aliases
260+
261+
To improve developer experience, all resource methods are also available
262+
directly from the client instance through aliases. This means developers can
263+
choose between two equivalent approaches:
264+
265+
```python
266+
# Standard resource-based access
267+
client.user.get_profile()
268+
client.activity.get_daily_activity_summary(date="2025-03-06")
269+
270+
# Direct access via method aliases
271+
client.get_profile()
272+
client.get_daily_activity_summary(date="2025-03-06")
273+
```
274+
275+
#### Rationale for Method Aliases
276+
277+
Method aliases were implemented for several important reasons:
278+
279+
1. **Reduced Verbosity**: Typing `client.resource_name.method_name(...)` with
280+
many parameters can be tedious, especially when used frequently.
281+
282+
2. **Flatter API Surface**: Many modern APIs prefer a flatter design that avoids
283+
deep nesting, making the API more straightforward to use.
284+
285+
3. **Method Name Uniqueness**: All resource methods in the Fitbit API have
286+
unique names (e.g., there's only one `get_profile()` method), making it safe
287+
to expose these methods directly on the client.
288+
289+
4. **Preserve Both Options**: By maintaining both the resource-based access and
290+
direct aliases, developers can choose the approach that best fits their needs
291+
\- organization or conciseness.
292+
293+
All method aliases are set up in the `_setup_method_aliases()` method in the
294+
`FitbitClient` class, which is called during initialization. Each alias is a
295+
direct reference to the corresponding resource method, ensuring consistent
296+
behavior regardless of how the method is accessed.
297+
238298
## Testing
239299

240300
The project uses pytest for testing and follows a consistent testing approach
@@ -339,18 +399,32 @@ TODO
339399
- Use issue templates when reporting bugs
340400
- Include Python version and environment details in bug reports
341401

342-
## Scope and Limitations - Intraday Data Support
402+
## Intraday Data Support
343403

344-
This client explicitly does not implement intraday data endpoints (detailed
345-
heart rate, steps, etc). These endpoints:
404+
This client implements intraday data endpoints (detailed heart rate, steps, etc)
405+
through the `IntradayResource` class. These endpoints:
346406

347407
- Require special access from Fitbit (typically limited to research
348408
applications)
349409
- Have different rate limits than standard endpoints
350-
- Need additional OAuth2 scopes
351-
- Often require institutional review board (IRB) approval
352-
353-
If you need intraday data access:
354-
355-
1. Apply through Fitbit's developer portal
356-
2. Pull requests welcome!
410+
- Need additional OAuth2 scopes (specifically the 'activity' and 'heartrate'
411+
scopes)
412+
- Often require institutional review board (IRB) approval for research
413+
applications
414+
415+
To use intraday data:
416+
417+
1. Apply for intraday access through the
418+
[Fitbit developer portal](https://dev.fitbit.com/)
419+
2. Ensure your application requests the appropriate scopes
420+
3. Use the intraday methods with appropriate detail level parameters:
421+
```python
422+
client.intraday.get_heartrate_intraday_by_date(
423+
date="today",
424+
detail_level="1min" # or "1sec" depending on your access level
425+
)
426+
```
427+
428+
See the
429+
[Intraday API documentation](https://dev.fitbit.com/build/reference/web-api/intraday/)
430+
for more details on available endpoints and access requirements.

0 commit comments

Comments
 (0)