whoop-client
A Python wrapper for the WHOOP API.
Provides both synchronous and asynchronous clients with Pydantic models, automatic retries, OAuth2 token management, and an MCP server for AI assistants.
Installation
pip install whoop-client
Requires Python 3.10+.
Quick Start
With an access token
from whoop_client import WhoopClient
with WhoopClient("your-access-token") as client:
profile = client.get_profile()
print(f"Hello, {profile.first_name}!")
for cycle in client.iter_cycles():
if cycle.score:
print(f"Strain: {cycle.score.strain}")
Async
import asyncio
from whoop_client import AsyncWhoopClient
async def main():
async with AsyncWhoopClient("your-access-token") as client:
profile = await client.get_profile()
print(f"Hello, {profile.first_name}!")
async for cycle in client.iter_cycles():
if cycle.score:
print(f"Strain: {cycle.score.strain}")
asyncio.run(main())
With OAuth2 token refresh
from whoop_client import WhoopClient, OAuthTokenProvider
token_provider = OAuthTokenProvider(
client_id="your-client-id",
client_secret="your-client-secret",
refresh_token="your-refresh-token",
)
with WhoopClient(token_provider) as client:
profile = client.get_profile()
The OAuthTokenProvider automatically refreshes expired tokens. An AsyncOAuthTokenProvider is available for the async client.
API
Clients
Both WhoopClient and AsyncWhoopClient accept the same constructor arguments:
WhoopClient(
token_provider, # Access token string or TokenProvider instance
*,
base_url="...", # Override API base URL
timeout=30.0, # Request timeout in seconds
retry_policy=None, # Custom RetryPolicy, or None for defaults
httpx_client=None, # Bring your own httpx.Client
)
Endpoints
| Method | Description |
|---|---|
get_cycles(...) |
List cycles (paginated) |
get_cycle_by_id(id) |
Get a single cycle |
get_cycle_sleep(id) |
Get sleep for a cycle |
get_cycle_recovery(id) |
Get recovery for a cycle |
get_recoveries(...) |
List recoveries (paginated) |
get_sleeps(...) |
List sleeps (paginated) |
get_sleep_by_id(id) |
Get a single sleep |
get_workouts(...) |
List workouts (paginated) |
get_workout_by_id(id) |
Get a single workout |
get_profile() |
Get basic user profile |
get_body_measurement() |
Get body measurements |
revoke_access() |
Revoke the OAuth access token |
get_activity_mapping(v1_id) |
Map a V1 activity ID to V2 |
Paginated endpoints accept limit, start, end, and next_token parameters. They return a PaginatedResponse[T] with records and next_token fields.
Auto-Pagination
Use the iter_* methods to automatically paginate through all results:
iter_cycles(...)iter_recoveries(...)iter_sleeps(...)iter_workouts(...)
These return Iterator[T] (sync) or AsyncIterator[T] (async).
Retry Policy
Requests are retried automatically on transient failures (429, 5xx, timeouts, connection errors) with exponential backoff and jitter. Customize with RetryPolicy:
from whoop_client import WhoopClient, RetryPolicy
policy = RetryPolicy(
max_retries=5,
backoff_factor=1.0,
max_backoff_seconds=120.0,
)
client = WhoopClient("token", retry_policy=policy)
Exceptions
All exceptions inherit from WhoopError:
| Exception | Trigger |
|---|---|
WhoopBadRequestError |
400 response |
WhoopAuthenticationError |
401 response |
WhoopNotFoundError |
404 response |
WhoopRateLimitError |
429 response (has retry_after attribute) |
WhoopServerError |
5xx response |
WhoopConnectionError |
Network failure |
WhoopTimeoutError |
Request timeout |
WhoopAuthTokenError |
Token refresh failure |
API errors carry status_code and response attributes for full introspection.
Obtaining Tokens (whoop-client auth)
The whoop-client auth command runs the OAuth2 Authorization Code flow to obtain access and refresh tokens from WHOOP.
Prerequisites
Set your OAuth2 credentials as environment variables (or pass them as flags):
export WHOOP_CLIENT_ID="your-client-id"
export WHOOP_CLIENT_SECRET="your-client-secret"
Usage
whoop-client auth
This opens your browser, waits for the OAuth2 callback, and saves the tokens to ~/.config/whoop-client/tokens.json.
Options
| Flag | Description | Default |
|---|---|---|
--client-id |
OAuth2 client ID | $WHOOP_CLIENT_ID |
--client-secret |
OAuth2 client secret | $WHOOP_CLIENT_SECRET |
--scopes |
OAuth2 scopes to request | All read scopes |
--port |
Local callback server port | 8080 |
--redirect-uri |
OAuth2 redirect URI | http://localhost:8080/callback |
--token-file |
Output file path | ~/.config/whoop-client/tokens.json |
--no-open |
Print the URL instead of opening the browser | — |
Example
# Use env vars, save to custom file
whoop-client auth --token-file my-tokens.json
# Pass credentials directly
whoop-client auth --client-id ID --client-secret SECRET
# Headless (e.g. SSH session) — prints the URL to visit manually
whoop-client auth --no-open
MCP Server
whoop-client includes an MCP server that exposes WHOOP data as tools for AI assistants like Claude.
Installation
pip install "whoop-client[mcp]"
Configuration
The server requires WHOOP API credentials via environment variables:
Option 1: OAuth2 with auto-refresh (recommended)
| Variable | Description |
|---|---|
WHOOP_CLIENT_ID |
OAuth2 client ID |
WHOOP_CLIENT_SECRET |
OAuth2 client secret |
WHOOP_REFRESH_TOKEN |
OAuth2 refresh token |
WHOOP_ACCESS_TOKEN |
(Optional) Initial access token to avoid an initial refresh |
Option 2: Static access token
| Variable | Description |
|---|---|
WHOOP_ACCESS_TOKEN |
A valid WHOOP API access token |
Usage
Run the server directly:
whoop-client mcp
Available Tools
| Tool | Description |
|---|---|
get_cycles |
List physiological cycles (paginated) |
get_cycle_by_id |
Get a single cycle |
get_cycle_sleep |
Get sleep for a cycle |
get_cycle_recovery |
Get recovery for a cycle |
get_recoveries |
List recovery records (paginated) |
get_sleeps |
List sleep records (paginated) |
get_sleep_by_id |
Get a single sleep record |
get_workouts |
List workout records (paginated) |
get_workout_by_id |
Get a single workout record |
get_profile |
Get basic user profile |
get_body_measurement |
Get body measurements |
Development
uv sync # Install dependencies
uv run pre-commit install # Install pre-commit hooks
uv run pytest # Run tests
uv run ruff check # Lint
uv run ruff format # Format
uv run ty check # Type check
License
MIT
Metadata
Release files for whoop-client 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| whoop_client-0.1.0.tar.gz | 17.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| whoop_client-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.4 kB
Release files / whoop_client-0.1.0.tar.gz
| Download URL | whoop_client-0.1.0.tar.gz |
|---|---|
| Size | 17.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
865d05d2a11cff9f297dd4d08b0fd3f24ef791bdeee43785edb03d7885e1f7ee
|
|
BLAKE2b-256 checksum How to use checksums |
e8786f569b163b0fc62526fa549d977fd83686fe48ec32f2879cc4f13453d27b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / whoop_client-0.1.0-py3-none-any.whl
| Download URL | whoop_client-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c4ca498c6350bc80e0eaa6495786296ed2d152a3e0bb7b65905b62ce6427793e
|
|
BLAKE2b-256 checksum How to use checksums |
65783da61903d210ebf886ec777b164dcb7257e86f74a89fe778f4baeae96f10
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|