11# Conventions, Patterns, and Development Guide
22
3- ## Contents
4-
5- - [ Development Environment Setup] ( #development-environment-setup )
6- - [ Prerequisites] ( #prerequisites )
7- - [ Initial Setup] ( #initial-setup )
8- - [ Project Structure] ( #project-structure )
9- - [ Goals, Notes, and TODOs] ( #goals-notes-and-todos )
10- - [ Development Tools and Standards] ( #development-tools-and-standards )
11- - [ Code Formatting and Style] ( #code-formatting-and-style )
12- - [ Import Style] ( #import-style )
13- - [ Resource Implementation Guidelines] ( #resource-implementation-guidelines )
14- - [ Error Handling] ( #error-handling )
15- - [ Enum Usage] ( #enum-usage )
16- - [ Logging System] ( #logging-system )
17- - [ Application Logger] ( #application-logger )
18- - [ Data Logger] ( #data-logger )
19- - [ API Design] ( #api-design )
20- - [ Resource-Based API] ( #resource-based-api )
21- - [ Method Aliases] ( #method-aliases )
22- - [ Testing] ( #testing )
23- - [ Test Organization] ( #test-organization )
24- - [ Standard Test Fixtures] ( #standard-test-fixtures )
25- - [ Error Handling Tests] ( #error-handling-tests )
26- - [ Response Mocking] ( #response-mocking )
27- - [ OAuth Callback Implementation] ( #oauth-callback-implementation )
28- - [ Implementation Flow] ( #implementation-flow )
29- - [ Git Workflow] ( #git-workflow )
30- - [ Release Process] ( #release-process )
31- - [ Getting Help] ( #getting-help )
32- - [ Scope and Limitations - Intraday Data Support] ( #scope-and-limitations---intraday-data-support )
33-
343## Development Environment Setup
354
365### Prerequisites
376
38- - Python 3.12 +
7+ - Python 3.13 +
398- PDM
409- Git
4110
@@ -53,9 +22,9 @@ cd fitbit-client-python
5322``` bash
5423asdf plugin add python
5524asdf plugin add pdm
56- asdf install python 3.12 .0
25+ asdf install python 3.13 .0
5726asdf install pdm latest
58- asdf local python 3.12 .0
27+ asdf local python 3.13 .0
5928asdf local pdm latest
6029```
6130
@@ -79,7 +48,8 @@ fitbit-client/
7948│ ├── client.py
8049│ ├── resources/
8150│ │ ├── __init__.py
82- │ │ ├── [resource files]
51+ │ │ ├── [resource modules]
52+ │ │ ├── base.py
8353│ │ └── constants.py
8454│ ├── utils/
8555│ │ ├── __init__.py
@@ -186,84 +156,29 @@ The codebase implements a comprehensive error handling system through
186156
187157## Logging System
188158
189- The project implements dual logging through the BaseResource class: application
190- logging for API interactions and data logging for tracking important response
191- fields.
192-
193- ### Application Logger
194-
195- Each resource class inherits logging functionality from BaseResource, which
196- initializes a logger with the resource's class name:
197-
198- ``` python
199- self .logger = getLogger(f " fitbit_client. { self .__class__ .__name__ } " )
200- ```
201-
202- The application logger handles:
203-
204- - Success responses at INFO level
205- - Error responses at ERROR level
206- - Debug information about requests and responses
207- - Internal server logging
208-
209- The BaseResource.\_ log_response method standardizes log message formats:
210-
211- - For errors: "[ error_type] field_name: message" (if field name available)
212- - For success: "method succeeded for endpoint (status code)"
213-
214- ### Data Logger
215-
216- The data logger specifically tracks important fields from API responses.
217- BaseResource defines these fields in IMPORTANT_RESPONSE_FIELDS:
218-
219- ``` python
220- IMPORTANT_RESPONSE_FIELDS : Set[str ] = {
221- " access" , # PUBLIC/PRIVATE/SHARED
222- " date" , # Dates
223- " dateTime" , # Timestamps
224- " deviceId" , # Device IDs
225- " foodId" , # Food resource IDs
226- " logId" , # Log entry IDs
227- " name" , # Resource names
228- " subscriptionId" # Subscription IDs
229- }
230- ```
231-
232- The BaseResource.\_ log_data method extracts and logs these fields when present
233- in API responses.
234-
235- Data log entries contain:
236-
237- - Timestamp (ISO format)
238- - Method name
239- - Important fields found in the response
240-
241- This logging system provides both operational visibility through the application
242- logger and structured data capture through the data logger.
159+ The project implements two different logs in through the
160+ [ ` BaseResource ` ] ( fitbit_client/resources/base.py ) class: application logging for
161+ API interactions and data logging for tracking important response fields. See
162+ [ LOGGING] ( docs/LOGGING.md ) for details.
243163
244164## API Design
245165
246- The client implements a dual-level API design pattern that balances both
247- organization and ease-of-use.
248-
249166### Resource-Based API
250167
251168The primary API structure is resource-based, organizing related endpoints into
252- dedicated resource classes:
169+ dedicated resource classes based on the structure and organzation of the
170+ [ Fibit Web API] ( https://dev.fitbit.com/build/reference/web-api/ ) itself, e.g.
253171
254172- ` client.user ` - User profile and badges endpoints
255173- ` client.activity ` - Activity tracking, goals, and summaries
256174- ` client.sleep ` - Sleep logs and goals
257175- etc.
258176
259- This organization provides a clean separation of concerns and makes the code
260- more maintainable by grouping related functionality.
261-
262177### Method Aliases
263178
264- To improve developer experience, all resource methods are also available
265- directly from the client instance through aliases. This means developers can
266- choose between two equivalent approaches:
179+ All resource methods are also available directly from the client instance
180+ through aliases. This means developers can choose between two equivalent
181+ approaches:
267182
268183``` python
269184# Standard resource-based access
@@ -275,8 +190,6 @@ client.get_profile()
275190client.get_daily_activity_summary(date = " 2025-03-06" )
276191```
277192
278- #### Rationale for Method Aliases
279-
280193Method aliases were implemented for several important reasons:
281194
2821951 . ** Reduced Verbosity** : Typing ` client.resource_name.method_name(...) ` with
@@ -294,9 +207,9 @@ Method aliases were implemented for several important reasons:
294207 \- organization or conciseness.
295208
296209All method aliases are set up in the ` _setup_method_aliases() ` method in the
297- ` FitbitClient ` class, which is called during initialization. Each alias is a
298- direct reference to the corresponding resource method, ensuring consistent
299- behavior regardless of how the method is accessed.
210+ [ ` FitbitClient ` ] ( fitbit_client/client.py ) class, which is called during
211+ initialization. Each alias is a direct reference to the corresponding resource
212+ method, ensuring consistent behavior regardless of how the method is accessed.
300213
301214## Testing
302215
@@ -305,8 +218,9 @@ across all components.
305218
306219### Test Organization
307220
308- The test directory mirrors the main package structure, with corresponding test
309- modules for each component:
221+ The test directory mirrors the main package structure (except that the root is
222+ named "test" rather than "fitbit_client"), with corresponding test modules for
223+ each component:
310224
311225- auth/: Tests for authentication and OAuth functionality
312226- client/: Tests for the main client implementation
@@ -384,46 +298,19 @@ The OAuth callback mechanism is implemented using two main classes:
384298## Git Workflow
385299
3863001 . Create a new branch for your feature/fix
387- 2 . Make your changes, following the style guidelines
388- 3 . Run formatting checks (` pdm format ` )
301+ 2 . Make your changes, following the style guidelines (see also:
302+ [ LINTING] ( docs/LINTING.md ) )
303+ 3 . Run formatting checks (` pdm format ` ) and tests (` pdm run pytest ` )
3893044 . Submit a pull request with a clear description of changes
390305
391306## Release Process
392307
393308This section will be documented as we near our first release.
394309
395- ## Getting Help
396-
397- - Check existing issues before creating new ones
398- - Use issue templates when reporting bugs
399- - Include Python version and environment details in bug reports
400-
401310## Intraday Data Support
402311
403312This client implements intraday data endpoints (detailed heart rate, steps, etc)
404- through the ` IntradayResource ` class. These endpoints:
405-
406- - Require special access from Fitbit (typically limited to research
407- applications)
408- - Have different rate limits than standard endpoints
409- - Need additional OAuth2 scopes (specifically the 'activity' and 'heartrate'
410- scopes)
411- - Often require institutional review board (IRB) approval for research
412- applications
413-
414- To use intraday data:
415-
416- 1 . Apply for intraday access through the
417- [ Fitbit developer portal] ( https://dev.fitbit.com/ )
418- 2 . Ensure your application requests the appropriate scopes
419- 3 . Use the intraday methods with appropriate detail level parameters:
420- ``` python
421- client.intraday.get_heartrate_intraday_by_date(
422- date = " today" ,
423- detail_level = " 1min" # or "1sec" depending on your access level
424- )
425- ```
426-
427- See the
313+ through the ` IntradayResource ` class. These endpoints have some special
314+ requirements if you're using them for anyone other that yourself. See the
428315[ Intraday API documentation] ( https://dev.fitbit.com/build/reference/web-api/intraday/ )
429- for more details on available endpoints and access requirements .
316+ for more details.
0 commit comments