Skip to content

Add DailySleepData with sleep need from coach#171

Merged
matin merged 2 commits intomainfrom
add-daily-sleep-data
Jan 9, 2026
Merged

Add DailySleepData with sleep need from coach#171
matin merged 2 commits intomainfrom
add-daily-sleep-data

Conversation

@matin
Copy link
Copy Markdown
Owner

@matin matin commented Jan 9, 2026

Summary

  • Adds DailySleepData class for detailed sleep data with sleep need recommendations
  • Uses /sleep-service/sleep/dailySleepData?date={date} endpoint
  • Includes sleep need from Garmin coach with training, HRV, and sleep history adjustments
  • Includes additional metrics: body battery change, resting heart rate, skin temperature

Closes #170

Test plan

  • Added tests for get() and list() methods
  • Tests verify sleep need data is present
  • All 119 tests pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Daily sleep data retrieval and listing functionality is now publicly available
    • Added convenience properties for accessing sleep need metrics including baseline and actual values
  • Documentation

    • Added comprehensive API documentation for daily sleep data, including detailed usage examples and complete response object structures
  • Tests

    • Added test coverage for daily sleep data retrieval and listing operations with integration tests

✏️ Tip: You can customize this high-level summary in your review settings.

Adds a new endpoint for detailed sleep data including:
- Sleep need recommendations from Garmin coach
- Next day's sleep need
- Body battery change
- Resting heart rate
- Skin temperature deviations

Closes #170

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 9, 2026

Walkthrough

This PR introduces a new data layer module for daily sleep data including sleep need information. It adds the DailySleepData class alongside supporting dataclasses (SleepScore, SleepScores, SleepNeed, SleepDTO, SpO2SleepSummary), exposes them through public API exports, includes tests, and documents the new functionality.

Changes

Cohort / File(s) Summary
Documentation
docs/api/data.md
Added API documentation section describing DailySleepData structure, including usage examples, object schema with nested SleepNeed and related fields, convenience properties, and list endpoint example.
Core Implementation
src/garth/data/daily_sleep_data.py
New module defining dataclasses for sleep metrics (SleepScore, SleepScores, SleepNeed, SleepDTO, SpO2SleepSummary) and container DailySleepData with get() and list() class methods for API interaction, convenience properties for sleep_need_minutes and next_sleep_need_minutes, and key conversion from camelCase to snake_case.
Public API Integration
src/garth/data/__init__.py, src/garth/__init__.py
Exposed DailySleepData and related dataclasses through package __all__ exports, making them available at both data subpackage and top-level package levels.
Tests
tests/data/test_daily_sleep_data.py
Added two tests using VCR: test_daily_sleep_data_get verifies data retrieval for a specific date with assertions on nested fields and returns None for future dates; test_daily_sleep_data_list validates list retrieval and sorting by calendar_date.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding DailySleepData class with sleep need functionality from coach, which is the primary purpose of this PR.
Linked Issues check ✅ Passed The PR implements the requirements from issue #170: provides detailed sleep view via DailySleepData, includes sleep need from coach, and implements both get() and list() methods with tests.
Out of Scope Changes check ✅ Passed All changes are in-scope: new DailySleepData module, integration into public API, documentation, and comprehensive tests directly address the linked issue #170 objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-daily-sleep-data

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e62fc57 and efecb55.

⛔ Files ignored due to path filters (2)
  • tests/data/cassettes/test_daily_sleep_data_get.yaml is excluded by !tests/**/cassettes/**
  • tests/data/cassettes/test_daily_sleep_data_list.yaml is excluded by !tests/**/cassettes/**
📒 Files selected for processing (5)
  • docs/api/data.md
  • src/garth/__init__.py
  • src/garth/data/__init__.py
  • src/garth/data/daily_sleep_data.py
  • tests/data/test_daily_sleep_data.py
🧰 Additional context used
📓 Path-based instructions (4)
**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Keep code examples in documentation concise and focused on usage, omitting import statements like import garth

Files:

  • docs/api/data.md
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: Auto-format Python source files using ruff via make format
Lint Python source files using ruff format check, ruff check, and mypy via make lint
Methods that make API calls should return Pydantic dataclasses of the response for consistency

Files:

  • src/garth/data/__init__.py
  • src/garth/__init__.py
  • tests/data/test_daily_sleep_data.py
  • src/garth/data/daily_sleep_data.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Run all tests with coverage via make test and make testcov
Use pytest with VCR cassettes for HTTP recording/playback in tests

Files:

  • tests/data/test_daily_sleep_data.py
tests/**

⚙️ CodeRabbit configuration file

tests/**: - test functions shouldn't have a return type hint

  • it's ok to use assert instead of pytest.assume()

Files:

  • tests/data/test_daily_sleep_data.py
🧬 Code graph analysis (3)
src/garth/data/__init__.py (1)
src/garth/data/daily_sleep_data.py (1)
  • DailySleepData (113-160)
tests/data/test_daily_sleep_data.py (3)
src/garth/data/daily_sleep_data.py (4)
  • DailySleepData (113-160)
  • get (127-143)
  • sleep_need_minutes (151-154)
  • next_sleep_need_minutes (157-160)
tests/conftest.py (3)
  • vcr (79-82)
  • authed_client (65-75)
  • client (21-22)
src/garth/data/body_battery/daily_stress.py (1)
  • body_battery_change (65-70)
src/garth/data/daily_sleep_data.py (3)
src/garth/utils.py (2)
  • camel_to_snake_dict (17-33)
  • format_end_date (66-71)
src/garth/data/_base.py (1)
  • Data (15-50)
src/garth/http.py (2)
  • Client (19-245)
  • connectapi (186-192)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test 3.12
🔇 Additional comments (10)
src/garth/data/__init__.py (1)

8-8: LGTM! Clean public API export.

The addition of DailySleepData to the public API exports is correctly implemented with proper alphabetical ordering in both the __all__ list and the import statement.

Also applies to: 27-27

src/garth/__init__.py (1)

6-6: LGTM! Proper top-level API exposure.

The DailySleepData class is correctly exported from the top-level garth package, maintaining alphabetical order and consistency with other data classes.

Also applies to: 44-44

docs/api/data.md (1)

363-421: LGTM! Comprehensive and well-structured documentation.

The new documentation section for DailySleepData is clear and follows the established pattern used for other data classes. The examples correctly omit import statements (using garth. prefix instead) and demonstrate both the get() and list() methods along with the convenience properties.

tests/data/test_daily_sleep_data.py (2)

9-36: LGTM! Comprehensive test coverage for get().

The test properly validates:

  • Successful data retrieval with all key fields (sleep need, scores, body battery, heart rate)
  • Convenience properties (sleep_need_minutes, next_sleep_need_minutes)
  • None return for future dates with no data

Follows coding guidelines with VCR cassette usage and appropriate assertion style.


39-52: LGTM! Proper validation of list() behavior.

The test correctly verifies:

  • Expected list length
  • Chronological sorting by calendar_date

Uses the recommended max_workers=1 for deterministic test execution.

src/garth/data/daily_sleep_data.py (5)

15-109: LGTM! Well-structured dataclass hierarchy.

The Pydantic dataclasses provide comprehensive typing for the sleep data API response:

  • SleepScore and SleepScores capture sleep quality metrics
  • SleepNeed represents coach-derived sleep recommendations (key feature of this PR)
  • SleepDTO is a comprehensive sleep data transfer object
  • SpO2SleepSummary handles oxygen saturation data

The optional fields are appropriately typed, and the structure aligns with the API response format.


112-124: LGTM! Comprehensive data model for daily sleep.

The DailySleepData class effectively captures all relevant sleep metrics including the new coach-derived sleep need data. The use of builtins.list[Any] on lines 117-118 is a good practice to avoid shadowing the list() method defined below.


126-143: LGTM! Clean API implementation.

The get() method follows the established pattern for Data classes:

  • Proper endpoint construction with date formatting
  • Response conversion from camelCase to snake_case
  • Returns None for invalid/missing data (line 140)
  • Returns Pydantic dataclass instance as required by coding guidelines

The assertion on line 137 ensures type safety after API call.


145-148: LGTM! Sorted list implementation.

The list() method appropriately delegates to the base class and ensures chronological ordering by calendar_date, which provides a consistent and intuitive user experience when retrieving multiple days of sleep data.


150-160: LGTM! Helpful convenience properties.

The sleep_need_minutes and next_sleep_need_minutes properties provide clean, direct access to the coach-derived sleep recommendations, safely handling the case where sleep need data may be absent.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (e62fc57) to head (efecb55).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main      #171    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files           62        64     +2     
  Lines         2807      2970   +163     
==========================================
+ Hits          2807      2970   +163     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@matin matin mentioned this pull request Jan 9, 2026
19 tasks
- Remove redundant `if not data` check (API always returns dict)
- Simplify daily_sleep_dto check (dict always has daily_sleep_dto key)
- Convert properties to single-line ternary expressions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@matin matin merged commit 4a95ce1 into main Jan 9, 2026
26 checks passed
@matin matin deleted the add-daily-sleep-data branch January 9, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detailed sleep view with sleep need from coach

1 participant