Skip to main content

BLE Message Bridge

BLE Message Bridge is a small transport layer for sending framed JSON and binary payloads over Bluetooth Low Energy GATT.

It is useful when you want a desktop Python app to talk to an Android device over BLE without rewriting the same plumbing every time:

  • split large payloads into BLE-sized packets;
  • reassemble packets on the other side;
  • gzip larger JSON/text payloads;
  • send compact binary ping/pong heartbeats;
  • reconnect with jittered backoff;
  • use one write characteristic and one notify characteristic for duplex messages.

This library started as the reusable BLE transport extracted from a desktop-to-Android app. The public package is intentionally app-agnostic: it does not know about chat, AI models, prompts, screenshots, or any product-specific message schema.

Install

pip install ble-message-bridge

Quick Start

import asyncio

from ble_message_bridge import BleBridgeClient


def on_event(event: dict) -> None:
    print(event)


async def main() -> None:
    async with BleBridgeClient(event_sink=on_event) as client:
        devices = await client.scan()
        if not devices:
            raise SystemExit("No bridge devices found")

        await client.connect(devices[0].address)
        await client.send_json({"type": "hello", "text": "ciao"})
        await asyncio.sleep(3)


asyncio.run(main())

Custom UUIDs

The defaults are stable UUIDs from the reference Android bridge. For your own app, create your own service and characteristic UUIDs:

from ble_message_bridge import BleBridgeClient, BleBridgeConfig

config = BleBridgeConfig(
    service_uuid="00000000-0000-0000-0000-000000000001",
    write_char_uuid="00000000-0000-0000-0000-000000000002",
    notify_char_uuid="00000000-0000-0000-0000-000000000003",
)

client = BleBridgeClient(config=config)

Events

BleBridgeClient reports everything through an optional event sink:

def on_event(event: dict) -> None:
    match event["type"]:
        case "json":
            print("message", event["message"])
        case "payload":
            print("bytes", event["payload"])
        case "link_quality":
            print("rtt", event.get("rtt_ms"))

Common event types:

  • scan_result
  • connected
  • disconnected
  • sent
  • transfer_progress
  • json
  • payload
  • bundle
  • link_quality
  • link_status
  • error

Android

This repo includes reference Kotlin sources in android/ for an Android BLE peripheral/server that speaks the same framing protocol.

The Android side is not published to Maven yet. For now, copy the small reference classes into your app module, or use them as the basis for your own BLE service.

See docs/android.md.

Protocol

The packet format is intentionally small:

[version:1][transport_id:2][chunk_index:2][chunk_total:2][payload:n]

All integers are big-endian. Payloads larger than one BLE write/notification are split into multiple frames with the same transport_id.

See docs/protocol.md.

Status

0.1.x is alpha. The framing format is simple and tested, but the public API may still evolve while real projects try it.

License

MIT

Metadata

Release files for ble-message-bridge 0.1.1

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

Source distribution (sdist)

Source distribution for ble-message-bridge 0.1.1
File Size Uploaded
ble_message_bridge-0.1.1.tar.gz 18.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ble-message-bridge 0.1.1
File Interpreter ABI Platform
ble_message_bridge-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 29.8 kB

Release files / ble_message_bridge-0.1.1.tar.gz

Download URL ble_message_bridge-0.1.1.tar.gz
Size 18.5 kB
Tags Source
SHA-256 checksum
How to use checksums
66d84c44061264a7f48599becd32b91295d25724ca4b3ef3bfd2dc5997aaeb43
BLAKE2b-256 checksum
How to use checksums
d166a4a5d34a11e2e49f68a0fd6ca0a30a9537b30ceb951a370ab72a42fcd351
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Apr 27, 2026.

Transparency log

Release files / ble_message_bridge-0.1.1-py3-none-any.whl

Download URL ble_message_bridge-0.1.1-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9d5415188f13910a8890f8f9c213eec254e975d0c90ce7ca5dced39c9a8d3967
BLAKE2b-256 checksum
How to use checksums
799975ecdf4b2f0e51d94464a5b49e7c3109f3ab5341036f64a50c619c0fd456
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Apr 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

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