Python API¶
The entire public surface is importable directly from the top-level package:
from cp_anndata_validator import (
validate, # the one function that runs everything
Report, # what validate() returns
Issue, # a single structured finding
Severity, # error | warning | information
Category, # e.g. identifiers, matrix, provenance, ...
ProfileLevel, # single-cell | well | treatment
LoadError, # raised if the dataset can't be opened
SchemaError, # raised if the schema can't be loaded
)
validate()¶
def validate(
path: str | Path,
*,
schema: str | Path = "generic-cell-painting",
profile_level: ProfileLevel | str | None = None,
backed: bool | None = None,
sample_rows: int = 5000,
strict: bool = False,
) -> Report: ...
from cp_anndata_validator import ProfileLevel, validate
report = validate(
"experiment.h5ad",
schema="jump-cp",
profile_level=ProfileLevel.WELL,
)
# Equivalent — plain strings are coerced to ProfileLevel before checks run:
report = validate("experiment.h5ad", profile_level="well")
print(report.status) # "pass" or "fail"
print(report.counts.by_severity) # {Severity.ERROR: 2, Severity.WARNING: 1}
for issue in report.issues:
print(issue.code, issue.severity, issue.location, issue.message)
profile_level accepts either a ProfileLevel member or its string value
("single-cell", "well", "treatment"); a string is coerced to the enum
before any check runs. Warnings alone do not fail a normal run; pass
strict=True to treat warnings (including AGG001) as failures.
Raises ValueError if profile_level is not one of those values,
cp_anndata_validator.LoadError if the file can't be safely opened, and
cp_anndata_validator.SchemaError if the requested schema can't be
loaded — all before any checks run.
Rendering a report¶
Renderers are pure functions, independent of validation logic — you can
call them on any Report, including ones you constructed yourself (for
example in a test):
from cp_anndata_validator.reporting import render_console, render_html, render_json
print(render_console(report))
Path("report.json").write_text(render_json(report))
Path("report.html").write_text(render_html(report))
Working with Issue and Report¶
Both are frozen Pydantic models (model_config = ConfigDict(frozen=True, extra="forbid")),
so they serialize/deserialize losslessly:
payload = report.model_dump_json()
restored = Report.model_validate_json(payload)
assert restored == report
See Rule catalogue for the full field list on Issue, and
src/cp_anndata_validator/models/report.py for Report's complete shape
(profile_level, counts, checks, input_file, etc.).
Advanced: running the check registry directly¶
Most users only need validate(). If you need lower-level access (for
example, to run a custom subset of checks), the building blocks are all
independently importable:
from cp_anndata_validator.loading import load_anndata
from cp_anndata_validator.schema.loader import load_schema
from cp_anndata_validator.schema.resolve import resolve_schema
from cp_anndata_validator.profiles import detect_profile_level
from cp_anndata_validator.checks.registry import CheckContext
from cp_anndata_validator.orchestrator import run_checks, build_report
import cp_anndata_validator.checks # registers all built-in checks
handle = load_anndata("experiment.h5ad")
schema = load_schema("generic-cell-painting")
resolved = resolve_schema(handle.adata.obs, handle.adata.var, schema)
profile = detect_profile_level(handle.adata.obs, resolved)
ctx = CheckContext(handle=handle, resolved_schema=resolved, profile=profile)
issues, checks = run_checks(ctx)
See Contributing for how to register a new check.
API reference¶
validate
¶
validate(
path: str | Path,
*,
schema: str | Path = "generic-cell-painting",
profile_level: ProfileLevel | str | None = None,
backed: bool | None = None,
sample_rows: int = DEFAULT_SAMPLE_ROWS,
strict: bool = False,
) -> Report
Validate one AnnData dataset and return a structured :class:Report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to an |
required |
schema
|
str | Path
|
A built-in schema name (for example |
'generic-cell-painting'
|
profile_level
|
ProfileLevel | str | None
|
Declare the profile level explicitly, overriding
auto-detection (the report still records what was detected).
Accepts a :class: |
None
|
backed
|
bool | None
|
Force backed ( |
None
|
sample_rows
|
int
|
Maximum number of rows sampled for numeric validity and AI-readiness checks. |
DEFAULT_SAMPLE_ROWS
|
strict
|
bool
|
Treat warnings as failures when computing the report status. |
False
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
LoadError
|
If the dataset cannot be safely opened. |
SchemaError
|
If the requested schema cannot be loaded. |
Source code in src/cp_anndata_validator/api.py
Report
¶
Bases: BaseModel
The complete, structured result of validating one AnnData dataset.
Issue
¶
Bases: BaseModel
A single, structured validation finding.
code is a stable rule code (for example "IDENT003") that must
never be renumbered or reused once shipped. location should point at
an AnnData path such as "obs.plate_id", "var.index" or
"uns.provenance".
Severity
¶
Bases: StrEnum
How serious a validation issue is.
Category
¶
Bases: StrEnum
The validation category an issue (or check) belongs to.
ProfileLevel
¶
Bases: StrEnum
The granularity at which observations in an AnnData object are profiled.
LoadError
¶
Bases: Exception
Raised when an AnnData file cannot be opened safely for validation.
SchemaError
¶
Bases: Exception
Raised when a schema (built-in or custom) cannot be loaded or is invalid.