Skip to main content

🐝 broodminder-data

CI Quality Gate Status License: MIT Python 3.10+ PyPI version OpenAPI 3.1 MCP Ready

Make BroodMinder beehive data easily accessible across diverse consumption use cases — bulk export, periodic delta sync, OpenAPI 3.1, and AI agents via MCP.

broodminder-data provides a unified developer platform for BroodMinder beehive sensor telemetry (internal/ambient temperature, relative humidity, scale weight, swarm indicators, acoustics, radar, and inspection notes). This project provides a published OpenAPI 3.1 specification, a Python CLI and client SDK, and a Model Context Protocol (MCP) server for AI agents.


5 Core Consumption Modalities

                     ┌──────────────────────────────────────────────┐
                     │         BroodMinder Cloud API               │
                     └──────────────────────┬───────────────────────┘
                                            │
                                ┌───────────▼───────────┐
                                │   broodminder-data    │
                                └───────────┬───────────┘
                                            │
         ┌──────────────────┬───────────────┼───────────────┬──────────────────┐
         ▼                  ▼               ▼               ▼                  ▼
  📦 Bulk Export      🔄 Delta Sync   📜 OpenAPI 3.1   🤖 MCP Server    🐍 Python SDK / CLI
  Full history       Incremental     Published spec   Claude, Cursor,   Typed models &
  JSON / CSV / NDJSON catch-up cron   & Redocly docs   Antigravity CLI   scriptable client
  1. 📦 Bulk Historical Export: Walks your entire apiary → hive → device hierarchy with rate-limit-aware, resumable 180-day windowing to extract complete multi-year histories into compressed JSON, NDJSON, and CSV.
  2. 🔄 Periodic Delta Sync: Lightweight, incremental polling engine designed for regular cron or background services, fetching only new readings since the last checkpoint while buffering for late-arriving BLE uploads.
  3. 📜 Published OpenAPI 3.1 Specification: Formal, validated OpenAPI 3.1 contract covering all observed endpoints, query parameters, error responses (including HTTP 412 auth responses), and canonical telemetry schemas.
  4. 🤖 Model Context Protocol (MCP) Server: Native MCP integration (broodminder-mcp) connecting AI agents (Claude Desktop, Antigravity CLI, Cursor, Windsurf, Claude Code) directly to hive metrics, temperature trends, weight deltas, and notes.
  5. 🐍 Unified Python Client Library & CLI: Strongly-typed domain models, offline sandbox mode, and a standalone broodminder CLI.

Architecture Discussions & Roadmap

We are tracking each expanded capability in GitHub Discussions. Join the conversation:


Table of Contents


Features

  • 📦 Complete export — walks every apiary → hive → device and pulls all readings and notes across your entire history.
  • 🔁 Resumable — checkpoints each time window; stop and re-run anytime and it skips what's already fetched.
  • 🚦 Rate-limit-aware — respects the ~1000 calls/day cap, self-throttles, and resumes cleanly after a 429.
  • 🧹 Idempotent outputs — de-duplicates overlapping windows, so re-runs never double-count.
  • 🗜️ Compact — raw and flattened outputs are gzipped (a multi-year, 90-hive account is tens of MB).
  • 📜 OpenAPI 3.1 spec — formal machine-readable API definition with Redocly validation.
  • 🤖 Agent-ready — MCP server architecture for conversational hive analysis and automated inspections.
  • 🧪 Contract-tested — live contract test suite pins the API's real behavior and acts as a canary when upstream changes.
  • 🔌 Reusable client — bm/client.py is transport-clean and easy to lift into a notebook, script, or MCP server.

What You Get

A flattened, analysis-ready row per reading:

field description
apiaryId, apiaryName apiary the hive belongs to
hiveId, hiveName hive identity
positionID, deviceId sensor position + device (deviceId is the unique series key)
timestamp, datetime Unix epoch seconds (UTC) + ISO-8601 string
batteryLevel, chargeRemaining device power (nullable; the two alternate)
m_temperature temperature (all devices)
m_humidity relative humidity (humidity-capable devices)
m_weight scale weight (hives with a scale)
m_swarmState BroodMinder swarm indicator
m_audio acoustic reading (audio-capable devices; unit/scale unconfirmed)
m_radar movement/activity indicator (radar-equipped devices)

Metric presence varies by device type — temperature is near-universal; weight appears only on hives with a scale; audio and radar appear on specialized monitors.


Get an API Key

The External User API is in alpha. Request a key from BroodMinder (support@broodminder.com). The key is tied to your account and only authorizes access to your own data.


Installation

From PyPI

# Core package
pip install broodminder-data

# With Model Context Protocol (MCP) agent support:
pip install "broodminder-data[mcp]"

From Source (Local Development)

git clone https://github.com/petry-projects/broodminder-data.git
cd broodminder-data

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/pip install -e ".[mcp,dev]"

Requires Python 3.10+.


Configuration

cp .env.example .env

Edit .env and paste your key:

BROODMINDER_API_KEY=your-api-key-here
BROODMINDER_BASE_URL=https://external-api.mybroodminder.com

.env is git-ignored and never leaves your machine.


Quickstart Usage

1. Discover Account Topology

Confirm auth and see your apiaries, hives, and a sensor data sample:

.venv/bin/python scripts/discover.py

2. Bulk History Export

Pull historical telemetry (resumable; respects the daily quota):

.venv/bin/python scripts/extract_all.py --start 2025-01-01

Options:

flag default purpose
--start YYYY-MM-DD 2021-01-01 history start
--end YYYY-MM-DD today (UTC) history end
--catchup off resume forward from each hive's latest completed window in manifest.json
--window-days N 180 request window size (API caps at ~6 months)
--apiary NAME|ID all limit to one apiary (repeatable)
--max-calls N 900 stop before this many API calls (daily-cap guard)
--reverse off walk newest→oldest (for backfilling)
--stop-after-empty N 0 with --reverse, stop a hive after N empty windows
--no-notes off skip the notes endpoint

3. Incremental Catch-up Sync

Resume forward from each hive's latest extracted window:

.venv/bin/python scripts/extract_all.py --catchup

4. Build Analysis-Ready Datasets

Convert raw windows into clean, de-duplicated NDJSON and CSV:

.venv/bin/python scripts/flatten.py --merge

5. Inspect Battery Health & Offline Sensors

Identify sensors that have low batteries or stopped reporting:

.venv/bin/python scripts/battery_health.py
# or via entrypoint: broodminder-battery

🔋 Battery Health & Offline Sensor Monitoring

Answers the critical question: "What batteries are low and need to be changed?"

In beehive deployments, two distinct conditions indicate battery replacement or inspection:

  1. Low Battery (<80%): Cold cluster and winter ambient temperatures accelerate coin-cell and alkaline voltage dropoff. Sensors dipping below 80% should be checked or replaced before winter cluster closure.
  2. "Not Reporting" (Silent Dropouts): When a battery fully dies in the field, the sensor simply goes dark. Sensors that have not reported data for more than 7 days are flagged as stale.
# Scan local dataset and show devices needing attention (<80% or >7d stale)
.venv/bin/python scripts/battery_health.py

# Show all devices including healthy ones
.venv/bin/python scripts/battery_health.py --all

# Custom warning thresholds
.venv/bin/python scripts/battery_health.py --threshold 75 --stale-days 5

# Filter by apiary
.venv/bin/python scripts/battery_health.py --apiary "Home"

# Export as JSON or CSV
.venv/bin/python scripts/battery_health.py --format json
.venv/bin/python scripts/battery_health.py --format csv

# Automation/Alerting mode (exits with code 1 if devices need attention)
.venv/bin/python scripts/battery_health.py --check

OpenAPI 3.1 Specification & Interactive Docs

broodminder-data maintains a formal OpenAPI 3.1 specification (also accessible via the root symlink openapi.yaml).

Local Linting & Preview

Using Redocly CLI:

# Lint specification against OpenAPI 3.1 rules
npx @redocly/cli lint openapi.yaml

# Launch interactive documentation preview server
npx @redocly/cli preview-docs openapi.yaml

Model Context Protocol (MCP) Server

Connect your hive data directly to AI agents (Claude Desktop, Antigravity CLI, Cursor, Windsurf, Claude Code):

Agent Configuration (claude_desktop_config.json or mcp.json)

{
  "mcpServers": {
    "broodminder": {
      "command": "python3",
      "args": ["-m", "bm.mcp_server"],
      "env": {
        "BROODMINDER_API_KEY": "your-api-key-here"
      }
    }
  }
}

Core MCP Tools

  • get_apiary_summary: High-level inventory of apiaries, hives, and device counts.
  • get_hive_status: Latest sensor telemetry (brood temperature, ambient temperature, humidity, weight).
  • get_telemetry_trends: Time-series rollups (min, max, mean, delta) over specified lookback windows.
  • get_hive_notes: Recent inspection notes, treatments, and queen observations.
  • get_device_health: Battery levels and sync freshness across sensors.

Python SDK Usage

from bm.client import BroodMinderClient

# Automatically reads BROODMINDER_API_KEY from environment or .env
client = BroodMinderClient()

# List apiaries and hives
apiaries = client.get_apiaries()
for apiary in apiaries:
    print(f"Apiary: {apiary['name']} (ID: {apiary['apiary_id']})")
    hives = client.get_hives(apiary_id=apiary['apiary_id'])
    for hive in hives:
        print(f"  - Hive: {hive['name']}")

# Fetch time-series readings for a device (epoch seconds)
readings = client.get_device_readings(
    device_id="42:11:22:33:44:55",
    start=1704067200,  # 2024-01-01T00:00:00Z
    end=1706745600,    # 2024-02-01T00:00:00Z
)
print(f"Fetched {len(readings)} readings")

PyPI Packaging & Automated Publishing

broodminder-data uses automated, tokenless PyPI Trusted Publishing (OIDC).

1. Tokenless Trusted Publishing Architecture

Releases publish directly from GitHub Actions without storing long-lived, sensitive API tokens:

  • GitHub Actions exchanges its cryptographic OIDC ID token with PyPI for a short-lived upload token.
  • PyPI validates the repository (petry-projects/broodminder-data), workflow (publish.yml), and environment (pypi).

2. Onboarding Steps (First Release Setup)

Before publishing the first release, the account owner registers a Pending Publisher on PyPI:

  1. Log in to pypi.org/manage/account/publishing/.
  2. Under "Add a pending publisher", enter:
    • PyPI Project Name: broodminder-data
    • Owner: petry-projects
    • Repository name: broodminder-data
    • Workflow name: publish.yml
    • Environment name: pypi
  3. Click "Add publisher".

3. Local Onboarding & Verification

Run the onboarding tool to inspect registry availability, build the sdist and wheel, and verify package metadata:

# Probe PyPI status, build sdist/wheel, and run twine verification
python scripts/pypi_onboard.py

4. Automated Publishing Workflow

  • Automated on Merge to main: When a PR bumping the package version in pyproject.toml is merged to main, .github/workflows/publish.yml detects that git tag v<version> does not exist yet, builds and verifies the distribution packages with twine check --strict, publishes to PyPI tokenlessly via Trusted Publishing OIDC, and automatically creates the git tag and GitHub Release with generated release notes.
  • GitHub Release Trigger: Publishing a release manually or via the GitHub UI also triggers .github/workflows/publish.yml.
  • Manual Trigger (with Dry Run): You can run the workflow manually via workflow_dispatch with dry_run: true (default) to test artifact generation without releasing.

Output Files & Schema

Extracted data is saved under data/extract/ (git-ignored):

file contents
raw/<hiveId>/<start>-<end>.readings.json.gz lossless raw responses (replay source)
raw/<hiveId>/<start>-<end>.notes.json.gz lossless raw notes
manifest.json per-window progress + row counts (drives resume)
readings.ndjson.gz one JSON object per reading (analysis-ready)
readings.csv.gz same, columnar
notes.ndjson one object per note
coverage.json per-hive earliest/latest reading + counts

API Behavior & Rate Limits

The machine-readable description is in openapi.yaml. Notable quirks handled automatically:

  • Authentication: X-Api-Key header. Missing or invalid keys return HTTP 412 (not 401/403).
  • Time Windows: Maximum ~6 months per request — auto-chunked.
  • No Pagination: Each window is a single JSON array payload.
  • Rate Limit: ~1,000 calls per UTC day with no Retry-After header — the client tracks calls, self-throttles, and catches 429 responses cleanly.

Testing & Quality Gates

# Run unit & offline tests
.venv/bin/python -m pytest

# Byte-compile verification
python3 -m compileall bm scripts tests
  • Offline tests (tests/test_offline.py, tests/test_scripts_refactor.py): Run fast and hermetically without network access.
  • Live contract tests (tests/test_contract.py): Automatically run when BROODMINDER_API_KEY is present to verify live API compatibility; skip gracefully otherwise.
  • OpenAPI validation: npx @redocly/cli lint openapi.yaml.

Project Structure

broodminder-data/
├── bm/
│   ├── __init__.py
│   └── client.py            # Reusable BroodMinderClient (auth, retry, windowing)
├── scripts/
│   ├── discover.py          # Auth check + account topology/schema sample
│   ├── extract_all.py       # Resumable, budget-aware extraction (--catchup)
│   ├── flatten.py           # Raw → NDJSON/CSV/coverage (--merge)
│   ├── cron_sync.sh         # Routine unattended forward catch-up sync
│   └── cron_backfill.sh     # Initial unattended multi-day backfill
├── tests/
│   ├── conftest.py
│   ├── test_offline.py      # Fast deterministic unit tests
│   ├── test_scripts_refactor.py # Script unit test coverage
│   └── test_contract.py     # Live contract tests (skip without key)
├── openapi/
│   └── broodminder-openapi.yaml # OpenAPI 3.1 specification
├── openapi.yaml -> openapi/broodminder-openapi.yaml # Root symlink
├── redocly.yaml             # Redocly linting & preview configuration
├── requirements.txt         # Runtime dependencies
└── pyproject.toml           # Build configuration & metadata

Privacy & Security

.env (your API key) and data/ (your extracted hive data) are git-ignored and never leave your machine. All test fixtures use synthetic or anonymized values. Please never paste an API key or raw hive telemetry into an issue, PR, or discussion.


Contributing

See CONTRIBUTING.md, SECURITY.md, and the Code of Conduct. Check out open Discussions to weigh in on upcoming features and architectural decisions.


License

MIT © Petry Projects.

Metadata

Release files for broodminder-data 0.1.3

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

Source distribution (sdist)

Source distribution for broodminder-data 0.1.3
File Size Uploaded
broodminder_data-0.1.3.tar.gz 60.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for broodminder-data 0.1.3
File Interpreter ABI Platform
broodminder_data-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 78.0 kB

Release files / broodminder_data-0.1.3.tar.gz

Download URL broodminder_data-0.1.3.tar.gz
Size 60.2 kB
Tags Source
SHA-256 checksum
How to use checksums
5759244cffb4ca5be3f023f00d7bab6b309f81b904b5536e508d4ba72d28e96d
BLAKE2b-256 checksum
How to use checksums
0b32cef87e2029ec53750f7667272a83cb746379b11c51f953205dea6a688ca7
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 Oct 3, 2026.

Transparency log

Release files / broodminder_data-0.1.3-py3-none-any.whl

Download URL broodminder_data-0.1.3-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c5c043e89da5368d636741451388189e4b1b3ac95db369ac237cd6390284f4d
BLAKE2b-256 checksum
How to use checksums
0b32f17ff3cbf79240045160a1f77d7b27ec488e07c6d4bf2ca6ccf4673bedd7
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 Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

2 release files

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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