CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pygatt

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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

docs

backend-management.md

bgapi-backend.md

device-operations.md

error-handling.md

gatttool-backend.md

index.md

utilities.md

tile.json