Coverage for health / models / activity.py: 100%
33 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 17:44 +0800
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 17:44 +0800
1"""
2Pydantic models for exercise activities and workouts.
3"""
5from datetime import datetime, date as date_type
6from typing import Optional, List, Dict, Any
7from pydantic import BaseModel, Field
10class Activity(BaseModel):
11 """Exercise activity summary."""
13 activity_id: str = Field(..., description="Unique activity ID")
14 activity_type: str = Field(..., description="Type of activity (running, cycling, etc.)")
15 activity_name: Optional[str] = Field(default=None, description="Activity name")
16 date: date_type = Field(..., description="Date of the activity")
17 start_time: Optional[datetime] = Field(default=None, description="Activity start time")
18 duration_seconds: Optional[float] = Field(
19 default=None, description="Activity duration in seconds"
20 )
21 distance_meters: Optional[float] = Field(
22 default=None, description="Distance covered in meters"
23 )
24 elevation_gain_meters: Optional[float] = Field(
25 default=None, description="Elevation gain in meters"
26 )
27 elevation_loss_meters: Optional[float] = Field(
28 default=None, description="Elevation loss in meters"
29 )
30 calories: Optional[int] = Field(default=None, description="Calories burned")
31 average_heart_rate: Optional[int] = Field(
32 default=None, description="Average heart rate in bpm"
33 )
34 max_heart_rate: Optional[int] = Field(
35 default=None, description="Maximum heart rate in bpm"
36 )
37 average_speed_mps: Optional[float] = Field(
38 default=None, description="Average speed in meters per second"
39 )
40 max_speed_mps: Optional[float] = Field(
41 default=None, description="Maximum speed in meters per second"
42 )
43 average_pace_min_per_km: Optional[float] = Field(
44 default=None, description="Average pace in minutes per kilometer"
45 )
46 average_cadence: Optional[float] = Field(
47 default=None, description="Average cadence (steps/min or rpm)"
48 )
49 training_effect: Optional[float] = Field(
50 default=None, description="Aerobic training effect"
51 )
52 anaerobic_training_effect: Optional[float] = Field(
53 default=None, description="Anaerobic training effect"
54 )
55 location_name: Optional[str] = Field(
56 default=None, description="Location of the activity"
57 )
58 description: Optional[str] = Field(
59 default=None, description="Activity description"
60 )
61 raw_data: Optional[Dict[str, Any]] = Field(
62 default=None, description="Raw API response"
63 )
66class ActivityDetail(BaseModel):
67 """Detailed activity data including splits and laps."""
69 activity_id: str = Field(..., description="Activity ID")
70 summary: Activity = Field(..., description="Activity summary")
71 laps: Optional[List[Dict[str, Any]]] = Field(
72 default=None, description="Lap data"
73 )
74 splits: Optional[List[Dict[str, Any]]] = Field(
75 default=None, description="Split data"
76 )
77 samples: Optional[List[Dict[str, Any]]] = Field(
78 default=None, description="Time-series samples (HR, speed, etc.)"
79 )
80 gear: Optional[str] = Field(default=None, description="Gear used")
81 raw_data: Optional[Dict[str, Any]] = Field(
82 default=None, description="Raw API response"
83 )