Slide Ingestion Flow
- Date: 2026-04-07
- Status: Active
- Author: Kyle McMaster - NimblePros
Overview
See also: slide-ingestion-overview
The overview diagram shows the end-to-end slide pipeline at a high level: a tenant-specific ingestion client detects incoming slide files, hands them to the slide worker through messaging, and then the converted DZI output is served back through the tenant web app and viewer.
Development Flow
Slide Ingestion Client
The slide ingestion flow is tenant-specific in Aspire. In src/HyperPath.AppHost/AppHost.cs, each tenant with EnableSlideWorkflow = true gets:
- a tenant
HyperPath.Webapp - a tenant
HyperPath.SlideWorker - a tenant
HyperPath.SlideIngestion.Client
For local development, the slide ingestion client is started with per-tenant folders such as:
WATCH_FOLDER=./data/{institutionId}/inputUPLOAD_FOLDER=./data/{institutionId}/outputTRACKING_PATH=./data/{institutionId}/tracking.dbHyperPath__InstitutionId={institutionId}
The ingestion client watches the tenant input folder for .svs files. When a file arrives, FileWatcher validates and processes it, generates the tenant key or prefix, and calls the configured uploader.
In local development, Configuration.MakePathsAbsolute() overrides the upload location to the OS temp directory:
%TEMP%/hyperpath/tenant-{institutionId}-slide-uploadon Windows/tmp/hyperpath/tenant-{institutionId}-slide-uploadon Linux and macOS
The local uploader then:
- Copies the
.svsfile into the tenant upload area. - Starts a send-only NServiceBus endpoint.
- Sends
SlideUploadedEventto the tenant slide worker endpoint.
For S3 uploads, an S3 event message is routed to an SQS queue that the slide worker listens to in S3NotificationPollingService, where it is translated into SlideUploadedEvent.
Slide Worker
Inside HyperPath.SlideWorker, SlideUploadedEventHandler:
- Receives
SlideUploadedEvent. - Creates a
Sliderow in the tenant database. - Sends
SlideCreatedEvent.
Then SlideCreatedEventHandler:
- Loads the
Slidefrom the tenant database. - Marks it as converting.
- Calls
VipsSlideConverter.ConvertToDeepZoomAsync().
VipsSlideConverter uses ISlideStorage, so behavior differs by environment:
- In development,
LocalSlideStoragecopies the source.svslocally, converts it with libvips, and writes the DZI output back under the temphyperpathdirectory. - Outside development,
S3SlideStoragedownloads from S3, converts the source, and uploads.dziplus tile output to the workspace bucket.
The conversion output is:
- one
.dzidescriptor file - one
{slideName}_files/tile directory
When conversion and upload complete, the worker marks the slide as complete.
Viewing the Slide in the Tenant App
Open the tenant HyperPath.Web instance and navigate to the Slides tab. The list of slides is populated from tenant database metadata, including the generated DZI URL.
The viewer page at /viewer/{slideId} calls GET /api/slides/{slideId} to load metadata and the DZI URL, then OpenSeadragon loads the tile pyramid.