From 431fe4e265c656033c869741be63336c27384274 Mon Sep 17 00:00:00 2001 From: Gustavo Stor Date: Sat, 21 Jun 2025 09:05:49 -0300 Subject: [PATCH 1/2] Fix daily activity model: correct MET field structure The MET field in daily activity data is a complex object containing time-series data, not a simple string. Added MetData model to properly handle the structure with interval, items array, and timestamp. This fix resolves validation errors when retrieving real daily activity data from the Oura API. --- .gitignore | 7 ++++++- oura_api_client/models/daily_activity.py | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e3d6aae..2dc4911 100644 --- a/.gitignore +++ b/.gitignore @@ -139,4 +139,9 @@ heart_rate_data.json .claude_private PROJECT_STATE.md ARCHITECTURE.md -SESSION_NOTES.md \ No newline at end of file +SESSION_NOTES.md + +# API testing files (contain sensitive tokens) +test_api_live.py +*_live_test.py +*.token diff --git a/oura_api_client/models/daily_activity.py b/oura_api_client/models/daily_activity.py index 5d2b521..4bd731c 100644 --- a/oura_api_client/models/daily_activity.py +++ b/oura_api_client/models/daily_activity.py @@ -3,6 +3,13 @@ from datetime import date, datetime +class MetData(BaseModel): + """MET (Metabolic Equivalent of Task) time series data.""" + interval: float = Field(..., description="Interval between measurements in minutes") + items: List[float] = Field(..., description="MET values for each interval") + timestamp: str = Field(..., description="Timestamp for the data") + + class ActivityContributors(BaseModel): meet_daily_targets: Optional[int] = Field(None, alias="meet_daily_targets") move_every_hour: Optional[int] = Field(None, alias="move_every_hour") @@ -41,7 +48,7 @@ class DailyActivityModel(BaseModel): medium_activity_time: Optional[int] = Field( None, alias="medium_activity_time" ) - met: Optional[str] = Field(None, alias="met") + met: Optional[MetData] = Field(None, alias="met") meters_to_target: Optional[int] = Field(None, alias="meters_to_target") non_wear_time: Optional[int] = Field(None, alias="non_wear_time") resting_time: Optional[int] = Field(None, alias="resting_time") From b05cabc6f870c7f4601bf3eb4f5df20e591d8535 Mon Sep 17 00:00:00 2001 From: Gustavo Stor Date: Sat, 21 Jun 2025 21:13:55 -0300 Subject: [PATCH 2/2] Fix test: update MET field to use proper MetData structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test was using a string for the 'met' field but the model now expects a structured MetData object with interval, items, and timestamp fields. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- tests/test_client.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_client.py b/tests/test_client.py index 0b3be57..c3df0ca 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -259,7 +259,11 @@ def test_get_daily_activity_document(self, mock_get): "low_activity_time": 1200, "medium_activity_met_minutes": 90, "medium_activity_time": 1800, - "met": "test_met", + "met": { + "interval": 5, + "items": [1.5, 2.0, 1.8, 2.2], + "timestamp": "2024-03-10T12:00:00+00:00" + }, "meters_to_target": 1000, "non_wear_time": 300, "resting_time": 3600,