Appearance
Python API
python
import microscope
from microscope import Slide
slide = microscope.open('case.svs', project='default')Slide is a context manager; call close() otherwise. The image decoder is lazy for existing workspaces. A new WSI needs imaging to discover dimensions; dependency-free callers can supply known width/height explicitly. Opening does not save anything.
| API | Result / behavior |
|---|---|
dimensions | (width,height) in level-0 pixels |
mpp | Actual (mpp_x,mpp_y), possibly None per axis |
levels, inspect() | Primary pyramid/slide metadata, layer catalog, revisions |
read_region(region, size=None, target_mpp=None, level=None) | Opaque RGB PIL image with transform metadata |
render(region=None, layers=None, annotations=True, size=None, target_mpp=None, output=None) | Static RGB composite; optional explicit image export |
save() | Explicit annotation/manifest commit, then loaded overlay-stack commit |
layers | The persisted read-only generated layer collection |
annotations | The editable ROI API |
rois, classes, workspace | Existing lower-level editable lists/workspace |
size and target_mpp are mutually exclusive. layers=None renders visible generated layers; layers=[] renders none. Explicit names/IDs select those layers, including hidden ones, in persisted stack order. Ambiguous duplicate names require IDs. Annotations render above generated layers unless disabled. render returns the image whether or not output is specified.
Generated layer collection
python
slide.layers.add_points(rows_or_array, name='detections')
slide.layers.add_polygons(polygons, scores=None, name='boundaries')
slide.layers.add_geojson(feature_collection, name='geometry')
slide.layers.add_mask(mask, shape=None, bounds=None, labels=False, name='mask')
slide.layers.add_probability(values, shape=None, bounds=None, name='probability')Creation returns a layer descriptor with its id. Point NumPy arrays are converted to float32; mask creation accepts integer/bool NumPy arrays and refuses label identity loss. Probability arrays use float32. Flat masks/probabilities require shape=(height,width); values must match it exactly.
resolve(name_or_id), describe(...), update(..., settings=..., position=..., expected_revision=...), remove(id), read_array(id), read_geometry(name_or_id), array_path(id), import_file(path, kind=..., name=..., bounds=...), query(...), and save(expected_revision=...) provide inspection, mutation, and persistence. Removal changes membership and keeps saved assets. Source arrays are immutable/content-addressed: create a new layer to replace scientific data. array_path also returns the local MPOLY/GeoJSON asset path for geometry sources; it does not imply all assets are NPY.
Appearance settings: visible, opacity, palette, color, lineWidth, radius, binSize, threshold, valueMax, and a compatible renderer. position is the zero-based bottom-to-top stack position. Invalid updates leave the original in-memory document intact.
read_array returns (shape,array('f')). read_geometry returns a GeoJSON collection or packed arrays (polygon_offsets, ring_offsets, positions, scores, shape). Optional NumPy can read saved NPY files with allow_pickle=False; use memory mapping in external analysis as appropriate. Library/browser validation still checks full files before use/save.
Editable annotations
python
roi = slide.annotations.add_polygon(
[outer_ring, hole_ring], name='Tumor ROI', class_id='unclassified',
metadata={'reviewed': True}, style={'fillOpacity': .2},
)
slide.annotations.save()annotations.query(region=None, offset=0, limit=100, max_vertices=10000) returns a bounded page plus classes/revision. annotations.update(upsert=[features], remove=[ids], classes=None, expected_revision=None) performs a validated in-memory batch; save(expected_revision=...) commits it. classes, if supplied, replaces the class list and must leave all ROI class references valid. Read revisions before cross-call writes. Generated geometry is added to annotations only when the caller explicitly requests that representation.
Revisions and files
Annotation and layer revisions are SHA-256 tokens of exact committed index text (or a stable missing-file sentinel). A stale expected token raises ConflictError; existing checks also detect disk changes after opening. They are optimistic checks, not process locks or compare-and-swap. Use one writer per slide/project. Slide.save() is not a transaction across independent files. Backups retain one previous valid document; orphan assets may remain after a failed commit.
Queries use bounding-box intersection, not geometric intersection tests. Pagination offsets refer to the filtered result. Limits are 1–1000 items, at most 100k returned vertices, and ~512 KiB per page. A single geometry exceeding the page budget is refused, never silently simplified or dropped; access the local artifact for bulk work.
The legacy dependency-free open_slide, standalone annotation IO, project APIs, and restricted NPY helpers remain exported for existing users. The microscope_io namespace is a compatibility alias; use microscope for new applications.