### Setup and Run Demo Software Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Clone the repository and set up a virtual environment to run the example and demo scripts. This is the recommended way to get started. ```bash python3 -m venv .venv --copies source .venv/bin/activate # On Windows: .venv\Scripts\activate pip install -e ".[example]" python3 ./example.py # simple getting-started example python3 ./demo.py # comprehensive demo (130+ API methods) ``` -------------------------------- ### Get Activities with Pagination Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Demonstrates how to fetch activities using start and limit parameters for pagination. Some endpoints may auto-paginate. ```python activities = client.get_activities(start=0, limit=20) ``` ```python activities = client.get_activities(start=20, limit=20) ``` -------------------------------- ### Development Environment Setup with PDM Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Set up a virtual environment and install project dependencies using PDM. This is crucial for managing development tasks and avoiding system package conflicts. ```bash python3 -m venv .venv --copies source .venv/bin/activate # On Windows: .venv\Scripts\activate pip install pdm python -m pdm install --group :all pre-commit install --install-hooks # optional but recommended ``` -------------------------------- ### Get Daily Steps Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Retrieve the total daily steps for a specified date range. This example fetches steps for a single day. ```python garmin.get_daily_steps(yesterday, yesterday) ``` -------------------------------- ### Minimal Setup (Development) Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Use this basic setup for development environments. It requires direct input of email and password for authentication. ```python from garminconnect import Garmin client = Garmin( email="user@example.com", password="password123", ) client.login() ``` -------------------------------- ### GarminConnect Usage Example Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/errors.md Demonstrates the usage of the safe login, get stats, and upload activity functions within a main execution block. ```python # Usage if __name__ == "__main__": client = safe_login("user@example.com", "password") if client: stats = safe_get_stats(client, "2026-04-21") safe_upload_activity(client, "activity.fit") ``` -------------------------------- ### Get Full User Profile Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Fetches all user settings and profile information. The example shows how to access the display name from the returned dictionary. ```python profile = client.get_user_profile() print(profile["userData"]["displayName"]) ``` -------------------------------- ### Get Activities with Sample Response Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/graphql_queries.txt Example query to retrieve a list of activities for a given display name and time range, along with a sample response structure. ```graphql query{activitiesScalar(displayName:"ca8406dd-d7dd-4adb-825e-16967b1e82fb", startTimestampLocal:"2024-07-02T00:00:00.00", endTimestampLocal:"2024-07-08T23:59:59.999", limit:40)} ``` -------------------------------- ### Install python-garminconnect Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Install the library and its dependencies from PyPI. Ensure you upgrade to the latest version. ```bash pip install --upgrade garminconnect curl_cffi ``` -------------------------------- ### Get Workouts with Pagination Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves a list of workout templates with support for pagination. Specify the starting offset and the number of workouts to return. ```python def get_workouts(self, start: int = 0, limit: int = 100) -> list[dict[str, Any]] ``` -------------------------------- ### Install Garmin Connect with Workout Support Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Install the garminconnect library with the optional workout extra, enabling typed workout models. ```bash pip install garminconnect[workout] ``` -------------------------------- ### Install Twine for Publishing Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Install the twine package, which is used for uploading Python packages to PyPI. ```bash pip install twine ``` -------------------------------- ### Python Usage Example Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Example demonstrating how to fetch and access sleep data using the Garmin Connect Python library. ```APIDOC ## Python Usage Example ### Description Example demonstrating how to fetch and access sleep data using the Garmin Connect Python library. ### Code ```python sleep_data = g.typed.get_sleep_data("2026-04-21") print(f"Sleep time: {sleep_data.summary.sleep_time_seconds}s") print(f"Deep sleep: {sleep_data.summary.deep_sleep_seconds}s") print(f"Overall score: {sleep_data.scores.overall.value}") ``` ``` -------------------------------- ### Example ExecutableStep Instance Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Demonstrates how to instantiate an ExecutableStep with specific parameters for order, type, and duration. ```python from garminconnect.workout import ExecutableStep step = ExecutableStep( stepOrder=1, stepType={"stepTypeId": 1, "stepTypeKey": "warmup"}, endCondition={"conditionTypeId": 2, "conditionTypeKey": "time"}, endConditionValue=300.0, # 5 minutes ) ``` -------------------------------- ### Get User Activity Summary Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Fetches a comprehensive summary of user activity for a specific date, including steps, calories, and heart rate. The example demonstrates accessing total steps and calories. ```python summary = client.get_user_summary("2026-04-21") print(f"Steps: {summary.get('totalSteps')}") print(f"Calories: {summary.get('totalKilocalories')}") ``` -------------------------------- ### Get Ad-hoc Challenges with Pagination Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieve ad-hoc challenges with support for pagination. Specify the starting offset and the number of challenges to return. ```python def get_adhoc_challenges(self, start: int, limit: int) -> dict[str, Any]: ``` -------------------------------- ### Install Typed Workouts (Pydantic) Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Install the 'workout' extra to utilize Pydantic models for creating and uploading structured workout data. This requires Pydantic version 2.0.0 or higher. ```bash pip install garminconnect[workout] ``` ```bash pip install garminconnect[pydantic>=2.0.0] ``` -------------------------------- ### Get Activities with Pagination Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Fetches a list of activities with support for pagination and filtering by type. Use 'start' for offset and 'limit' for the number of results. The 'activitytype' parameter can filter by specific activity types. ```python activities = client.get_activities(start=0, limit=20) for activity in activities: print(f"{activity['activityName']}: {activity['distance']}m") ``` -------------------------------- ### Get Body Battery Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Retrieve the Body Battery level data for a specific day. This example shows the keys of the first entry. ```python garmin.get_body_battery(yesterday)[0].keys() ``` -------------------------------- ### PyPI Configuration INI Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Example of a .pypirc file content for PyPI configuration. ```ini [pypi] username = __token__ password = ``` -------------------------------- ### Install Typed Responses (Pydantic) Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Install the 'typed' extra to enable Pydantic validation for API responses. This allows for structured data access using generated models. ```bash pip install garminconnect[typed] ``` ```bash pip install garminconnect[pydantic>=2.0.0] ``` -------------------------------- ### Import Garmin Connect Library Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Import the necessary library to start using Garmin Connect functionalities. ```python import garminconnect ``` -------------------------------- ### Advanced Example: Batch API Calls Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/client-methods.md Fetch data for multiple dates efficiently by iterating through a list of dates and making individual API calls within a try-except block to handle potential connection errors. This example demonstrates logging fetched data and storing results in a dictionary. ```python from garminconnect import Garmin, GarminConnectConnectionError import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) g = Garmin(email, password) g.login() # Fetch multiple dates efficiently dates = ["2026-04-21", "2026-04-22", "2026-04-23"] results = {} for date in dates: try: result = g.connectapi( f"/usersummary-service/usersummary/daily/{g.display_name}", params={"calendarDate": date} ) results[date] = result logger.info(f"Fetched {date}: {result.get('totalSteps')} steps") except GarminConnectConnectionError as e: logger.error(f"Failed to fetch {date}: {e}") results[date] = None print(results) ``` -------------------------------- ### create_manual_activity Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Creates a manual activity entry with basic parameters such as start time, duration, distance, and name. ```APIDOC ## create_manual_activity() ### Description Creates a manual activity entry with basic parameters such as start time, duration, distance, and name. ### Method POST ### Endpoint /activities/manual ### Parameters #### Request Body - **start_datetime** (str) - Required - Start time in ISO format (e.g., "2023-12-02T10:00:00.000") - **time_zone** (str) - Required - Timezone (e.g., "Europe/Paris") - **type_key** (str) - Required - Activity type key (without "activity_type_" prefix) - **distance_km** (float) - Required - Distance in kilometers - **duration_min** (int) - Required - Duration in minutes - **activity_name** (str) - Required - Activity title ### Response #### Success Response (200) - **response** (Any) - Server response ``` -------------------------------- ### Get Gear Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of the user's gear. ```APIDOC ## Get Gear ### Description Retrieves a list of the user's gear. ### Method GET ### Endpoint /gear-service/gear/filterGear ### Query Parameters - **userProfilePk** (int) - Optional - The primary key of the user profile. ``` -------------------------------- ### List Workouts Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Lists available workouts with optional start and limit parameters for pagination. ```APIDOC ## GET /workout-service/workouts ### Description Lists available workouts with optional start and limit parameters for pagination. ### Method GET ### Endpoint /workout-service/workouts ### Parameters #### Query Parameters - **start** (int) - Optional - The starting index for the list of workouts. - **limit** (int) - Optional - The maximum number of workouts to return. ``` -------------------------------- ### Get Devices Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of registered devices for the user. ```APIDOC ## GET /device-service/deviceregistration/devices ### Description Retrieves a list of registered devices for the user. ### Method GET ### Endpoint /device-service/deviceregistration/devices ### Response #### Success Response (200) - **deviceId** (string) - Description of the device ID. - **displayName** (string) - The display name of the device. - **deviceType** (string) - The type of the device. #### Response Example [ { "deviceId": "1234567890", "displayName": "Fenix 6", "deviceType": "Smartwatch" } ] ``` -------------------------------- ### upload_running_workout() Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Uploads a typed running workout using a Pydantic model. Requires the 'workout' extra to be installed. ```APIDOC ## upload_running_workout() ### Description Upload a typed running workout (Pydantic model). ### Parameters #### Request Body - `workout` (RunningWorkout): A RunningWorkout instance from `garminconnect.workout`. ### Returns dict[str, Any]: Dictionary with uploaded workout data. ### Requires `pip install garminconnect[workout]` ``` -------------------------------- ### Get Blood Pressure Records Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieve blood pressure records for a specified date range. If only a start date is provided, the end date defaults to the start date. ```python def get_blood_pressure( self, startdate: str, enddate: str | None = None ) -> dict[str, Any] ``` -------------------------------- ### Get VO2 Max Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/graphql_queries.txt Retrieve VO2 Max data within a specified start and end date. ```graphql query{{vo2MaxScalar(startDate:"{startDate}", endDate:"{endDate}")}} ``` -------------------------------- ### List Workouts Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of workouts. Supports pagination using 'start' and 'limit' query parameters. ```python # Handled by: Garmin.get_workouts() ``` -------------------------------- ### Run All Tests Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Execute all tests for the project. Ensure example.py is run first to create saved tokens. ```bash pdm run test ``` -------------------------------- ### Get User Settings Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Fetches the user's specific settings. ```APIDOC ## GET /userprofile-service/userprofile/settings ### Description Retrieves the user's settings. ### Method GET ### Endpoint /userprofile-service/userprofile/settings ### Response #### Success Response (200) - **User settings dictionary** (object) - A dictionary containing various user settings. ``` -------------------------------- ### Get Primary Training Device Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Fetches information about the user's primary training device. ```python # Handled by: Garmin.get_primary_training_device() ``` -------------------------------- ### Example RunningWorkout Creation and Upload Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Demonstrates creating a structured running workout with multiple segments and steps using helper functions, and then uploading it via a client. Requires `garminconnect` library and a configured client. ```python from garminconnect.workout import ( RunningWorkout, WorkoutSegment, create_warmup_step, create_interval_step, create_cooldown_step ) workout = RunningWorkout( workoutName="5K Intervals", estimatedDurationInSecs=2400, workoutSegments=[ WorkoutSegment( segmentOrder=1, sportType={"sportTypeId": 1, "sportTypeKey": "running"}, workoutSteps=[ create_warmup_step(600.0), # 10 min warmup create_interval_step(300.0, target_speed=12), # 5 min hard create_recovery_step(300.0), # 5 min easy create_cooldown_step(300.0), # 5 min cooldown ] ) ] ) result = client.upload_running_workout(workout) ``` -------------------------------- ### upload_cycling_workout() Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Uploads a typed cycling workout using a Pydantic model. Requires the 'workout' extra to be installed. ```APIDOC ## upload_cycling_workout() ### Description Upload a typed cycling workout (Pydantic model). ### Parameters #### Request Body - `workout` (CyclingWorkout): A CyclingWorkout instance. ### Returns dict[str, Any]: Dictionary with uploaded workout data. ### Requires `pip install garminconnect[workout]` ``` -------------------------------- ### Garmin Class Constructor and Usage Example Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Instantiate the Garmin client with credentials and optional MFA handling. Then, log in and retrieve statistics for a specific date. Ensure environment variables GARMIN_EMAIL and GARMIN_PASSWORD are set. ```python import os from garminconnect import Garmin # Create client with credentials client = Garmin( email=os.getenv("GARMIN_EMAIL"), password=os.getenv("GARMIN_PASSWORD"), prompt_mfa=lambda: input("Enter MFA code: "), ) # Login (loads tokens or performs fresh auth) client.login("~/.garminconnect") # Use the client stats = client.get_stats("2026-04-21") ``` -------------------------------- ### upload_swimming_workout() Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Uploads a typed swimming workout using a Pydantic model. Requires the 'workout' extra to be installed. ```APIDOC ## upload_swimming_workout() ### Description Upload a typed swimming workout (Pydantic model). ### Parameters #### Request Body - `workout` (SwimmingWorkout): A SwimmingWorkout instance. ### Returns dict[str, Any]: Dictionary with uploaded workout data. ### Requires `pip install garminconnect[workout]` ``` -------------------------------- ### Get In-Progress Virtual Challenges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieve virtual challenges that are currently in progress. Use the start offset and limit parameters for pagination. ```python def get_inprogress_virtual_challenges(self, start: int, limit: int) -> dict[str, Any]: ``` -------------------------------- ### Get Badge-Based Challenges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieve challenges that are based on earning specific badges. Supports pagination by specifying the starting offset and the limit. ```python def get_badge_challenges(self, start: int, limit: int) -> dict[str, Any]: ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Execute tests and generate a coverage report. Ensure example.py is run first to create saved tokens. ```bash pdm run testcov ``` -------------------------------- ### Get All-Day Stress Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Fetch all-day stress data for a specific day. This example shows the first 10 entries of the `bodyBatteryValuesArray`. ```python garmin.get_all_day_stress(yesterday)["bodyBatteryValuesArray"][:10] ``` -------------------------------- ### Initialize Garmin Client and Get Stats Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Initialize the Garmin client, log in using saved tokens or credentials, and retrieve today's statistics. ```python import os from datetime import date from garminconnect import Garmin # First run: logs in and saves tokens to ~/.garminconnect # Subsequent runs: loads saved tokens and auto-refreshes client = Garmin( os.getenv("EMAIL"), os.getenv("PASSWORD"), prompt_mfa=lambda: input("MFA code: "), ) client.login("~/.garminconnect") # Get today's stats today = date.today().isoformat() stats = client.get_stats(today) # Get heart rate data hr_data = client.get_heart_rates(today) print(f"Resting HR: {hr_data.get('restingHeartRate', 'n/a')}") ``` -------------------------------- ### Get Stats and Body Composition Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Retrieve both general statistics and body composition data for a specific day. ```python garmin.get_stats_and_body(yesterday).keys() ``` -------------------------------- ### With Early MFA Return (Custom Handling) Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Configure the login process to return on MFA requirement instead of prompting directly. This allows for custom MFA handling logic, such as sending codes via email or displaying QR codes. ```python from garminconnect import Garmin client = Garmin( email="user@example.com", password="password123", return_on_mfa=True, # Return on MFA instead of prompting ) mfa_status, client_state = client.login() if mfa_status == "MFA_REQUIRED": # Custom MFA handling (e.g., email to user, show QR code) code = send_mfa_to_user() client.resume_login(client_state, code) ``` -------------------------------- ### Get User Profile Settings Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves specific user profile settings. Returns a dictionary containing the settings. ```python def get_userprofile_settings(self) -> dict[str, Any] ``` -------------------------------- ### Get Available Badge Challenges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieve a list of badge challenges that are currently available. Pagination is supported by providing the starting offset and the limit. ```python def get_available_badge_challenges(self, start: int, limit: int) -> dict[str, Any]: ``` -------------------------------- ### Get Non-Completed Badge Challenges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieve badge challenges that have not yet been completed by the user. Pagination is available via start offset and limit parameters. ```python def get_non_completed_badge_challenges(self, start: int, limit: int) -> dict[str, Any]: ``` -------------------------------- ### Garmin Client Constructor Options Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Instantiate the Garmin client with full configuration options. All parameters are optional and have default values. ```python client = Garmin( email: str | None = None, password: str | None = None, is_cn: bool = False, prompt_mfa: Callable[[], str] | None = None, return_on_mfa: bool = False, retry_attempts: int = 3, retry_min_wait: float = 1.0, retry_max_wait: float = 10.0, verify_login: bool = True, ) ``` -------------------------------- ### Get Weigh-in Records Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves a list of weigh-in records within a specified date range. Requires start and end dates in 'YYYY-MM-DD' format. ```python def get_weigh_ins(self, startdate: str, enddate: str) -> dict[str, Any] ``` -------------------------------- ### Example: Create a Repeating Workout Group Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Demonstrates creating a repeating group of interval and recovery steps using helper functions. ```python from garminconnect.workout import create_repeat_group, create_interval_step, create_recovery_step # 5x (5 min hard + 2 min recovery) repeat = create_repeat_group( [ create_interval_step(300.0), create_recovery_step(120.0), ], repeats=5 ) ``` -------------------------------- ### Get Body Composition Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves body composition data for a specified date range. Requires start and end dates in 'YYYY-MM-DD' format. ```python def get_body_composition( self, startdate: str, enddate: str | None = None ) -> dict[str, Any] ``` -------------------------------- ### Get Badge Challenges Endpoint Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of completed badge challenges. Supports pagination with `start` and `limit` parameters. This endpoint is handled by the `get_badge_challenges()` method. ```Python Garmin.get_badge_challenges() ``` -------------------------------- ### Creating and Uploading a Running Workout Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/README.md Illustrates the process of defining a running workout with warm-up, interval, and cool-down steps using the library's workout objects. This is useful for programmatically creating and uploading structured training plans. ```python from garminconnect.workout import ( RunningWorkout, WorkoutSegment, create_warmup_step, create_interval_step, create_cooldown_step ) workout = RunningWorkout( workoutName="5K Training", estimatedDurationInSecs=2400, workoutSegments=[ WorkoutSegment( segmentOrder=1, sportType={"sportTypeId": 1, "sportTypeKey": "running"}, workoutSteps=[ create_warmup_step(600.0), create_interval_step(300.0), create_cooldown_step(300.0), ] ) ] ) g.upload_running_workout(workout) ``` -------------------------------- ### Get Device Solar Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Fetches solar data for compatible Garmin devices within a specified date range. Requires device ID and start date. ```python def get_device_solar_data( self, device_id: str, startdate: str, enddate: str | None = None ) -> list[dict[str, Any]] ``` -------------------------------- ### Publish Pre-built Package Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Publish a package that has already been built. ```bash pdm publish ``` -------------------------------- ### Get Daily Stats with Pydantic Model Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Demonstrates how to fetch daily statistics using the typed Pydantic model and access its fields. Requires `pip install garminconnect[typed]`. ```python g = Garmin(email, password) g.login() stats = g.typed.get_stats("2026-04-21") print(f"Steps: {stats.total_steps}") print(f"HR: {stats.resting_heart_rate}") print(f"Stress: {stats.average_stress_level}") # Raw response still available raw_dict = g.get_stats("2026-04-21") ``` -------------------------------- ### Build and Publish to PyPI Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Build the package and publish it to the Python Package Index (PyPI). ```bash pdm run publish ``` -------------------------------- ### Get Endurance Score for a Date Range Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves the endurance score for a specified date range. The end date can be used for weekly aggregates. Requires a start date string in 'YYYY-MM-DD' format. ```python def get_endurance_score( self, startdate: str, enddate: str | None = None ) -> dict[str, Any] ``` -------------------------------- ### Get Running Tolerance Data for a Date Range Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Fetches running tolerance data for a specified date range. Allows for daily or weekly aggregation. Requires start and end dates in 'YYYY-MM-DD' format. ```python def get_running_tolerance( self, startdate: str, enddate: str, aggregation: str = "weekly" ) -> list[dict[str, Any]] ``` -------------------------------- ### Garmin Constructor Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Initializes the Garmin client with authentication credentials and configuration options. ```APIDOC ## Constructor ```python def __init__( self, email: str | None = None, password: str | None = None, is_cn: bool = False, prompt_mfa: Callable[[], str] | None = None, return_on_mfa: bool = False, retry_attempts: int = 3, retry_min_wait: float = 1.0, retry_max_wait: float = 10.0, verify_login: bool = True, ) -> None ``` ### Parameters | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | email | str \| None | None | No | Email for Garmin Connect login | | password | str \| None | None | No | Password for Garmin Connect login | | is_cn | bool | False | No | Set to True for Garmin China (garmin.cn) domain | | prompt_mfa | Callable[[], str] \| None | None | No | Callback function to prompt for MFA code (receives no args, returns code string) | | return_on_mfa | bool | False | No | Return early when MFA is required instead of calling prompt_mfa | | retry_attempts | int | 3 | No | Number of retries for 5xx/network errors (0 to disable). 401/429/4xx always fail fast | | retry_min_wait | float | 1.0 | No | Initial backoff in seconds (grows exponentially with jitter) | | retry_max_wait | float | 10.0 | No | Maximum backoff in seconds | | verify_login | bool | True | No | When True, validate each login strategy's token against API before accepting it | ### Example ```python import os from garminconnect import Garmin # Create client with credentials client = Garmin( email=os.getenv("GARMIN_EMAIL"), password=os.getenv("GARMIN_PASSWORD"), prompt_mfa=lambda: input("Enter MFA code: "), ) # Login (loads tokens or performs fresh auth) client.login("~/.garminconnect") # Use the client stats = client.get_stats("2026-04-21") ``` ``` -------------------------------- ### With Saved Tokens (Production) Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md For production, use environment variables for credentials and save tokens to a file for faster subsequent logins. The library automatically handles token refreshing. ```python import os from garminconnect import Garmin client = Garmin( email=os.getenv("GARMIN_EMAIL"), password=os.getenv("GARMIN_PASSWORD"), ) # First run: saves tokens to ~/.garminconnect # Subsequent runs: loads tokens and auto-refreshes client.login("~/.garminconnect") ``` -------------------------------- ### Get Hill Score for a Date Range Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Calculates the hill score for a specified date range. If no end date is provided, it defaults to a single day. Requires a start date string in 'YYYY-MM-DD' format. ```python def get_hill_score( self, startdate: str, enddate: str | None = None ) -> dict[str, Any] ``` -------------------------------- ### Get Lactate Threshold Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves lactate threshold data, including heart rate, power, and speed. Can fetch the latest data or a range based on start and end dates. Supports daily, weekly, monthly, or yearly aggregation. ```python def get_lactate_threshold( self, *, latest: bool = True, start_date: str | date | None = None, end_date: str | date | None = None, aggregation: str = "daily", ) -> dict[str, Any] ``` -------------------------------- ### Download Workout as FIT File Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Downloads a workout as a FIT file. Provide the workout ID, which can be an integer or a string. ```python def download_workout(self, workout_id: int | str) -> bytes ``` -------------------------------- ### create_warmup_step Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Creates a warmup step for a workout routine with a specified duration in seconds. ```APIDOC ## create_warmup_step() ### Description Creates a warmup step with a specified duration in seconds. ### Signature ```python def create_warmup_step(duration: float) -> ExecutableStep ``` ``` -------------------------------- ### Get Daily Stats Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Retrieve daily statistics for a given date. Use this to get an overview of the day's metrics. ```python garmin.get_stats(yesterday).keys() ``` -------------------------------- ### Training Plan Query Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/graphql_queries.txt Fetches the user's training plan for a specific calendar date, with language and first day of week options. ```APIDOC ## trainingPlanScalar ### Description Retrieves the training plan details for a specific calendar date, with options for language and the first day of the week. ### Parameters #### Query Parameters - **calendarDate** (YYYY-MM-DD) - Required - The specific date for which to retrieve the training plan. - **lang** (str) - Optional - The language for the training plan details (e.g., 'en-US'). Defaults to 'en-US'. - **firstDayOfWeek** (str) - Optional - Specifies the first day of the week (e.g., 'monday'). Defaults to 'monday'. ``` -------------------------------- ### Create Activity Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Creates a new manual activity with specified details including type, name, start time, distance, and duration. ```APIDOC ## POST /activity-service/activity ### Description Creates a new manual activity. ### Method POST ### Endpoint /activity-service/activity ### Parameters #### Request Body - **activityTypeDTO** (object) - Required - Details about the activity type. - **typeKey** (string) - Required - The key identifier for the activity type (e.g., `running`). - **activityName** (string) - Required - The name of the activity. - **summaryDTO** (object) - Required - Summary details of the activity. - **startTimeLocal** (string) - Required - The local start time of the activity (e.g., `2026-04-21T10:00:00.000`). - **distance** (float) - Required - The distance covered in the activity. - **duration** (integer) - Required - The duration of the activity in seconds. ### Request Example ```json { "activityTypeDTO": { "typeKey": "running" }, "activityName": "My Activity", "summaryDTO": { "startTimeLocal": "2026-04-21T10:00:00.000", "distance": 5000.0, "duration": 1800 } } ``` ### Response #### Success Response (200) - **activityId** (string) - The unique identifier for the newly created activity. ### Response Example ```json { "activityId": "123456789" } ``` ``` -------------------------------- ### Get Daily Respiration Data from Garmin Connect Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieve daily respiration data for a specified date using a GET request to the wellness service. ```python Garmin.get_respiration_data() ``` -------------------------------- ### Configure PyPI Credentials Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Configure PyPI credentials using a .pypirc file. It is recommended to use environment variables for security. ```bash cat > ~/.pypirc <<'EOF' [pypi] username = __token__ password = EOF ``` -------------------------------- ### Get Step Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Retrieve the step count data for a given day. This snippet shows how to get the first two entries of the step data. ```python garmin.get_steps_data(yesterday)[:2] ``` -------------------------------- ### Create and Upload Typed Workouts Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Use the imported workout builder classes to construct complex workout structures with Pydantic models. Upload the created workout using the `upload_running_workout` method. ```python from garminconnect import Garmin from garminconnect.workout import ( RunningWorkout, WorkoutSegment, create_warmup_step, create_interval_step, create_cooldown_step ) g = Garmin(email, password) g.login() workout = RunningWorkout( workoutName="Easy Run", estimatedDurationInSecs=1800, workoutSegments=[ WorkoutSegment( segmentOrder=1, sportType={"sportTypeId": 1, "sportTypeKey": "running"}, workoutSteps=[create_warmup_step(300.0)] ) ] ) result = g.upload_running_workout(workout) ``` -------------------------------- ### Get Heart Rate Data Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/reference.ipynb Fetch heart rate data for a given day. This snippet shows how to get the keys of the heart rate data dictionary. ```python garmin.get_heart_rates(yesterday).keys() ``` -------------------------------- ### Download Activity (FIT) Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Downloads an activity in FIT file format. The file is returned zipped. ```python Garmin.download_activity(ActivityDownloadFormat.ORIGINAL) ``` -------------------------------- ### Project Directory Structure Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/MANIFEST.md This snippet shows the organizational structure of the project's documentation files. ```tree /output/ ├── INDEX.md ← Master index (start here) ├── README.md ← Overview & navigation ├── configuration.md ← Setup guide ├── types.md ← Type definitions ├── errors.md ← Error handling ├── endpoints.md ← HTTP endpoints ├── MANIFEST.md ← This file └── api-reference/ ├── garmin-class.md ← Main API class └── client-methods.md ← Low-level HTTP ``` -------------------------------- ### Get Daily SpO2 Data from Garmin Connect Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Fetch daily SpO2 (blood oxygen saturation) data for a given date via a GET request to the wellness service. ```python Garmin.get_spo2_data() ``` -------------------------------- ### Get Daily Heart Rates from Garmin Connect Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieve daily heart rate data for a specified display name and date. Requires a GET request to the wellness service. ```python Garmin.get_heart_rates() ``` -------------------------------- ### Create and Upload a Running Workout Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Define a structured running workout using Pydantic models and upload it to Garmin Connect. Optionally schedule it for a future date. ```python from garminconnect.workout import ( RunningWorkout, WorkoutSegment, create_warmup_step, create_interval_step, create_cooldown_step, create_repeat_group, ) # Create a structured running workout workout = RunningWorkout( workoutName="Easy Run", estimatedDurationInSecs=1800, workoutSegments=[ WorkoutSegment( segmentOrder=1, sportType={"sportTypeId": 1, "sportTypeKey": "running"}, workoutSteps=[create_warmup_step(300.0)] ) ] ) # Upload and optionally schedule it result = client.upload_running_workout(workout) client.schedule_workout(result["workoutId"], "2026-03-20") # Delete a workout or remove it from the calendar client.delete_workout(workout_id) client.unschedule_workout(scheduled_workout_id) ``` -------------------------------- ### Safe Login with Error Handling Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/errors.md Handles authentication errors, rate limiting with exponential backoff, and connection errors during login. Returns a client instance on success or None on failure. ```python import logging import time from pathlib import Path from garminconnect import ( Garmin, GarminConnectAuthenticationError, GarminConnectTooManyRequestsError, GarminConnectConnectionError, GarminConnectInvalidFileFormatError, ) from garminconnect.typed import GarminConnectResponseValidationError logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def safe_login(email, password, max_attempts=3): """Login with comprehensive error handling.""" for attempt in range(max_attempts): try: client = Garmin(email, password) client.login() logger.info("Login successful") return client except GarminConnectAuthenticationError as e: logger.error(f"Authentication failed: {e}") return None except GarminConnectTooManyRequestsError as e: if attempt < max_attempts - 1: wait = 60 * (2 ** attempt) logger.warning(f"Rate limited, waiting {wait}s...") time.sleep(wait) else: logger.error("Rate limited, max attempts exceeded") raise except GarminConnectConnectionError as e: logger.error(f"Connection error: {e}") return None ``` -------------------------------- ### Get Activity by ID Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Retrieves a specific activity's summary and basic splits using its unique ID. This is useful for getting a quick overview of an activity's performance metrics. ```python activity = client.get_activity("1234567890") print(f"Distance: {activity['distance']}m") print(f"Duration: {activity['duration']}s") ``` -------------------------------- ### Create Warmup Step Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/types.md Factory function to create a warmup step with a specified duration in seconds. ```python def create_warmup_step(duration: float) -> ExecutableStep ``` -------------------------------- ### Get Daily Body Battery Reports from Garmin Connect Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieve daily body battery reports, including charged and drained values, for a specified date range. Requires a GET request to the wellness service. ```python Garmin.get_body_battery() ``` -------------------------------- ### Download a file Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/client-methods.md Use this method to download files such as activities or workouts, returning raw bytes. Any `requests` compatible keyword arguments can be passed. ```python def download(self, path: str, **kwargs: Any) -> bytes: """Download a file (activity, workout, etc.) and return raw bytes.""" pass ``` ```python # Download activity as TCX data = g.download(f"/download-service/export/tcx/activity/123456") with open("activity.tcx", "wb") as f: f.write(data) ``` -------------------------------- ### Get Workout Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a specific workout by its ID. ```APIDOC ## GET /workout-service/workout/{workoutId} ### Description Retrieves a specific workout by its ID. ### Method GET ### Endpoint /workout-service/workout/{workoutId} ### Parameters #### Path Parameters - **workoutId** (string) - Required - The ID of the workout to retrieve. ``` -------------------------------- ### Run Garmin Connect API Demo Script Source: https://github.com/cyberjunky/python-garminconnect/blob/master/README.md Execute the comprehensive demo script to interact with the Garmin Connect API. This script provides a menu-driven interface for accessing over 130 API methods across 13 categories. ```bash $ ./demo.py 🏃‍♂️ Full-blown Garmin Connect API Demo - Main Menu ================================================== Select a category: [1] 👤 User & Profile [2] 📊 Daily Health & Activity [3] 🔬 Advanced Health Metrics [4] 📈 Historical Data & Trends [5] 🏃 Activities & Workouts [6] ⚖️ Body Composition & Weight [7] 🏆 Goals & Achievements [8] ⌚ Device & Technical [9] 🎽 Gear & Equipment [0] 💧 Hydration & Wellness [a] 🔧 System & Export [b] 📅 Training plans [c] ⛳ Golf [q] Exit program Make your selection: ``` -------------------------------- ### Get Device Settings Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves the settings for a specific device. ```APIDOC ## GET /device-service/deviceservice/device-info/settings/{deviceId} ### Description Retrieves the settings for a specific device. ### Method GET ### Endpoint /device-service/deviceservice/device-info/settings/{deviceId} ### Parameters #### Path Parameters - **deviceId** (string) - Required - The ID of the device for which to retrieve settings. ``` -------------------------------- ### Get Hydration Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves hydration data for a specific date. ```APIDOC ## GET /usersummary-service/usersummary/hydration/daily/{date} ### Description Retrieves hydration data for a specific date. ### Method GET ### Endpoint /usersummary-service/usersummary/hydration/daily/{date} ### Parameters #### Path Parameters - **date** (string) - Required - The date for which to retrieve hydration data (e.g., YYYY-MM-DD). ``` -------------------------------- ### get_stats Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Gets the user's activity summary for a specific date. ```APIDOC ## get_stats(cdate: str) ### Description Get user activity summary for a specific date (compatibility method, calls get_user_summary). ### Parameters #### Path Parameters - **cdate** (str) - Required - Date in format 'YYYY-MM-DD' ### Returns Dictionary with activity stats ### Raises `ValueError` if date format invalid ``` -------------------------------- ### With Custom Token Path Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/configuration.md Specify a custom directory for storing authentication tokens instead of the default location. ```python from garminconnect import Garmin client = Garmin( email="user@example.com", password="password123", ) # Use custom token directory client.login("/var/app/tokens") ``` -------------------------------- ### Get Gear Stats Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves statistics for a specific piece of gear. ```APIDOC ## Get Gear Stats ### Description Retrieves statistics for a specific piece of gear. ### Method GET ### Endpoint /gear-service/gear/stats/{gearUUID} ``` -------------------------------- ### Get Badge Challenges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of completed badge challenges. ```APIDOC ## Get Badge Challenges ### Description Retrieves a list of completed badge challenges. ### Method GET ### Endpoint /badgechallenge-service/badgeChallenge/completed ### Query Parameters - **start** (int) - Optional - The starting index for the challenges. - **limit** (int) - Optional - The maximum number of challenges to return. ``` -------------------------------- ### download_workout() Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/garmin-class.md Downloads a workout template as a FIT file. Requires the workout ID to specify which template to download. ```APIDOC ## download_workout() ### Description Download workout as FIT file. ### Parameters #### Path Parameters - `workout_id` (int | str): The unique identifier of the workout template to download. ### Returns bytes: Raw FIT file data. ``` -------------------------------- ### Get Available Badges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of badges that are available to be earned. ```APIDOC ## Get Available Badges ### Description Retrieves a list of badges that are available to be earned. ### Method GET ### Endpoint /badge-service/badge/available ### Query Parameters - **showExclusiveBadge** (string) - Optional - Indicates whether to show exclusive badges. ``` -------------------------------- ### download() Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/api-reference/client-methods.md Download a file such as an activity or workout and return the raw bytes. This is useful for exporting data in its original format. ```APIDOC ## download() ### Description Download a file (activity, workout, etc.) and return raw bytes. ### Method `download` ### Parameters - `path` (str) - Required - Download endpoint path - `**kwargs` - Optional - Passed to requests ### Returns Raw file bytes ### Raises `GarminConnectConnectionError` ### Example ```python # Download activity as TCX data = g.download(f"/download-service/export/tcx/activity/123456") with open("activity.tcx", "wb") as f: f.write(data) ``` ``` -------------------------------- ### Get Earned Badges Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves a list of badges that the user has earned. ```APIDOC ## Get Earned Badges ### Description Retrieves a list of badges that the user has earned. ### Method GET ### Endpoint /badge-service/badge/earned ``` -------------------------------- ### Import Garmin Client Class Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/README.md Import the main Garmin client class to interact with the Garmin Connect API. This is the primary entry point for using the library. ```python from garminconnect import Garmin ``` -------------------------------- ### Get Activity Splits Source: https://github.com/cyberjunky/python-garminconnect/blob/master/_autodocs/endpoints.md Retrieves the split data for a specific activity. ```APIDOC ## GET /activity-service/activity/{activityId}/splits ### Description Retrieves the split data for a specific activity. ### Method GET ### Endpoint /activity-service/activity/{activityId}/splits ### Parameters #### Path Parameters - **activityId** (string) - Required - The ID of the activity. ### Response #### Success Response (200) - **activitySplits** (array) - An array of split objects. - **splitIndex** (integer) - The index of the split. - **distance** (number) - The distance covered in the split. - **duration** (integer) - The duration of the split in milliseconds. - **pace** (number) - The pace for the split. ### Response Example ```json { "activitySplits": [ { "splitIndex": 0, "distance": 1000.0, "duration": 360000, "pace": 360.0 } ] } ``` ``` -------------------------------- ### Fetch Training Plan Source: https://github.com/cyberjunky/python-garminconnect/blob/master/docs/graphql_queries.txt Query for training plan details for a specific calendar date, language, and first day of the week. Dates should be in YYYY-MM-DD format. ```graphql query{{trainingPlanScalar(calendarDate:"{calendarDate}", lang:"en-US", firstDayOfWeek:"monday")}} ```