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.2.tar.gz (681.8 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.2-py3-none-any.whl (681.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: bidsval-0.0.2.tar.gz
  • Upload date:
  • Size: 681.8 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.2.tar.gz
Algorithm Hash digest
SHA256 72b454699e19992236cc05c3d3d0a699975d8478a9b4e575e7f72ae39ee2aef7
MD5 f02ef1fe434b2b3b803374b4ffde54ce
BLAKE2b-256 77d83f699ef7b680ac1f039e635f74a14521c1b5ddb3f2e3efe7bc76aff0d30d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bidsval-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 681.8 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ddbefa08b7bb272ad9bbc2383c455d6c78f67e67c8f815d97890c4cea9629256
MD5 cbe9456565d693ea98fff86461ab922d
BLAKE2b-256 89268384c9fd90bd94c1e1e0350b77fe4046dbca0b81d3d96ab88036e3bfb70f

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