Skip to content

Commit 8947721

Browse files
committed
Corruption cleanup; merges a few commits:
- 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 5ecc6e1 commit 8947721

File tree

11 files changed

+924
-461
lines changed

11 files changed

+924
-461
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,5 @@ _scripts
5858
_cov_html
5959
secrets.json
6060
tokens.json
61+
TODO.mdø
62+

README.md

Lines changed: 56 additions & 35 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,77 @@ 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
9198
)
9299

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`)
100+
# Will open browser and handle callback automatically
96101
client.authenticate()
97102
```
98103

104+
The `token_cache_path` parameter allows you to persist authentication tokens
105+
between sessions. If provided, the client will:
106+
107+
1. Load existing tokens from this file if available (avoiding re-authentication)
108+
2. Save new or refreshed tokens to this file automatically
109+
3. Handle token refresh when expired tokens are detected
110+
99111
## Setting Up Your Fitbit App
100112

101113
1. Go to dev.fitbit.com and create a new application
102114
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
115+
3. Set Callback URL to "https://localhost:8080" (or your preferred local URL)
106116
4. Copy your Client ID and Client Secret
107117

108-
Additional documentation:
118+
## Additional Documentation
109119

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).
120+
### For API Library Users
121+
122+
- [LOGGING.md](docs/LOGGING.md): Understanding the dual-logger system
123+
- [TYPES.md](docs/TYPES.md): JSON type system and method return types
124+
- [NAMING.md](docs/NAMING.md): API method naming conventions
125+
- [VALIDATIONS.md](docs/VALIDATIONS.md): Input parameter validation
126+
- [ERROR_HANDLING.md](docs/ERROR_HANDLING.md): Exception hierarchy and handling
127+
128+
It's also worth reviewing
129+
[Fitbit's Best Practices](https://dev.fitbit.com/build/reference/web-api/developer-guide/best-practices/)
130+
for API usage.
131+
132+
### Project Best Practices
133+
134+
- [DEVELOPMENT.md](docs/DEVELOPMENT.md): Development environment and guidelines
135+
- [STYLE.md](docs/STYLE.md): Code style and formatting standards
119136

120137
## Important Note - Subscription Support
121138

@@ -124,9 +141,13 @@ This client does not currently support the
124141
and
125142
[deletion](https://dev.fitbit.com/build/reference/web-api/subscription/delete-subscription/)
126143
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.
144+
[webhook subscriptions](https://dev.fitbit.com/build/reference/web-api/developer-guide/using-subscriptions/).
145+
The methods are implemented in comments and should work, but I have not had a
146+
chance to verify them since this requires a publicly accessible server to
147+
receive webhook notifications.
148+
149+
If you're using this library with subscriptions and would like to help test and
150+
implement this functionality, please open an issue or pull request!
130151

131152
## License
132153

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)