Skip to content

Commit 7127367

Browse files
docs: add worked example for withings-export (#40)
Moves the withings-export worked example out of quantcli/common (where it was misfiled in PR #24) and into this repo where it belongs — next to the binary it documents. Co-references in GETTING_STARTED.md will be updated in a follow-up PR against quantcli/common. Co-authored-by: LeadGoEngineer <noreply@paperclip.ing>
1 parent d19480c commit 7127367

1 file changed

Lines changed: 214 additions & 0 deletions

File tree

docs/example.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# Worked example: withings-export
2+
3+
**Audience:** Withings device owners (scale, sleep tracker, activity watch) who want their health data in a terminal or piped to an LLM agent.
4+
5+
**Prerequisites:** `withings-export` installed (see [GETTING_STARTED.md](https://github.com/quantcli/common/blob/main/GETTING_STARTED.md)), a Withings account, `withings-export auth login` completed.
6+
7+
---
8+
9+
## 1. Authenticate
10+
11+
Withings uses OAuth2. Run the login flow once:
12+
13+
```sh
14+
withings-export auth login
15+
```
16+
17+
This opens a browser tab. Complete the OAuth consent and the token is stored at `~/.config/withings-export/auth.json`.
18+
19+
Check readiness:
20+
21+
```sh
22+
withings-export auth status
23+
```
24+
25+
**Expected when logged in:**
26+
27+
```
28+
logged in
29+
```
30+
31+
Exit 0. **Expected when not logged in:**
32+
33+
```
34+
Error: not logged in — run: withings-export auth login
35+
```
36+
37+
Exit 1. `auth status` makes no network call — it only reads the local token file.
38+
39+
**HTTPS callback workaround:** If your Withings OAuth app requires HTTPS, register `https://redirectmeto.com/http://localhost:8128/oauth/authorize` as the callback URL and set:
40+
41+
```sh
42+
export WITHINGS_CALLBACK_URL="https://redirectmeto.com/http://localhost:8128/oauth/authorize"
43+
```
44+
45+
---
46+
47+
## 2. Orient with `prime`
48+
49+
```sh
50+
withings-export prime
51+
```
52+
53+
**Output** (reproduced at HEAD, 2026-05-19):
54+
55+
```
56+
withings-export — primer for LLM agents
57+
=======================================
58+
59+
WHAT IT IS
60+
CLI for personal Withings data: activity, sleep, workouts, body
61+
measurements, minute-level intraday samples (HR/HRV/SpO2/steps).
62+
63+
I/O
64+
stdout: data in --format markdown (default), json, or csv.
65+
stderr: errors. Exit 0 on success including empty results.
66+
67+
AUTH
68+
withings-export auth login OAuth2 in browser; tokens stored locally.
69+
withings-export auth status Exit 0 if usable, 1 with reason. No network call.
70+
withings-export auth refresh|logout
71+
72+
Optional env: WITHINGS_CLIENT_ID, WITHINGS_CLIENT_SECRET, WITHINGS_CALLBACK_URL.
73+
HTTPS-callback workaround: register https://redirectmeto.com/http://localhost:8128/oauth/authorize
74+
(verbatim) and set WITHINGS_CALLBACK_URL to the same string.
75+
76+
DATE FLAGS (every subcommand)
77+
--since VALUE / --until VALUE
78+
VALUE: today | yesterday | YYYY-MM-DD | Nd/Nw/Nm/Ny
79+
See https://github.com/quantcli/common/blob/main/CONTRACT.md#3-date-flags
80+
81+
SUBCOMMANDS (defaults in parens)
82+
activity (30d) daily steps/distance/calories/HR zones
83+
sleep (30d) stages, score, HR/RR; --derive polyfills missing nights
84+
workouts (90d) runs/walks/bikes/lifts with calories/HR/distance
85+
measurements (30d) weight/fat/BP/SpO2/temp; --types LIST filters
86+
intraday (1d) minute-level HR/HRV/SpO2/steps; dense — keep windows narrow
87+
88+
Inspect any subcommand's row schema with: <subcommand> --since 1d --format json
89+
90+
EXAMPLES
91+
withings-export sleep --since 7d
92+
withings-export workouts --since 30d --format json |
93+
jq '.[] | {date, category, hr: .data.hr_average}'
94+
withings-export measurements --since 30d --types 1 --format json |
95+
jq 'sort_by(.date) | last'
96+
97+
GOTCHAS
98+
- Times are LOCAL; JSON epoch seconds are zone-agnostic.
99+
- 'intraday' is a firehose — wide windows take minutes.
100+
- Withings rate-limits aggressive callers (HTTP 601). 'sleep --derive' throttles itself.
101+
- Sleep score / apnea fields appear only on supported devices.
102+
- 'workouts.category' is an integer code in JSON; markdown/CSV map common codes to names.
103+
```
104+
105+
---
106+
107+
## 3. Export last week's activity
108+
109+
```sh
110+
withings-export activity --since 7d
111+
```
112+
113+
**Expected output** (markdown, one row per day):
114+
115+
```
116+
| Date | Steps | Distance (km) | Calories | Active (min) |
117+
|------------|-------|---------------|----------|--------------|
118+
| 2026-05-12 | 9240 | 6.8 | 2341 | 42 |
119+
| 2026-05-13 | 7110 | 5.2 | 2190 | 28 |
120+
```
121+
122+
---
123+
124+
## 4. Export sleep summaries
125+
126+
```sh
127+
withings-export sleep --since 7d
128+
```
129+
130+
For structured data including HR and sleep stages:
131+
132+
```sh
133+
withings-export sleep --since 7d --format json | jq '.[0]'
134+
```
135+
136+
---
137+
138+
## 5. Get most recent body weight measurement
139+
140+
```sh
141+
withings-export measurements --since 30d --types 1 --format json \
142+
| jq 'sort_by(.date) | last'
143+
```
144+
145+
`--types 1` filters to weight measurements (Withings measurement type 1). Omit `--types` to get all measurement types.
146+
147+
---
148+
149+
## 6. Export workout HR data
150+
151+
```sh
152+
withings-export workouts --since 30d --format json \
153+
| jq '.[] | {date, category, hr: .data.hr_average}'
154+
```
155+
156+
`category` is an integer in JSON; markdown and CSV output maps common codes to names like `Running`, `Cycling`.
157+
158+
---
159+
160+
## 7. Check flag validation (contract §4, §7)
161+
162+
These run without credentials (hermetic by [CONTRACT.md §7](https://github.com/quantcli/common/blob/main/CONTRACT.md#7-hermeticity)):
163+
164+
```sh
165+
withings-export activity --help # exits 0; no network call
166+
```
167+
168+
**Expected:** help text including `--since`, `--until`, `--format` flags; exit 0.
169+
170+
```sh
171+
withings-export activity --format lol 2>&1; echo "exit: $?"
172+
```
173+
174+
**Expected:**
175+
176+
```
177+
Error: invalid argument "lol" for "--format" flag: must be one of: markdown, json, csv
178+
exit: 1
179+
```
180+
181+
Error on stderr, nothing on stdout, exit 1.
182+
183+
---
184+
185+
## 8. Run the contract conformance suite
186+
187+
`withings-export` has the most complete compat coverage of the three CLIs: the suite stands up a stub HTTP server and a fake token so the data-path subtests run fully without real Withings credentials.
188+
189+
```sh
190+
git clone https://github.com/quantcli/withings-export-cli
191+
cd withings-export-cli
192+
go build -o /tmp/withings-export .
193+
WITHINGS_EXPORT_BIN=/tmp/withings-export go test -tags=compat ./...
194+
```
195+
196+
**Expected:**
197+
198+
```
199+
ok github.com/quantcli/withings-export-cli 0.003s
200+
ok github.com/quantcli/withings-export-cli/internal/auth 0.003s
201+
```
202+
203+
The suite covers CONTRACT.md §4 (format flag surface, `--format json` returns a JSON array, `--format csv` returns a header row, default equals `--format markdown`) and §7 (hermeticity) across all five data subcommands. All cells in the CONTRACT.md Status table for `withings-export` are **machine**-attested.
204+
205+
---
206+
207+
## What to look at next
208+
209+
- `withings-export intraday --help` — minute-level HR/HRV/SpO2 (keep windows narrow)
210+
- `withings-export prime` — jq recipes and rate-limit gotchas
211+
- [CONTRACT.md §3](https://github.com/quantcli/common/blob/main/CONTRACT.md#3-date-flags) — date flag semantics
212+
- [CONTRACT.md §4](https://github.com/quantcli/common/blob/main/CONTRACT.md#4-output-format) — output format contract (`csv` is withings-only today)
213+
- [crono-export example](https://github.com/quantcli/crono-export-cli/blob/main/docs/example.md) — if you also track nutrition
214+
- [liftoff-export example](https://github.com/quantcli/liftoff-export-cli/blob/main/docs/example.md) — if you also track gym workouts

0 commit comments

Comments
 (0)