or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-transfers.mddescriptors.mddevice-access.mdindex.mdsync-transfers.mdusb-context.md

usb-context.mddocs/

0

# USB Context Management

1

2

The USBContext class provides the entry point for all USB operations, managing system resources, device enumeration, and global USB settings. All USB operations require an active context, which handles low-level libusb-1.0 initialization and cleanup.

3

4

## Capabilities

5

6

### Context Creation and Lifecycle

7

8

Create and manage USB contexts with optional configuration for logging, Windows backend selection, and device discovery behavior.

9

10

```python { .api }

11

class USBContext:

12

def __init__(self, log_level=None, use_usbdk=False, with_device_discovery=True, log_callback=None):

13

"""

14

Create a new USB context.

15

16

Args:

17

log_level: Log level constant (LOG_LEVEL_NONE, LOG_LEVEL_ERROR, etc.)

18

use_usbdk (bool): Windows only - use UsbDk backend if available

19

with_device_discovery (bool): Linux only - enable device scan during init

20

log_callback: Function accepting (context, level, message) for log messages

21

"""

22

23

def __enter__(self):

24

"""Context manager entry - initializes the context."""

25

26

def __exit__(self, exc_type, exc_val, exc_tb):

27

"""Context manager exit - closes the context."""

28

29

def open(self):

30

"""

31

Finish context initialization manually.

32

33

Returns:

34

USBContext: Self for method chaining

35

"""

36

37

def close(self):

38

"""Close and destroy the USB context, releasing all resources."""

39

```

40

41

### Device Enumeration

42

43

Discover and iterate over USB devices connected to the system with flexible filtering and error handling options.

44

45

```python { .api }

46

def getDeviceIterator(self, skip_on_error=False):

47

"""

48

Return iterator over all USB devices currently connected.

49

50

Args:

51

skip_on_error (bool): If True, ignore devices that raise USBError

52

53

Yields:

54

USBDevice: Device instances for each connected device

55

"""

56

57

def getDeviceList(self, skip_on_access_error=False, skip_on_error=False):

58

"""

59

Return list of all USB devices currently connected.

60

61

Args:

62

skip_on_error (bool): If True, ignore devices that raise USBError

63

skip_on_access_error (bool): Deprecated alias for skip_on_error

64

65

Returns:

66

list[USBDevice]: List of device instances

67

"""

68

69

def getByVendorIDAndProductID(self, vendor_id, product_id, skip_on_access_error=False, skip_on_error=False):

70

"""

71

Find first device matching vendor and product IDs.

72

73

Args:

74

vendor_id (int): USB vendor ID (16-bit)

75

product_id (int): USB product ID (16-bit)

76

skip_on_error (bool): If True, ignore devices that raise USBError

77

skip_on_access_error (bool): Deprecated alias for skip_on_error

78

79

Returns:

80

USBDevice or None: Device instance or None if not found

81

"""

82

83

def openByVendorIDAndProductID(self, vendor_id, product_id, skip_on_access_error=False, skip_on_error=False):

84

"""

85

Find and open first device matching vendor and product IDs.

86

87

Args:

88

vendor_id (int): USB vendor ID (16-bit)

89

product_id (int): USB product ID (16-bit)

90

skip_on_error (bool): If True, ignore devices that raise USBError

91

skip_on_access_error (bool): Deprecated alias for skip_on_error

92

93

Returns:

94

USBDeviceHandle or None: Opened device handle or None if not found

95

"""

96

```

97

98

### Event Handling

99

100

Handle USB events for asynchronous operations with timeout control and interrupt capabilities.

101

102

```python { .api }

103

def handleEvents(self):

104

"""Handle pending USB events (blocking with internal timeout)."""

105

106

def handleEventsTimeout(self, tv=0):

107

"""

108

Handle pending USB events with specified timeout.

109

110

Args:

111

tv (float): Timeout in seconds, 0 for immediate return

112

"""

113

114

def interruptEventHandler(self):

115

"""Interrupt active event handling thread."""

116

117

def getNextTimeout(self):

118

"""

119

Get next internal timeout libusb needs to handle.

120

121

Returns:

122

float or None: Timeout in seconds or None if no timeout needed

123

"""

124

```

125

126

### Hotplug Device Detection

127

128

Register callbacks for USB device connection and disconnection events with flexible filtering options.

129

130

```python { .api }

131

def hotplugRegisterCallback(self, callback, events=HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT,

132

flags=HOTPLUG_ENUMERATE, vendor_id=HOTPLUG_MATCH_ANY,

133

product_id=HOTPLUG_MATCH_ANY, dev_class=HOTPLUG_MATCH_ANY):

134

"""

135

Register hotplug callback for device arrival/departure events.

136

137

Args:

138

callback: Function accepting (context, device, event) returning bool

139

events (int): Event mask (HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT)

140

flags (int): Callback flags (HOTPLUG_ENUMERATE to get existing devices)

141

vendor_id (int): Vendor ID filter or HOTPLUG_MATCH_ANY

142

product_id (int): Product ID filter or HOTPLUG_MATCH_ANY

143

dev_class (int): Device class filter or HOTPLUG_MATCH_ANY

144

145

Returns:

146

int: Opaque handle for hotplugDeregisterCallback

147

148

Note:

149

Callback must return True to unregister, False to stay registered.

150

Callback cannot call synchronous libusb functions.

151

"""

152

153

def hotplugDeregisterCallback(self, handle):

154

"""

155

Deregister hotplug callback.

156

157

Args:

158

handle (int): Handle returned by hotplugRegisterCallback

159

"""

160

```

161

162

### System Device Wrapping

163

164

Wrap existing system device file descriptors for USB communication without device enumeration.

165

166

```python { .api }

167

def wrapSysDevice(self, sys_device):

168

"""

169

Wrap system device file descriptor as USBDeviceHandle.

170

171

Args:

172

sys_device: File object or file descriptor of sys device node

173

174

Returns:

175

USBDeviceHandle: Handle for wrapped device

176

177

Note:

178

Keep the file open while using the device handle.

179

"""

180

```

181

182

### Advanced Event Loop Integration

183

184

Low-level file descriptor polling support for integration with select/poll-based event loops.

185

186

```python { .api }

187

def getPollFDList(self):

188

"""

189

Get file descriptors for USB event polling.

190

191

Returns:

192

list[tuple]: List of (fd, events) tuples for polling

193

194

Raises:

195

NotImplementedError: If libusb doesn't support pollable FDs

196

"""

197

198

def setPollFDNotifiers(self, added_cb=None, removed_cb=None, user_data=None):

199

"""

200

Set callbacks for file descriptor addition/removal.

201

202

Args:

203

added_cb: Function called when FD is added: (fd, events, user_data)

204

removed_cb: Function called when FD is removed: (fd, user_data)

205

user_data: User data passed to callbacks

206

"""

207

```

208

209

### Logging and Debugging

210

211

Configure context-specific logging and debug output for troubleshooting USB operations.

212

213

```python { .api }

214

def setLogCallback(self, log_callback):

215

"""

216

Set context-specific log callback.

217

218

Args:

219

log_callback: Function accepting (context, level, message) or None to disable

220

"""

221

222

def setDebug(self, level):

223

"""

224

Set debug level for this context.

225

226

Args:

227

level (int): Log level constant (LOG_LEVEL_NONE through LOG_LEVEL_DEBUG)

228

"""

229

```

230

231

## Usage Examples

232

233

### Basic Context Usage

234

235

```python

236

import usb1

237

238

# Simple context manager usage

239

with usb1.USBContext() as context:

240

devices = context.getDeviceList()

241

print(f"Found {len(devices)} USB devices")

242

243

# Manual context management

244

context = usb1.USBContext()

245

context.open()

246

try:

247

device = context.getByVendorIDAndProductID(0x1234, 0x5678)

248

if device:

249

print(f"Found device: {device}")

250

finally:

251

context.close()

252

```

253

254

### Device Enumeration with Error Handling

255

256

```python

257

import usb1

258

259

with usb1.USBContext() as context:

260

# Iterate with automatic error skipping

261

for device in context.getDeviceIterator(skip_on_error=True):

262

try:

263

print(f"Device {device.getVendorID():04x}:{device.getProductID():04x}")

264

print(f" Manufacturer: {device.getManufacturer()}")

265

print(f" Product: {device.getProduct()}")

266

except usb1.USBError as e:

267

print(f" Error accessing device: {e}")

268

```

269

270

### Hotplug Event Monitoring

271

272

```python

273

import usb1

274

import threading

275

import time

276

277

def hotplug_callback(context, device, event):

278

if event == usb1.HOTPLUG_EVENT_DEVICE_ARRIVED:

279

print(f"Device connected: {device.getVendorID():04x}:{device.getProductID():04x}")

280

elif event == usb1.HOTPLUG_EVENT_DEVICE_LEFT:

281

print(f"Device disconnected: {device.getVendorID():04x}:{device.getProductID():04x}")

282

return False # Keep callback registered

283

284

with usb1.USBContext() as context:

285

# Register hotplug callback

286

handle = context.hotplugRegisterCallback(hotplug_callback)

287

288

# Event handling loop

289

try:

290

while True:

291

context.handleEventsTimeout(1.0) # 1 second timeout

292

except KeyboardInterrupt:

293

print("Stopping...")

294

finally:

295

context.hotplugDeregisterCallback(handle)

296

```

297

298

### Event Loop Integration

299

300

```python

301

import usb1

302

import select

303

304

with usb1.USBContext() as context:

305

# Get file descriptors for polling

306

try:

307

poll_fds = context.getPollFDList()

308

print(f"Monitoring {len(poll_fds)} file descriptors")

309

310

# Integration with select

311

read_fds = [fd for fd, events in poll_fds if events & select.POLLIN]

312

write_fds = [fd for fd, events in poll_fds if events & select.POLLOUT]

313

314

# Poll with timeout

315

ready_read, ready_write, _ = select.select(read_fds, write_fds, [], 1.0)

316

317

if ready_read or ready_write:

318

context.handleEventsTimeout(0) # Process immediately

319

320

except NotImplementedError:

321

print("Platform doesn't support pollable file descriptors")

322

# Fall back to timeout-based event handling

323

context.handleEventsTimeout(1.0)

324

```