Skip to main content

Harp logo

harp

Python interface to Harp devices and their recorded data, implementing the Harp binary protocol.

Harp is a standard for asynchronous real-time data acquisition and experimental control in neuroscience. Every command and event is hardware timestamped on the device. Devices sharing a clock line continuously self-synchronize, so events across a rig sit on one clock and need no post-hoc alignment.

This project includes four main packages:

  • harp-protocol: Implements the Harp binary protocol in Python, with registers, messages, and payload parsing. See Protocol API Documentation for details.

  • harp-device: Implements the transport-agnostic Device interface and the core register set. See Device API Documentation for details.

  • harp-serial: Connects to a Device over a serial COM or tty port. See Serial API Documentation for details.

  • harp-data: Reads logged register files into pandas DataFrames. See Data API Documentation for details.

Installation

All packages are published to PyPI. The harp package is a metapackage with no code of its own. It depends on the four packages above, so it is the easiest way to get everything:

pip install harp

uv add substitutes for pip install throughout.

To install only part of the stack, for example when reading recorded data with no need for serial I/O, install the individual packages. Each one only pulls in what it actually depends on:

Package Depends on
harp-protocol none
harp-device harp-protocol
harp-serial harp-protocol, harp-device
harp-data harp-protocol
pip install harp-protocol
pip install harp-device
pip install harp-serial
pip install harp-data

harp-benchmarks, under src/packages/, is internal-only and is never published to PyPI.

Quickstart

There are two typical ways to use harp: talking to a live device over a serial connection, or reading data recorded to disk.

Talk to a live device. Open a connection and read/write registers by class:

from harp import serial
from harp.device import behavior, core

# Use "COMx" on Windows, "/dev/ttyUSBx" on Linux.
with serial.open_device(behavior, port="COM3") as device:
    print(device.read(core.WhoAmI).payload)         # a core register
    print(device.read(behavior.AnalogData).payload) # a device register
    device.write(
        core.OperationControl,
        core.OperationControlPayload(operation_mode=core.OperationMode.ACTIVE),
    )

Read a recorded session. Point a DatasetReader at a dataset folder and read registers into pandas DataFrames, with no hardware required:

from harp import data

# Finds device.yml in the folder, builds the device, returns a ready-to-use reader
reader = data.open_dataset("session.harp")
df = reader.read("AnalogData")  # by name
df = reader.read(44)            # or by address

# `contents` names every register the folder holds
frames = {name: reader.read(name) for name in reader.contents}

Given a device package already in hand, pass it as the second argument and read by register class. This is the form that type-checks, and it also checks the device identity against the device.yml in the folder:

from harp import data
from harp.device import behavior

reader = data.open_dataset("session.harp", behavior)
df = reader.read(behavior.AnalogData)

Both paths are based on a device schema. Given only a device.yml and no pre-generated package, create_device_module compiles it into a module of register classes at runtime, with no code-generation step. This is exactly what open_dataset does internally:

from pathlib import Path

from harp.device import schema

behavior = schema.create_device_module(Path("device.yml").read_bytes())
AnalogData = behavior.AnalogData                 # registers are accessed by name
assert behavior.REGISTER_MAP[44] is AnalogData   # or by address

See the examples in the documentation for the full walkthroughs, including subscribing to device events and working with custom interface-type converters.

Contributing

harp is a uv workspace: every package under src/packages/ is its own distribution, plus the root harp metapackage. Bug reports and contributions are welcome, so please open an issue or pull request.

Clone the repository and install everything with the dev dependency group: all workspace packages, editable, plus test and lint tooling.

uv sync --group dev

Before opening a pull request, run the same checks CI runs:

uv run ruff format --check   # formatting
uv run ruff check            # lint
uv run pyright               # type checking
uv run codespell             # spelling
uv run pytest --cov harp     # tests

To add a new package, place it under src/packages/<name>/ with its own pyproject.toml and add it to [tool.uv.sources] in the root pyproject.toml. If it should ship as part of harp, add it to the dependencies of the root package as well.

Build the documentation

Install the docs dependency group and run mkdocs through uv:

uv sync --group docs --group dev
uv run mkdocs serve   # live-reloading local preview
uv run mkdocs build   # static site in ./site

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

harp-0.5.0.tar.gz (224.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

harp-0.5.0-py3-none-any.whl (4.8 kB view details)

Uploaded Python 3

File details

Details for the file harp-0.5.0.tar.gz.

File metadata

  • Download URL: harp-0.5.0.tar.gz
  • Upload date:
  • Size: 224.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for harp-0.5.0.tar.gz
Algorithm Hash digest
SHA256 dc9249046701a76781f643be2b899b8ddf95efa738f2af565500864fc078b922
MD5 1bffa11c6a8b01f07652a9cc8efbc71d
BLAKE2b-256 be0fa155d49ec05765f121e07e9328dcbd437c632a6aa49ffd6f5b859a15814d

See more details on using hashes here.

File details

Details for the file harp-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: harp-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 4.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for harp-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5d4562f59144163db10b5a1bd6d2c199d1cae91ad6e950b191dd26c53b5f21a
MD5 cb260e67f03edf85a919a818a8411c37
BLAKE2b-256 ebe383e24411ad3ea7dc616d37a480e1c4bd5f321e85f25f9fefa809ac56659a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page