Skip to content

API reference

The public surface is small. check_id and is_valid_id are the entry points, sources lists what can be checked, and the rest support cache mode and the framework adapters.

Checking identifiers

biobouncer.check_id

check_id(
    x: str | Iterable[str],
    source_db: str,
    how: str = "pattern",
    species: str | int | None = None,
    version: str | None = None,
    refresh: bool = False,
    on_error: str = "raise",
) -> list[Result]

Check one or more identifiers against a source.

Parameters:

Name Type Description Default
x str | Iterable[str]

A string or an iterable of strings.

required
source_db str

Source key, for example "mondo". See sources().

required
how str

Checking mode. "pattern" and "cache" run offline; "remote" checks live existence against the source API; "existence" uses a pinned snapshot when one is available for version, otherwise falls back to "remote", and for a source with no resolver falls back to "pattern".

'pattern'
species str | int | None

Optional species context, echoed in the result.

None
version str | None

Optional version context. In cache mode it selects the snapshot and defaults to the latest installed one when omitted; in existence mode it selects a snapshot when available. Ignored in pattern mode.

None
refresh bool

In remote checks, skip any cached response and refetch. Ignored by the offline modes.

False
on_error str

How a per-id remote failure is handled. "raise" (the default) lets the failure unwind the whole call. "indeterminate" leaves just that id valid=None with the reason in its error field and checks the rest of the batch, so one unreachable id does not lose the others. Ignored by the offline modes.

'raise'

Returns:

Type Description
list[Result]

A list of Result, one per input, in the input order.

biobouncer.is_valid_id

is_valid_id(
    x: str | Iterable[str],
    source_db: str,
    how: str = "pattern",
    species: str | int | None = None,
    version: str | None = None,
    refresh: bool = False,
) -> bool | None | list[bool | None]

Return just the validity verdict.

Returns a single verdict for a scalar input, or a list of verdicts for an iterable, matching the shape of x. A verdict is True (valid), False (invalid), or None for a missing input (None, a float NaN, or pandas NA). A missing input is deliberately not False, so callers can tell "absent" apart from "present but wrong".

biobouncer.Result dataclass

One verdict, with enough context to be self-describing.

Attributes:

Name Type Description
input str | None

The original value, or None for a missing input.

valid bool | None

Whether the input passed the check, or None for a missing input.

normalized str | None

Canonical form when valid, else None.

suggestion str | None

Best-effort correction when invalid but mappable, else None.

source_db str

The source the check ran against.

version str | None

Snapshot or release used. None for pattern mode.

species str | int | None

Species context, when applicable.

how str

The checking mode used: "pattern", "cache", "remote", or "existence".

error str | None

Why the value could not be checked, else None. Set only for an indeterminate verdict (valid is None with a non-None error), which a remote failure under on_error="indeterminate" produces. A missing input is valid is None with error is None.

Cleaning a column

report is the recommended entry point for validating and repairing a whole column. See the report cookbook.

biobouncer.report

Validate a whole column, then report or repair it in one call.

report() is the recommended entry point for the "clean my column" job. It runs :func:check_id over a column and returns a :class:Report you can turn into a data frame, count, or use to substitute the fixable values. It builds on narwhals, so the frame it returns is pandas, polars, or pyarrow to match the column you passed. Pure-Python callers can pass a list and read Report.results with no data-frame dependency at all.

For enforcing validity inside a framework (pandera, Great Expectations, pydantic, shiny), reach for the adapters instead; report is for inspecting and cleaning.

Report

The outcome of checking a whole column, ready to inspect or repair.

Attributes:

Name Type Description
results

One :class:Result per input, in order. Always available, with no data-frame dependency.

source_db

The source the column was checked against.

how

The checking mode used.

summary property

summary: dict

Counts: total, valid, invalid, repairable, missing, indeterminate.

to_frame

to_frame(backend=None)

Return a native data frame of the per-row verdicts.

The frame has the columns input, valid, normalized, suggestion, and error (the reason a remote check was left indeterminate, else null). It comes back on the same backend as the column passed to report (pandas, polars, or pyarrow); a report built from a plain list defaults to pandas. Pass backend to force one. Requires narwhals.

repair

repair()

Return the column with every fixable value substituted.

An invalid value that has a suggestion is replaced by that suggestion. Valid values, invalid values with no suggestion, and missing values are left as they were, so the result is the same length and order as the input. A report built from a native series returns a native series on the same backend; one built from a list returns a list.

report

report(
    column: Any,
    source_db: str,
    how: str = "pattern",
    species: str | None = None,
    version: str | None = None,
    refresh: bool = False,
    on_error: str = "raise",
) -> Report

Check a whole column and return a :class:Report.

Parameters:

Name Type Description Default
column Any

A list of ids, or a pandas, polars, or pyarrow series.

required
source_db str

Source key, for example "hgnc". See sources().

required
how str

Checking mode, as in :func:check_id.

'pattern'
species str | None

Optional species context.

None
version str | None

Optional version context. In cache mode it defaults to the latest installed snapshot.

None
refresh bool

In remote checks, skip any cached response and refetch.

False
on_error str

How a per-id remote failure is handled, as in :func:check_id. Pass "indeterminate" so an unreachable id lands in the report as indeterminate instead of failing the whole column.

'raise'

Returns:

Name Type Description
A Report

class:Report. Use .to_frame() for a data frame of verdicts,

Report

.repair() to substitute the fixable values, .summary for counts,

Report

or .results for the raw list.

biobouncer.Report

The outcome of checking a whole column, ready to inspect or repair.

Attributes:

Name Type Description
results

One :class:Result per input, in order. Always available, with no data-frame dependency.

source_db

The source the column was checked against.

how

The checking mode used.

summary property

summary: dict

Counts: total, valid, invalid, repairable, missing, indeterminate.

to_frame

to_frame(backend=None)

Return a native data frame of the per-row verdicts.

The frame has the columns input, valid, normalized, suggestion, and error (the reason a remote check was left indeterminate, else null). It comes back on the same backend as the column passed to report (pandas, polars, or pyarrow); a report built from a plain list defaults to pandas. Pass backend to force one. Requires narwhals.

repair

repair()

Return the column with every fixable value substituted.

An invalid value that has a suggestion is replaced by that suggestion. Valid values, invalid values with no suggestion, and missing values are left as they were, so the result is the same length and order as the input. A report built from a native series returns a native series on the same backend; one built from a list returns a list.

Generating test data

synthesize builds a labeled "messy column" of ids for a source (valid, repairable, invalid, and missing), useful for exercising a validation pipeline or report without hand-writing test data.

biobouncer.synthesize

synthesize(
    source_db: str,
    how: str = "pattern",
    version: str | None = None,
    n_valid: int = 2,
    n_repairable: int = 1,
    n_invalid: int = 1,
    missing: int = 1,
    seed: int = 0,
) -> list[dict]

Build a synthetic, labeled column of ids for one source.

Parameters:

Name Type Description Default
source_db str

Source key, for example "mondo". See sources().

required
how str

Checking mode to label against. "pattern" (the shape, any source) or "cache" (the snapshot; the source must ship one).

'pattern'
version str | None

In cache mode, the snapshot version. Defaults to "sample".

None
n_valid int

How many well-formed / in-snapshot ids to include.

2
n_repairable int

How many repairable ids (a wrong-case or unpadded form that suggests a valid id, or in cache mode a retired id that maps to a successor). Sources with no such form yield none.

1
n_invalid int

How many hard-invalid ids.

1
missing int

How many missing cells (None).

1
seed int

Shifts the numeric variants, for a different but still deterministic column (pattern mode).

0

Returns:

Type Description
list[dict]

A list of row dicts, woven so the categories are interleaved. Each row has

list[dict]

input, category ("valid", "repairable", "invalid", or

list[dict]

"missing"), and the valid, normalized, and suggestion the

list[dict]

checker returned for that input. Categories a source cannot produce are

list[dict]

simply absent.

Sources

biobouncer.sources

sources() -> list[str]

Return the sorted list of available source keys.

Snapshots and cache

biobouncer.pull

pull(
    source_db: str,
    version: str | None = None,
    quiet: bool = False,
    timeout: int = 120,
) -> Path

Download a full snapshot for cache mode into the cache directory.

Dispatches on the source's cache.builder: obo fetches the ontology release, hgnc_tsv fetches the HGNC complete set. Identifiers that match the source pattern are written to cache_dir()/<source>/<version>.txt, and a retired-id map, when the builder produces one, to the matching <version>.retired.tsv sidecar. An OBO version defaults to the ontology's own data-version; an HGNC version defaults to the source's default_version.

biobouncer.snapshots

snapshots() -> list[dict]

List installed snapshots, both cached and bundled.

biobouncer.cache_dir

cache_dir() -> Path

Directory where downloaded snapshots are stored.

Set the BIOBOUNCER_CACHE_DIR environment variable to override the default.

Errors

Extrinsic modes raise rather than returning a silent False.

biobouncer.RemoteError

Bases: RuntimeError

Raised when a remote check fails to get a definite answer.

biobouncer.NoResolverError

Bases: ValueError

Raised when a source has no remote resolver.

biobouncer.MissingSnapshotError

Bases: FileNotFoundError

Raised when no snapshot is installed for a (source, version).

biobouncer.MissingVersionError

Bases: ValueError

Raised when cache mode is used without a version.

biobouncer.NoBuilderError

Bases: ValueError

Raised when a source has no snapshot builder.

biobouncer.MissingDependencyError

Bases: ImportError

An optional dependency for an adapter or the report is not installed.

It subclasses ImportError so existing except ImportError handlers still catch it, and it renders the exact pip install to run, naming the missing module and the extra that provides it.

Framework adapters

The pandera and pydantic adapters install with pip install "biobouncer[adapters]"; the narwhals adapter with pip install "biobouncer[narwhals]".

biobouncer.checks.is_id

is_id(
    source_db: str,
    how: str = "pattern",
    species=None,
    version=None,
    **kwargs,
)

Return a pandera Check that validates a column of identifiers.

Use it as a column check in a schema::

schema = pa.DataFrameSchema({"term": pa.Column(str, is_id("mondo"))})

The check is vectorized: it hands the whole column to :func:biobouncer.is_valid_id and flags each value that is not valid for source_db. Any extra keyword arguments are passed through to pandera.Check (for example name or raise_warning).

biobouncer.types.Id

Id(
    source_db: str,
    how: str = "pattern",
    species=None,
    version=None,
)

Return a pydantic string type that validates a biological identifier.

Use the returned type as a field annotation, most readably through an alias::

MondoId = Id("mondo")


class Row(BaseModel):
    term: MondoId

A value that is not valid for source_db raises a pydantic ValidationError.

biobouncer.narwhals.valid_id_mask

valid_id_mask(
    column,
    source_db,
    how="pattern",
    species=None,
    version=None,
)

Return a boolean mask over a column: False marks an invalid id.

column is a native series from any narwhals-supported backend (pandas, polars, or pyarrow); the result is a native boolean series of the same backend. A value is False only when it is a malformed or non-existent identifier. A missing cell is True, because a missing value is not a failed identifier (mirroring how the pandera adapter leaves null cells to column nullability). So ~mask selects the rows that fail an id check, and mask.all() is true when nothing fails.

biobouncer.gx.ExpectColumnValuesToBeValidId

Bases: ColumnMapExpectation

Expect each value in a column to be a valid identifier for a source.

Configure it with source_db (the source key, for example "mondo") and how (the checking mode: "pattern" and "cache" are offline while "remote" checks live existence), plus an optional species for species-aware sources and the usual Great Expectations mostly tolerance, a fraction in [0, 1].