CLI tool
MIT-LCP/wfdb-python avatar
MIT-LCP/wfdb-python

wfdb: reading and writing physiologic signals from Python

Native Python WFDB package

853 stars323 forksJupyter NotebookMIT

At a glance

What is it?
The wfdb package is the Python face of WFDB, the set of open standards and software tools for storing, sharing and analysing physiologic signal and annotation data that biomedical research has used for decades. It reimplements the command line APIs of the original package, and the README is careful to say it makes no promise of matching them exactly.
Who is it for?
Adopt wfdb if you work with electrocardiogram or other physiologic recordings and need an open, specification-based format for both the signals and their annotations, especially if your existing tooling already speaks WFDB. Do not adopt it expecting the original command line package to behave identically, because the README says there is no promise of consistency between the two, only that many of the command line APIs are replicated.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 115 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The standards came first, the Python package came second

WFDB defines a set of open standards and software tools for the storage, sharing and analysis of physiologic signal and annotation data, and the README notes that it has been widely used for decades to support biomedical research, clinical studies and education. The main WFDB site is at wfdb.mit.edu, and the original software package lives on PhysioNet.

This package is described as heavily inspired by that original WFDB Software Package, and the README says it aims to replicate many of its command line APIs in Python, with the important qualifier that there is no promise of consistency between the two. That is the single most useful sentence in the README for a user deciding whether to migrate, because the command line package is decades old and its behaviour is what a lot of existing scripts assume.

What the Python package does anchor itself to is the format. The core input and output functionality is based on the Waveform Database specifications, which live in their own repository. So the file format is the shared contract, and the API shape is the reimplementation. A file written here should be readable by the original tools, and the reverse should hold, but a function that behaves subtly differently in the two is possible and is not treated as a bug in the Python package.

The package is MIT licensed, published on PyPI as wfdb, and its primary language is recorded as Jupyter Notebook, which reflects where the documentation examples live rather than where the code is. The last push was on 2026-06-30, and the releases listed are v4.2.0 in January 2025, v4.3.0 in April 2025 and v4.3.1 on 2026-02-03, so the release history is slow and deliberate rather than frequent.

Installation is one command, with one exception to check

The distribution is hosted on PyPI, and the install is:

sh
pip install wfdb

There is one caveat and the README states it clearly. On some less-common systems you may need to install the sound file library separately, and it points at the installation notes for the sound file package for the details. That dependency comes from the audio side of the format, since waveform files can carry sound alongside the samples, and it is the kind of thing that only bites on a platform where the bundled binary is not available.

The development path is the standard one. The development version is hosted in the repository, which also contains the demo scripts and example data, and you clone or download it, move to the base directory and run:

sh
pip install .

If you intend to change the repository, you add the development extras, which are declared in the project file:

sh
pip install ".[dev]"

The extras cover the toolchain a contributor needs, and they are a good indicator of how the project is developed. The test runner is pytest with the parallel execution plugin, the linter is pylint with a configuration file at the repository root, the formatter is black with a line length of 80 and a target of Python 3.9, and the documentation is built with Sphinx, which matches the readthedocs configuration file also in the root.

The development documentation has its own file, DEVELOPING.md, and the README points at it twice, once for the contribution and development instructions and once, at a specific anchor, for the guidance on creating a new release. That second pointer matters for anyone who wants to cut a version, because the release procedure is written down rather than living in the maintainer's head.

The dependency list is a description of the package

The project file lists eight runtime dependencies, and each one tells you something about what the package does.

numpy, scipy and pandas are the data layer, and they are the reason the package requires Python 3.9 or newer with recent versions of each: numpy at 1.26.4, scipy at 1.13.0 and pandas at 2.2.3.

The sound file library is the audio side, and it is the dependency with the installation caveat mentioned earlier, so it is worth knowing that it is a first class part of the package rather than an optional extra.

matplotlib is the plotting dependency, which fits a package that exists to let you look at recordings.

Then there are the three that describe the range of the package beyond local files. requests is the synchronous HTTP client, aiohttp is the asynchronous one, and fsspec is the filesystem abstraction layer, which is the one that lets the same code read a recording that lives on a remote store as well as one in a local directory. Together they are the reason the package can sit behind a notebook that pulls data from a PhysioNet-hosted dataset and a script that reads a local file with the same call.

The version number is read from a file inside the package, wfdb/version.py, with the build backend configured to read it from there, so the version is a single source of truth rather than a number duplicated between the manifest and the code.

The build backend is hatchling, and the source distribution configuration excludes the tests, the sample data, the demo image and the demo notebook, so those artefacts ship in the repository and not in the package.

Notebooks and sample data are part of the repository, not the package

The repository listing shows a directory of sample data, a demo notebook, an image of the demo, a docs directory and a tests directory, and the primary language field says Jupyter Notebook. That combination tells you how this project teaches.

The demo notebook is listed in the resources section of the README alongside the website, the documentation, the specification repository and the development repository, which means the notebook is treated as a primary reference rather than a leftover script. The same listing calls out the repository as containing demo scripts and example data.

The sample data has a second job, which is testing. A package that reads binary physiological recordings needs fixtures that exercise the format, and the sample-data directory is where they live, and the tests directory is a peer to it. The development extras include the parallel execution plugin for pytest, which suggests the suite is large enough that serial execution is a nuisance, which in turn is what you expect when every test needs a signal file.

For a user, the practical consequence is that you can read the format through the notebook before you read it through the API, and that the data the documentation uses is the data the tests use, so the examples are not fictional.

The same care shows in the citation instruction. The README asks that the software publication on PhysioNet be cited when you use the resource, and the badge in the header links to the DOI for that publication. For a package in a research setting, where a result may end up in a paper, a documented citation path is not a formality, it is the difference between your analysis being reproducible and your reader being able to find the exact thing you used.

A slow release cadence and a stable dependency floor

Two numbers frame any decision to depend on this package.

The first is the release history. v4.2.0 came in January 2025, v4.3.0 in April 2025 and v4.3.1 on 2026-02-03, and the last push to the repository was on 2026-06-30. So the code moves in small steps, roughly one minor release every few months, with the patches that keep the existing API working. For a package whose whole purpose is compatibility with a format used by research groups going back decades, that is the right pace. Nobody benefits from a rewrite of a file format reader, and the project says outright that it aims to replicate the original command line APIs rather than replace them.

The second number is the Python floor, 3.9, which with recent versions of numpy, scipy and pandas is the real constraint rather than the interpreter itself. The black configuration targets the same version, so the codebase is written to run on the oldest interpreter it supports, and the formatting is set to a line length of 80 rather than the default, which is the kind of detail that only shows up in a project with a long history of contributors.

So the shape of the project is: an open, stable file format, an authoritative specification repository, an original implementation in another language that defines the expected behaviour, a Python package that tracks it closely without promising to match it, and a test suite with real recordings in it. The documentation lives on readthedocs, the project is under the MIT Laboratory for Computational Physiology, and the contact address is the one given in the project metadata.

If your work involves recordings, this is the format-level dependency rather than a convenience library, and the repository's age is a feature of the domain rather than a warning sign.

Editorial conclusion

Adopt wfdb if you work with electrocardiogram or other physiologic recordings and need an open, specification-based format for both the signals and their annotations, especially if your existing tooling already speaks WFDB. Do not adopt it expecting the original command line package to behave identically, because the README says there is no promise of consistency between the two, only that many of the command line APIs are replicated. Before you rely on it, check the file format support you need against the WFDB specification, and if you install on an unusual system, check the sound file dependency, since the audio path may need a separate library.

Frequently asked questions

What is the wfdb Python package?

It is a MIT licensed Python package for reading, writing and processing physiologic signal and annotation data. WFDB itself defines open standards and software tools for storing, sharing and analysing that data, and has been widely used for decades in biomedical research, clinical studies and education.

Is wfdb-python a drop-in replacement for the original WFDB software package?

Not exactly. The README says the package is heavily inspired by the original WFDB Software Package and aims to replicate many of its command line APIs in Python, but that there is no promise of consistency between the two. The core input and output functionality is based on the WFDB specifications rather than on the original implementation.

How do I install wfdb and what might go wrong?

The package is on PyPI and installs with pip install wfdb. On some less-common systems you may need to install the sound file library separately, and the README points at the installation notes for that package. From a clone you run pip install ., and pip install ".[dev]" adds the test, lint, format and documentation tools.

What are the runtime dependencies of the wfdb package?

numpy, scipy and pandas for the data layer, the sound file library for audio, matplotlib for plotting, requests for synchronous HTTP, aiohttp for asynchronous access, and fsspec for filesystem abstraction, with Python 3.9 or newer required.

How should I cite the wfdb Python package?

The README asks that the software publication hosted on PhysioNet be cited when you use the resource, and the badge in the README links to its DOI. The project also publishes a development guide in DEVELOPING.md that covers contributions and the process for creating a release.

Official sources

  1. License: MIT
  2. MIT-LCP/wfdb-python on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mit-lcp-wfdb-python.svg)](https://hysenlabs.com/projects/mit-lcp-wfdb-python)

Was this useful?