Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

PyMAUDE

PyMAUDE is a Python library for local, reproducible analysis of the FDA MAUDE (Manufacturer and User Facility Device Experience) adverse event database. It bulk-loads FDA's raw flat files into a local DuckDB database and gives you a fast, scriptable API for searching, enriching, and filtering medical device adverse event reports — without depending on the MAUDE web UI or a rate-limited API for every query.

MAUDE is updated continuously and isn't versioned, so PyMAUDE also supports checksummed, portable snapshots (db.archive(), restored with MaudeDatabase.from_archive()) for analyses that need to be reproducible for peer review or publication.

Why

  • Local and fast. FDA's own search UI and the openFDA API are fine for one-off lookups, but slow and rate-limited for the kind of bulk, iterative querying research requires. PyMAUDE downloads the raw data once and queries it locally via DuckDB.
  • Reproducible. db.archive() freezes the exact database backing an analysis into a directory of compressed Parquet tables, the original FDA zips, and a manifest recording every file's SHA-256 checksum, row counts, and load timestamps — so results can be cited, verified, and re-derived later.
  • Covers the full MDR family. Master records, device info, event narratives, patient demographics/outcomes, and both device- and patient-side problem codes — joined on MDR_REPORT_KEY throughout.

Installation

Use a virtual environment. Installing PyMAUDE (or any Python package) directly into your system or base conda Python can silently break other tools you depend on. Create and activate a virtual environment first:

python -m venv .venv
source .venv/bin/activate   # on Windows: .venv\Scripts\activate

Do this before running any pip install command below.

From PyPI

pip install pymaude

Note: this package is under active development ahead of its associated manuscript (see Publication below) — if pymaude isn't yet available on PyPI, install from source instead.

From source

git clone https://github.com/jhschwartz/PyMAUDE.git
cd PyMAUDE
pip install .

For development (editable install + test dependencies):

pip install -e ".[dev]"
pytest tests/

Requires Python ≥3.9.

Quickstart

from pymaude import MaudeDatabase

db = MaudeDatabase('./maude.duckdb', data_dir='./maude_data')
db.add_years('2024-2026', tables=['master', 'device', 'text', 'patient'], download=True)

results = db.query_device(product_code='NIQ')  # e.g. venous stents
print(f'{len(results):,} events')

For a guided walkthrough, open quickstart.ipynb — it downloads real FDA data and runs your first few queries. For deeper dives into specific capabilities, see examples/.

Project structure

pymaude-new/
├── src/pymaude/                       # library source
│   ├── database.py                    # MaudeDatabase — the main API
│   ├── archive.py                     # write / verify / restore snapshots (used by MaudeDatabase.archive)
│   └── metadata.py                    # TABLE_METADATA — FDA file layout config
├── tests/                             # pytest test suite (synthetic data, no FDA download needed)
├── quickstart.ipynb                   # short intro notebook — start here
├── examples/                          # deeper-dive notebooks
│   ├── searching.ipynb                # substring/OR/AND/grouped search, narratives
│   ├── enrichment_and_filtering.ipynb # patient outcomes, problem codes, chained filters
│   ├── trends_and_sql.ipynb           # year-over-year trends, raw SQL
│   └── archiving.ipynb                # archive, verify, and restore snapshots for publication
├── publication/                       # validation & benchmark scripts supporting the manuscript
├── dev_local/                         # personal dev scripts (gitignored, not part of the package)
├── pyproject.toml
└── LICENSE

Data tables

add_years() loads any subset of these into your local DuckDB file, all joinable on MDR_REPORT_KEY:

Table FDA source Description
master mdrfoi Master adverse event records
device foidev Device information
text foitext Event narrative text (FOI_TEXT)
patient patient Patient demographics and outcomes
device_problem foidevproblem Device problem codes
patient_problem patientproblemcode Patient problem codes

Core API

  • Loading: add_years(), update()
  • Querying: query_device() (exact-field), search_by_device_names() (substring, with OR/AND/grouped logic), get_narratives(), query() (raw SQL)
  • Enrichment: enrich_with_patient_data(), enrich_with_device_problems(), enrich_with_patient_problems()
  • Filtering: filter_by_outcome(), filter_by_patient(), filter_by_device_problem(), filter_by_patient_problem(), filter_by_narrative()
  • Analysis & reproducibility: get_trends_by_year(), info(), archive(), MaudeDatabase.from_archive(), verify_archive(), extract_raw()

See the docstrings in src/pymaude/database.py or examples/ for details on each.

Archiving a snapshot

db.archive('maude_archive')                      # write the snapshot
problems = verify_archive('maude_archive')       # [] if every file matches the manifest
db2 = MaudeDatabase.from_archive('maude_archive', 'restored.duckdb')

An archive is a plain directory, so you can upload it wherever you like:

maude_archive/
    master.parquet, device.parquet, text.parquet, ...   one zstd-compressed Parquet file per table
    raw.tar                                             the FDA source zips, byte-identical
    manifest.json                                       SHA-256s, row counts, load records, versions

For a full MAUDE database that is about 13 GB (roughly 6 GB of Parquet plus 7 GB of raw zips). A restored .duckdb file is much larger (roughly 50 GB), so if you only need to query the data, DuckDB can read the Parquet files in place. See examples/archiving.ipynb for the details.

Publication

A manuscript describing PyMAUDE is in preparation. Citation details will be added here once it's published.

@article{pymaude,
  title   = {PyMAUDE: a Python library for local and reproducible analysis of the FDA Manufacturer and User Facility Device Experience (MAUDE) database},
  author  = {Schwartz, Jacob; Almoussa, Maya; Blattman, Nicole; Makary, Mina S},
  journal = {},
  year    = {2026},
  doi     = {}
}

License

MIT — see LICENSE.

Contact

Jacob Schwartz — jaschwa@umich.edu

Release files for pymaude 0.3.0a0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pymaude 0.3.0a0
File Size Uploaded
pymaude-0.3.0a0.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pymaude 0.3.0a0
File Interpreter ABI Platform
pymaude-0.3.0a0-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / pymaude-0.3.0a0.tar.gz

Download URL pymaude-0.3.0a0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
1e1e33111a6693bed9269331d716e3ae4ff9507c49c402d2a16016e49e0010b1
BLAKE2b-256 checksum
How to use checksums
cefaa561b23059b0a9b3f74ffe93c6cc55aec3022bd4b7e3bdc7220d0c5a7f45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.

Transparency log

Release files / pymaude-0.3.0a0-py3-none-any.whl

Download URL pymaude-0.3.0a0-py3-none-any.whl
Size 31.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ebabdadb85e59e82b26a4b2fbe48e5cc989692aa69c170741065fe29d3a586e0
BLAKE2b-256 checksum
How to use checksums
2d2fa6cc51e892a37682461f302643f77365a61b989ff396c4f722a779b19b73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0a0 This release

2 release files

0.2.0

2 release 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