Skip to main content

A schema-driven, pydantic-typed, in-process BIDS validator.

Project description

bidsval

Validate BIDS datasets in pure Python.

bidsval reads the official BIDS schema and checks datasets against the rules it contains. It runs in-process with no external runtime, returns typed (pydantic) results, and validates a whole dataset, a single subject, a single file, or a single expression. Every published BIDS schema version ships inside the package, so it works offline and you choose the version with one argument.

Because the schema drives everything, bidsval covers all of BIDS - anatomical, functional, diffusion, fieldmaps, perfusion, EEG, MEG, iEEG, behavioural, PET, microscopy, motion, NIRS, MRS - not a fixed set of modalities. Point it at a newer schema and the newer rules apply with no code change.

Verified against the reference Deno bids-validator across the full bids-examples corpus and real MRI/EEG/MEG/PET datasets, at a matched schema, with zero false positives. It covers filename and path legality, file integrity, sidecar field presence and value types, associated files, tabular columns (types, order, uniqueness), the inheritance principle, and dataset-level checks. The remaining gaps are HED and symlink validation; see the comparison and "Roadmap".

Install

pip install bidsval

That is all you need: the bundled BIDS schemas and the content readers (nibabel, pandas, mne) come with it, so it works offline. Python 3.10 to 3.14.

For development, from a clone:

git clone https://github.com/karellopez/bidsval
cd bidsval
pip install -e ".[dev]"   # editable install, plus the test and lint tooling

Validate a dataset

From Python:

import bidsval

report = bidsval.validate("/path/to/dataset")
report.is_valid            # False if there are any errors
report.counts              # {'error': 3, 'warning': 27, 'ignore': 0}
for verdict in report.files:
    for issue in verdict.issues:
        print(issue.severity.value, issue.code, verdict.path, issue.message)

# Narrower granularity:
bidsval.validate_subject("/path/to/dataset", "sub-01")
bidsval.validate_file("/path/to/dataset", "sub-01/anat/sub-01_T1w.nii.gz")

From the command line:

# Text summary to the terminal (exits non-zero on errors, so it drops into CI):
bidsval validate /path/to/dataset

# Validate one subject; also check NIfTI headers:
bidsval validate /path/to/dataset --subject sub-01 --headers

# Pick the output type (independent of where it goes):
bidsval validate /path/to/dataset --output-type json     # JSON to stdout
bidsval validate /path/to/dataset --output-type sarif    # SARIF to stdout (CI / IDE code scanning)

# Write report files: --out-dir holds report.<ext> for each selected type:
bidsval validate /path/to/dataset --output-type html --out-dir reports/   # reports/report.html
bidsval validate /path/to/dataset --output-type all  --out-dir reports/   # report.txt/.json/.sarif/.html

# Show only the severities you care about (does not change pass/fail):
bidsval validate /path/to/dataset --show error           # errors only

Flags: --schema <version|url|path>, --subject sub-01, --headers (also check NIfTI headers, needs nibabel), --output-type text|json|sarif|html|all (default text; one type prints to stdout, several need --out-dir), --out-dir DIR (write report.<ext> per type), --show error,warning,ignore,all (filter displayed findings; default error,warning).

Choose a schema version

Every published BIDS schema is bundled, and any other version or a URL is fetched and cached. One argument selects the schema; everything downstream is unchanged:

bidsval.validate("/data", schema="1.10.0")               # a bundled version
bidsval.validate("/data", schema="latest")               # the development tip (fetched)
bidsval.validate("/data", schema="https://.../schema.json")  # any URL (fetched + cached)
bidsval.validate("/data", schema="/path/to/schema.json") # a local dereferenced schema.json
bidsval.validate("/data", schema="/path/to/src/schema")  # a YAML schema source directory
bidsval.available_versions()                             # bundled: ['1.8.0', ... '1.11.1']
bidsval validate /data --schema 1.9.0
bidsval validate /data --schema latest
bidsval validate /data --schema https://bids-specification.readthedocs.io/en/v1.10.0/schema.json
bidsval schema --schema 1.10.0      # show the versions a selector resolves to

Evaluate a single expression

The expression engine is usable on its own - handy for understanding a rule or checking one condition:

from bidsval import evaluate_string

evaluate_string("suffix == 'T1w'", {"suffix": "T1w"})                       # True
evaluate_string("nifti_header.dim[0] == 3", {"nifti_header": {"dim": [4]}}) # False
bidsval eval "suffix == 'T1w'" --context '{"suffix": "T1w"}'

How it works

  • The schema is the engine. The BIDS schema expresses validation logic as expressions: selectors that decide when a rule applies (suffix == 'T1w') and checks that must hold (nifti_header.dim[0] == 3). bidsval reads the schema's vocabulary (datatypes, entities, suffixes, extensions) and rules, builds a context for each file, and evaluates the rules against it. No BIDS terms are hardcoded.
  • Parsing comes from bidsschematools; bidsval adds the evaluator that walks the syntax tree (no eval/exec), the file/context layers, and the rule loop.
  • A finding is reported only when a rule produces a determinate failure. When the context cannot determine a rule (for example a check that needs a content layer not yet built), the rule is skipped rather than guessed, so the validator does not emit false errors.
  • Results are pydantic models, ready to serialise to JSON or bind to a GUI.

Layout

Module Responsibility
bidsval.schema Resolve a selector to one schema object; read BIDS vocabulary from it. The only version-aware code.
bidsval.files Index a dataset's files (FileTree).
bidsval.context Build the per-file context: entities, datatype, inheritance-merged sidecar, associated files, loaded content.
bidsval.expr Evaluate BIDS schema expressions against a context.
bidsval.rules Apply the schema's checks, sidecar fields (presence + value type), and tabular-column rules; plus bespoke checks.
bidsval.validate validate / validate_subject / validate_file.
bidsval.render Render a report as text / JSON / SARIF / HTML.
bidsval.issues / bidsval.report Typed findings and results.
bidsval.cli The bidsval command.

Done: the schema engine and the file/context/rule layers; dataset/subject/file validation; filename and path legality (with .bidsignore); file-integrity checks; sidecar field presence and full value-type checks; the associations layer (events, bval/bvec, channels, ASL, coordsystem, atlas, ...); tabular checks (types, order, uniqueness, additional columns); inheritance checks; dataset-level checks; CITATION.cff; derivatives recursion; bundled + URL + latest schema selection; text / JSON / SARIF / HTML output.

Roadmap

Filename/path legality, file integrity, the cross-file and tabular checks (including full value-type checking and type redefinition), inheritance checks, CITATION.cff, derivatives recursion, and the coordsystems/atlas-description aggregates are all in (see comparison vs the Deno reference validator for full coverage). Remaining:

  1. Deferred reference checks: HED (needs a HED validator dependency) and symlink checks (the annex-symlink tension). Only the gzip/ome/tiff content-header aggregates are still unbuilt.
  2. The ahead-of-market features: requirement-level completeness per subject, reasoned waivers, explain mode, and one-click fixes (provenance and fix hints are already on every finding).

Documentation

The docs live in docs/ on GitHub:

Develop

pytest                                  # unit suite, incl. the schema expression oracle
BIDSVAL_REAL_DATA=1 pytest tests/test_real_data.py   # real-data validation (if datasets present)
ruff check src tests

License

MIT. See LICENSE.

Project details


Download files

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

Source Distribution

bidsval-0.0.3.tar.gz (682.0 kB view details)

Uploaded Source

Built Distribution

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

bidsval-0.0.3-py3-none-any.whl (682.0 kB view details)

Uploaded Python 3

File details

Details for the file bidsval-0.0.3.tar.gz.

File metadata

  • Download URL: bidsval-0.0.3.tar.gz
  • Upload date:
  • Size: 682.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for bidsval-0.0.3.tar.gz
Algorithm Hash digest
SHA256 bae4a44a4d314df34b704eaaf00810466325ef4aea0231f2a5a846650af556d0
MD5 4afa8b8ee0b832375b2fad03ed58aa11
BLAKE2b-256 0dbe6f4a688bb7079ad0db5bcfa87f4d29ba55327f050359c3a9bc7fd999e894

See more details on using hashes here.

File details

Details for the file bidsval-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: bidsval-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 682.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for bidsval-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 98d4bda3bdf718cc813e58bd5c61fcd7f241df709333f32a5ba52c15a19ce809
MD5 b13f5e157684cbbffd391947b7459849
BLAKE2b-256 46e0f8c4eefe95da0b97163b2be1c991531597dbeda6c5a02d52b412ed80f653

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page