or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

backend-management.mdbgapi-backend.mddevice-operations.mderror-handling.mdgatttool-backend.mdindex.mdutilities.md
tile.json

tessl/pypi-pygatt

Python Bluetooth LE (Low Energy) and GATT Library providing cross-platform BLE operations with multiple backends

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pygatt@5.0.x

To install, run

npx @tessl/cli install tessl/pypi-pygatt@5.0.0

index.mddocs/

pygatt

Python Bluetooth LE (Low Energy) and GATT Library that provides a Pythonic API for reading and writing GATT descriptors on BLE devices such as fitness trackers, sensors, and standard GATT-compliant devices. The library wraps two different backends to provide cross-platform compatibility: BlueZ (Linux-based using gatttool) and Bluegiga's BGAPI (compatible with USB adapters like BLED112).

Package Information

  • Package Name: pygatt
  • Language: Python
  • Installation: pip install pygatt
  • GATT Tool Backend: pip install "pygatt[GATTTOOL]" (Linux only, requires pexpect)

Core Imports

import pygatt

Main components:

from pygatt import BGAPIBackend, GATTToolBackend, BLEAddressType, BLEError, BLEDevice
from pygatt.backends import Characteristic

Basic Usage

BGAPI Backend (Cross-platform)

import pygatt

# Initialize BGAPI backend for USB dongle (BLED112, etc.)
adapter = pygatt.BGAPIBackend()

try:
    adapter.start()
    device = adapter.connect('01:23:45:67:89:ab')
    
    # Read a characteristic
    value = device.char_read("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b")
    print(f"Read value: {value.hex()}")
    
    # Write to a characteristic
    device.char_write("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b", bytearray([0x01, 0x02]))
    
finally:
    adapter.stop()

GATTTool Backend (Linux only)

import pygatt

# Initialize GATTTool backend for BlueZ
adapter = pygatt.GATTToolBackend()

try:
    adapter.start()
    device = adapter.connect('01:23:45:67:89:ab')
    value = device.char_read("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b")
finally:
    adapter.stop()

Notifications and Indications

import pygatt
from binascii import hexlify

adapter = pygatt.GATTToolBackend()

def handle_data(handle, value):
    """
    Callback function for notifications
    handle -- integer, characteristic handle
    value -- bytearray, the notification data
    """
    print(f"Received data on handle {handle}: {hexlify(value)}")

try:
    adapter.start()
    device = adapter.connect('01:23:45:67:89:ab')
    
    # Subscribe to notifications
    device.subscribe("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b", callback=handle_data)
    
    # Keep program running to receive notifications
    import time
    while True:
        time.sleep(1)
        
finally:
    adapter.stop()

Architecture

pygatt uses a backend abstraction pattern to support different BLE communication methods:

  • BLEBackend: Abstract base class defining the adapter interface
  • BLEDevice: Abstract base class defining the device connection interface
  • Backend implementations provide concrete implementations for specific hardware/OS combinations
  • All backends expose the same high-level API for consistent cross-platform development

Capabilities

Backend Management

Core backend lifecycle and configuration operations for initializing and managing BLE adapters.

class BLEBackend:
    def start(self): ...
    def stop(self): ...
    def supports_unbonded(self) -> bool: ...
    def connect(self, address: str, timeout: float = 5.0, **kwargs) -> BLEDevice: ...
    def scan(self, *args, **kwargs) -> list: ...
    def filtered_scan(self, name_filter: str = "", *args, **kwargs) -> list: ...
    def clear_bond(self, address: str = None): ...

Backend Management

Device Operations

Core BLE device connection operations including characteristic reading, writing, and subscription management.

class BLEDevice:
    def bond(self, permanent: bool = False): ...
    def disconnect(self): ...
    def get_rssi(self) -> int: ...
    def char_read(self, uuid: str) -> bytearray: ...
    def char_read_handle(self, handle: int) -> bytearray: ...
    def char_read_long(self, uuid: str) -> bytearray: ...
    def char_read_long_handle(self, handle: int) -> bytearray: ...
    def char_write(self, uuid: str, value: bytearray, wait_for_response: bool = True): ...
    def char_write_handle(self, handle: int, value: bytearray, wait_for_response: bool = True): ...
    def char_write_long(self, uuid: str, value: bytearray, wait_for_response: bool = False): ...
    def char_write_long_handle(self, handle: int, value: bytearray, wait_for_response: bool = False): ...
    def subscribe(self, uuid: str, callback=None, indication: bool = False, wait_for_response: bool = True): ...
    def unsubscribe(self, uuid: str, wait_for_response: bool = True): ...
    def subscribe_handle(self, handle: int, callback=None, indication: bool = False, wait_for_response: bool = True): ...
    def unsubscribe_handle(self, handle: int, wait_for_response: bool = True): ...
    def get_handle(self, char_uuid: str) -> int: ...
    def discover_characteristics(self) -> dict: ...
    def exchange_mtu(self, mtu: int) -> int: ...
    def resubscribe_all(self): ...

Device Operations

BGAPI Backend

BGAPI-specific backend implementation for USB dongles with advanced configuration options and low-level protocol access.

class BGAPIBackend(BLEBackend):
    def __init__(self, serial_port: str = None, receive_queue_timeout: float = 0.1): ...
    def start(self, reset: bool = True, delay_after_reset_s: float = 1): ...
    def get_mac(self) -> str: ...
    def scan(self, timeout: int = 10, scan_interval: int = 75, scan_window: int = 50, active: bool = True, **kwargs): ...
    def set_bondable(self, bondable: bool): ...
    def discover_characteristics(self, connection_handle: int, timeout: int = 30) -> dict: ...

BGAPI Backend

GATTTool Backend

GATTTool-specific backend implementation for Linux BlueZ with CLI integration and advanced debugging capabilities.

class GATTToolBackend(BLEBackend):
    def __init__(self, hci_device: str = "hci0", gatttool_logfile: str = None, cli_options: list = None, search_window_size: int = None, max_read: int = None): ...
    def start(self, reset_on_start: bool = True, initialization_timeout: int = 3): ...
    def scan(self, timeout: int = 10, run_as_root: bool = False) -> list: ...
    def reset(self): ...
    def sendline(self, command: str): ...

GATTTool Backend

Error Handling

Exception classes and error management for comprehensive BLE error handling and debugging.

class BLEError(Exception): ...
class NotConnectedError(BLEError): ...
class NotificationTimeout(BLEError):
    def __init__(self, msg: str = None, gatttool_output: str = None): ...
class BGAPIError(Exception): ...
class ExpectedResponseTimeout(BGAPIError):
    def __init__(self, expected_packets, timeout): ...

Error Handling

Utilities

Utility functions and classes for UUID conversion, device discovery, and USB serial device management.

def uuid16_to_uuid(uuid16: int) -> UUID: ...
def find_usb_serial_devices(vendor_id: int = None, product_id: int = None) -> list: ...
def extract_vid_pid(info_string: str) -> tuple: ...

Utilities

Types

from enum import Enum
from uuid import UUID
from collections import defaultdict

class BLEAddressType(Enum):
    public = "public"
    random = "random"

class Characteristic:
    def __init__(self, uuid: UUID, handle: int):
        self.uuid = uuid
        self.handle = handle
        self.descriptors = {}
    
    def add_descriptor(self, uuid: str, handle: int): ...

class USBSerialDeviceInfo:
    def __init__(self, device_name: str, port_name: str, vendor_id: int, product_id: int):
        self.device_name = device_name
        self.port_name = port_name
        self.vendor_id = vendor_id
        self.product_id = product_id