whoop-py 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- whoop_py-0.1.0/.gitignore +14 -0
- whoop_py-0.1.0/.python-version +1 -0
- whoop_py-0.1.0/PKG-INFO +139 -0
- whoop_py-0.1.0/README.md +111 -0
- whoop_py-0.1.0/main.ipynb +5039 -0
- whoop_py-0.1.0/main.py +28 -0
- whoop_py-0.1.0/pyproject.toml +43 -0
- whoop_py-0.1.0/requirements.txt +5 -0
- whoop_py-0.1.0/src/whoop_py/__init__.py +355 -0
- whoop_py-0.1.0/src/whoop_py/py.typed +0 -0
- whoop_py-0.1.0/uv.lock +843 -0
- whoop_py-0.1.0/whoop.py +352 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
whoop_py-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: whoop-py
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the WHOOP API with OAuth 2.0 support
|
|
5
|
+
Project-URL: Homepage, https://github.com/kartheekpnsn/whoop-api
|
|
6
|
+
Project-URL: Repository, https://github.com/kartheekpnsn/whoop-api
|
|
7
|
+
Project-URL: Issues, https://github.com/kartheekpnsn/whoop-api/issues
|
|
8
|
+
Author-email: Kartheek Palepu <kartheekpnsn@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: api,fitness,health,oauth,wearable,whoop
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Requires-Dist: authlib>=1.3.0
|
|
20
|
+
Requires-Dist: requests>=2.32.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: build>=1.0.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: ipykernel>=6.29.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: pandas>=2.2.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: twine>=5.0.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# whoop-api
|
|
30
|
+
|
|
31
|
+
Personal WHOOP data explorer using the [WHOOP API](https://developer.whoop.com/api).
|
|
32
|
+
|
|
33
|
+
## Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
whoop.py # WhoopClient (OAuth2 + API) and WhoopAPI (token persistence)
|
|
37
|
+
main.py # CLI entry point
|
|
38
|
+
main.ipynb # Interactive data exploration
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Auth Flow
|
|
42
|
+
|
|
43
|
+
```mermaid
|
|
44
|
+
sequenceDiagram
|
|
45
|
+
participant U as User
|
|
46
|
+
participant A as WhoopAPI
|
|
47
|
+
participant W as WHOOP OAuth
|
|
48
|
+
|
|
49
|
+
U->>A: WhoopAPI()
|
|
50
|
+
A->>A: load token from disk
|
|
51
|
+
alt no token / missing scopes
|
|
52
|
+
A->>W: create_authorization_url()
|
|
53
|
+
W-->>U: redirect URL
|
|
54
|
+
U->>W: approve access
|
|
55
|
+
W-->>U: redirect with code
|
|
56
|
+
U->>A: paste redirect URL
|
|
57
|
+
A->>W: fetch_token(code)
|
|
58
|
+
W-->>A: access + refresh token
|
|
59
|
+
A->>A: save token to disk
|
|
60
|
+
else token expired
|
|
61
|
+
A->>W: refresh_access_token()
|
|
62
|
+
W-->>A: new token
|
|
63
|
+
A->>A: save token to disk
|
|
64
|
+
end
|
|
65
|
+
A-->>U: authenticated WhoopClient
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Data Flow
|
|
69
|
+
|
|
70
|
+
```mermaid
|
|
71
|
+
flowchart LR
|
|
72
|
+
E[.env\nCLIENT_ID\nCLIENT_SECRET\nREDIRECT_URI] --> API[WhoopAPI]
|
|
73
|
+
T[.whoop_token.json] <-->|load / save| API
|
|
74
|
+
API --> C[WhoopClient]
|
|
75
|
+
C -->|GET| S[/sleep]
|
|
76
|
+
C -->|GET| R[/recovery]
|
|
77
|
+
C -->|GET| W[/workout]
|
|
78
|
+
C -->|GET| CY[/cycle]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Setup
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install -r requirements.txt
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**.env**
|
|
88
|
+
```
|
|
89
|
+
CLIENT_ID=your_client_id
|
|
90
|
+
CLIENT_SECRET=your_client_secret
|
|
91
|
+
REDIRECT_URI=your_redirect_uri
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Register your app at [developer.whoop.com](https://developer.whoop.com) to get credentials.
|
|
95
|
+
|
|
96
|
+
## Usage
|
|
97
|
+
|
|
98
|
+
**Script**
|
|
99
|
+
```bash
|
|
100
|
+
python main.py
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Notebook**
|
|
104
|
+
```bash
|
|
105
|
+
jupyter notebook main.ipynb
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Library**
|
|
109
|
+
```python
|
|
110
|
+
from dotenv import load_dotenv
|
|
111
|
+
from whoop import WhoopAPI
|
|
112
|
+
|
|
113
|
+
load_dotenv()
|
|
114
|
+
|
|
115
|
+
with WhoopAPI() as api:
|
|
116
|
+
sleep = api.get_sleep_collection(start_date="2026-06-01")
|
|
117
|
+
recovery = api.get_recovery_collection()
|
|
118
|
+
workouts = api.get_workout_collection()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The first run opens an interactive auth flow and saves the token to `.whoop_token.json`. Subsequent runs reuse or auto-refresh it.
|
|
122
|
+
|
|
123
|
+
## API Reference
|
|
124
|
+
|
|
125
|
+
| Method | Description |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `get_profile()` | User profile |
|
|
128
|
+
| `get_body_measurement()` | Height, weight, max HR |
|
|
129
|
+
| `get_sleep_collection(start, end)` | All sleep records |
|
|
130
|
+
| `get_sleep_by_id(id)` | Single sleep record |
|
|
131
|
+
| `get_sleep_stream(id)` | Raw HR/temp signal stream |
|
|
132
|
+
| `get_recovery_collection(start, end)` | All recovery scores |
|
|
133
|
+
| `get_recovery_for_cycle(cycle_id)` | Recovery for a cycle |
|
|
134
|
+
| `get_cycle_collection(start, end)` | All physiological cycles |
|
|
135
|
+
| `get_cycle_by_id(id)` | Single cycle |
|
|
136
|
+
| `get_workout_collection(start, end)` | All workouts |
|
|
137
|
+
| `get_workout_by_id(id)` | Single workout |
|
|
138
|
+
|
|
139
|
+
`start` / `end` are ISO date strings (e.g. `"2026-06-01"`). Defaults to the last 7 days.
|
whoop_py-0.1.0/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# whoop-api
|
|
2
|
+
|
|
3
|
+
Personal WHOOP data explorer using the [WHOOP API](https://developer.whoop.com/api).
|
|
4
|
+
|
|
5
|
+
## Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
whoop.py # WhoopClient (OAuth2 + API) and WhoopAPI (token persistence)
|
|
9
|
+
main.py # CLI entry point
|
|
10
|
+
main.ipynb # Interactive data exploration
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Auth Flow
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
sequenceDiagram
|
|
17
|
+
participant U as User
|
|
18
|
+
participant A as WhoopAPI
|
|
19
|
+
participant W as WHOOP OAuth
|
|
20
|
+
|
|
21
|
+
U->>A: WhoopAPI()
|
|
22
|
+
A->>A: load token from disk
|
|
23
|
+
alt no token / missing scopes
|
|
24
|
+
A->>W: create_authorization_url()
|
|
25
|
+
W-->>U: redirect URL
|
|
26
|
+
U->>W: approve access
|
|
27
|
+
W-->>U: redirect with code
|
|
28
|
+
U->>A: paste redirect URL
|
|
29
|
+
A->>W: fetch_token(code)
|
|
30
|
+
W-->>A: access + refresh token
|
|
31
|
+
A->>A: save token to disk
|
|
32
|
+
else token expired
|
|
33
|
+
A->>W: refresh_access_token()
|
|
34
|
+
W-->>A: new token
|
|
35
|
+
A->>A: save token to disk
|
|
36
|
+
end
|
|
37
|
+
A-->>U: authenticated WhoopClient
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Data Flow
|
|
41
|
+
|
|
42
|
+
```mermaid
|
|
43
|
+
flowchart LR
|
|
44
|
+
E[.env\nCLIENT_ID\nCLIENT_SECRET\nREDIRECT_URI] --> API[WhoopAPI]
|
|
45
|
+
T[.whoop_token.json] <-->|load / save| API
|
|
46
|
+
API --> C[WhoopClient]
|
|
47
|
+
C -->|GET| S[/sleep]
|
|
48
|
+
C -->|GET| R[/recovery]
|
|
49
|
+
C -->|GET| W[/workout]
|
|
50
|
+
C -->|GET| CY[/cycle]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Setup
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install -r requirements.txt
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**.env**
|
|
60
|
+
```
|
|
61
|
+
CLIENT_ID=your_client_id
|
|
62
|
+
CLIENT_SECRET=your_client_secret
|
|
63
|
+
REDIRECT_URI=your_redirect_uri
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Register your app at [developer.whoop.com](https://developer.whoop.com) to get credentials.
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
**Script**
|
|
71
|
+
```bash
|
|
72
|
+
python main.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Notebook**
|
|
76
|
+
```bash
|
|
77
|
+
jupyter notebook main.ipynb
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Library**
|
|
81
|
+
```python
|
|
82
|
+
from dotenv import load_dotenv
|
|
83
|
+
from whoop import WhoopAPI
|
|
84
|
+
|
|
85
|
+
load_dotenv()
|
|
86
|
+
|
|
87
|
+
with WhoopAPI() as api:
|
|
88
|
+
sleep = api.get_sleep_collection(start_date="2026-06-01")
|
|
89
|
+
recovery = api.get_recovery_collection()
|
|
90
|
+
workouts = api.get_workout_collection()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The first run opens an interactive auth flow and saves the token to `.whoop_token.json`. Subsequent runs reuse or auto-refresh it.
|
|
94
|
+
|
|
95
|
+
## API Reference
|
|
96
|
+
|
|
97
|
+
| Method | Description |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `get_profile()` | User profile |
|
|
100
|
+
| `get_body_measurement()` | Height, weight, max HR |
|
|
101
|
+
| `get_sleep_collection(start, end)` | All sleep records |
|
|
102
|
+
| `get_sleep_by_id(id)` | Single sleep record |
|
|
103
|
+
| `get_sleep_stream(id)` | Raw HR/temp signal stream |
|
|
104
|
+
| `get_recovery_collection(start, end)` | All recovery scores |
|
|
105
|
+
| `get_recovery_for_cycle(cycle_id)` | Recovery for a cycle |
|
|
106
|
+
| `get_cycle_collection(start, end)` | All physiological cycles |
|
|
107
|
+
| `get_cycle_by_id(id)` | Single cycle |
|
|
108
|
+
| `get_workout_collection(start, end)` | All workouts |
|
|
109
|
+
| `get_workout_by_id(id)` | Single workout |
|
|
110
|
+
|
|
111
|
+
`start` / `end` are ISO date strings (e.g. `"2026-06-01"`). Defaults to the last 7 days.
|