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 (formerly broodminder-export) provides a unified developer platform for BroodMinder beehive sensor telemetry (internal/ambient temperature, relative humidity, scale weight, swarm indicators, acoustics, radar, and inspection notes). Similar to empower-personal-dashboard, 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

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 adopts the automated, tokenless PyPI Trusted Publishing (OIDC) approach pioneered in don-petry/brand-ops.

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

  • Automatic: Creating a GitHub Release automatically builds and publishes packages to PyPI via .github/workflows/publish.yml.
  • Manual Trigger (with Dry Run): You can also 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.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 broodminder-data 0.1.0
File Size Uploaded
broodminder_data-0.1.0.tar.gz 49.2 kB Details

Built distribution (wheel)

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

Total release size: 61.1 kB

Release files / broodminder_data-0.1.0.tar.gz

Download URL broodminder_data-0.1.0.tar.gz
Size 49.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1ed7cb98f2a6b7524aa179bbc929d280630ec81490276977a6811c7cfafb4220
BLAKE2b-256 checksum
How to use checksums
0aba0e5c4c78f527b55323b03f65517a6d3f74eae5d958447e689d24f2aba029
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 2, 2026.

Transparency log

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

Download URL broodminder_data-0.1.0-py3-none-any.whl
Size 11.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a833fb3e7c8a5e17f3206903a9d01dcd8660439c97d752f0071f08f9becdc85
BLAKE2b-256 checksum
How to use checksums
c0e1bded2f2f7a25ea89c1558c1a8e9c5012d6dc724a30aa1c3080f6cdbf0e2c
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 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

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