Eager, process-isolated reader for SlideBook .sld microscopy files via Bio-Formats, with metadata and optional napari support
Project description
sldread
Read SlideBook .sld microscopy containers in Python via Bio-Formats, with the
vendor SlideBook reader jar added to the JVM classpath.
A .sld file is a proprietary container holding multiple images (captures /
scenes). sldread reads a chosen scene eagerly into a NumPy array
(C, Z, Y, X) together with basic metadata (scene/channel names, physical pixel
sizes), and can hand a scene to napari.
Runtime dependencies are minimal: numpy + scyjava only. scyjava pulls
in JPype, provisions a JVM (via cjdk) on first use, and fetches Bio-Formats
from Maven. napari is an optional extra.
Why does this repo exist? (and when it should disappear)
This is not meant to be yet another microscopy reader. It exists only to work around a single, specific bug in the upstream SlideBook Bio-Formats reader:
- The native reader (
loci.formats.in.SlideBook6Reader) keeps a single, process-global file session. It is not re-entrant and not safe across the open/close/reopen and threading patterns that modern lazy I/O stacks rely on. - Because of this, bioio /
bioio-bioformatscannot read SlideBook pixels reliably: their lazy/dask path opens short-lived helper readers and suspends/reopens the file, which trips the global session (AssertionError: File already open./File not open.). It is fundamentally a threading / multiple-open problem, not something a wrapper can configure away. - The only reliable pattern is one uninterrupted
setId() → openBytes() → close()session per process.sldreaddoes exactly that, eagerly, in an isolated subprocess — nothing more.
So sldread is deliberately tiny and single-purpose. If the upstream issue is
fixed — i.e. a future SlideBook reader build gives each reader an independent
native session so that reopen-after-close and concurrent/threaded readers work —
then this package becomes pointless and bioio should be used directly instead.
At that point this repository will be archived and forgotten. Please prefer the
upstream tools the moment they work. (The bug has been reported to the vendor, 3i.)
Read this first. SlideBook's native reader has a hard constraint that shapes the whole design — see Limitations. In short: a
.sldfile can only be read reliably in one uninterrupted reader session per process, so lazy/dask access does not work.sldreadreads eagerly and isolates each read in its own subprocess.
Install
pip install sldread
# with napari support:
pip install "sldread[napari]"
Or with uv for development:
uv sync
Requires Python ≥ 3.10 (the floor set by scyjava).
The SlideBook reader jar (proprietary — not bundled)
The SlideBook6Reader.jar is proprietary and is NOT redistributed with this
package. You must obtain it yourself, subject to the vendor's (3i / SlideBook)
terms. sldread locates it, in order, from:
- the
jar_path=argument (or--jaron the CLI), - the
SLIDEBOOK_READER_JARenvironment variable, ./jars/SlideBook6Reader.jar(relative to the working directory).
A convenience downloader is provided (standard-library only, no extra deps), which fetches the pinned build from the SlideBook ImageJ update site:
sld-read download-jar # -> ./jars/SlideBook6Reader.jar
sld-read download-jar /some/dir # custom destination
Downloading the jar is your responsibility and governed by the vendor's licensing terms; this convenience command does not grant any rights to it.
The verified build is SlideBook6Reader.jar-20250730183505 from
https://sites.imagej.net/SlideBook/jars/bio-formats/.
Usage
Library
from sldread import list_sld_scenes, read_sld_scene, sld_scene_to_napari
list_sld_scenes("file.sld") # -> ['undiff_WT_...', ...]
data, meta = read_sld_scene("file.sld", scene=0)
# data: numpy array, axis order (C, Z, Y, X)
# meta: scene_name, n_scenes, all_scene_names, channel_names,
# physical_pixel_sizes {z, y, x in µm}, scale_zyx, shape, dtype,
# dims_order, n_timepoints, timepoint
# napari (each channel becomes a layer, with physical scale on Z, Y, X):
import napari
img, kwargs, _ = sld_scene_to_napari("file.sld", scene=0)[0]
napari.view_image(img, **kwargs)
Public API:
read_sld_scene(path, scene=0, *, t=0, jar_path=None) -> (ndarray (C,Z,Y,X), dict)
list_sld_scenes(path, *, jar_path=None) -> list[str]
sld_scene_to_napari(path, scene=0, *, t=0, jar_path=None) -> napari LayerData list
napari_get_reader(path) -> reader callable or None
If sldread[napari] is installed, the .sld reader is also registered as a
napari plugin (via a napari manifest), so files open through napari's
File → Open.
A ready-to-run demo lives in examples/view_scene_napari.py:
uv run --extra napari python examples/view_scene_napari.py path/to/file.sld 5
Command line
sld-read list "file.sld" # list scenes
sld-read read "file.sld" 0 # read scene 0, print a summary
sld-read read "file.sld" 0 --view # open scene 0 in napari (needs the napari extra)
sld-read download-jar # fetch the reader jar into ./jars
The jar is found via --jar, SLIDEBOOK_READER_JAR, or ./jars/.
Limitations (and what NOT to implement)
These come from the SlideBook native Bio-Formats reader
(loci.formats.in.SlideBook6Reader), not from this code:
- One open per process. The reader keeps a single, process-global native
file session. Opening the same file a second time in one process is unreliable
(intermittent
AssertionError: File already open.), and closing one of two readers that have the file open deterministically breaks the other (AssertionError: File not open.). The only reliable pattern is a single, uninterruptedsetId() -> openBytes()... -> close()session — which is why each read here runs in a fresh subprocess. (Reported upstream to the vendor, 3i.) - Eager only. Reads load a whole scene into memory (≈
C·Z·Y·X·bytes; e.g. ~99 MB for a 3×12×1200×1200 uint16 scene). Fine for typical scenes; not suitable for very large time-lapses in one shot. - Single timepoint by default.
read_sld_scenereadst=0; passt=for another timepoint. All Z and channels of that timepoint are read. - No RGB/interleaved planes. Expects one sample per plane (true for the
SlideBook files seen here) and raises
NotImplementedErrorotherwise, rather than returning wrong data.
Do not spend time on the following — they are blocked by the reader limitation above, not by missing effort:
- Lazy / dask-backed loading of SlideBook pixels. Any access pattern that opens the file more than once per process, or keeps a reader open and reopens it later, fails non-deterministically.
- A long-lived shared reader reused across many calls in one process.
- Using
bioio/bffilefor pixel data. Their lazy pixel path opens/closes helper readers and hits the one-open-per-process limit.
If a future SlideBook build gives each reader an independent native session, these constraints can be revisited — until then, eager + process-isolated is the correct design.
Development
uv sync
uv run pytest # API tests run anywhere; the read test is gated
uv build # build sdist + wheel into dist/
The end-to-end read test is skipped unless both SLIDEBOOK_READER_JAR and
SLDREAD_TEST_SLD (a sample .sld file) are set, so CI and other contributors
can run the suite without proprietary data.
Publishing
uv build
uv publish # uploads dist/* to PyPI
uv publish accepts a token via --token / UV_PUBLISH_TOKEN, or use PyPI
trusted publishing from CI (no
long-lived token needed).
License
MIT (this package). The SlideBook reader jar is not covered by this license and is not distributed here.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sldread-0.1.0.tar.gz.
File metadata
- Download URL: sldread-0.1.0.tar.gz
- Upload date:
- Size: 12.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa577e95aa6b0aa9759153c19cc2d25474a56d3efde265e0446036439697d6d3
|
|
| MD5 |
55020d025b5aa3a4b5d64d811f995854
|
|
| BLAKE2b-256 |
cd4cf59fc91f94623a1db9a5a928047371344dd7795d49f158d7415040f4000e
|
Provenance
The following attestation bundles were made for sldread-0.1.0.tar.gz:
Publisher:
release.yml on unige-biochem/sldread
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sldread-0.1.0.tar.gz -
Subject digest:
aa577e95aa6b0aa9759153c19cc2d25474a56d3efde265e0446036439697d6d3 - Sigstore transparency entry: 1838953595
- Sigstore integration time:
-
Permalink:
unige-biochem/sldread@03e6656f4e76ab992ec12b9e5232990fef95516a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/unige-biochem
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@03e6656f4e76ab992ec12b9e5232990fef95516a -
Trigger Event:
release
-
Statement type:
File details
Details for the file sldread-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sldread-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1c33ae1989f0953f86b9da3a7a5bb55816dfc3ba298628a8597d0e3278e8a6e
|
|
| MD5 |
8039b1a657e5c44e71efdc25971b9a38
|
|
| BLAKE2b-256 |
443abc9ac49a468eea1b9f88c26a03d6c31be7f711d2c24b5e11b1b31209ffa1
|
Provenance
The following attestation bundles were made for sldread-0.1.0-py3-none-any.whl:
Publisher:
release.yml on unige-biochem/sldread
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sldread-0.1.0-py3-none-any.whl -
Subject digest:
a1c33ae1989f0953f86b9da3a7a5bb55816dfc3ba298628a8597d0e3278e8a6e - Sigstore transparency entry: 1838953819
- Sigstore integration time:
-
Permalink:
unige-biochem/sldread@03e6656f4e76ab992ec12b9e5232990fef95516a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/unige-biochem
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@03e6656f4e76ab992ec12b9e5232990fef95516a -
Trigger Event:
release
-
Statement type: