Skip to main content

Healthlog

Read Google Health data, and write explicit nutrient data to it.

healthlog auth login
healthlog food log "Bean salad" --grams 350 --kcal 420 --protein 25 --fat 12 --carbs 48
healthlog food log --input meal.json
cat meal.json | healthlog food log --input -
healthlog food history
healthlog food history yesterday
healthlog food history 2026-08-17 2026-08-23
healthlog food duplicate POINT_ID --protein 0
healthlog food delete POINT_ID

healthlog weight history 2026-08-01 2026-08-27
healthlog sleep history yesterday
healthlog types

Every data type is a noun and every noun reads the same way, so a caller that can read one can read all of them. healthlog types lists them. Food is the only type this version writes, and the only one with more than history.

Food

JSON input is a flat item carrying name, meal_type, optional time, optional grams, and nutrient fields. Omit time to use the device's current local time. Every new entry needs kcal, protein, fat, and carbs; explicit zero is a valid value. Use --nutrient NAME=GRAMS for another nutrient; names come from mealtime-nutrients, the list the mealtime tools share, which holds exactly one per nutrient. Dietary fibre is fiber, and carbohydrate has its own field, so it is carbs and never carbohydrates. Explicit flags override the input. Piped tool output keeps its {"ok":true,"data":...} envelope, and a field this version has not heard of is dropped, so the other tools stay free to add one. A bare JSON object is read as hand-written instead: an unrecognised key there is an error, rather than a nutrient quietly left out of the entry. grams is written to Google as a gram serving and survives reads. When it is absent, the shared format treats the nutrients as a 100 g fallback.

An item's nutrients describe the weight that item states, so --grams may not contradict it: piping a 100 g product and asking for 250 g is refused, because it would relabel the nutrients rather than convert them. Ask the source for the weight you mean, as with pantry lookup --grams 250, or state every nutrient here yourself. Restating the four core macros is not an escape, and is not accepted as one: an item carrying fibre or sugar would keep those at the old weight. An item stating no weight has nothing to contradict, so --grams records what was eaten; an Eatout meal is the usual case.

food duplicate always keeps the source and accepts the same overrides as food log. To correct an entry, duplicate it with the correction, inspect the result, then delete the source explicitly. JSON overrides may use null to remove a value.

Output carries kcal, protein, fat and carbs always, plus only the nutrients the entry states; an absent key and a null mean the same, while an explicit zero survives. Missing legacy Google core macros render as zero in Healthlog output. Unstated nutrients are omitted from writes. --dry-run --json shows the record without authenticating or writing.

food history totals the core macros always. Every other nutrient is totalled only when an entry states it, over the entries that state it, so a total may cover part of the range.

Reading a range

Every history reads today by default. Pass one date for that day or two dates for an inclusive range; dates may be ISO dates, today, or yesterday. Dates become UTC bounds using the device's local timezone. Offset-aware ISO datetimes are exact bounds; the end datetime is exclusive. Points are then compared only in UTC.

Google Health spells its server-side time filter differently for nearly every data type and rejects a wrong spelling outright, so the range is applied here instead. Points arrive newest first, so a read stops at the first page holding nothing new enough rather than walking a whole history.

Types other than food report each point as the API stated it, under data, with only the time lifted out — samples state a sampleTime, intervals and sessions an interval, and daily summaries a civil date. --limit caps a dense type at 500 points by default; a capped read always says truncated, and --limit 0 reads every point in the range.

Authentication

healthlog auth login asks for the read scope of every type in healthlog types, plus the nutrition write scope. Google refuses to refresh a token for a scope it never granted, so a token from an earlier version keeps working for what it does cover: healthlog auth status reports the scopes it lacks, and a read it cannot do fails with a 403 naming the re-login.

OAuth tokens remain in ~/.config/healthlog/tokens.json with mode 0600.

Release files for healthlog 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for healthlog 0.1.0
File Size Uploaded
healthlog-0.1.0.tar.gz 60.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for healthlog 0.1.0
File Interpreter ABI Platform
healthlog-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 91.5 kB

Release files / healthlog-0.1.0.tar.gz

Download URL healthlog-0.1.0.tar.gz
Size 60.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ba452017d98ec6bbbee0bc8455eebfd1e0aaeaffa1def9f669abaf0ea6bcd610
BLAKE2b-256 checksum
How to use checksums
1b2328a08b54ef62ecd0965228ef2400071aa02774258b212ee6d7e0a250d5fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.

Transparency log

Release files / healthlog-0.1.0-py3-none-any.whl

Download URL healthlog-0.1.0-py3-none-any.whl
Size 30.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d0dd41c73c3ba796e5e511bfcbd7dc42b6e098080ba55ebd0a073b011f3ee94e
BLAKE2b-256 checksum
How to use checksums
f46a92fd579bbec44869dd2dd9a917185874aa2712818251a255635499372366
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page