or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# pygatt

1

2

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).

3

4

## Package Information

5

6

- **Package Name**: pygatt

7

- **Language**: Python

8

- **Installation**: `pip install pygatt`

9

- **GATT Tool Backend**: `pip install "pygatt[GATTTOOL]"` (Linux only, requires pexpect)

10

11

## Core Imports

12

13

```python

14

import pygatt

15

```

16

17

Main components:

18

19

```python

20

from pygatt import BGAPIBackend, GATTToolBackend, BLEAddressType, BLEError, BLEDevice

21

from pygatt.backends import Characteristic

22

```

23

24

## Basic Usage

25

26

### BGAPI Backend (Cross-platform)

27

28

```python

29

import pygatt

30

31

# Initialize BGAPI backend for USB dongle (BLED112, etc.)

32

adapter = pygatt.BGAPIBackend()

33

34

try:

35

adapter.start()

36

device = adapter.connect('01:23:45:67:89:ab')

37

38

# Read a characteristic

39

value = device.char_read("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b")

40

print(f"Read value: {value.hex()}")

41

42

# Write to a characteristic

43

device.char_write("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b", bytearray([0x01, 0x02]))

44

45

finally:

46

adapter.stop()

47

```

48

49

### GATTTool Backend (Linux only)

50

51

```python

52

import pygatt

53

54

# Initialize GATTTool backend for BlueZ

55

adapter = pygatt.GATTToolBackend()

56

57

try:

58

adapter.start()

59

device = adapter.connect('01:23:45:67:89:ab')

60

value = device.char_read("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b")

61

finally:

62

adapter.stop()

63

```

64

65

### Notifications and Indications

66

67

```python

68

import pygatt

69

from binascii import hexlify

70

71

adapter = pygatt.GATTToolBackend()

72

73

def handle_data(handle, value):

74

"""

75

Callback function for notifications

76

handle -- integer, characteristic handle

77

value -- bytearray, the notification data

78

"""

79

print(f"Received data on handle {handle}: {hexlify(value)}")

80

81

try:

82

adapter.start()

83

device = adapter.connect('01:23:45:67:89:ab')

84

85

# Subscribe to notifications

86

device.subscribe("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b", callback=handle_data)

87

88

# Keep program running to receive notifications

89

import time

90

while True:

91

time.sleep(1)

92

93

finally:

94

adapter.stop()

95

```

96

97

## Architecture

98

99

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

100

101

- **BLEBackend**: Abstract base class defining the adapter interface

102

- **BLEDevice**: Abstract base class defining the device connection interface

103

- Backend implementations provide concrete implementations for specific hardware/OS combinations

104

- All backends expose the same high-level API for consistent cross-platform development

105

106

## Capabilities

107

108

### Backend Management

109

110

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

111

112

```python { .api }

113

class BLEBackend:

114

def start(self): ...

115

def stop(self): ...

116

def supports_unbonded(self) -> bool: ...

117

def connect(self, address: str, timeout: float = 5.0, **kwargs) -> BLEDevice: ...

118

def scan(self, *args, **kwargs) -> list: ...

119

def filtered_scan(self, name_filter: str = "", *args, **kwargs) -> list: ...

120

def clear_bond(self, address: str = None): ...

121

```

122

123

[Backend Management](./backend-management.md)

124

125

### Device Operations

126

127

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

128

129

```python { .api }

130

class BLEDevice:

131

def bond(self, permanent: bool = False): ...

132

def disconnect(self): ...

133

def get_rssi(self) -> int: ...

134

def char_read(self, uuid: str) -> bytearray: ...

135

def char_read_handle(self, handle: int) -> bytearray: ...

136

def char_read_long(self, uuid: str) -> bytearray: ...

137

def char_read_long_handle(self, handle: int) -> bytearray: ...

138

def char_write(self, uuid: str, value: bytearray, wait_for_response: bool = True): ...

139

def char_write_handle(self, handle: int, value: bytearray, wait_for_response: bool = True): ...

140

def char_write_long(self, uuid: str, value: bytearray, wait_for_response: bool = False): ...

141

def char_write_long_handle(self, handle: int, value: bytearray, wait_for_response: bool = False): ...

142

def subscribe(self, uuid: str, callback=None, indication: bool = False, wait_for_response: bool = True): ...

143

def unsubscribe(self, uuid: str, wait_for_response: bool = True): ...

144

def subscribe_handle(self, handle: int, callback=None, indication: bool = False, wait_for_response: bool = True): ...

145

def unsubscribe_handle(self, handle: int, wait_for_response: bool = True): ...

146

def get_handle(self, char_uuid: str) -> int: ...

147

def discover_characteristics(self) -> dict: ...

148

def exchange_mtu(self, mtu: int) -> int: ...

149

def resubscribe_all(self): ...

150

```

151

152

[Device Operations](./device-operations.md)

153

154

### BGAPI Backend

155

156

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

157

158

```python { .api }

159

class BGAPIBackend(BLEBackend):

160

def __init__(self, serial_port: str = None, receive_queue_timeout: float = 0.1): ...

161

def start(self, reset: bool = True, delay_after_reset_s: float = 1): ...

162

def get_mac(self) -> str: ...

163

def scan(self, timeout: int = 10, scan_interval: int = 75, scan_window: int = 50, active: bool = True, **kwargs): ...

164

def set_bondable(self, bondable: bool): ...

165

def discover_characteristics(self, connection_handle: int, timeout: int = 30) -> dict: ...

166

```

167

168

[BGAPI Backend](./bgapi-backend.md)

169

170

### GATTTool Backend

171

172

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

173

174

```python { .api }

175

class GATTToolBackend(BLEBackend):

176

def __init__(self, hci_device: str = "hci0", gatttool_logfile: str = None, cli_options: list = None, search_window_size: int = None, max_read: int = None): ...

177

def start(self, reset_on_start: bool = True, initialization_timeout: int = 3): ...

178

def scan(self, timeout: int = 10, run_as_root: bool = False) -> list: ...

179

def reset(self): ...

180

def sendline(self, command: str): ...

181

```

182

183

[GATTTool Backend](./gatttool-backend.md)

184

185

### Error Handling

186

187

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

188

189

```python { .api }

190

class BLEError(Exception): ...

191

class NotConnectedError(BLEError): ...

192

class NotificationTimeout(BLEError):

193

def __init__(self, msg: str = None, gatttool_output: str = None): ...

194

class BGAPIError(Exception): ...

195

class ExpectedResponseTimeout(BGAPIError):

196

def __init__(self, expected_packets, timeout): ...

197

```

198

199

[Error Handling](./error-handling.md)

200

201

### Utilities

202

203

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

204

205

```python { .api }

206

def uuid16_to_uuid(uuid16: int) -> UUID: ...

207

def find_usb_serial_devices(vendor_id: int = None, product_id: int = None) -> list: ...

208

def extract_vid_pid(info_string: str) -> tuple: ...

209

```

210

211

[Utilities](./utilities.md)

212

213

## Types

214

215

```python { .api }

216

from enum import Enum

217

from uuid import UUID

218

from collections import defaultdict

219

220

class BLEAddressType(Enum):

221

public = "public"

222

random = "random"

223

224

class Characteristic:

225

def __init__(self, uuid: UUID, handle: int):

226

self.uuid = uuid

227

self.handle = handle

228

self.descriptors = {}

229

230

def add_descriptor(self, uuid: str, handle: int): ...

231

232

class USBSerialDeviceInfo:

233

def __init__(self, device_name: str, port_name: str, vendor_id: int, product_id: int):

234

self.device_name = device_name

235

self.port_name = port_name

236

self.vendor_id = vendor_id

237

self.product_id = product_id

238

```