How to Find All Bluetooth LE Devices Near You with a MacBook and Python
Use code to see into the “Internet of Things” matrix.
TLDR version of this article available here.
If you’re sitting in your living room, chances are you’re surrounded by tech: smart watches, home assistants, smart lightbulbs, smart ovens, and the like. If you don’t, your neighbors have their own dozen or so devices. Did you know that you can use code to find all of them on your computer?
In this tutorial, we’ll write some Python code to look for (AKA “scan” for) all of the Bluetooth LE devices near you. Our end product will be a 20-line piece of code called a “Bluetooth scanner.”
Bluetooth LE (Low Energy) is a lightweight protocol used for most modern “Internet of Things” devices and wearables. If you’ve ever connected your phone to a heart rate monitor, you were probably using Bluetooth LE.
Note: This tutorial excludes finding devices like headphones. These devices actually use “Bluetooth Classic,” which is like Bluetooth LE, but can handle heavier data, like music. Bluetooth LE code does not work with and can’t find Bluetooth Classic devices.
A Windows version of this tutorial is available here as well as a condensed version with code only.

Requirements
- Mac OS 12.x+
- Python 3
- Bleak (a Python Bluetooth LE library)
- Bluetooth LE devices within 20–100 meters of you
Overall Steps to Making a Scanner
The pieces to this project are going to be:
- Installing Bleak, a popular Bluetooth LE library for Python.
- Using Bleak’s
discover()function to find all nearby Bluetooth LE devices. - Using Bleak to then ask each Bluetooth device more specific info about itself (i.e., what it can do, like capturing heart rates, etc.)
If you’re looking to connect to a single Bluetooth LE device or are looking for more background on how Bluetooth LE works, check out our other article here.
Why We Need “Bleak”
Bleak is a Bluetooth LE library for Python. It handles all of the messy code and logic that is required for Macs to talk to Bluetooth.
Without it, we’d have to write about 1000 lines of code to talk to our Mac’s Bluetooth module. Contrast that with writing 1–2 lines to install and import Bleak into our code, then 10 or so more lines to get it to find Bluetooth devices. You can see Bleak’s underlying code here.
Installing Bleak
To use Bleak, we have to install it then import it into our code. We install it once, then in every Python file want to use Bleak in, we write import bleak (more details on this later).
To install Bleak, we have to use Pip, the package manager for Python. We can use Pip to install Bleak with one line in Terminal:
pip install bleak
Pip comes built-in with Python 3, so you shouldn’t have to install anything to use it.
To check if you have Pip, open Terminal on your Mac and type pip. Press Enter. If it’s installed, you’ll see a help menu print out.

If have Python 3 but not Pip for some reason, go to Pip’s official installation page.
If you don’t have Python 3, install it here. It will come with Pip.
Importing Bleak
How do we use Bleak after it is installed? Does Python just know where it is?
Python has to be told what Bleak is in every Python file that we want to use Bleak in. We’ll only have one Python file for this scanner project, so we’ll import Bleak once at the top of the file.
# scanner.py
import bleakNow, we can use Bleak in the rest of our code. For example, we can call bleak.BleakScanner() to create the first part of our scanner, which we’ll cover in a minute.
An alternative way to import Bleak is to import specific classes from Bleak, like so:
from bleak import BleakClient
# OR
from bleak import BleakScannerThis is more specific (and makes for cleaner, faster code). We’ll end up using both BleakClient and BleakScanner to make our scanner.
The Most Basic Bluetooth Scanner
The main pieces of a simple Bluetooth scanner are:
- scanning for nearby devices
printing them to the screen
That’s most of what we have to worry about, thanks to Bleak taking care of the rest. All we have to write is:
# scanner.py
import asyncio
from bleak import BleakScanner
async def main():
devices = await BleakScanner.discover()
for device in devices:
print(device)
asyncio.run(main())There are some extra statements in there (async and await) that are necessary for Bleak due to the nature of wireless communication. We’ll cover this more below.
For now, the code above starts BleakScanner, spends 5–10 seconds finding devices, then prints them all to your screen.

Why We Need to Use Asyncio
Usually, code runs from top to bottom, one line after the other. But what about code where we need to send a wireless message to a Bluetooth device and then we don’t know when we’ll hear back from that device? We can’t make our code pause and wait indefinitely, so what do we do?
We can use asynchronous code to allow our computer to interact with Bluetooth devices without jamming up and stalling our program. In Python, this is done using Asyncio, which is included with Python 3 (unlike Bleak). A complete guide on Asyncio is available here.
Without asyncio, our scanner would look like this (and wouldn’t work):
# scanner.py without asynchronous code
from bleak import BleakScanner
def main():
devices = BleakScanner.discover()
for device in devices:
print(device)
main()Instead, we make main() asynchronous and specify that BleakScanner.discover() is going to take a while with await:
# scanner.py
import asyncio
from bleak import BleakScanner
async def main():
devices = await BleakScanner.discover()
for device in devices:
print(device)
asyncio.run(main())Then the code can start BleakScanner.discover() without freaking out if it doesn’t hear anything back immediately.
A Better Bluetooth Scanner
Getting the addresses and names of device is cool and all, but is that all we can do with a scanner?
We can do way more, like asking a device what it is capable of (e.g. measuring heart rate, measuring movement, etc.) and determining how strong the Bluetooth signal is (how close the device is to us), among other things.
To make a more detailed scanner, check out our other article, How to Make a Detailed Bluetooth LE Scanner with a MacBook and Python.
Questions and Feedback
If you have questions or comments, email us at [email protected] or message us on Instagram (@protobioengineering).
If you liked this article, consider supporting us by donating a coffee.
