spacr.report

Workflow inputs and outputs

Report

Package recorded results, settings and QC into a shareable report without silently rerunning the analysis.

Open: the application’s Help/tools menus.

Inputs and outputs below include conditional alternatives. The guidance and handoff notes say which route applies.

Inputs

  • Run history and artifacts — Project run records, settings, output paths, artifact provenance, status and logs.

  • Quality-control results — Stored project checks and QC reports; a missing check is not a passing result.

  • Figures and table exports — The output location chosen by the tool; exports describe the selected data and filters.

Outputs

  • Shareable reports — Exported HTML/PDF or methods/results documents derived from recorded analysis outputs.

API reference.

Module tutorial.

One-click, shareable report for a finished spaCR run.

Why this exists

A spaCR run leaves behind a plate folder: a SQLite database, a qc folder, a results tree of PDFs and CSVs, a settings folder, and — somewhere in ~/.spacr/runs — a journal entry recording the exact settings and package versions that produced all of it. Every piece of that is legible to somebody with spaCR installed and a terminal. None of it is legible to the collaborator who asks “so did it work?”.

This module walks that folder, gathers what is actually there, and writes a single self-contained HTML file (and, optionally, a PDF) that answers the question without spaCR, without Python and without the original machine.

Three rules govern what it does, because a report that breaks any of them is worse than no report:

A missing section is stated, never omitted.

If segmentation QC was never run, the report contains a “Segmentation QC” heading that says not run. A reader cannot distinguish “clean” from “never checked” if unchecked things silently vanish, and that is exactly how a partial run gets forwarded as though it were complete.

Failure goes at the top.

spacr.errors stamps every artifact with a run_status recording how many items failed. If anything failed — or if nothing was stamped at all, so completeness is unknown — that is the first thing in the document, not an appendix entry.

Nothing is recomputed.

Every number here was produced by the pipeline and read back off disk. The one exception is deliberate and narrow: the segmentation scorecard CSV is re-fed to spacr.seg_qc.summarize_qc(), the same function that printed the verdict at run time, so the plate verdict in the report is the verdict spaCR gave — not a second opinion. No p-value, no effect size and no aggregate statistic is invented by this module. Where a check exists but has to be run on demand (plate edge effects, inter-annotator κ), the report says so and names the tool.

What it reads

source

section

spacr.errors run-status stamps

Run status (stamps on *.db and *.run_status.json sidecars)

~/.spacr/runs journal

Provenance + versions

<src>/qc/segmentation_qc_*

Segmentation QC

<src>/qc/ layout exports

Plate QC / edge effects

<src>/results, <src>/figure

Key figures

<src>/results/**/*.csv

Statistics

<src>/settings/*.csv, journal

Settings

<src>/measurements/*.db

Appendix (feature dictionary, annotations)

Usage:

from spacr.report import build_report
build_report('/data/plate1', '/tmp/plate1_report.html')
build_report('/data/plate1', '/tmp/reports', fmt='both')

Or from the GUI: Tools → Report.

Output formats

The HTML is the real deliverable: one file, no external requests, images base64-embedded, CSS in a <style> block, no JavaScript at all. It opens from a USB stick on a machine with no network.

The PDF is composed with matplotlib.backends.backend_pdf.PdfPages — a monospace transcription of the same content plus one page per embedded figure. spaCR has no HTML-to-PDF engine among its dependencies and this module refuses to add one, so the PDF is a faithful summary, not a rendering of the HTML. Send the HTML when you can.

Classes

Figure

One figure found under src.

Report

Everything collect_report() gathered.

Section

One chapter of the report.

Table

A rectangle of already-stringified cells.

Functions

build_report(→ List[pathlib.Path])

Collect and write a report for src in one call.

collect_report(→ Report)

Gather everything reportable about the run folder src.

pdf_page_count(→ int)

How many pages write_pdf() will produce for report.

render_html(→ str)

Render report as a single self-contained HTML document.

render_text(→ str)

Render report as plain text.

write_html(→ pathlib.Path)

Write report as a single self-contained HTML file.

write_pdf(→ pathlib.Path)

Write report as a PDF composed with matplotlib.

Module Contents

class spacr.report.Figure[source]

One figure found under src.

Parameters:
  • path – location of the discovered figure on disk.

  • title – caption displayed with the figure.

  • mime – MIME type used for embedded data.

  • data – embedded image bytes, or None when the figure was only listed.

  • reason – explanation for why a discovered figure was not embedded.

  • n_bytes – size of the source file on disk.

data_uri() → str[source]

Return the data: URI for data.

Raises:

ValueError – when the figure was not embedded.

property embedded: bool[source]

True when the bytes are in the report.

class spacr.report.Report[source]

Everything collect_report() gathered.

Parameters:
  • src – resolved run or plate directory described by the report; an unresolvable input path is retained so its failure can be reported.

  • title – document title shown by the HTML, text, and PDF renderers.

  • generated_utc – timezone-aware ISO timestamp recording when collection completed, or "" on a manually constructed report.

  • sections – report chapters in reading order: the core SECTION_KEYS sections followed or interleaved with registered plugin contributions.

  • status – overall collection verdict: "complete", "partial", "failed", "unknown", or "empty".

  • status_detail – human-readable sentence expanding the overall status.

  • spacr_version – version of spaCR running report collection, or "unknown" when it cannot be read.

  • n_figures_found – number of raster and vector figures discovered during the bounded artifact scan.

  • n_figures_embedded – number of raster figures whose bytes were retained for embedding in rendered output.

section(key: str) → Section | None[source]

Return the section with key, or None.

Parameters:

key – stable report-section key to locate.

property found_sections: List[str][source]

Keys of sections that have something to show.

property has_failures: bool[source]

True when something in this run is known to have failed.

property missing_sections: List[str][source]

Keys of sections whose evidence was not found.

class spacr.report.Section[source]

One chapter of the report.

A section is always present, even when its evidence is not: a section whose status is STATUS_MISSING renders with its heading and a sentence explaining what was looked for and not found.

Parameters:
  • title – section heading shown in rendered reports.

  • body_html – ready-to-render HTML fragment; callers must escape dynamic values before supplying it.

  • figures – figures embedded in or listed by this section.

  • table – primary tabular result, or None when the section has no table.

  • notes – caveats rendered as a bullet list beneath the section body.

  • key – stable section identifier; built-in sections use SECTION_KEYS, while plugins use their registered contribution key.

  • status – STATUS_OK, STATUS_MISSING, or STATUS_PROBLEM.

  • text_lines – plain-text rendering used by text and PDF output without reparsing body_html.

property found: bool[source]

True when the section’s evidence exists on disk.

class spacr.report.Table[source]

A rectangle of already-stringified cells.

Parameters:
  • columns – header cells, already converted to display strings.

  • rows – displayed body rows, already converted to strings and truncated to what will be shown.

  • caption – optional line rendered above the table.

  • n_total_rows – original source-row count; zero defaults to the number of retained rows during initialization.

__post_init__() → None[source]

Default the source-row count to the number of retained rows.

Returns:

None.

property n_omitted: int[source]

Rows the source had that are not shown.

spacr.report.build_report(src: Any, out: Any, fmt: str = 'html', **kwargs: Any) → List[pathlib.Path][source]

Collect and write a report for src in one call.

Parameters:
  • src – the plate / run folder to report on.

  • out – destination. A path ending in .html or .pdf names the file; anything else is treated as a folder and the files are named after src and the current time.

  • fmt – "html", "pdf" or "both".

  • kwargs – forwarded to collect_report().

Returns:

the paths written, in the order html, pdf.

Raises:

ValueError – for an unknown fmt.

Example

from spacr.report import build_report
paths = build_report('/data/plate1', '/tmp/reports', fmt='both')
spacr.report.collect_report(src: Any, *, title: str | None = None, max_figures: int = DEFAULT_MAX_FIGURES, max_figure_px: int = DEFAULT_MAX_FIGURE_PX, max_table_rows: int = DEFAULT_MAX_TABLE_ROWS, run_dirs: Sequence[Any] | None = None, search_journal: bool = True, journal_limit: int = DEFAULT_JOURNAL_LIMIT, include_plan: bool = True) → Report[source]

Gather everything reportable about the run folder src.

Headless and read-only: nothing is written, no pipeline is invoked, no statistic is computed. A folder that does not exist, or holds no spaCR output at all, yields a valid Report that says so — this function does not raise for missing input.

Parameters:
  • src – the plate / run folder.

  • title – document title. Defaults to "spaCR report — <folder>".

  • max_figures – raster figures embedded before the rest are only listed. See DEFAULT_MAX_FIGURES.

  • max_figure_px – longest edge a figure is downscaled to.

  • max_table_rows – rows previewed from any one table.

  • run_dirs – explicit run-journal folders to use instead of searching. Every one given is used, whether or not its src setting matches — callers that pass this know which runs they mean.

  • search_journal – when run_dirs is None, scan ~/.spacr/runs for runs whose src is this folder.

  • journal_limit – how many recent journal entries to consider.

  • include_plan – render spacr.validate.describe_plan() into the settings section.

Returns:

a Report holding one section per SECTION_KEYS, plus any section contributed by a plugin, each inserted after the existing section it names — core, or one an earlier plugin added — or appended when that key is absent.

Example

from spacr.report import collect_report, write_html
report = collect_report('/data/plate1')
print(report.status, report.missing_sections)
write_html(report, '/tmp/plate1.html')
spacr.report.pdf_page_count(report: Report) → int[source]

How many pages write_pdf() will produce for report.

Parameters:

report – a Report.

Returns:

the page count.

spacr.report.render_html(report: Report) → str[source]

Render report as a single self-contained HTML document.

The output has no external dependencies of any kind: the stylesheet is inline, every image is a base64 data: URI, and there is no JavaScript. It renders identically on a machine that has never heard of spaCR and has no network.

Parameters:

report – a Report from collect_report().

Returns:

the complete HTML document as a string.

spacr.report.render_text(report: Report) → str[source]

Render report as plain text.

This is what the PDF transcribes, and what the GUI shows as a preview.

Parameters:

report – a Report.

Returns:

a multi-line string.

spacr.report.write_html(report: Report, path: Any) → pathlib.Path[source]

Write report as a single self-contained HTML file.

Parameters:
  • report – a Report.

  • path – destination file. Parent directories are created.

Returns:

the path written.

spacr.report.write_pdf(report: Report, path: Any) → pathlib.Path[source]

Write report as a PDF composed with matplotlib.

spaCR depends on matplotlib and on nothing that converts HTML to PDF, and this module will not add such a dependency for one feature. The PDF is therefore a monospace transcription of the same content — the same sections, the same tables, the same “not run” statements — plus one page per embedded figure. Compared with the HTML it loses colour emphasis, table borders, collapsible detail blocks and clickable contents, and long cells are truncated to the page width. Send the HTML when the recipient can open one.

Parameters:
  • report – a Report.

  • path – destination file. Parent directories are created.

Returns:

the path written.

Nested helpers

_zenodo_opener._NoRedirect.redirect_request(self, req, fp, code, msg, headers, newurl)

Return None: the redirect is not followed.

spacr/report.py:4013