Skip to content

Add BIDS schema code generator and generated utilities#49

Merged
nx10 merged 5 commits into
mainfrom
static-bids-utils
Feb 9, 2026
Merged

Add BIDS schema code generator and generated utilities#49
nx10 merged 5 commits into
mainfrom
static-bids-utils

Conversation

@nx10
Copy link
Copy Markdown
Contributor

@nx10 nx10 commented Feb 9, 2026

The BIDS specification defines entities, datatypes, suffixes, and naming conventions that we use throughout the codebase for file naming and path construction. Rather than hand-maintaining string constants and relying on loosely-typed **kwargs APIs, this PR introduces a code generator that reads the official BIDS schema and produces a fully-typed Python module with IDE autocomplete, validation, and docstrings pulled directly from the spec.

The generator is a standalone script (scripts/generate_bids_tools.py) runnable via uv run with no project dependency on bidsschematools, it can be re-run whenever the BIDS schema is updated to keep the generated code in sync.

Entity parameters use concrete types (int for index entities like run, Literal unions for enum entities like hemi/mt/part, str for labels) so type checkers and IDEs catch mistakes at development time rather than runtime.

@nx10 nx10 requested a review from kaitj February 9, 2026 19:19
Copy link
Copy Markdown
Contributor

@kaitj kaitj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some general comments (also chatted about some of this offline already):

  1. Something like this, I think, is always useful for building out these bids paths. One thing I think is necessary though before we consider merging this in is dealing with derivative entities (ones that may not be in the schema). Almost everything I think will be a derivative. And ideally, we should be able to pass them in similarly (e.g. entity=value). And as of the most recent commit, what happens if someone passes an extra entity (in the dictionary) that is also a standard entity (e.g. extra={'desc': extra}, desc=reg -> sub-<subject>_desc-extra_desc-reg).
  2. Some of the entities may be more obscure. Naming semantics / correctness aside, how would mismatches in expected type from existing datasets be handled. For example if we pull a run entity that is run-02, and then pass it to bids_name, will it return run-2 instead? I think there is something to be said about having consistency in the name as well.
  3. I don't think we want to make extension and suffix required, unless we are only using these for files which we know exist. For example, we may want to use this to create a BIDS-esque prefix. Ultimately, this may not matter as much, but something to keep in mind.

@nx10
Copy link
Copy Markdown
Contributor Author

nx10 commented Feb 9, 2026

  1. Something like this, I think, is always useful for building out these bids paths. One thing I think is necessary though before we consider merging this in is dealing with derivative entities (ones that may not be in the schema). Almost everything I think will be a derivative. And ideally, we should be able to pass them in similarly (e.g. entity=value). And as of the most recent commit, what happens if someone passes an extra entity (in the dictionary) that is also a standard entity (e.g. extra={'desc': extra}, desc=reg -> sub-<subject>_desc-extra_desc-reg).

Should already be implemented

  1. Some of the entities may be more obscure. Naming semantics / correctness aside, how would mismatches in expected type from existing datasets be handled. For example if we pull a run entity that is run-02, and then pass it to bids_name, will it return run-2 instead? I think there is something to be said about having consistency in the name as well.

yes it will always consistently not use leading zeros on indices - would you expect this to be configurable on a per entity basis?

  1. I don't think we want to make extension and suffix required, unless we are only using these for files which we know exist. For example, we may want to use this to create a BIDS-esque prefix. Ultimately, this may not matter as much, but something to keep in mind.

im not sure that im following - why would only the prefix be generated not the rest of the name?

@nx10 nx10 merged commit c5b8aaa into main Feb 9, 2026
6 checks passed
@nx10 nx10 deleted the static-bids-utils branch February 9, 2026 20:24
@kaitj
Copy link
Copy Markdown
Contributor

kaitj commented Feb 9, 2026

im not sure that im following - why would only the prefix be generated not the rest of the name?

For a file we expect to exist, it wouldn't. But if we wanted to generate a BIDS-esque prefix to pass to a tool.

@nx10
Copy link
Copy Markdown
Contributor Author

nx10 commented Feb 10, 2026

We could add something like bids_partial() but I wonder if it's not better to just do it when we move them.

@kaitj
Copy link
Copy Markdown
Contributor

kaitj commented Feb 10, 2026

but I wonder if it's not better to just do it when we move them.

💯

we could probably just put something sensible in its place in case of debugging needs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants