Import Patterns¶
This guide shows you how to import the parts of bluetooth-sig you need for different tasks.
Quick Reference¶
Import the primary API for most tasks:
from bluetooth_sig import BluetoothSIGTranslator, Device
For Device usage, you also need a connection manager:
from examples.connection_managers.bleak_retry import (
BleakRetryClientManager,
)
Import from submodules when you need specific features:
from bluetooth_sig.advertising import AdvertisingPDUParser
from bluetooth_sig.gatt.characteristics import BatteryLevelCharacteristic
Choosing an Import Path¶
You pay for what you import. The library loads individual characteristic and service implementations on first use, so you can keep startup lean when you only need parsing.
Start with the top-level API unless you have a reason not to:
from bluetooth_sig import BluetoothSIGTranslator
Use a submodule import when you need a specific feature (advertising, a named characteristic class, or the device layer):
from bluetooth_sig.advertising import AdvertisingPDUParser
from bluetooth_sig.gatt.characteristics import BatteryLevelCharacteristic
from bluetooth_sig import Device
If you integrate inside an async host (for example Home Assistant) and want to avoid
blocking I/O on the first parse, see Performance Tuning for
how to call :func:~bluetooth_sig.utils.prewarm.prewarm_registries during setup.
Named characteristic imports still work as before. Accessing
BatteryLevelCharacteristic for the first time loads only that module, not the full
characteristic catalogue.
How to Import for Common Tasks¶
Task: Parse characteristic data (type-safe)¶
Import the characteristic class directly for full type inference:
from bluetooth_sig.gatt.characteristics import BatteryLevelCharacteristic
battery = BatteryLevelCharacteristic()
level = battery.parse_value(bytearray([85])) # IDE knows: int
encoded = battery.build_value(85) # Encode back to bytes
Task: Parse unknown characteristics (dynamic)¶
Use the Translator when scanning unknown devices:
from bluetooth_sig import BluetoothSIGTranslator
translator = BluetoothSIGTranslator()
# UUID and data from device discovery (replace with actual BLE reads)
uuid = "2A19" # Battery Level
raw_data = bytearray([75])
value = translator.parse_characteristic(uuid, raw_data)
info = translator.get_characteristic_info_by_uuid(uuid)
print(f"{info.name}: {value}") # Battery Level: 75
Task: Parse advertising packets¶
Import from the advertising module:
from bluetooth_sig.advertising import AdvertisingPDUParser
parser = AdvertisingPDUParser()
raw_adv_bytes = bytearray([0x02, 0x01, 0x06]) # Example advertising data
adv_data = parser.parse_advertising_data(raw_adv_bytes)
Task: Work with multiple characteristics (type-safe)¶
Import characteristic classes for full IDE support:
from bluetooth_sig.gatt.characteristics import (
BatteryLevelCharacteristic,
BodySensorLocationCharacteristic,
HeartRateMeasurementCharacteristic,
)
# Example data (replace with actual BLE reads)
hr_bytes = bytearray([0x00, 75]) # Heart rate 75 bpm
loc_bytes = bytearray([0x01]) # Chest location
bat_bytes = bytearray([85]) # 85% battery
hr_char = HeartRateMeasurementCharacteristic()
sensor_char = BodySensorLocationCharacteristic()
battery_char = BatteryLevelCharacteristic()
# All have full type inference
hr_data = hr_char.parse_value(hr_bytes) # HeartRateData
location = sensor_char.parse_value(loc_bytes) # int
level = battery_char.parse_value(bat_bytes) # int
Task: Add type hints to your code¶
Import the data types you need. The library returns parsed values directly, so type hints use the actual value types:
from bluetooth_sig.gatt.characteristics import (
HeartRateMeasurementCharacteristic,
)
# Example data (replace with actual BLE reads)
raw_bytes = bytearray([0x00, 72]) # Heart rate 72 bpm
# Type annotations use the characteristic's return type
hr_char = HeartRateMeasurementCharacteristic()
hr_data = hr_char.parse_value(raw_bytes) # IDE knows: HeartRateData
# For dynamic parsing, return type is Any
from bluetooth_sig import BluetoothSIGTranslator
translator = BluetoothSIGTranslator()
uuid = "2A37"
data = bytearray([0x00, 72])
value = translator.parse_characteristic(uuid, data) # Returns Any
Task: Use the Device abstraction (type-safe)¶
Import Device with characteristic classes:
# SKIP: Requires async context and BLE hardware
from bluetooth_sig import Device
from bluetooth_sig.gatt.characteristics import BatteryLevelCharacteristic
from examples.connection_managers.bleak_retry import (
BleakRetryClientManager,
)
connection_manager = BleakRetryClientManager("AA:BB:CC:DD:EE:FF")
device = Device(connection_manager)
# Type-safe read - IDE knows level is int
battery = BatteryLevelCharacteristic()
level = await device.read_characteristic(battery)
Task: Use the Device abstraction (dynamic)¶
Import Device with Translator for unknown devices:
# SKIP: Requires async context and BLE hardware
from bluetooth_sig import BluetoothSIGTranslator, Device
from examples.connection_managers.bleak_retry import (
BleakRetryClientManager,
)
translator = BluetoothSIGTranslator()
connection_manager = BleakRetryClientManager("AA:BB:CC:DD:EE:FF")
device = Device(connection_manager, translator)
# Dynamic read - returns CharacteristicData with Any value
uuid_from_discovery = "2A19" # Example: Battery Level from service discovery
result = await device.read_characteristic_by_uuid(uuid_from_discovery)
Task: Work with registries programmatically¶
Import from the registry module:
from bluetooth_sig import BluetoothSIGTranslator
translator = BluetoothSIGTranslator()
char_uuid = translator.get_characteristic_uuid_by_name("Battery Level")
Task: Create a custom characteristic¶
Import base classes:
from bluetooth_sig.gatt.characteristics.base import BaseCharacteristic
from bluetooth_sig.types.data_types import CharacteristicInfo
class MyCustomCharacteristic(BaseCharacteristic):
_info = CharacteristicInfo(
uuid="12345678-1234-5678-1234-56789abcdef0",
name="My Custom Characteristic",
)
What’s Available at Each Level¶
Top level (from bluetooth_sig import X)¶
The primary API and essential types. Importing here loads the translator and shared infrastructure, but not every characteristic implementation:
BluetoothSIGTranslator- Main parsing APIAsyncParsingSession- Async context managerDevice- High-level device abstractionCharacteristicData- Return type for parsed dataCharacteristicInfo- Characteristic metadataServiceInfo- Service metadataValidationResult- Validation resultsSIGInfo- SIG standard infoprewarm_registries- Optional eager registry loading for production hosts__version__- Package version
Submodules (explicit imports)¶
Import from specific modules as needed:
Advertising: bluetooth_sig.advertising
AdvertisingPDUParserAdvertisingDataInterpreterAdvertisingInterpreterRegistry
Characteristics: bluetooth_sig.gatt.characteristics
All characteristic classes (for example
BatteryLevelCharacteristic) — loaded on first access
Services: bluetooth_sig.gatt.services
All service classes (e.g.,
BatteryService)
Registries: bluetooth_sig.registry
UUID resolution utilities
YAML cross-reference system
Base classes (for extending): bluetooth_sig.gatt.characteristics.base
BaseCharacteristicBaseGattService
Connection managers (from examples): examples.connection_managers
BleakRetryClientManager- Bleak-based async manager with retry logicSimplePyBLEConnectionManager- SimplePyBLE synchronous adapterBluePyConnectionManager- BluePy adapter
These implement ConnectionManagerProtocol and are required for Device usage.
Troubleshooting Imports¶
Problem: ImportError: cannot import name 'AdvertisingPDUParser'
Solution: Use explicit submodule import:
from bluetooth_sig.advertising import AdvertisingPDUParser
Problem: Need to find where a class lives
Solution: Check the module structure:
Advertising →
bluetooth_sig.advertisingCharacteristics →
bluetooth_sig.gatt.characteristicsServices →
bluetooth_sig.gatt.servicesDevice →
bluetooth_sig.deviceRegistries →
bluetooth_sig.registry
Best Practices¶
Start simple: Begin with
BluetoothSIGTranslatorfrom the top levelImport what you need: Only import from submodules when necessary
No wildcards: Avoid
from bluetooth_sig import *Group logically: Keep standard library, third-party, and bluetooth-sig imports separated
Be explicit: Clear imports make code easier to understand and maintain
Best Practices¶
Start with the primary API: Always begin with
BluetoothSIGTranslatorat the top levelImport what you use: Only import from submodules when you need specific features
Use type hints: Import data types (
CharacteristicInfo, etc.) for better type checkingAvoid wildcards: Never use
from bluetooth_sig import *- be explicit about what you’re importingGroup imports logically:
# Standard library
import asyncio
# Third-party
from bleak import BleakClient
# bluetooth-sig primary API
from bluetooth_sig import BluetoothSIGTranslator, CharacteristicInfo
# bluetooth-sig submodules
from bluetooth_sig.advertising import AdvertisingPDUParser
from bluetooth_sig.gatt.characteristics import (
HeartRateMeasurementCharacteristic,
)
Related Documentation¶
Usage Guide - Complete usage examples
Migration Guide - Upgrading from earlier versions
API Reference - Complete API documentation
Architecture Overview - Understanding the design (for context on why imports are structured this way)