Skip to main content

A Django app for the Google Health API (successor to the Fitbit Web API), backed by django-healthdatamodel.

Project description

django-google-health

CI

A reusable Django app for the Google Health API — the successor to the Fitbit Web API. Handles the Google OAuth 2.0 flow, fetches user health data from health.googleapis.com, and persists it through django-healthdatamodel so the same storage and query layer serves Apple Health, Fitbit, and Google Health side-by-side.

Google recommends launching new integrations after the end of May 2026 to align with legacy Fitbit account deprecation. See docs/google-health/get-started.md.

Status

Early scaffolding. The package, demo project, OAuth model, and CI are in place. OAuth views, the HTTP client, ingest mapping, and webhook handling are stubbed and will land in follow-up slices.

Install

pip install django-google-health

Add both this app and django-healthdatamodel to INSTALLED_APPS, then run migrations:

INSTALLED_APPS = [
    ...
    "healthdatamodel",
    "googlehealth",
]
python manage.py migrate

The model uses settings.AUTH_USER_MODEL so it works with any custom user model.

Configuration

GOOGLE_HEALTH_CLIENT_ID = "..."        # from Google Cloud Console
GOOGLE_HEALTH_CLIENT_SECRET = "..."
GOOGLE_HEALTH_REDIRECT_URI = "https://your-app.example.com/google-health/callback"

Set up the OAuth client in Google Cloud Console and enable the Google Health API. See docs/google-health/codelabs-make-your-first-api-call.md for a step-by-step walkthrough.

Scopes

Google Health scopes are namespaced under https://www.googleapis.com/auth/googlehealth.*. The complete list lives in googlehealth.constants and is documented in docs/google-health/scopes.md. Examples:

  • googlehealth.activity_and_fitness.readonly — steps, distance, exercise, floors, altitude
  • googlehealth.health_metrics_and_measurements.readonly — heart rate, weight, body fat, SpO2
  • googlehealth.sleep.readonly — sleep stages and sessions
  • googlehealth.location.readonly — exercise GPS

Storage

This app does not define Record / Workout tables — those live in django-healthdatamodel. The googlehealth.ingest module maps Google Health API responses to healthdatamodel.schemas.RecordInput and WorkoutInput, then calls healthdatamodel.ingest.ingest_records to persist them. Read the data back with healthdatamodel.query.* (see that project's docs).

The only model defined here is GoogleHealthConnection: per-user OAuth tokens, granted scopes, connection status, and last sync timestamp.

Documentation

The Google Health API documentation is vendored as Markdown under docs/google-health/ so it's grep-able offline:

  • get-started.md — overview, benefits, getting started paths
  • migration.md — Fitbit Web API → Google Health API migration guide
  • data-types.md — every data type with operations and scopes
  • scopes.md — OAuth scopes
  • webhooks.md — subscriber registration, endpoint verification, notification payloads
  • codelabs-make-your-first-api-call.md — end-to-end OAuth + first API call
  • reference-rest.md — REST resource index
  • migration-parity-tool.md — parity tool reference
  • support.md — issue tracker and forum links

Demo project

The repo includes a runnable demo Django project under demo/:

uv sync
uv run python manage.py migrate
uv run python manage.py createsuperuser
uv run python manage.py runserver

Visit http://localhost:8000/admin/ to browse the googlehealth and healthdatamodel apps.

Development

uv sync --group dev
uv run pytest tests/ -v
uv run pre-commit run --all-files

Live integration tests

The default test suite mocks all HTTP with respx and runs offline. A small subset (marked @pytest.mark.live) hits the real health.googleapis.com and is skipped unless you set up real credentials.

You need three environment variables, all sourced from your own Google Cloud project:

GOOGLE_HEALTH_TEST_CLIENT_ID
GOOGLE_HEALTH_TEST_CLIENT_SECRET
GOOGLE_HEALTH_TEST_REFRESH_TOKEN

1. Create the OAuth client (one-time)

Follow the codelab in docs/google-health/codelabs-make-your-first-api-call.md for the full walkthrough. Condensed:

  1. Sign in to Google Cloud Console, create a project, and enable the Google Health API under APIs & Services → Library.
  2. APIs & Services → Credentials → + Create Credentials → OAuth client ID. Application type: Web application. Add https://www.google.com to Authorized redirect URIs — Google's homepage is the simplest receiver for a one-time manual exchange.
  3. Save the client ID and client secret. The secret is shown only once.
  4. Under Audience, add your own Google account (the one signed into the Fitbit app) as a Test user.
  5. Under Data Access, add the scopes you want to test against. For a smoke test of the activity endpoints, .../auth/googlehealth.activity_and_fitness.readonly is enough.

2. Run the consent flow and capture a refresh token (one-time)

Open this URL in a browser (substituting your client ID), sign in as the test user, and click through the consent screen. access_type=offline&prompt=consent guarantees a refresh token even on repeat consents:

https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=https://www.google.com&response_type=code&access_type=offline&prompt=consent&scope=https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly

After consenting you'll land on https://www.google.com/?code=<AUTH_CODE>&scope=.... Copy the value between code= and &scope=.

Exchange that code for tokens (one shot — auth codes are single-use):

curl -s https://oauth2.googleapis.com/token \
  -d code=YOUR_AUTH_CODE \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_CLIENT_SECRET \
  -d redirect_uri=https://www.google.com \
  -d grant_type=authorization_code

Pluck refresh_token out of the JSON response and store it somewhere safe. Access tokens expire in 1 hour; the test harness uses the refresh token to mint fresh ones, so you only repeat this step if your refresh token expires (6 months of inactivity) or you revoke consent.

3. Run the live tests

export GOOGLE_HEALTH_TEST_CLIENT_ID=...
export GOOGLE_HEALTH_TEST_CLIENT_SECRET=...
export GOOGLE_HEALTH_TEST_REFRESH_TOKEN=...
uv run pytest tests/ -v -m live

The default pytest run skips these. CI does not run live tests — they need credentials that aren't safe to commit.

The Fitbit mobile app needs to have data in your account for most endpoints to return anything. The codelab walks through manually logging a Walk activity if you don't already have data.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_google_health-0.1.0.tar.gz (111.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_google_health-0.1.0-py3-none-any.whl (31.1 kB view details)

Uploaded Python 3

File details

Details for the file django_google_health-0.1.0.tar.gz.

File metadata

  • Download URL: django_google_health-0.1.0.tar.gz
  • Upload date:
  • Size: 111.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_google_health-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7e3a2ebf41485b6ce2048a5a019fbe7a4c0644f0e20c713df1cbc8276145ae41
MD5 16e5656f02dd61d57251554fdf5ed678
BLAKE2b-256 7f025bb4246fe960831a9e053f13ae0b6d575de57abc556613c5890ead5aab28

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_google_health-0.1.0.tar.gz:

Publisher: ci.yml on andyreagan/django-google-health

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_google_health-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_google_health-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ce2408782c424fd3cb468e3645b61ec0696e7d04a0e481bc2830875a10d6346f
MD5 5569a56879b23d197c49ddf3877a63d9
BLAKE2b-256 166edc076ab87aeacf142b7316ebafda6cd6c2ec4e73617ada5938e52b108017

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_google_health-0.1.0-py3-none-any.whl:

Publisher: ci.yml on andyreagan/django-google-health

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page