Skip to main content

Python API client for Huckleberry baby tracking app using Firebase Firestore

Project description

Huckleberry API

Integration Tests

Python API client for the Huckleberry baby tracking app using Firebase Firestore.

Overview

This is a reverse-engineered API client that connects directly to Huckleberry's Firebase backend using the official Google Cloud Firestore SDK. It provides programmatic access to baby tracking features including sleep, feeding, diaper changes, and growth measurements.

Features

  • 🔐 Firebase Authentication: Secure email/password authentication with automatic token refresh
  • 💤 Sleep Tracking: Start, pause, resume, cancel, and complete sleep sessions
  • 🍼 Feeding Tracking: Track breastfeeding with left/right side switching
  • 🤱 Pumping Tracking: Log pumping sessions and fetch latest/history
  • 🧷 Diaper Changes: Log pee, poo, both, or dry checks with color/consistency
  • 📏 Growth Measurements: Record weight, height, and head circumference
  • 🔄 Real-time Updates: Firebase snapshot listeners for instant synchronization
  • 👶 Child Management: Support for multiple children profiles

Installation

uv add huckleberry-api
# or
pip install huckleberry-api

Quick Start

import asyncio
from datetime import datetime, timedelta
import aiohttp

from huckleberry_api import HuckleberryAPI

async def main() -> None:
    async with aiohttp.ClientSession() as websession:
        api = HuckleberryAPI(
            email="your-email@example.com",
            password="your-password",
            timezone="Europe/London",
            websession=websession,
        )

        await api.authenticate()

        user_doc = await api.get_user()
        child_uid = user_doc.childList[0].cid

        await api.start_sleep(child_uid)
        await api.complete_sleep(child_uid)
        await api.log_sleep(
            child_uid,
            start_time=datetime.now() - timedelta(hours=3),
            end_time=datetime.now() - timedelta(hours=2),
        )

        await api.start_nursing(child_uid, side="left")
        await api.switch_nursing_side(child_uid)
        await api.complete_nursing(child_uid)
        await api.log_nursing(
            child_uid,
            start_time=datetime.now() - timedelta(hours=4),
            end_time=datetime.now() - timedelta(hours=3, minutes=30),
            side="right",
        )

        await api.log_bottle(
            child_uid,
            start_time=datetime.now() - timedelta(hours=1),
            amount=120.0,
            bottle_type="Formula",
            units="ml",
        )
        await api.log_pump(
            child_uid,
            start_time=datetime.now(),
            total_amount=120.0,
            duration=900,
            units="ml",
        )
        await api.log_diaper(
            child_uid,
            start_time=datetime.now() - timedelta(minutes=45),
            mode="both",
            pee_amount="medium",
            poo_amount="medium",
            color="yellow",
            consistency="solid",
        )
        await api.log_growth(
            child_uid,
            start_time=datetime.now() - timedelta(days=1),
            weight=5.2,
            height=52.0,
            head=35.0,
            units="metric",
        )


asyncio.run(main())

Real-time Listeners

Set up real-time listeners for instant updates:

import aiohttp

def on_sleep_update(data):
    timer = data.get("timer", {})
    print(f"Sleep active: {timer.get('active')}")
    print(f"Sleep paused: {timer.get('paused')}")

async def main() -> None:
    async with aiohttp.ClientSession() as websession:
        api = HuckleberryAPI(
            email="your-email@example.com",
            password="your-password",
            timezone="Europe/London",
            websession=websession,
        )
        await api.authenticate()
        user_doc = await api.get_user()
        child_uid = user_doc.childList[0].cid

        await api.setup_sleep_listener(child_uid, on_sleep_update)
        await api.stop_all_listeners()

API Methods

Authentication

  • await authenticate() - Authenticate with Firebase
  • await ensure_session() - Ensure valid auth/session state
  • await refresh_session_token() - Refresh expired token

Children

  • await get_user() - Get full users/{uid} document
  • await get_child(child_uid) - Get a single child profile by id

Sleep Tracking

  • await start_sleep(child_uid) - Start sleep session
  • await pause_sleep(child_uid) - Pause active session
  • await resume_sleep(child_uid) - Resume paused session
  • await cancel_sleep(child_uid) - Cancel without saving
  • await complete_sleep(child_uid) - Complete and save to history
  • await log_sleep(child_uid, start_time=..., end_time=..., details=None) - Log a completed sleep interval with explicit timestamps

Feeding Tracking

  • await start_nursing(child_uid, side) - Start breastfeeding session
  • await pause_nursing(child_uid) - Pause active session
  • await resume_nursing(child_uid, side) - Resume paused session
  • await switch_nursing_side(child_uid) - Switch left/right
  • await cancel_nursing(child_uid) - Cancel without saving
  • await complete_nursing(child_uid) - Complete and save to history
  • await log_nursing(child_uid, start_time=..., end_time=..., side="left") - Log a completed breastfeeding interval with explicit timestamps
  • await log_bottle(child_uid, start_time=..., amount=..., bottle_type=..., units=...) - Log bottle feeding with an explicit event timestamp
    • bottle_type: "Breast Milk", "Formula", "Cow Milk", "Soy Milk", etc.
    • amount: Volume fed (e.g., 120.0)
    • units: "ml" or "oz"

Pumping Tracking

  • await log_pump(child_uid, start_time=..., total_amount=..., duration=..., units=...) - Log pumping entry; total entries are stored split evenly across leftAmount and rightAmount
  • await list_pump_intervals(child_uid, start_time, end_time) - List pump history for a range using datetime objects

Solids Tracking

  • await list_solids_curated_foods() - List curated solids food catalog
  • await list_solids_custom_foods(child_uid, include_archived=False) - List custom solids foods
  • await create_solids_custom_food(child_uid, name, image="") - Create custom solids food
  • await log_solids(child_uid, start_time=..., foods=..., notes="", reaction=None, food_note_image=None) - Log solids meal with an explicit event timestamp

Diaper Tracking

  • await log_diaper(child_uid, start_time=..., mode=..., pee_amount=..., poo_amount=..., color=..., consistency=...) - Log diaper change with an explicit event timestamp
  • await log_potty(child_uid, start_time=..., mode=..., how_it_happened=..., pee_amount=..., poo_amount=..., color=..., consistency=...) - Log potty event with an explicit event timestamp
    • mode: "pee", "poo", "both", or "dry"
    • color: "yellow", "green", "brown", "black", "red"
    • consistency: "runny", "soft", "solid", "hard"

Growth Tracking

  • await log_growth(child_uid, start_time=..., weight=..., height=..., head=..., units=...) - Log measurements with an explicit event timestamp
    • units: "metric" (kg/cm) or "imperial" (lbs/inches)
  • await get_latest_growth(child_uid) - Get latest measurements

Real-time Listeners

  • await setup_sleep_listener(child_uid, callback) - Listen to sleep updates
  • await setup_feed_listener(child_uid, callback) - Listen to feeding updates
  • await setup_health_listener(child_uid, callback) - Listen to health updates
  • await setup_pump_listener(child_uid, callback) - Listen to pump updates
  • await stop_all_listeners() - Stop all active listeners

Type Definitions

The package includes Pydantic models for type safety.

Canonical Firebase schema definitions are in src/huckleberry_api/firebase_types.py.

  • FirebaseChildDocument - Child profile information
  • FirebaseSleepDocumentData / FirebaseSleepTimerData - Sleep tracking data
  • FirebaseFeedDocumentData / FirebaseFeedTimerData - Feeding tracking data
  • FirebaseHealthDocumentData - Health tracking data
  • FirebaseGrowthData - Growth measurements

Architecture

This library uses:

  • Firebase Firestore Python SDK - Official Google Cloud SDK (not REST API)
  • gRPC over HTTP/2 - Real-time communication protocol
  • Protocol Buffers - Efficient data encoding
  • Firebase Authentication - Secure token-based auth

Why Not REST API?

Huckleberry's Firebase Security Rules block non-SDK requests. Direct REST API calls return 403 Forbidden. This library uses the official Firebase SDK which uses gRPC, the same protocol as the Huckleberry mobile app.

Requirements

  • Python 3.14+
  • google-cloud-firestore>=2.11.0
  • aiohttp>=3.10.0
  • pydantic>=2.10.0

Development

Running Tests

Integration tests require Huckleberry account credentials:

# Set environment variables
$env:HUCKLEBERRY_EMAIL = "test@example.com"
$env:HUCKLEBERRY_PASSWORD = "test-password"

# Run tests
.\run-tests.ps1

Linting, Formatting, and Type Checking

# Lint
uv run ruff check .

# Format
uv run ruff format .

# Type check
uv run ty check --python-version 3.14 --ignore unknown-argument

# Add release notes about your feature
uv run towncrier create

# Build release notes from fragments when cutting a release
uv run towncrier build --yes --version <version>

See tests/README.md for detailed testing documentation.

CI/CD

  • PR Validation runs on pull requests and pushes to main and checks Ruff linting/formatting and Ty type checking.
  • Integration tests run on GitHub Actions and require Huckleberry credentials.

License

MIT License

Disclaimer

This is an unofficial, reverse-engineered API client. It is not affiliated with, endorsed by, or connected to Huckleberry Labs Inc. Use at your own risk.

Related Projects

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

huckleberry_api-0.4.0.tar.gz (25.4 kB view details)

Uploaded Source

Built Distribution

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

huckleberry_api-0.4.0-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

Details for the file huckleberry_api-0.4.0.tar.gz.

File metadata

  • Download URL: huckleberry_api-0.4.0.tar.gz
  • Upload date:
  • Size: 25.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for huckleberry_api-0.4.0.tar.gz
Algorithm Hash digest
SHA256 eb47afe3e9ee0c1f3a62fd918abf7fc055d9b82fc3699ad4511ea89b7d4a77be
MD5 542599d58ba11eafccc506f5d7e4bd87
BLAKE2b-256 606698d3a5912aa784757a15ab231f1842e6e184434b2ce49d2366cfe38f035c

See more details on using hashes here.

Provenance

The following attestation bundles were made for huckleberry_api-0.4.0.tar.gz:

Publisher: publish.yml on Woyken/py-huckleberry-api

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

File details

Details for the file huckleberry_api-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for huckleberry_api-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d502838dd1b458b47abe0799f0201e6478ca70940fa49c7afcae2571415484b4
MD5 40ebc978e04b35148fc9827f3c108acd
BLAKE2b-256 877db394094bbf07efd17d237913f54525c1546ceed9d1df69fbda199f1f4caa

See more details on using hashes here.

Provenance

The following attestation bundles were made for huckleberry_api-0.4.0-py3-none-any.whl:

Publisher: publish.yml on Woyken/py-huckleberry-api

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