Skip to content

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.Web app
  • 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}/input
  • UPLOAD_FOLDER=./data/{institutionId}/output
  • TRACKING_PATH=./data/{institutionId}/tracking.db
  • HyperPath__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-upload on Windows
  • /tmp/hyperpath/tenant-{institutionId}-slide-upload on Linux and macOS

The local uploader then:

  1. Copies the .svs file into the tenant upload area.
  2. Starts a send-only NServiceBus endpoint.
  3. Sends SlideUploadedEvent to 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:

  1. Receives SlideUploadedEvent.
  2. Creates a Slide row in the tenant database.
  3. Sends SlideCreatedEvent.

Then SlideCreatedEventHandler:

  1. Loads the Slide from the tenant database.
  2. Marks it as converting.
  3. Calls VipsSlideConverter.ConvertToDeepZoomAsync().

VipsSlideConverter uses ISlideStorage, so behavior differs by environment:

  • In development, LocalSlideStorage copies the source .svs locally, converts it with libvips, and writes the DZI output back under the temp hyperpath directory.
  • Outside development, S3SlideStorage downloads from S3, converts the source, and uploads .dzi plus tile output to the workspace bucket.

The conversion output is:

  • one .dzi descriptor 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.

Related Documents