Python bindings for the SiFi Bridge tool.
Project description
SiFi Bridge Python
A Python wrapper over the SiFi Bridge CLI for talking to SiFi Labs devices (BioPoint, SiFiBand). Spawns sifibridge as a subprocess, drives it via its REPL, and delivers sensor data over a local TCP socket — so your code reads typed Python objects instead of parsing JSON lines.
Installing
pip install sifi-bridge-py
The sifibridge CLI binary ships bundled per platform via the sifibridge-bin wheel; no separate install is needed on Linux (x86_64, aarch64), macOS (x86_64, arm64), or Windows (x86_64).
Quickstart
from sifi_bridge_py import SifiBridge
with SifiBridge() as sb:
# Block until a device is found (sb.connect() returns False on no-match)
while not sb.connect():
pass
sb.configure_sensors(emg=True)
sb.configure_emg(fs=1000, mains_notch=60)
sb.start()
for _ in range(50):
packet = sb.get_emg(timeout=2.0)
if not packet:
continue # timed out, no data this tick
print(packet["sample_rate"], packet["data"]["emg"][:4])
sb.stop()
SifiBridge is a context manager — leaving the with block closes the data socket and shuts down the subprocess. If you can't use with, call sb.close() explicitly when done.
API tour
Lifecycle
SifiBridge(use_lsl=False)spawns the CLI; passuse_lsl=Trueto also stream data to Lab Streaming Layer.sb.close()(orwithblock exit) terminates the subprocess.
Discovery & connection
sb.list_devices(ListSources.BLE)/.SERIAL/.DEVICESreturns the names sifibridge can see.sb.connect()connects to any available device. Pass aDeviceType, a MAC address (Linux/Windows), or a CoreBluetooth UUID (macOS) to target a specific one. ReturnsTrueon success,Falseif no device matched in time (safe to retry in a loop).sb.select_device(name)/sb.get_active_device()/sb.show()introspect the current session.
Sensor configuration
sb.configure_sensors(ecg=…, emg=…, eda=…, imu=…, ppg=…)toggles which sensors stream.sb.configure_ecg(...),configure_emg(...),configure_eda(...),configure_imu(...),configure_ppg(...)set per-sensor sampling rate, filtering, ranges, etc.sb.set_onboard_filtering(enable)turns the device's onboard filtering on/off globally.sb.set_memory_mode(MemoryMode.STREAMING | DEVICE | BOTH)controls whether data streams over BLE, lands on onboard flash, or both.
Acquisition & data
sb.start()/sb.stop()toggle streaming.sb.get_ecg(timeout=…),get_emg,get_eda,get_imu,get_ppg,get_temperaturepop the next packet of that sensor. Each sensor has its own internal queue, so callingget_ecg()does not drop EMG data that arrived in between. Returns{}on timeout. NOTE: each packet is also routed to a generic queue read byget_data()— don't mix the two APIs on the same instance, or you'll see duplicates.sb.clear_data_buffer()drains all internal queues.
Onboard memory
sb.start_memory_download(timeout=10.0)triggers a memory dump; pullmemorypackets viaget_data()and checksb.is_memory_download_completed(packet).sb.buffer_export(fmt="csv"|"hdf5", output_dir=...)writes buffered acquisitions to disk.sb.erase_onboard_memory()wipes the device's flash.
Device controls (no REPL escape hatch needed)
sb.set_led(index, on),sb.set_motor(on),sb.set_motor_intensity(level)sb.power_off(),sb.reset_to_default_config()sb.start_status_updates()/stop_status_updates()sb.get_memory_size(),sb.get_device_info()— reply asynchronously asstatuspackets on the data channel.sb.set_ble_power(BleTxPower.LOW|MEDIUM|HIGH),sb.set_night_mode(on),sb.set_low_latency_mode(on)
Software events
sb.send_event()emits a software event on the device — useful for marking experiment timestamps.
Error handling
from sifi_bridge_py import SifiBridgeError, SifiBridgeTimeout
ConnectionError— Bluetooth adapter is off or unavailable. Raised byconnect()andlist_devices().SifiBridgeTimeout(subclass ofSifiBridgeError) — the CLI didn't reply within the timeout. Retry-friendly.connect()already catches this internally and returnsFalse.SifiBridgeError— the CLI returned an explicit{"error": ...}response. Indicates malformed input or an unsupported operation; fix the call rather than retrying.
Catch SifiBridgeTimeout specifically when you want to distinguish "still trying" from "broken":
try:
sb.configure_emg(fs=1000)
except SifiBridgeTimeout:
# CLI is wedged — back off and retry
...
except SifiBridgeError as e:
# Bad arguments — surface to the user
raise
Examples
Examples are available on our documentation website.
Advanced usage
The wrapper exposes the common surface, but the underlying CLI has more. To explore, run sifibridge interactively and type help — anything you find there can also be reached from Python by subclassing SifiBridge and calling self._request("…") directly. The REPL command reference is documented in SiFiLabs/sifi-bridge-pub.
Tests
python -m unittest -v
Tests do not need a connected device. Some assertions exercise live REPL responses, so the bundled sifibridge binary must be runnable on your platform.
Versioning
The wrapper is updated for every SiFi Bridge release. Major and minor versions are kept in lockstep with the CLI; patch versions vary for project-specific fixes.
Local development
See DEVELOPMENT.md for setup. The short version:
export SIFIBRIDGE_EXE=./sifibridge # point to a local CLI build
uv sync
Deployment
NOTE: If you add new enums or types, re-export them in sifi_bridge_py/__init__.py.
Publishing sifibridge-bin
- Update
versioninsifibridge-bin/pyproject.toml - Build wheels:
cd sifibridge-bin && python scripts/build_wheels.py <release-tag> - Publish:
uv publish dist/*or push abin-<version>tag
Publishing sifi-bridge-py
- Update
versioninpyproject.toml(and thesifibridge-binpin if needed) - Run tests:
python -m unittest -v - Push a version tag (e.g.
2.0.0-b9) tomain— CI handles the rest
sifibridge-bin must be on PyPI before publishing a sifi-bridge-py version that depends on it.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sifi_bridge_py-2.0.0b15.tar.gz.
File metadata
- Download URL: sifi_bridge_py-2.0.0b15.tar.gz
- Upload date:
- Size: 129.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1f6ca1a0068cc5b2e92c83d8fe6d059aec17c53fb71760bd68186f655b9e759
|
|
| MD5 |
41f2022c4b90de7b658fbd537910f11f
|
|
| BLAKE2b-256 |
0433ec9e2e5f239f829d4db9d61b5cac22c7dfb97c0a98554b1d1aaf4802c3ab
|
Provenance
The following attestation bundles were made for sifi_bridge_py-2.0.0b15.tar.gz:
Publisher:
release.yml on SiFiLabs/sifi-bridge-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sifi_bridge_py-2.0.0b15.tar.gz -
Subject digest:
a1f6ca1a0068cc5b2e92c83d8fe6d059aec17c53fb71760bd68186f655b9e759 - Sigstore transparency entry: 1819445462
- Sigstore integration time:
-
Permalink:
SiFiLabs/sifi-bridge-py@472bf116d9b183f4ded30d2557d37fe55fb9abba -
Branch / Tag:
refs/tags/2.0.0-b15 - Owner: https://github.com/SiFiLabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@472bf116d9b183f4ded30d2557d37fe55fb9abba -
Trigger Event:
push
-
Statement type:
File details
Details for the file sifi_bridge_py-2.0.0b15-py3-none-any.whl.
File metadata
- Download URL: sifi_bridge_py-2.0.0b15-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5af718792ea41a1524d45084b654954db08408f8b7bbc9610180a70d87d75fe1
|
|
| MD5 |
b702f098170ac9fb8776bbb811f8ebdc
|
|
| BLAKE2b-256 |
15ece4ec8ea9ce60eb4c91f8e71a3f0cf2486a99bb8b2c39f45ae57aad490e54
|
Provenance
The following attestation bundles were made for sifi_bridge_py-2.0.0b15-py3-none-any.whl:
Publisher:
release.yml on SiFiLabs/sifi-bridge-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sifi_bridge_py-2.0.0b15-py3-none-any.whl -
Subject digest:
5af718792ea41a1524d45084b654954db08408f8b7bbc9610180a70d87d75fe1 - Sigstore transparency entry: 1819445953
- Sigstore integration time:
-
Permalink:
SiFiLabs/sifi-bridge-py@472bf116d9b183f4ded30d2557d37fe55fb9abba -
Branch / Tag:
refs/tags/2.0.0-b15 - Owner: https://github.com/SiFiLabs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@472bf116d9b183f4ded30d2557d37fe55fb9abba -
Trigger Event:
push
-
Statement type: