# Bleak Retry Connector

<p align="center">
  <a href="https://github.com/bluetooth-devices/bleak-retry-connector/actions?query=workflow%3ACI">
    <img src="https://img.shields.io/github/actions/workflow/status/bluetooth-devices/bleak-retry-connector/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
  </a>
  <a href="https://bleak-retry-connector.readthedocs.io">
    <img src="https://img.shields.io/readthedocs/bleak-retry-connector.svg?logo=read-the-docs&logoColor=fff&style=flat-square" alt="Documentation Status">
  </a>
  <a href="https://codecov.io/gh/bluetooth-devices/bleak-retry-connector">
    <img src="https://img.shields.io/codecov/c/github/bluetooth-devices/bleak-retry-connector.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
  </a>
</p>
<p align="center">
  <a href="https://python-poetry.org/">
    <img src="https://img.shields.io/badge/packaging-poetry-299bd7?style=flat-square&logo=data:image/png;base64, " alt="Poetry">
  </a>
  <a href="https://github.com/astral-sh/ruff">
    <img src="https://img.shields.io/badge/code%20style-ruff-000000.svg?style=flat-square" alt="ruff">
  </a>
  <a href="https://github.com/pre-commit/pre-commit">
    <img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
  </a>
</p>
<p align="center">
  <a href="https://pypi.org/project/bleak-retry-connector/">
    <img src="https://img.shields.io/pypi/v/bleak-retry-connector.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
  </a>
  <img src="https://img.shields.io/pypi/pyversions/bleak-retry-connector.svg?style=flat-square&logo=python&amp;logoColor=fff" alt="Supported Python versions">
  <img src="https://img.shields.io/pypi/l/bleak-retry-connector.svg?style=flat-square" alt="License">
</p>

A connector for Bleak Clients that handles transient connection failures

## Installation

Install this via pip (or your favourite package manager):

`pip install bleak-retry-connector`

## Usage

### Quick Start

Replace your direct `BleakClient.connect()` calls with `establish_connection()` for automatic retry logic and better error handling:

```python
import asyncio
from bleak import BleakScanner
from bleak_retry_connector import establish_connection, BleakClientWithServiceCache

async def connect_to_device():
    # Find your device
    device = await BleakScanner.find_device_by_address("AA:BB:CC:DD:EE:FF")

    if device is None:
        print("Device not found!")
        return

    # Establish connection with automatic retry logic
    client = await establish_connection(
        BleakClientWithServiceCache,  # Use BleakClientWithServiceCache for service caching
        device,
        device.name or "Unknown Device",
        max_attempts=3  # Will retry up to 3 times with backoff
    )

    try:
        # Use the connected client normally
        services = client.services
        print(f"Connected! Found {len(list(services))} services")

        # Read a characteristic
        value = await client.read_gatt_char("00002a00-0000-1000-8000-00805f9b34fb")
        print(f"Read value: {value}")

    finally:
        await client.disconnect()

# Run the example
asyncio.run(connect_to_device())
```

### Why Use bleak-retry-connector?

- **Automatic Retry Logic**: Handles transient connection failures automatically
- **Intelligent Backoff**: Uses appropriate delays between retry attempts
- **Service Caching**: `BleakClientWithServiceCache` caches services for faster reconnections
- **Better Error Messages**: Provides clear, actionable error messages
- **Platform-Specific Handling**: Manages quirks across different operating systems
- **Connection Slot Management**: Handles limited connection slots on some devices

### Common Connection Issues This Solves

- Device not found errors that resolve on retry
- Connection timeouts on first attempt
- "Out of connection slots" errors on ESP32 devices
- Interference from other Bluetooth operations
- Platform-specific connection quirks

For detailed documentation and advanced usage, see the [full documentation](https://bleak-retry-connector.readthedocs.io/en/latest/usage.html).

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- prettier-ignore-start -->
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
<!-- prettier-ignore-end -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

## Credits

This package was created with
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
[browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage)
project template.
