Metadata-Version: 2.3
Name: garmin-training-toolkit-sdk
Version: 0.6.0
Summary: A robust, type-safe Python SDK for Garmin Connect data extraction.
Keywords: garmin,health,biometrics,telemetry,sdk
Author: Federico Sirio
Author-email: Federico Sirio <federico.sirio@gmail.com>
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: garminconnect>=0.3.2
Requires-Dist: playwright>=1.40.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: requests>=2.31.0
Requires-Dist: requests-oauthlib>=1.3.0
Requires-Python: >=3.10
Project-URL: Homepage, https://github.com/restrok/garmin-training-toolkit-sdk
Project-URL: Repository, https://github.com/restrok/garmin-training-toolkit-sdk.git
Project-URL: Issues, https://github.com/restrok/garmin-training-toolkit-sdk/issues
Description-Content-Type: text/markdown

# Garmin Training Toolkit SDK

A robust, type-safe Python SDK for extracting biometric data and telemetry from Garmin Connect, optimized for autonomous agents and LLM tool-calling.

## Architecture: LLM-Native & Vendor-Agnostic

The SDK has been refactored to prioritize:
1.  **Semantic Naming:** No more cryptic Garmin fields. We use `min_target`, `max_target`, and `target_type`.
2.  **Provider Pattern:** Logic is decoupled from Garmin-specific APIs. You can now use a standardized `BaseBiometricProvider` interface.
3.  **Agent-First Schema:** Pydantic models include exhaustive descriptions and `Literal` types, allowing LLMs to understand the tool requirements with 100% accuracy from the JSON schema alone.

## Installation

This project uses `uv` for dependency management.

```bash
# In your consumer project:
uv add git+https://github.com/restrok/garmin-training-toolkit-sdk.git#subdirectory=garmin_toolkit
```

## Quick Start

### 1. Standardized Provider Interface

The recommended way to use the SDK is via the `GarminProvider`.

```python
from datetime import date
from garmin_training_toolkit_sdk.core.garmin import GarminProvider

# 1. Initialize (automatically finds local tokens)
provider = GarminProvider()
# 2. Fetch Activities (Returns vendor-agnostic Protocol models)
activities = provider.get_activities(date(2026, 4, 1), date(2026, 4, 30))
latest = activities[0]
print(f"Activity: {latest.name} | Distance: {latest.distance_m}m")

# 3. Calendar Range Queries (New)
items = provider.get_calendar_range(date(2026, 5, 25), date(2026, 6, 5))
print(f"Found {len(items)} scheduled items across month boundaries.")

# 4. Wellness Metrics (New)
sleep = provider.get_sleep_history(date(2026, 4, 1), date(2026, 4, 7))
hrv = provider.get_hrv_history(date(2026, 4, 1), date(2026, 4, 7))
profile = provider.get_user_profile()

# 5. Get Telemetry
telemetry = provider.get_telemetry(latest.id)
```

## Key Features

### 🛡️ Robust Authentication & Self-Healing
The SDK now handles OAuth scopes more comprehensively (including `USER_PROFILE`) and features automated self-healing. If a `401 Unauthorized` is encountered on a non-critical endpoint, the provider automatically attempts a token refresh and retries the operation seamlessly. This protection now covers all activity, calendar, and wellness data fetches.

### 📅 Date-Based Query Standardization
Methods like `get_scheduled_workouts` have been refactored to accept standard `date` objects. The SDK handles all internal year/month pagination and boundary logic, including the new `get_calendar_range` method which deduplicates items across month boundaries.

### 🧩 Provider-Agnostic Interface
The `BaseBiometricProvider` now includes standardized methods for:
*   **Deletion**: `unschedule_workout` and `delete_workout_template`.
*   **Wellness**: `get_sleep_history`, `get_hrv_history`, and `get_user_profile`.
This allows higher-level coaching and ETL logic to remain completely brand-agnostic.

### 🧪 Agent Tool Compatibility
Tools generated by the `ToolFactory` now include a `.run()` method, ensuring full compatibility with LangChain `StructuredTool` expectations and making them directly callable for internal execution. The factory now exposes 9 core tools covering activities, workouts, and biometrics.

## Tool Factory (For AI Agents)
### 2. LLM-Native Workouts (Agent Friendly)

Agents can create workouts using semantic naming or high-level helpers.

```python
from garmin_training_toolkit_sdk.protocol.workouts import create_simple_hr_workout

# High-level helper for Agents
workout = create_simple_hr_workout(
    name="Z2 Recovery Run",
    date="2026-05-01",
    bpm_min=135,
    bpm_max=145,
    duration_mins=45
)

# Upload via the provider
report = provider.upload_training_plan(workout)
print(f"Status: {report.message}")
```

## Tool Factory (For AI Agents)

If you are building an AI Agent (LangChain, AutoGPT, etc.), you can use the `ToolFactory` to generate a standardized set of tools from any provider.

```python
from garmin_training_toolkit_sdk.core.factory import ToolFactory
from garmin_training_toolkit_sdk.core.garmin import GarminProvider

provider = GarminProvider()
tools = ToolFactory.create_tools(provider)

# These tools have semantic descriptions that LLMs love:
# - get_activities
# - get_telemetry
# - upload_training_plan
```

## Directory Structure

*   `core/`: Provider implementations (Garmin, etc.) and the Tool Factory.
*   `protocol/`: Vendor-agnostic Pydantic models (Activity, Telemetry, Workout).
*   `extractors/`: Low-level data extraction logic.
*   `uploaders/`: Logic for calendar and workout management.

## Testing & Mocks

The SDK includes a `MockGarminClient` in `testing/mock.py` to allow consumers to test their pipelines without hitting Garmin's production APIs.

```python
from garmin_training_toolkit_sdk.testing.mock import MockGarminClient
# Use in your unit tests to avoid rate limits
```
