Skip to content

Quick start

Installing

What you get Command
Core + clinical text (loaders, de-id, chunking, pipelines) pip install "openbtk[text]"
Everything pip install "openbtk[text,ehr,retrieval,llms,langchain]"
Core only (registry, config, provenance — no modality) pip install openbtk
Latest main from source pip install "openbtk[text] @ git+https://github.com/openbtk/openbtk-core.git"

Optional extras: text, ehr, retrieval, llms, langchain, langgraph. A component that needs one says which, by name, when you construct it.

The optional NER recognizer additionally needs a downloaded spaCy model:

python -m spacy download en_core_web_sm

A real pipeline

This example is extracted from the project README and executed in CI on every change (tests/unit/test_readme.py), so it cannot silently go stale.

import contextlib
import io
import tempfile
from pathlib import Path

from openbtk.data import clinical_text  # noqa: F401 -- registers loaders/preprocessors/chunkers
from openbtk.pipelines import Pipeline, Step

with tempfile.TemporaryDirectory() as notes_dir:
    (Path(notes_dir) / "note1.txt").write_text(
        "Chief Complaint:\n"
        "Patient SSN: 123-45-6789 reports chest pain.\n"
        "Plan:\n"
        "Admit for observation.\n"
    )

    pipeline = (
        Pipeline("clinical-rag")
        .add(Step("load", "loader.clinical_text.plain_text", path=notes_dir))
        .add(Step("deid", "preprocessor.general.deidentify", mode="surrogate"))
        .add(Step("segment", "preprocessor.clinical_text.section_segment"))
        .add(Step("chunk", "chunker.clinical_text.section_aware", max_tokens=200))
    )
    with contextlib.redirect_stdout(io.StringIO()):  # structured JSON logs, not errors
        manifest = pipeline.run()

assert manifest.status == "success"
for step in manifest.steps:
    print(f"{step.step_id}: {step.records_out} record(s)")
# load: 1 record(s)
# deid: 1 record(s)
# segment: 1 record(s)
# chunk: 2 record(s)

Every submodule you use (here, openbtk.data.clinical_text) must be imported explicitly — import openbtk alone stays deliberately light (no modality module, no heavy dependency, under 500 ms) so pip install openbtk with zero extras still works.

Inspecting the run

pipeline.run() returns a RunManifest — never the processed records themselves. It carries per-step throughput, component identity, and (when a guardrail is attached) aggregated pass/warn/block counts, all with no document content anywhere in it:

print(manifest.status)  # "success" or "failed"
print(manifest.run_id)  # a fresh id per run
for step in manifest.steps:
    print(step.step_id, step.component.class_name, step.records_out)

See the API reference for the full shape of RunManifest, StepProvenance, and the Pipeline/Step builder.